// File: /workspace/github_cpp_makefile_star2_O2/tlaloc1313[P]chess-project/Board.cpp
// Function: Board::castle(int, int)
int Board::castle (int castleColour, int castleKingSide){
  int rook, king, numSquares, s1, s2, s3, checkTest[3];
  //Sets up the correct squares to check, and checksChecks
  if (castleColour){
      king = 32;
    if (castleKingSide){// White kingside
      rook = 56;
      numSquares = 2;
      s1 = 40;
      s2 = 48;
    } else { // White Queenside
      rook = 0;
      numSquares = 3;
      s1 = 24;
      s2 = 16;
      s3 = 8;
    }
  } else {
      king = 39;
    if (castleKingSide) { //Black kingside
      rook = 63;
      numSquares = 2;
      s1 = 47;
      s2 = 55;
    } else { //Black queenside
      rook = 7;
      numSquares = 3;
      s1 = 31;
      s2 = 23;
      s3 = 15;
    }
  }
  //If pieces are not in place, fails.
  if (!(activeArray[king] && activeArray[rook])){
    return 0;
  }
  //If pieces are in the way, fails.
  if (numSquares == 2) {
    if (activeArray[s1] || activeArray[s2]){
      return 0;
    }
  } else {
    if (activeArray[s1] || activeArray[s2] || activeArray[s3]){
      return 0;
    }
  }
  //Check pieces aren't the wrong colour or type
  if (!(pieceArray[king]->getIsWhite()==castleColour && pieceArray[rook]->getIsWhite()==castleColour && pieceArray[king]->getType()=='k' && pieceArray[rook]->getType()=='r' )){
    return 0;
  }
  //If pieces have moved, casling fails
  if (pieceArray[king]->getHasMoved() || pieceArray[rook]->getHasMoved()){
    return 0;
  }
  //Checks that the king isn't moving into, through, or out of check.
  if (castleColour) {
    checkTest[0] = checkCheck(king, -1);
    checkTest[1] = checkCheck(s1, -1);
    checkTest[2] = checkCheck(s2, -1);
    for (int i = 0; i < 3; i++) {
      if ((checkTest[i] == 1) || (checkTest[i] == 3)) {
        return -5;
      }
    }
  } else {
    checkTest[0] = checkCheck(-1, king);
    checkTest[1] = checkCheck(-1, s1);
    checkTest[2] = checkCheck(-1, s2);
    for (int i = 0; i < 3; i++) {
      if ((checkTest[i] == 2) || (checkTest[i] == 3)) {
        return -5;
      }
    }
  }
  //Attempts to castle
	pieceArray[king]->castle(s2);
	pieceArray[rook]->castle(s1);
  activeArray[king] = 0; //Clears the startSpace since the piece is moving
  activeArray[rook] = 0;
  activeArray[s2] = 1; //Marks the endSpace as taken
  activeArray[s1] = 1;
  pieceArray[s1] = pieceArray[rook]; //Copies the pointer to the piece within the array
  pieceArray[s2] = pieceArray[king];

  //Adds move to history arrays
  pastPieces.push_back('x');
  if (castleKingSide){
    pastMoves.push_back(69);
  } else {
    pastMoves.push_back(70);
  }
  movesSince++;
  moveNumber++;
  return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %esi, %r13d
testl %esi, %esi
je 0x45a5
xorl %eax, %eax
xorl %r15d, %r15d
testl %edx, %edx
pushq $0x38
popq %r14
cmoveq %rax, %r14
setne %r15b
movl %r15d, %r12d
shll $0x4, %r12d
addl $0x18, %r12d
shll $0x5, %r15d
orl $0x10, %r15d
pushq $0x20
popq %rcx
pushq $0x8
jmp 0x45d1
xorl %r15d, %r15d
testl %edx, %edx
pushq $0x7
popq %rax
pushq $0x3f
popq %r14
cmoveq %rax, %r14
setne %r15b
movl %r15d, %r12d
shll $0x4, %r12d
addl $0x1f, %r12d
shll $0x5, %r15d
orl $0x17, %r15d
pushq $0x27
popq %rcx
pushq $0xf
popq %rax
xorl %ebx, %ebx
testl %edx, %edx
cmovneq %rbx, %rax
movl %ecx, %esi
cmpb $0x1, 0x208(%rdi,%rsi)
jne 0x484c
cmpb $0x1, 0x208(%rdi,%r14)
jne 0x484c
movl %r12d, %r8d
movb 0x208(%rdi,%r8), %cl
movl %r15d, %r9d
testl %edx, %edx
je 0x4623
testb %cl, %cl
jne 0x484c
cmpb $0x0, 0x208(%rdi,%r9)
je 0x4648
jmp 0x484c
testb %cl, %cl
jne 0x484c
cmpb $0x0, 0x208(%rdi,%r9)
jne 0x484c
cmpb $0x0, 0x208(%rdi,%rax)
jne 0x484c
movq %r9, -0x58(%rbp)
movq %r8, -0x60(%rbp)
movl %edx, -0x4c(%rbp)
movq %rsi, -0x38(%rbp)
movq %rdi, -0x30(%rbp)
movq 0x8(%rdi,%rsi,8), %rdi
callq 0x569e
movzbl %al, %eax
cmpl %r13d, %eax
jne 0x484c
movq -0x30(%rbp), %rax
movq 0x8(%rax,%r14,8), %rdi
callq 0x569e
movzbl %al, %eax
cmpl %r13d, %eax
jne 0x484c
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movq 0x8(%rcx,%rax,8), %rdi
callq 0x5694
cmpb $0x6b, %al
jne 0x484c
movq -0x30(%rbp), %rax
movq 0x8(%rax,%r14,8), %rdi
callq 0x5694
cmpb $0x72, %al
jne 0x484c
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movq 0x8(%rcx,%rax,8), %rdi
callq 0x56a8
testb %al, %al
jne 0x484c
movq -0x30(%rbp), %rax
movq 0x8(%rax,%r14,8), %rdi
callq 0x56a8
testb %al, %al
jne 0x484c
pushq $-0x1
popq %rbx
testl %r13d, %r13d
je 0x4748
movq -0x30(%rbp), %r13
movq %r13, %rdi
movq -0x38(%rbp), %rsi
movl %ebx, %edx
callq 0x3d10
movl %eax, -0x48(%rbp)
movq %r13, %rdi
movl %r12d, %esi
movl %ebx, %edx
callq 0x3d10
movl %eax, -0x44(%rbp)
movq %r13, %rdi
movl %r15d, %esi
movl %ebx, %edx
callq 0x3d10
movl %eax, -0x40(%rbp)
xorl %eax, %eax
cmpq $0x3, %rax
je 0x479c
movl -0x48(%rbp,%rax,4), %ecx
orl $0x2, %ecx
cmpl $0x3, %ecx
je 0x4741
incq %rax
jmp 0x472a
pushq $-0x5
jmp 0x484b
movq -0x30(%rbp), %r13
movq %r13, %rdi
movl %ebx, %esi
movq -0x38(%rbp), %rdx
callq 0x3d10
movl %eax, -0x48(%rbp)
movq %r13, %rdi
movl %ebx, %esi
movl %r12d, %edx
callq 0x3d10
movl %eax, -0x44(%rbp)
movq %r13, %rdi
movl %ebx, %esi
movl %r15d, %edx
callq 0x3d10
movl %eax, -0x40(%rbp)
xorl %eax, %eax
pushq $-0x5
popq %rbx
cmpq $0x3, %rax
je 0x479c
movl -0x48(%rbp,%rax,4), %ecx
andl $-0x2, %ecx
incq %rax
cmpl $0x2, %ecx
jne 0x4782
jmp 0x484c
movq -0x30(%rbp), %rbx
movq -0x38(%rbp), %r13
movq 0x8(%rbx,%r13,8), %rdi
movq (%rdi), %rax
movl %r15d, %esi
callq *0x10(%rax)
movq 0x8(%rbx,%r14,8), %rdi
movq (%rdi), %rax
movl %r12d, %esi
callq *0x10(%rax)
xorl %eax, %eax
movb %al, 0x208(%rbx,%r13)
movb %al, 0x208(%rbx,%r14)
movb $0x1, %al
movq -0x58(%rbp), %rdx
movb %al, 0x208(%rbx,%rdx)
movq -0x60(%rbp), %rcx
movb %al, 0x208(%rbx,%rcx)
movq 0x8(%rbx,%r14,8), %rax
movq %rax, 0x8(%rbx,%rcx,8)
movq 0x8(%rbx,%r13,8), %rax
movq %rax, 0x8(%rbx,%rdx,8)
leaq 0x248(%rbx), %rdi
leaq -0x3c(%rbp), %rsi
movb $0x78, (%rsi)
callq 0x4d3e
leaq 0x260(%rbx), %rdi
cmpl $0x0, -0x4c(%rbp)
je 0x482a
leaq -0x3c(%rbp), %rsi
movl $0x45, (%rsi)
jmp 0x4834
leaq -0x3c(%rbp), %rsi
movl $0x46, (%rsi)
callq 0x4e1e
movq -0x30(%rbp), %rax
incl 0x27c(%rax)
incl 0x278(%rax)
pushq $0x1
popq %rbx
movl %ebx, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop