// File: ATOMIC-LICHESS[P]ATOMKRAFT/create_book.cpp
// Function: san_to_move(Position&, char*)
Move san_to_move(Position& pos, char* s) {
	char str[10];
	strcpy(str, s);

	// generate legal moves
	MoveStack mlist[MAX_MOVES];
	MoveStack* last = generate<MV_LEGAL>(pos, mlist);


	// get rid of 'x' chars
	char* x = strchr(str, 'x');
	if (x) while (*x) *x++ = *(x+1);


	// get piece type
	int p = 1;
	PieceType pt = getPiece(str[0]);
	if (pt == PIECE_TYPE_NONE) {
		pt = PAWN;
		p = 0;
	}

	// there may be additional info regarding the file/rank
	File fromFile = getFile(str[p+0]);
	Rank fromRank = getRank(str[p+0]);
	Square to;

	// TODO: san can be like Bf3e4

	if (fromRank != RANK_NONE || getFile(str[p+1]) != FILE_NONE) {
		// san begins with a number e.g. B8d6 or with two letters e.g. Bfd6
		to = make_square(File(str[p+1] - 'a'), Rank(str[p+2] - '1'));
	} else {
		// san is like Bd6
		to = make_square(File(str[p+0] - 'a'), Rank(str[p+1] - '1'));
		fromFile = FILE_NONE;
	}


	// traverse legal moves and pick the right one
	Move m = MOVE_NONE;
	int possible_move_count = 0; // used to detect errors

	for (MoveStack* cur = mlist; cur != last; cur++) {
		Square sqfrom = move_from(cur->move);
		Square sqto = move_to(cur->move);

		if (strcmp(str, "O-O") == 0) {
			if (move_is_short_castle(cur->move)) {
				m = cur->move;
				possible_move_count = 1;
				break;
			}
		} else if (strcmp(str, "O-O-O") == 0) {
			if (move_is_long_castle(cur->move)) {
				m = cur->move;
				possible_move_count = 1;
				break;
			}
		} else {

			if (sqto == to && pt == pos.type_of_piece_on(sqfrom)) {
				if (fromFile != FILE_NONE) {
					if (square_file(sqfrom) == fromFile) {
						m = cur->move;
						++possible_move_count;
						//break;
					}
				} else if (fromRank != RANK_NONE) {
					if (square_rank(sqfrom) == fromRank) {
						m = cur->move;
						++possible_move_count;
						//break;
					}
				} else {
					m = cur->move;
					++possible_move_count;
					//break;
				}
			}
		}
	}


	if (possible_move_count != 1) {
		m = MOVE_NONE;
		cout << "incorrect SAN! (it may be ambiguous )" << endl;
	}


	return m;
}

