// File: /workspace/github_cpp_makefile_star2_O3/tlaloc1313[P]chess-project/Pawn.cpp
// Function: Pawn::move(int, bool*)
bool Pawn::move(int square, bool activeArray[64]){
  // Can't move to same square
  if (square == location) {
    return 0;
  }

  // Decoding the square numbers to useable values
  int fromRow = row(location);
  int fromCol = col(location);
  int toRow = row(square);
  int toCol = col(square);

  enPassantPossible = 0; // By default, pieces cannot be taken En Passant

  // Same-column movement only, when not taking another piece
  if (fromCol == toCol && activeArray[square]==0) {

    // Pawn behaves differently by colour
    switch(isWhite) {
      case 1: // Piece is White
      if (fromRow == 1) { // Move up to two squares forward if first move for the piece
        if ((toRow-fromRow)==2){
          if (activeArray[square-1]==0) { // Checks that intermediate square is empty
            location = square;
            hasMoved = 1;
            enPassantPossible = 1;
            return 1;
            }
          }
          if ((toRow-fromRow)==1) {
            location = square;
            hasMoved = 1;
            return 1;
            }
        } else {
          if ( (toRow-fromRow)==1) {
            location = square;
            hasMoved = 1;
            return 1;
            }
          }
      break;

      case 0: // Piece is Black
      // Move up to two if first move for the piece
      if (fromRow == 6){
          if ((toRow-fromRow)==-2){
            if (activeArray[square+1]==0){ // Checks that intermediate square is empty
              location = square;
              hasMoved = 1;
              enPassantPossible = 1;
              return 1;
            }
          }
          if ((toRow-fromRow)==-1){
            location = square;
            hasMoved = 1;
            return 1;
          }
        } else {
          if ( (toRow-fromRow)==-1){
            location = square;
            hasMoved = 1;
            return 1;
          }
      }
    }
  }

// The pawn has unique behaviour only when taking another piece
  if (abs(fromCol-toCol)==1 && activeArray[square]==1) {
    if (isWhite) {
      if (toRow-fromRow==1) { // Checks for a diagonal move forwards
        location = square;
        hasMoved = 1;
        return 1;
        }
    } else {
      if (toRow-fromRow==-1) { // Checks for a diagonal move backwards
        location = square;
        hasMoved = 1;
        return 1;
        }
    }
  }

  // If all tests fail, return 0
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl 0xc(%rdi), %edi
cmpl %esi, %edi
je 0x5902
movq %rdx, %r15
movl %esi, %r14d
callq 0x3a20
movl %eax, -0x2c(%rbp)
movl 0xc(%rbx), %edi
callq 0x3a35
movl %eax, %r12d
movl %r14d, %edi
callq 0x3a20
movl %eax, %r13d
movl %r14d, %edi
callq 0x3a35
movb $0x0, 0x12(%rbx)
subl %eax, %r12d
jne 0x58ad
movslq %r14d, %rax
cmpb $0x0, (%r15,%rax)
je 0x58d8
incl %r12d
testl $0xfffffffd, %r12d      # imm = 0xFFFFFFFD
jne 0x5902
movslq %r14d, %rax
cmpb $0x1, (%r15,%rax)
jne 0x5902
subl -0x2c(%rbp), %r13d
cmpb $0x1, 0x10(%rbx)
jne 0x58fc
cmpl $0x1, %r13d
jne 0x5902
jmp 0x595d
cmpb $0x1, 0x10(%rbx)
jne 0x5913
movl -0x2c(%rbp), %ecx
cmpl $0x1, %ecx
jne 0x593f
cmpl $0x2, %r13d
je 0x595d
cmpl $0x3, %r13d
jne 0x58ad
cmpb $0x0, -0x1(%r15,%rax)
jne 0x58ad
jmp 0x5933
cmpl $-0x1, %r13d
je 0x595d
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl -0x2c(%rbp), %ecx
cmpl $0x6, %ecx
jne 0x594f
cmpl $0x5, %r13d
je 0x595d
cmpl $0x4, %r13d
jne 0x58ad
cmpb $0x0, 0x1(%r15,%rax)
jne 0x58ad
movl %r14d, 0xc(%rbx)
movw $0x101, 0x11(%rbx)      # imm = 0x101
jmp 0x5965
movl %r13d, %eax
subl %ecx, %eax
cmpl $0x1, %eax
jne 0x58ad
jmp 0x595d
movl %r13d, %eax
subl %ecx, %eax
cmpl $-0x1, %eax
jne 0x58ad
movl %r14d, 0xc(%rbx)
movb $0x1, 0x11(%rbx)
movb $0x1, %al
jmp 0x5904
nop