// File: /workspace/github_cpp_makefile_star2_O2/vygr[P]C-Chess/chess.cpp
// Function: piece_moves(std::vector<score_board, std::allocator<score_board>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int, int, std::vector<move, std::allocator<move>> const&, unsigned long&)
auto piece_moves(score_boards &yield, board brd, unsigned int index, int colour, const moves &moves, std::size_t &king_index)
{
	auto piece = brd[index];
	auto promote = std::string("qrbn");
	if (colour == white) promote = "QRBN";
	auto cx = int(index % 8);
	auto cy = int(index / 8);
	for (auto &move : moves)
 	{
		auto dx = move.dx;
		auto dy = move.dy;
		auto length = move.length;
		auto flag = move.flag;
		auto x = cx;
		auto y = cy;
		//special length for pawns so we can adjust for starting 2 hop
		if (length == 0)
		{
			length = 1;
			if (piece == 'p')
			{
				if (y == 1) length = 2;
			}
			else
			{
				if (y == 6) length = 2;
			}
		}
		for (;length > 0; --length)
		{
			x += dx;
			y += dy;
			if ((x < 0) || (x >= 8) || (y < 0) || (y >= 8))
			{
				//gone off the board
				break;
			}
			auto newindex = y*8 + x;
			auto newpiece = brd[newindex];
			auto newtype = piece_type[newpiece];
			if (newtype == colour)
			{
				//hit one of our own piece type (black hit black etc)
				break;
			}
			if ((flag == no_capture) && (newtype != empty))
			{
				//not suposed to capture and not empty square
				break;
			}
			if ((flag == must_capture) && (newtype == empty))
			{
				//must capture and got empty square
				break;
			}
			brd[index] = ' ';
			if ((y == 0 || y == 7) && (piece == 'P' || piece == 'p'))
			{
				//try all the pawn promotion possibilities
				for (auto &promote_piece : promote)
				{
					brd[newindex] = promote_piece;
					if (!in_check(brd, colour, king_index)) yield.push_back(score_board{evaluate(brd, colour), 0, brd});
				}
			}
			else
			{
				//generate this as a possible move
				brd[newindex] = piece;
				if (!in_check(brd, colour, king_index)) yield.push_back(score_board{evaluate(brd, colour), 0, brd});
			}
			brd[index] = piece;
			brd[newindex] = newpiece;
			if ((flag == may_capture) && (newtype != empty))
			{
				//may capture and we did so !
				break;
			}
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r9, 0x40(%rsp)
movq %r8, %r14
movl %ecx, %ebp
movq %rsi, %r15
movq %rdi, 0x38(%rsp)
movl %edx, %ebx
movl %edx, %r12d
movq (%rsi), %rax
movb (%rax,%r12), %al
movb %al, 0x5(%rsp)
leaq 0x5939(%rip), %rsi      # 0x8c32
leaq 0x88(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x20c0
cmpl $0x1, %ebp
jne 0x3324
leaq 0x5920(%rip), %rsi      # 0x8c37
leaq 0x88(%rsp), %rdi
callq 0x2310
movl %ebx, %eax
andl $0x7, %eax
movl %eax, 0x1c(%rsp)
shrl $0x3, %ebx
movq (%r14), %rdx
movq 0x8(%r14), %rax
movq %rax, 0x70(%rsp)
xorl %eax, %eax
cmpl $0x6, %ebx
sete %al
xorl %esi, %esi
movl %ebx, 0x20(%rsp)
cmpl $0x1, %ebx
sete %sil
movb 0x5(%rsp), %cl
movl %ecx, %edi
andb $-0x21, %dil
movb %dil, 0x7(%rsp)
cmpb $0x70, %cl
cmovnel %eax, %esi
movq %rdx, %rax
incl %esi
movl %esi, 0x18(%rsp)
movq %r12, 0x80(%rsp)
cmpq 0x70(%rsp), %rax
je 0x358e
movl (%rax), %ecx
movl %ecx, 0x2c(%rsp)
movl 0x4(%rax), %ecx
movl %ecx, 0x28(%rsp)
movl 0x8(%rax), %ebx
movq %rax, 0x78(%rsp)
movl 0xc(%rax), %eax
testl %ebx, %ebx
cmovel 0x18(%rsp), %ebx
movl %eax, 0x10(%rsp)
xorl $0x2, %eax
movl %eax, 0x24(%rsp)
movl 0x1c(%rsp), %ecx
movl 0x20(%rsp), %eax
movq %rax, 0x8(%rsp)
testl %ebx, %ebx
jle 0x3580
addl 0x2c(%rsp), %ecx
cmpl $0x7, %ecx
ja 0x3580
movq 0x8(%rsp), %rdx
addl 0x28(%rsp), %edx
movq %rdx, 0x8(%rsp)
cmpl $0x7, %edx
ja 0x3580
movq 0x8(%rsp), %rax
leal (,%rax,8), %r13d
movl %ecx, 0x34(%rsp)
orl %ecx, %r13d
movq (%r15), %rax
movb (%rax,%r13), %al
movb %al, 0x6(%rsp)
leaq 0xadb5(%rip), %rdi      # 0xe1c0
leaq 0x6(%rsp), %rsi
callq 0x4d9e
movl (%rax), %eax
movl %eax, 0x14(%rsp)
cmpl %ebp, %eax
je 0x3580
cmpl $0x0, 0x10(%rsp)
sete %cl
movl 0x14(%rsp), %esi
testl %esi, %esi
setne %dl
movl 0x24(%rsp), %eax
orl %esi, %eax
sete %al
testb %dl, %cl
jne 0x3580
testb %al, %al
jne 0x3580
movq (%r15), %rax
movb $0x20, (%rax,%r12)
cmpl $0x7, 0x8(%rsp)
movl %ebx, 0x30(%rsp)
je 0x3467
cmpl $0x0, 0x8(%rsp)
jne 0x34e6
cmpb $0x50, 0x7(%rsp)
jne 0x34e6
movq 0x88(%rsp), %r14
movq 0x90(%rsp), %rbx
xorl %r12d, %r12d
cmpq %r12, %rbx
je 0x353e
movb (%r14,%r12), %al
movq (%r15), %rcx
movb %al, (%rcx,%r13)
movq %r15, %rdi
movl %ebp, %esi
movq 0x40(%rsp), %rdx
callq 0x313a
testb %al, %al
jne 0x34e1
movq %r15, %rdi
movl %ebp, %esi
callq 0x3215
movl %eax, 0x48(%rsp)
andl $0x0, 0x4c(%rsp)
leaq 0x50(%rsp), %rdi
movq %r15, %rsi
callq 0x2250
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x6ac4
leaq 0x50(%rsp), %rdi
callq 0x20f0
incq %r12
jmp 0x3481
movq (%r15), %rax
movb 0x5(%rsp), %cl
movb %cl, (%rax,%r13)
movq %r15, %rdi
movl %ebp, %esi
movq 0x40(%rsp), %rdx
callq 0x313a
testb %al, %al
jne 0x353e
movq %r15, %rdi
movl %ebp, %esi
callq 0x3215
leaq 0x50(%rsp), %r14
movl %eax, 0x48(%rsp)
andl $0x0, 0x4c(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x2250
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x6ac4
movq %r14, %rdi
callq 0x20f0
cmpl $0x0, 0x14(%rsp)
sete %al
cmpl $0x1, 0x10(%rsp)
setne %cl
movq (%r15), %rdx
movq 0x80(%rsp), %r12
movb 0x5(%rsp), %sil
movb %sil, (%rdx,%r12)
movb 0x6(%rsp), %dl
movq (%r15), %rsi
movb %dl, (%rsi,%r13)
orb %al, %cl
movl 0x30(%rsp), %ebx
je 0x3580
decl %ebx
movl 0x34(%rsp), %ecx
jmp 0x33b9
movq 0x78(%rsp), %rax
addq $0x10, %rax
jmp 0x3377
leaq 0x88(%rsp), %rdi
callq 0x20f0
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x35cc
movq %rax, %rbx
movq %r14, %rdi
jmp 0x35c3
jmp 0x35cc
jmp 0x35cc
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x20f0
jmp 0x35cf
jmp 0x35cc
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x20f0
movq %rbx, %rdi
callq 0x22e0