// Assembly:
subq $0x878, %rsp            # imm = 0x878
movq %rdi, 0x870(%rsp)
movq %rsi, 0x868(%rsp)
leaq 0x85e(%rsp), %rdi
movq 0x868(%rsp), %rsi
callq 0x6460
movq 0x870(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x30420
movq %rax, 0x48(%rsp)
leaq 0x85e(%rsp), %rdi
movl $0x78, %esi
callq 0x6190
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0x100ad
jmp 0x10084
movq 0x40(%rsp), %rax
cmpb $0x0, (%rax)
je 0x100ab
movq 0x40(%rsp), %rax
movb 0x1(%rax), %cl
movq 0x40(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x40(%rsp)
movb %cl, (%rax)
jmp 0x10084
jmp 0x100ad
movl $0x1, 0x3c(%rsp)
movsbl 0x85e(%rsp), %edi
callq 0xffb0
movl %eax, 0x38(%rsp)
cmpl $0x0, 0x38(%rsp)
jne 0x100dd
movl $0x1, 0x38(%rsp)
movl $0x0, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
addl $0x0, %eax
cltq
movsbl 0x85e(%rsp,%rax), %edi
callq 0xff30
movl %eax, 0x34(%rsp)
movl 0x3c(%rsp), %eax
addl $0x0, %eax
cltq
movsbl 0x85e(%rsp,%rax), %edi
callq 0xff70
movl %eax, 0x30(%rsp)
cmpl $-0x1, 0x30(%rsp)
jne 0x10133
movl 0x3c(%rsp), %eax
addl $0x1, %eax
cltq
movsbl 0x85e(%rsp,%rax), %edi
callq 0xff30
cmpl $-0x1, %eax
je 0x10166
movl 0x3c(%rsp), %eax
addl $0x1, %eax
cltq
movsbl 0x85e(%rsp,%rax), %edi
subl $0x61, %edi
movl 0x3c(%rsp), %eax
addl $0x2, %eax
cltq
movsbl 0x85e(%rsp,%rax), %esi
subl $0x31, %esi
callq 0xd740
movl %eax, 0x2c(%rsp)
jmp 0x1019f
movl 0x3c(%rsp), %eax
addl $0x0, %eax
cltq
movsbl 0x85e(%rsp,%rax), %edi
subl $0x61, %edi
movl 0x3c(%rsp), %eax
addl $0x1, %eax
cltq
movsbl 0x85e(%rsp,%rax), %esi
subl $0x31, %esi
callq 0xd740
movl %eax, 0x2c(%rsp)
movl $0xffffffff, 0x34(%rsp) # imm = 0xFFFFFFFF
movl $0x0, 0x28(%rsp)
movl $0x0, 0x24(%rsp)
leaq 0x50(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x48(%rsp), %rax
je 0x10339
movq 0x18(%rsp), %rax
movl (%rax), %edi
callq 0xf680
movl %eax, 0x14(%rsp)
movq 0x18(%rsp), %rax
movl (%rax), %edi
callq 0xf690
movl %eax, 0x10(%rsp)
leaq 0x85e(%rsp), %rdi
leaq 0x4933a(%rip), %rsi     # 0x59532
callq 0x6740
cmpl $0x0, %eax
jne 0x10231
movq 0x18(%rsp), %rax
movl (%rax), %edi
callq 0x11e70
testb $0x1, %al
jne 0x10214
jmp 0x1022c
movq 0x18(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x28(%rsp)
movl $0x1, 0x24(%rsp)
jmp 0x10339
jmp 0x10324
leaq 0x85e(%rsp), %rdi
leaq 0x492f0(%rip), %rsi     # 0x59530
callq 0x6740
cmpl $0x0, %eax
jne 0x10279
movq 0x18(%rsp), %rax
movl (%rax), %edi
callq 0x11ec0
testb $0x1, %al
jne 0x1025c
jmp 0x10274
movq 0x18(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x28(%rsp)
movl $0x1, 0x24(%rsp)
jmp 0x10339
jmp 0x10322
movl 0x10(%rsp), %eax
cmpl 0x2c(%rsp), %eax
jne 0x10320
movl 0x38(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x870(%rsp), %rdi
movl 0x14(%rsp), %esi
callq 0x11f10
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jne 0x10320
cmpl $-0x1, 0x34(%rsp)
je 0x102d8
movl 0x14(%rsp), %edi
callq 0xce10
cmpl 0x34(%rsp), %eax
jne 0x102d6
movq 0x18(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x28(%rsp)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x1031e
cmpl $-0x1, 0x30(%rsp)
je 0x10306
movl 0x14(%rsp), %edi
callq 0xce40
cmpl 0x30(%rsp), %eax
jne 0x10304
movq 0x18(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x28(%rsp)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x1031c
movq 0x18(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x28(%rsp)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x1031e
jmp 0x10320
jmp 0x10322
jmp 0x10324
jmp 0x10326
movq 0x18(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x18(%rsp)
jmp 0x101b9
cmpl $0x1, 0x24(%rsp)
je 0x1036a
movl $0x0, 0x28(%rsp)
movq 0x5bc69(%rip), %rdi     # 0x6bfb8
leaq 0x491e0(%rip), %rsi     # 0x59536
callq 0x64b0
movq %rax, %rdi
movq 0x5bc2b(%rip), %rsi     # 0x6bf90
callq 0x6520
movl 0x28(%rsp), %eax
addq $0x878, %rsp            # imm = 0x878
retq
nopw %cs:(%rax,%rax)