Rev 64 | Rev 74 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 64 | Rev 65 | ||
|---|---|---|---|
| Line 23... | Line 23... | ||
| 23 | 23 | ||
| 24 | int fieldstart; |
24 | int fieldstart; |
| 25 | int fieldstop; |
25 | int fieldstop; |
| 26 | int length; |
26 | int length; |
| 27 | 27 | ||
| 28 | // first, get string length |
28 | // first, get move string length |
| 29 | length = wcslen (new_move->pgntext); |
29 | length = wcslen (new_move->pgntext); |
| 30 | 30 | ||
| 31 | // parse it from the beginning |
31 | // parse it from the beginning |
| 32 | fieldstart = 0; |
32 | fieldstart = 0; |
| 33 | fieldstop = 0; |
33 | fieldstop = 0; |
| 34 | 34 | ||
| 35 | // find where it stops |
35 | // find where it stops |
| 36 | while ((fieldstop < length) && !iswspace (new_move->pgntext[fieldstop])) |
36 | while ((fieldstop < length) && !iswspace (new_move->pgntext[fieldstop])) |
| 37 | fieldstop++; // reach the |
37 | fieldstop++; // reach the first space |
| - | 38 | fieldstop--; // ignore the space |
|
| 38 | 39 | ||
| - | 40 | // does it finish with a move value estimation ? |
|
| - | 41 | while ((fieldstop >= fieldstart) && ((new_move->pgntext[fieldstop] == L'?') || (new_move->pgntext[fieldstop] == L'!'))) |
|
| 39 | fieldstop--; // ignore |
42 | fieldstop--; // ignore these signs, they are redundant |
| - | 43 | ||
| - | 44 | // does it finish with a check or a checkmate sign ? |
|
| - | 45 | if ((fieldstop >= fieldstart) && ((new_move->pgntext[fieldstop] == L'+') || (new_move->pgntext[fieldstop] == L'#'))) |
|
| - | 46 | fieldstop--; // chop off these signs, they are redundant |
|
| 40 | 47 | ||
| 41 | // reset relevant parts of the move we're about to build |
48 | // reset relevant parts of the move we're about to build |
| 42 | new_move->color = move_color; // save its color |
49 | new_move->color = move_color; // save its color |
| 43 | new_move->part = PART_NONE; |
50 | new_move->part = PART_NONE; |
| 44 | new_move->promotion_type = PART_NONE; |
51 | new_move->promotion_type = PART_NONE; |
| 45 | new_move->source[0] = -1; |
52 | new_move->source[0] = -1; |
| 46 | new_move->source[1] = -1; |
53 | new_move->source[1] = -1; |
| 47 | new_move->target[0] = -1; |
54 | new_move->target[0] = -1; |
| 48 | new_move->target[1] = -1; |
55 | new_move->target[1] = -1; |
| 49 | - | ||
| 50 | // does it finish with a move value estimation ? |
- | |
| 51 | while ((fieldstop >= fieldstart) && ((new_move->pgntext[fieldstop] == L'?') || (new_move->pgntext[fieldstop] == L'!'))) |
- | |
| 52 | fieldstop--; // chop off these signs, they are redundant |
- | |
| 53 | - | ||
| 54 | // does it finish with a check or a checkmate sign ? |
- | |
| 55 | if ((fieldstop >= fieldstart) && ((new_move->pgntext[fieldstop] == L'+') || (new_move->pgntext[fieldstop] == L'#'))) |
- | |
| 56 | fieldstop--; // chop off these signs, they are redundant |
- | |
| 57 | 56 | ||
| 58 | // is it a long castle ? |
57 | // is it a long castle ? |
| 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 | if ((_wcsnicmp (&new_move->pgntext[fieldstart], L"O-O-O", 5) == 0) || (wcsncmp (&new_move->pgntext[fieldstart], L"0-0-0", 5) == 0)) |
| 60 | { |
59 | { |
| 61 | new_move->source[0] = (move_color == COLOR_WHITE ? 0 : 7); |
60 | new_move->source[0] = (move_color == COLOR_WHITE ? 0 : 7); |
| Line 76... | Line 75... | ||
| 76 | } |
75 | } |
| 77 | 76 | ||
| 78 | // else it's a normal move |
77 | // else it's a normal move |
| 79 | else |
78 | else |
| 80 | { |
79 | { |
| 81 | // is the last character a part type ? |
80 | // is the last character a part type ? (WARNING: PART TYPES ARE MANDATORILY IN UPPERCASE) |
| 82 | if ((fieldstop >= fieldstart) && |
81 | if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'R')) |
| 83 | { |
82 | { |
| 84 | new_move->promotion_type = PART_ROOK; // there's a promotion to rook |
83 | new_move->promotion_type = PART_ROOK; // there's a promotion to rook |
| 85 | fieldstop--; // proceed to previous character |
84 | fieldstop--; // proceed to previous character |
| 86 | } |
85 | } |
| 87 | else if ((fieldstop >= fieldstart) && |
86 | else if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'N')) |
| 88 | { |
87 | { |
| 89 | new_move->promotion_type = PART_KNIGHT; // there's a promotion to knight |
88 | new_move->promotion_type = PART_KNIGHT; // there's a promotion to knight |
| 90 | fieldstop--; // proceed to previous character |
89 | fieldstop--; // proceed to previous character |
| 91 | } |
90 | } |
| 92 | else if ((fieldstop >= fieldstart) && |
91 | else if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'B')) |
| 93 | { |
92 | { |
| 94 | new_move->promotion_type = PART_BISHOP; // there's a promotion to bishop |
93 | new_move->promotion_type = PART_BISHOP; // there's a promotion to bishop |
| 95 | fieldstop--; // proceed to previous character |
94 | fieldstop--; // proceed to previous character |
| 96 | } |
95 | } |
| 97 | else if ((fieldstop >= fieldstart) && |
96 | else if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'Q')) |
| 98 | { |
97 | { |
| 99 | new_move->promotion_type = PART_QUEEN; // there's a promotion to queen |
98 | new_move->promotion_type = PART_QUEEN; // there's a promotion to queen |
| 100 | fieldstop--; // proceed to previous character |
99 | fieldstop--; // proceed to previous character |
| 101 | } |
100 | } |
| 102 | 101 | ||
| Line 117... | Line 116... | ||
| 117 | } |
116 | } |
| 118 | 117 | ||
| 119 | if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'x')) |
118 | if ((fieldstop >= fieldstart) && (new_move->pgntext[fieldstop] == L'x')) |
| 120 | fieldstop--; // if there's a taking piece indication, it's superfluous, so skip it |
119 | fieldstop--; // if there's a taking piece indication, it's superfluous, so skip it |
| 121 | 120 | ||
| 122 | // read the |
121 | // read the optional source line and column |
| 123 | if ((fieldstop >= fieldstart) && (WCHAR_TO_LINE (new_move->pgntext[fieldstop]) != -1)) |
122 | if ((fieldstop >= fieldstart) && (WCHAR_TO_LINE (new_move->pgntext[fieldstop]) != -1)) |
| 124 | { |
123 | { |
| 125 | new_move->source[0] = WCHAR_TO_LINE (new_move->pgntext[fieldstop]); // read the source line |
124 | new_move->source[0] = WCHAR_TO_LINE (new_move->pgntext[fieldstop]); // read the source line |
| 126 | fieldstop--; // proceed to previous character |
125 | fieldstop--; // proceed to previous character |
| 127 | } |
126 | } |
| Line 129... | Line 128... | ||
| 129 | { |
128 | { |
| 130 | new_move->source[1] = WCHAR_TO_COLUMN (new_move->pgntext[fieldstop]); // read the source column (WARNING: ONLY IF LOWERCASE) |
129 | new_move->source[1] = WCHAR_TO_COLUMN (new_move->pgntext[fieldstop]); // read the source column (WARNING: ONLY IF LOWERCASE) |
| 131 | fieldstop--; // proceed to previous character |
130 | fieldstop--; // proceed to previous character |
| 132 | } |
131 | } |
| 133 | 132 | ||
| 134 | // read the part's type |
133 | // read the part's type (WARNING: PART TYPES ARE MANDATORILY IN UPPERCASE) |
| 135 | if (fieldstop >= fieldstart) |
134 | if (fieldstop >= fieldstart) |
| 136 | { |
135 | { |
| 137 | if |
136 | if (new_move->pgntext[fieldstop] == L'R') new_move->part = PART_ROOK; // it's a rook |
| 138 | else if |
137 | else if (new_move->pgntext[fieldstop] == L'N') new_move->part = PART_KNIGHT; // it's a knight |
| 139 | else if |
138 | else if (new_move->pgntext[fieldstop] == L'B') new_move->part = PART_BISHOP; // it's a bishop |
| 140 | else if |
139 | else if (new_move->pgntext[fieldstop] == L'Q') new_move->part = PART_QUEEN; // it's a queen |
| 141 | else if |
140 | else if (new_move->pgntext[fieldstop] == L'K') new_move->part = PART_KING; // it's a king |
| 142 | else if |
141 | else if (new_move->pgntext[fieldstop] == L'P') new_move->part = PART_PAWN; // it's a pawn (Wikipedia says "P" is a valid part type in PGN texts...) |
| 143 | else return (false); // on error, cancel |
142 | else return (false); // on error, cancel |
| 144 | } |
143 | } |
| 145 | else |
144 | else |
| 146 | new_move->part = PART_PAWN; // if not specified, it's a pawn |
145 | new_move->part = PART_PAWN; // if not specified, it's a pawn |
| 147 | } |
146 | } |