// File: nesro[P]NCursesGomoku/src/ai.cpp
// Function: CAI::CAI(CBoard*, char)
CAI::CAI(CBoard *board, char mark) :
		CPlayer(board, mark) {

	char opponentMark;

	if (mark == CGame::PLAYER_0_CHAR) {
		opponentMark = CGame::PLAYER_1_CHAR;
	} else {
		opponentMark = CGame::PLAYER_0_CHAR;
	}

	/*
	 * First is next move, if a strategy is found. A is AI and O is opponent.
	 * 0 is EMPTY_CELL
	 * 1 is AI
	 * 2 is opponent
	 * -1 is end of pattern
	 */
	int strategy[STRATEGIES][PATTERN_LENGTH] = {

	/* my four, go for win */
	{ 0, /* */0, 1, 1, 1, 1, -1, -1, -1, -1 }, //".AAAA"0
			{ 1, /* */1, 0, 1, 1, 1, -1, -1, -1, -1 }, //"A.AAA"1
			{ 2, /* */1, 1, 0, 1, 1, -1, -1, -1, -1 }, //"AA.AA"2

			/* his four, need to block */
			{ 0, /* */0, 2, 2, 2, 2, -1, -1, -1, -1 }, //".OOOO"0
			{ 1, /* */2, 0, 2, 2, 2, -1, -1, -1, -1 }, //"O.OOO"1
			{ 2, /* */2, 2, 0, 2, 2, -1, -1, -1, -1 }, //"OO.OO"2

			/* my three, go for four*/
			{ 0, /* */0, 1, 1, 1, 0, -1, -1, -1, -1 }, //".AAA."0
			{ 2, /* */0, 1, 0, 1, 1, -1, -1, -1, -1 }, //".A.AA"2
			{ 1, /* */1, 0, 1, 1, 0, -1, -1, -1, -1 }, //"A.AA."1
			{ 1, /* */0, 0, 1, 1, 1, -1, -1, -1, -1 }, //"..AAA"1

			/* his three, need to block*/
			{ 0, /* */0, 2, 2, 2, 0, -1, -1, -1, -1 }, //".OOO."0
			{ 1, /* */2, 0, 2, 2, 0, -1, -1, -1, -1 }, //"O.OO."1
			{ 1, /* */0, 2, 0, 2, 2, -1 - 1, -1, -1 }, //".O.OO"2

			/* my two, let's make three*/
			{ 2, /* */0, 1, 0, 1, 0, -1, -1, -1, -1 }, //".A.A."2
			{ 1, /* */0, 0, 1, 1, 0, -1, -1, -1, -1 }, //"..AA."1
			{ 1, /* */0, 0, 1, 1, 0, 0, -1, -1, -1 }, //"..AA.."1

			/* really nothing to do, lets make mark next to another */
			{ 1, /* */0, 0, 1, 0, 0, -1, -1, -1, -1 }, //"..A.."1
			{ 1, /* */0, 0, 1, 0, -1, -1, -1, -1, -1 }, //"..A."1
			{ 0, /* */0, 1, 0, -1, -1, -1, -1, -1, -1 }, //".A."0

			/* okay... so, just block something */
			{ 1, /* */0, 0, 2, 0, -1, -1, -1, -1, -1 }, //"..O."1
			{ 0, /* */0, 2, 0, -1, -1, -1, -1, -1, -1 }, //".O."0
			};

	m_Patterns = new char *[STRATEGIES];
	m_Moves = new int[STRATEGIES];

	for (int i = 0; i < STRATEGIES; i++) {
		m_Patterns[i] = new char[PATTERN_LENGTH];
		memset(m_Patterns[i], 0, PATTERN_LENGTH);

		m_Moves[i] = strategy[i][0];

		for (int j = 0; j < PATTERN_LENGTH - 1; j++) {
			switch (strategy[i][1 + j]) {
			case 1:
				m_Patterns[i][j] = mark;
				break;
			case 2:
				m_Patterns[i][j] = opponentMark;
				break;
			case 0:
				m_Patterns[i][j] = CBoard::EMPTY_CELL;
				break;
			case -1:
				m_Patterns[i][j] = '\0';
				break;
			default:
				break;
			}
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3a0, %rsp            # imm = 0x3A0
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x380(%rbp)
movq -0x10(%rbp), %rsi
movsbl -0x11(%rbp), %edx
callq 0x6910
movq -0x380(%rbp), %rax
leaq 0x81ba(%rip), %rcx      # 0xbba8
addq $0x10, %rcx
movq %rcx, (%rax)
movsbl -0x11(%rbp), %eax
cmpl $0x78, %eax
jne 0x3a04
movb $0x6f, -0x12(%rbp)
jmp 0x3a08
movb $0x78, -0x12(%rbp)
leaq 0x4611(%rip), %rsi      # 0x8020
leaq -0x360(%rbp), %rdi
movl $0x348, %edx            # imm = 0x348
callq 0x3200
movl $0xa8, %edi
callq 0x3030
movq %rax, -0x388(%rbp)
jmp 0x3a33
movq -0x380(%rbp), %rax
movq -0x388(%rbp), %rcx
movq %rcx, 0x18(%rax)
movl $0x54, %edi
callq 0x3030
movq %rax, -0x390(%rbp)
jmp 0x3a58
movq -0x380(%rbp), %rax
movq -0x390(%rbp), %rcx
movq %rcx, 0x20(%rax)
movl $0x0, -0x370(%rbp)
cmpl $0x15, -0x370(%rbp)
jge 0x3c39
movl $0xa, %edi
callq 0x3030
movq %rax, -0x398(%rbp)
jmp 0x3a94
movq -0x380(%rbp), %rax
movq -0x398(%rbp), %rsi
movq 0x18(%rax), %rcx
movslq -0x370(%rbp), %rdx
movq %rsi, (%rcx,%rdx,8)
movq 0x18(%rax), %rax
movslq -0x370(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x3180
movq -0x380(%rbp), %rax
movslq -0x370(%rbp), %rdx
leaq -0x360(%rbp), %rcx
imulq $0x28, %rdx, %rdx
addq %rdx, %rcx
movl (%rcx), %edx
movq 0x20(%rax), %rax
movslq -0x370(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl $0x0, -0x374(%rbp)
cmpl $0x9, -0x374(%rbp)
jge 0x3c23
movslq -0x370(%rbp), %rax
leaq (%rax,%rax,4), %rax
leaq -0x360(%rbp,%rax,8), %rax
movslq -0x374(%rbp), %rcx
movl 0x4(%rax,%rcx,4), %eax
incl %eax
movl %eax, %ecx
movq %rcx, -0x3a0(%rbp)
subl $0x3, %eax
ja 0x3c0b
movq -0x3a0(%rbp), %rax
leaq 0x44c1(%rip), %rcx      # 0x8010
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x380(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x368(%rbp)
movl %eax, -0x36c(%rbp)
callq 0x6950
jmp 0x3c42
movq -0x380(%rbp), %rax
movb -0x11(%rbp), %dl
movq 0x18(%rax), %rax
movslq -0x370(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x374(%rbp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x3c0d
movq -0x380(%rbp), %rax
movb -0x12(%rbp), %dl
movq 0x18(%rax), %rax
movslq -0x370(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x374(%rbp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x3c0d
movq -0x380(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0x370(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x374(%rbp), %rcx
movb $0x5f, (%rax,%rcx)
jmp 0x3c0d
movq -0x380(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0x370(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x374(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x3c0d
jmp 0x3c0d
jmp 0x3c0f
movl -0x374(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x374(%rbp)
jmp 0x3b02
jmp 0x3c25
movl -0x370(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x370(%rbp)
jmp 0x3a74
addq $0x3a0, %rsp            # imm = 0x3A0
popq %rbp
retq
movq -0x368(%rbp), %rdi
callq 0x3410
nop