// File: 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
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, -0x38(%rbp)
movl -0x14(%rbp), %eax
cmpl 0xc(%rcx), %eax
jne 0x910c
movb $0x0, -0x1(%rbp)
jmp 0x9338
movq -0x38(%rbp), %rax
movl 0xc(%rax), %edi
callq 0x47f0
movl %eax, %ecx
movq -0x38(%rbp), %rax
movl %ecx, -0x24(%rbp)
movl 0xc(%rax), %edi
callq 0x4810
movl %eax, -0x28(%rbp)
movl -0x14(%rbp), %edi
callq 0x47f0
movl %eax, -0x2c(%rbp)
movl -0x14(%rbp), %edi
callq 0x4810
movl %eax, %ecx
movq -0x38(%rbp), %rax
movl %ecx, -0x30(%rbp)
movb $0x0, 0x12(%rax)
movl -0x28(%rbp), %eax
cmpl -0x30(%rbp), %eax
jne 0x92bf
movq -0x20(%rbp), %rax
movslq -0x14(%rbp), %rcx
movb (%rax,%rcx), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x92bf
movq -0x38(%rbp), %rax
movzbl 0x10(%rax), %ecx
movb %cl, %al
andl $0x1, %ecx
movl %ecx, -0x3c(%rbp)
testb $0x1, %al
je 0x922e
jmp 0x918b
movl -0x3c(%rbp), %eax
subl $0x1, %eax
jne 0x92bd
jmp 0x9199
cmpl $0x1, -0x24(%rbp)
jne 0x9205
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $0x2, %eax
jne 0x91e1
movq -0x20(%rbp), %rax
movl -0x14(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x91df
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, 0x12(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x91e1
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $0x1, %eax
jne 0x9203
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x9229
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $0x1, %eax
jne 0x9227
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x9229
jmp 0x92bd
cmpl $0x6, -0x24(%rbp)
jne 0x929a
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $-0x2, %eax
jne 0x9276
movq -0x20(%rbp), %rax
movl -0x14(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x9274
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, 0x12(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x9276
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $-0x1, %eax
jne 0x9298
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x92bb
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $-0x1, %eax
jne 0x92b9
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x92bb
jmp 0x92bd
jmp 0x92bf
movl -0x28(%rbp), %eax
subl -0x30(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
cmpl $0x1, %eax
jne 0x9334
movq -0x20(%rbp), %rax
movslq -0x14(%rbp), %rcx
movb (%rax,%rcx), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x9334
movq -0x38(%rbp), %rax
testb $0x1, 0x10(%rax)
je 0x9311
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $0x1, %eax
jne 0x930f
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x9332
movl -0x2c(%rbp), %eax
subl -0x24(%rbp), %eax
cmpl $-0x1, %eax
jne 0x9330
movq -0x38(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movb $0x1, 0x11(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x9338
jmp 0x9332
jmp 0x9334
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)