// File: /workspace/github_cpp_makefile_star2_O3/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, %ebx
testl %esi, %esi
je 0x4bed
xorl %eax, %eax
xorl %r15d, %r15d
testl %edx, %edx
movl $0x38, %r14d
cmoveq %rax, %r14
setne %r15b
movl %r15d, %r12d
shll $0x4, %r12d
addl $0x18, %r12d
shll $0x5, %r15d
orl $0x10, %r15d
movl $0x20, %ecx
movl $0x8, %eax
jmp 0x4c22
xorl %r15d, %r15d
testl %edx, %edx
movl $0x7, %eax
movl $0x3f, %r14d
cmoveq %rax, %r14
setne %r15b
movl %r15d, %r12d
shll $0x4, %r12d
addl $0x1f, %r12d
shll $0x5, %r15d
orl $0x17, %r15d
movl $0x27, %ecx
movl $0xf, %eax
xorl %r13d, %r13d
testl %edx, %edx
cmovneq %r13, %rax
movl %ecx, %esi
cmpb $0x1, 0x208(%rdi,%rsi)
jne 0x4ed7
cmpb $0x1, 0x208(%rdi,%r14)
jne 0x4ed7
movl %r12d, %r8d
movb 0x208(%rdi,%r8), %cl
testl %edx, %edx
je 0x4c66
testb %cl, %cl
jne 0x4ed7
movl %r15d, %eax
jmp 0x4c7f
testb %cl, %cl
jne 0x4ed7
movl %r15d, %ecx
cmpb $0x0, 0x208(%rdi,%rcx)
jne 0x4ed7
cmpb $0x0, 0x208(%rdi,%rax)
jne 0x4ed7
movq %r8, -0x58(%rbp)
movl %edx, -0x50(%rbp)
movq %rsi, -0x40(%rbp)
movq %rdi, -0x30(%rbp)
movq 0x8(%rdi,%rsi,8), %rdi
callq 0x5c52
movzbl %al, %eax
cmpl %ebx, %eax
jne 0x4ed7
movq -0x30(%rbp), %rax
movq 0x8(%rax,%r14,8), %rdi
callq 0x5c52
movzbl %al, %eax
cmpl %ebx, %eax
jne 0x4ed7
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movq 0x8(%rcx,%rax,8), %rdi
callq 0x5c48
cmpb $0x6b, %al
jne 0x4ed7
movq -0x30(%rbp), %rax
movq 0x8(%rax,%r14,8), %rdi
callq 0x5c48
cmpb $0x72, %al
jne 0x4ed7
movq -0x40(%rbp), %rax
movq -0x30(%rbp), %rcx
movq 0x8(%rcx,%rax,8), %rdi
callq 0x5c5c
testb %al, %al
jne 0x4ed7
movq -0x30(%rbp), %rax
movq 0x8(%rax,%r14,8), %rdi
callq 0x5c5c
testb %al, %al
jne 0x4ed7
testl %ebx, %ebx
je 0x4d89
movq -0x30(%rbp), %rbx
movq %rbx, %rdi
movq -0x40(%rbp), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x429a
movl %eax, -0x4c(%rbp)
movq %rbx, %rdi
movl %r12d, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x429a
movl %eax, -0x48(%rbp)
movq %rbx, %rdi
movl %r15d, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x429a
movl %eax, -0x44(%rbp)
xorl %eax, %eax
movl -0x4c(%rbp,%rax,4), %ecx
orl $0x2, %ecx
cmpl $0x3, %ecx
je 0x4e7b
incq %rax
cmpq $0x3, %rax
jne 0x4d6e
jmp 0x4de2
movq -0x30(%rbp), %rbx
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movq -0x40(%rbp), %rdx
callq 0x429a
movl %eax, -0x4c(%rbp)
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl %r12d, %edx
callq 0x429a
movl %eax, -0x48(%rbp)
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl %r15d, %edx
callq 0x429a
movl %eax, -0x44(%rbp)
xorl %eax, %eax
movl -0x4c(%rbp,%rax,4), %ecx
andl $-0x2, %ecx
cmpl $0x2, %ecx
je 0x4e7b
incq %rax
cmpq $0x3, %rax
jne 0x4dc9
movq -0x30(%rbp), %rbx
movq -0x40(%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)
movl %r15d, %eax
movb $0x1, %cl
movb %cl, 0x208(%rbx,%rax)
movq -0x58(%rbp), %rdx
movb %cl, 0x208(%rbx,%rdx)
movq 0x8(%rbx,%r14,8), %rcx
movq %rcx, 0x8(%rbx,%rdx,8)
movq 0x8(%rbx,%r13,8), %rcx
movq %rcx, 0x8(%rbx,%rax,8)
leaq 0x248(%rbx), %rdi
leaq -0x34(%rbp), %rsi
movb $0x78, (%rsi)
callq 0x4fd4
cmpl $0x0, -0x50(%rbp)
je 0x4e83
movl $0x45, -0x34(%rbp)
movq 0x268(%rbx), %rsi
cmpq 0x270(%rbx), %rsi
je 0x4ead
movl $0x45, (%rsi)
jmp 0x4ea0
movl $0xfffffffb, %r13d      # imm = 0xFFFFFFFB
jmp 0x4ed7
movl $0x46, -0x34(%rbp)
movq 0x268(%rbx), %rsi
cmpq 0x270(%rbx), %rsi
je 0x4ead
movl $0x46, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x268(%rbx)
jmp 0x4ec5
movq -0x30(%rbp), %rax
leaq 0x260(%rax), %rdi
leaq -0x34(%rbp), %rdx
callq 0x53e8
movq -0x30(%rbp), %rbx
incl 0x27c(%rbx)
incl 0x278(%rbx)
movl $0x1, %r13d
movl %r13d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop