2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 Contains stuff for setting up boards in examine mode
25 static int check_valid_square(char* square)
27 if (strlen (square) == 2) {
28 if ( (square[0] <= 'a') && (square[0] >= 'h')
29 && (square[1] <= '1') && (square [1] >= '8') )
36 /* Check the position is valid
37 ie two kings - one white one black
38 ie no pawns on 1st or 8th ranks
39 only the king that is to move may be in check,
40 checkmate and stalemate */
42 static int validate_position (int p,struct game_state_t *b)
48 for (f = 0; (f < 8); f++) {
49 for (r = 0; (r < 8); r++) {
50 if (b->board[f][r] == W_KING) {
53 pprintf (p,"You can only have one white king.\n");
57 if (b->board[f][r] == B_KING) {
60 pprintf (p,"You can only have one black king.\n");
64 if (((b->board[f][r] == W_PAWN) || (b->board[f][r] == B_PAWN)) &&
65 ((r == 0) || (r == 7))) {
66 pprintf (p,"Pawns cannot be placed on the first or eighth rank.\n");
72 pprintf (p,"There is no white king.\n");
76 pprintf (p,"There is no black king.\n");
79 if (b->onMove == WHITE) { pprintf(p, "WHITE to move\n"); }
80 else if (b->onMove == BLACK) { pprintf(p, "BLACK to move\n"); }
81 else pprintf(p, "ERROR!!\n");
84 pprintf (p,"Only the player to move may be in check.\n");
87 if (!has_legal_move(b)) {
88 b->onMove = CToggle(b->onMove);
90 pprintf (p, "%s is checkmated.\n",
91 b->onMove == WHITE ? "BLACK" : "WHITE");
93 pprintf (p, "%s is stalemated.\n",
94 b->onMove == WHITE ? "BLACK" : "WHITE");
96 b->onMove = CToggle(b->onMove);
98 return 1; /* valid position */
101 int com_setup (int p,param_list param)
103 struct player *pp = &player_globals.parray[p];
106 if ((pp->game <0) || (game_globals.garray[pp->game].status != GAME_SETUP)) {
107 if (param[0].type == TYPE_NULL) {
109 if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
110 game_free (pp->game);
111 game_globals.garray[pp->game].status = GAME_SETUP;
112 game_globals.garray[pp->game].numHalfMoves = 0;
113 game_globals.garray[pp->game].totalHalfMoves = 0;
114 game_globals.garray[pp->game].revertHalfMove = 0;
115 pprintf (p,"Entering examine(setup) mode.\n");
118 pcommand (p,"examine setup");
119 return COM_OK_NOPROMPT;
121 pprintf(p, "You are not setting up a position.\n");
125 gamenum = game_globals.garray[pp->game].game_state.gameNum;
126 if (param[0].type != TYPE_NULL) {
127 if (!strcmp("clear",param[0].val.word)) {
128 board_clear(&(game_globals.garray[pp->game].game_state));
129 game_globals.garray[pp->game].game_state.gameNum = gamenum;
130 send_board_to(pp->game, p);
131 pprintf (p,"Board cleared.\n");
133 } else if (!strcmp("start",param[0].val.word)) {
134 board_standard(&(game_globals.garray[pp->game].game_state));
135 game_globals.garray[pp->game].game_state.gameNum = gamenum;
136 send_board_to(pp->game, p);
137 pprintf (p,"Board set up as starting position.\n");
139 } else if (!strcmp("fen",param[0].val.word) && param[1].type != TYPE_NULL) {
140 FEN_to_board(param[1].val.string, &(game_globals.garray[pp->game].game_state));
141 game_globals.garray[pp->game].game_state.gameNum = gamenum;
142 send_board_to(pp->game, p);
143 pprintf (p,"Board set up by FEN.\n");
145 } else if (!strcmp("done",param[0].val.word)) {
146 if (validate_position (p,&(game_globals.garray[pp->game].game_state))) {
147 game_globals.garray[pp->game].status = GAME_EXAMINE;
148 pprintf(p,"Game is validated - entering examine mode.\n");
149 MakeFENpos(pp->game, game_globals.garray[pp->game].FENstartPos);
151 pprintf(p,"The position is not valid - staying in setup mode.\n");
153 } else { /* try to load a category of board */
154 if (param[1].type != TYPE_NULL) {
155 if (!board_init (pp->game,&(game_globals.garray[pp->game].game_state),param[0].val.word,param[1].val.word)) {
156 game_globals.garray[pp->game].game_state.gameNum = gamenum;
157 send_board_to(pp->game, p);
158 pprintf (p,"Board set up as %s %s.\n",param[0].val.word,param[1].val.word);
160 pprintf (p,"Board %s %s is unavailable.\n",param[0].val.word,param[1].val.word);
161 game_globals.garray[pp->game].game_state.gameNum = gamenum;
167 pprintf (p, "You have supplied an incorrect parameter to setup.\n");
171 int com_tomove (int p,param_list param)
173 struct player *pp = &player_globals.parray[p];
174 if ((pp->game <0) || (game_globals.garray[pp->game].status != GAME_SETUP)) {
176 if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
177 pprintf (p,"This game is active - type 'setup' to allow editing.\n");
180 pprintf(p, "You are not setting up a position.\n");
183 if (!strcmp("white",param[0].val.word))
184 game_globals.garray[pp->game].game_state.onMove = WHITE;
185 else if (!strcmp("black",param[0].val.word))
186 game_globals.garray[pp->game].game_state.onMove = BLACK;
188 pprintf (p,"Please type: tomove white or tomove black\n");
191 pcommand (p,"refresh");
192 return COM_OK_NOPROMPT;
195 int com_clrsquare (int p,param_list param)
197 struct player *pp = &player_globals.parray[p];
198 if ((pp->game <0) || (game_globals.garray[pp->game].status != GAME_SETUP)) {
200 if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
201 pprintf (p,"This game is active - type 'setup' to allow editing.\n");
204 pprintf(p, "You are not setting up a position.\n");
208 if (!check_valid_square(param[0].val.word)) {
209 pprintf (p,"You must specify a square.");
213 pcommand (p,"x@%s",param[0].val.word);
214 return COM_OK_NOPROMPT;
217 /* allows the following
219 x@rf or X@rf - clear a square
220 P@rf - drop a white pawn
221 p@rf - drop a black pawn
222 wp@rf - drop a white pawn
223 bp@rf - drop a black pawn
224 can replace the @ with a * - some people do not have a @ key
227 /* having to check before then after is lame - will change this later */
228 int is_drop(char* dropstr)
231 int len = strlen (dropstr);
233 if ((len < 4) || (len > 5))
238 if ((dropstr[0] == 'x') || (dropstr[0] == 'X')) {
239 if (!((dropstr[1] == '@') || (dropstr[1] == '*')))
241 if (!check_valid_square(dropstr+2))
246 } else if (dropstr[0] == 'w') {
247 if (!((dropstr[1] == 'p') || (dropstr[1] == 'r') || (dropstr[1] == 'n') || (dropstr[1] == 'b') || (dropstr[1] == 'q') || (dropstr[1] == 'k')))
249 if (!((dropstr[2] == '@') || (dropstr[2] == '*')))
251 if (!check_valid_square(dropstr+3))
256 } else if (len == 5) { /* so b@e2 and bb@e2 aren't confused */
257 if (dropstr[0] == 'b') {
258 if (!((dropstr[1] == 'p') || (dropstr[1] == 'r') || (dropstr[1] == 'n') || (dropstr[1] == 'b') || (dropstr[1] == 'q') || (dropstr[1] == 'k')))
260 if (!((dropstr[2] == '@') || (dropstr[2] == '*')))
262 if (!check_valid_square(dropstr+3))
264 } else return 0; /* Exhausted 5 char possibilities */
266 /* check p@e3 and P@e3 */
268 } else if ((dropstr[0] == 'p') || (dropstr[0] == 'r') || (dropstr[0] == 'n') || (dropstr[0] == 'b') || (dropstr[0] == 'q') || (dropstr[0] == 'k') ||
269 (dropstr[0] == 'P') || (dropstr[0] == 'R') || (dropstr[0] == 'N') || (dropstr[0] == 'B') || (dropstr[0] == 'Q') || (dropstr[0] == 'K')) {
271 if (!((dropstr[1] == '@') || (dropstr[1] == '*')))
273 if (!check_valid_square(dropstr+2))
276 return 1; /* valid drop */
279 static void getsquare(char* square,int *f, int *r)
281 *f = square[0] - 'a';
282 *r = square[1] - '1';
285 int attempt_drop(int p,int g,char* dropstr)
287 int len = strlen (dropstr);
293 if ((len < 4) || (len > 5))
298 if ((dropstr[0] == 'x') || (dropstr[0] == 'X')) { /* as x must be clear */
299 getsquare(dropstr+2,&f,&r);
304 } else if (dropstr[0] == 'w') {
305 piece = CharToPiece(dropstr[1]) & 0x07;
307 getsquare(dropstr+3,&f,&r);
311 } else if (len == 5) { /* check length to avoid b@e2 and bb@e2 being confused */
312 if (dropstr[0] == 'b') {
313 piece = CharToPiece(dropstr[1]) | BLACK;
314 getsquare(dropstr+3,&f,&r);
317 /* check p@e3 and P@e3 */
320 if (!((dropstr[1] == '@') || (dropstr[1] == '*')))
323 piece = CharToPiece(dropstr[0]);
324 getsquare(dropstr+2,&f,&r);
328 game_globals.garray[g].game_state.board[f][r] = piece;
329 return 1; /* valid drop */