Rev 1 | Rev 63 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1 | Rev 54 | ||
|---|---|---|---|
| Line 16... | Line 16... | ||
| 16 | 16 | ||
| 17 | bool Move_SetupFromSAN (boardmove_t *move, boardmove_t *new_move, int move_color) |
17 | bool Move_SetupFromSAN (boardmove_t *move, boardmove_t *new_move, int move_color) |
| 18 | { |
18 | { |
| 19 | // helper function to translate a SAN move into numeric from and to positions on the specified board |
19 | // helper function to translate a SAN move into numeric from and to positions on the specified board |
| 20 | // WARNING: THIS FUNCTION DOES NOT RETURN WITH A FULLY CONSTRUCTED MOVE! |
20 | // WARNING: THIS FUNCTION DOES NOT RETURN WITH A FULLY CONSTRUCTED MOVE! |
| - | 21 | ||
| - | 22 | // FIXME: accelerate this function by reducing the number of towupper()/towlower() calls |
|
| 21 | 23 | ||
| 22 | int fieldstart; |
24 | int fieldstart; |
| 23 | int fieldstop; |
25 | int fieldstop; |
| 24 | int length; |
26 | int length; |
| 25 | 27 | ||
| Line 52... | Line 54... | ||
| 52 | // does it finish with a check or a checkmate sign ? |
54 | // does it finish with a check or a checkmate sign ? |
| 53 | if ((fieldstop >= fieldstart) && ((new_move->pgntext[fieldstop] == L'+') || (new_move->pgntext[fieldstop] == L'#'))) |
55 | if ((fieldstop >= fieldstart) && ((new_move->pgntext[fieldstop] == L'+') || (new_move->pgntext[fieldstop] == L'#'))) |
| 54 | fieldstop--; // chop off these signs, they are redundant |
56 | fieldstop--; // chop off these signs, they are redundant |
| 55 | 57 | ||
| 56 | // is it a long castle ? |
58 | // is it a long castle ? |
| 57 | if (( |
59 | if ((_wcsnicmp (&new_move->pgntext[fieldstart], L"O-O-O", 5) == 0) || (wcsncmp (&new_move->pgntext[fieldstart], L"0-0-0", 5) == 0)) |
| 58 | { |
60 | { |
| 59 | new_move->source[0] = (move_color == COLOR_WHITE ? 0 : 7); |
61 | new_move->source[0] = (move_color == COLOR_WHITE ? 0 : 7); |
| 60 | new_move->source[1] = 4; |
62 | new_move->source[1] = 4; |
| 61 | new_move->target[0] = (move_color == COLOR_WHITE ? 0 : 7); |
63 | new_move->target[0] = (move_color == COLOR_WHITE ? 0 : 7); |
| 62 | new_move->target[1] = 2; |
64 | new_move->target[1] = 2; |
| 63 | new_move->part = PART_KING; // it's a king's move |
65 | new_move->part = PART_KING; // it's a king's move |
| 64 | } |
66 | } |
| 65 | 67 | ||
| 66 | // else is it a short castle ? |
68 | // else is it a short castle ? |
| 67 | else if (( |
69 | else if ((_wcsnicmp (&new_move->pgntext[fieldstart], L"O-O", 3) == 0) || (wcsncmp (&new_move->pgntext[fieldstart], L"0-0", 3) == 0)) |
| 68 | { |
70 | { |
| 69 | new_move->source[0] = (move_color == COLOR_WHITE ? 0 : 7); |
71 | new_move->source[0] = (move_color == COLOR_WHITE ? 0 : 7); |
| 70 | new_move->source[1] = 4; |
72 | new_move->source[1] = 4; |
| 71 | new_move->target[0] = (move_color == COLOR_WHITE ? 0 : 7); |
73 | new_move->target[0] = (move_color == COLOR_WHITE ? 0 : 7); |
| 72 | new_move->target[1] = 6; |
74 | new_move->target[1] = 6; |
| Line 75... | Line 77... | ||
| 75 | 77 | ||
| 76 | // else it's a normal move |
78 | // else it's a normal move |
| 77 | else |
79 | else |
| 78 | { |
80 | { |
| 79 | // is the last character a part type ? |
81 | // is the last character a part type ? |
| 80 | if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'R')) |
82 | if ((fieldstop >= fieldstart) && (towupper (new_move->pgntext[fieldstop]) == L'R')) |
| 81 | { |
83 | { |
| 82 | new_move->promotion_type = PART_ROOK; // there's a promotion to rook |
84 | new_move->promotion_type = PART_ROOK; // there's a promotion to rook |
| 83 | fieldstop--; // proceed to previous character |
85 | fieldstop--; // proceed to previous character |
| 84 | } |
86 | } |
| 85 | else if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'N')) |
87 | else if ((fieldstop >= fieldstart) && (towupper (new_move->pgntext[fieldstop]) == L'N')) |
| 86 | { |
88 | { |
| 87 | new_move->promotion_type = PART_KNIGHT; // there's a promotion to knight |
89 | new_move->promotion_type = PART_KNIGHT; // there's a promotion to knight |
| 88 | fieldstop--; // proceed to previous character |
90 | fieldstop--; // proceed to previous character |
| 89 | } |
91 | } |
| 90 | else if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'B')) |
92 | else if ((fieldstop >= fieldstart) && (towupper (new_move->pgntext[fieldstop]) == L'B')) |
| 91 | { |
93 | { |
| 92 | new_move->promotion_type = PART_BISHOP; // there's a promotion to bishop |
94 | new_move->promotion_type = PART_BISHOP; // there's a promotion to bishop |
| 93 | fieldstop--; // proceed to previous character |
95 | fieldstop--; // proceed to previous character |
| 94 | } |
96 | } |
| 95 | else if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'Q')) |
97 | else if ((fieldstop >= fieldstart) && (towupper (new_move->pgntext[fieldstop]) == L'Q')) |
| 96 | { |
98 | { |
| 97 | new_move->promotion_type = PART_QUEEN; // there's a promotion to queen |
99 | new_move->promotion_type = PART_QUEEN; // there's a promotion to queen |
| 98 | fieldstop--; // proceed to previous character |
100 | fieldstop--; // proceed to previous character |
| 99 | } |
101 | } |
| 100 | 102 | ||
| Line 108... | Line 110... | ||
| 108 | new_move->target[0] = WCHAR_TO_LINE (new_move->pgntext[fieldstop]); // read the target line |
110 | new_move->target[0] = WCHAR_TO_LINE (new_move->pgntext[fieldstop]); // read the target line |
| 109 | fieldstop--; // proceed to previous character |
111 | fieldstop--; // proceed to previous character |
| 110 | } |
112 | } |
| 111 | if (fieldstop >= fieldstart) |
113 | if (fieldstop >= fieldstart) |
| 112 | { |
114 | { |
| 113 | new_move->target[1] = WCHAR_TO_COLUMN (new_move->pgntext[fieldstop]); // read the target column |
115 | new_move->target[1] = WCHAR_TO_COLUMN (towlower (new_move->pgntext[fieldstop])); // read the target column |
| 114 | fieldstop--; // proceed to previous character |
116 | fieldstop--; // proceed to previous character |
| 115 | } |
117 | } |
| 116 | 118 | ||
| 117 | if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'x')) |
119 | if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'x')) |
| 118 | fieldstop--; // if there's a taking piece indication, it's superfluous, so skip it |
120 | fieldstop--; // if there's a taking piece indication, it's superfluous, so skip it |
| Line 121... | Line 123... | ||
| 121 | if ((fieldstop >= fieldstart) && (WCHAR_TO_LINE (new_move->pgntext[fieldstop]) != -1)) |
123 | if ((fieldstop >= fieldstart) && (WCHAR_TO_LINE (new_move->pgntext[fieldstop]) != -1)) |
| 122 | { |
124 | { |
| 123 | new_move->source[0] = WCHAR_TO_LINE (new_move->pgntext[fieldstop]); // read the source line |
125 | new_move->source[0] = WCHAR_TO_LINE (new_move->pgntext[fieldstop]); // read the source line |
| 124 | fieldstop--; // proceed to previous character |
126 | fieldstop--; // proceed to previous character |
| 125 | } |
127 | } |
| 126 | if ((fieldstop >= fieldstart) && (WCHAR_TO_COLUMN (new_move->pgntext[fieldstop]) != -1)) |
128 | if ((fieldstop >= fieldstart) && (WCHAR_TO_COLUMN (towlower (new_move->pgntext[fieldstop])) != -1)) |
| 127 | { |
129 | { |
| 128 | new_move->source[1] = WCHAR_TO_COLUMN (new_move->pgntext[fieldstop]); // read the source column |
130 | new_move->source[1] = WCHAR_TO_COLUMN (towlower (new_move->pgntext[fieldstop])); // read the source column |
| 129 | fieldstop--; // proceed to previous character |
131 | fieldstop--; // proceed to previous character |
| 130 | } |
132 | } |
| 131 | 133 | ||
| 132 | // read the part's type |
134 | // read the part's type |
| 133 | if (fieldstop >= fieldstart) |
135 | if (fieldstop >= fieldstart) |
| 134 | { |
136 | { |
| 135 | if (new_move->pgntext[fieldstop] == L'R') |
137 | if (towupper (new_move->pgntext[fieldstop]) == L'R') |
| 136 | new_move->part = PART_ROOK; // it's a rook |
138 | new_move->part = PART_ROOK; // it's a rook |
| 137 | else if (new_move->pgntext[fieldstop] == L'N') |
139 | else if (towupper (new_move->pgntext[fieldstop]) == L'N') |
| 138 | new_move->part = PART_KNIGHT; // it's a knight |
140 | new_move->part = PART_KNIGHT; // it's a knight |
| 139 | else if (new_move->pgntext[fieldstop] == L'B') |
141 | else if (towupper (new_move->pgntext[fieldstop]) == L'B') |
| 140 | new_move->part = PART_BISHOP; // it's a bishop |
142 | new_move->part = PART_BISHOP; // it's a bishop |
| 141 | else if (new_move->pgntext[fieldstop] == L'Q') |
143 | else if (towupper (new_move->pgntext[fieldstop]) == L'Q') |
| 142 | new_move->part = PART_QUEEN; // it's a queen |
144 | new_move->part = PART_QUEEN; // it's a queen |
| 143 | else if (new_move->pgntext[fieldstop] == L'K') |
145 | else if (towupper (new_move->pgntext[fieldstop]) == L'K') |
| 144 | new_move->part = PART_KING; // it's a king |
146 | new_move->part = PART_KING; // it's a king |
| 145 | else |
147 | else |
| 146 | return (false); // on error, cancel |
148 | return (false); // on error, cancel |
| 147 | } |
149 | } |
| 148 | else |
150 | else |