|
|
1.1 ! root 1: /* This file contains code for X-CHESS. ! 2: Copyright (C) 1986 Free Software Foundation, Inc. ! 3: ! 4: This file is part of X-CHESS. ! 5: ! 6: X-CHESS is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the X-CHESS General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: X-CHESS, but only under the conditions described in the ! 15: X-CHESS General Public License. A copy of this license is ! 16: supposed to have been given to you along with X-CHESS so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: /* RCS Info: $Revision: 1.4 $ on $Date: 86/11/23 17:17:32 $ ! 23: * $Source: /users/faustus/xchess/RCS/control.c,v $ ! 24: * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group ! 25: * Permission is granted to do anything with this code except sell it ! 26: * or remove this message. ! 27: * ! 28: * Deal with input from the user. ! 29: */ ! 30: ! 31: #include "xchess.h" ! 32: ! 33: move *moves; ! 34: move *foremoves; ! 35: color nexttomove = WHITE; ! 36: bool noisyflag = false; ! 37: ! 38: move *lastmove; ! 39: static move *thismove; ! 40: ! 41: static void screen_move(); ! 42: ! 43: void ! 44: button_pressed(event, win) ! 45: XEvent *event; ! 46: windata *win; ! 47: { ! 48: int x, y; ! 49: XKeyEvent *ev = (XKeyEvent *) event; ! 50: ! 51: if (!oneboard && (win->color != nexttomove)) { ! 52: message_add(win, "Wrong player!\n", true); ! 53: return; ! 54: } ! 55: if (progflag && (nexttomove == (blackflag ? WHITE : BLACK))) { ! 56: message_add(win, "Wait for the computer...\n", true); ! 57: return; ! 58: } ! 59: if (loading_flag) { ! 60: message_add(win, "You'd better not do that now...\n", true); ! 61: return; ! 62: } ! 63: ! 64: /* Figure out what piece he is pointing at. */ ! 65: x = ev->x / (SQUARE_WIDTH + BORDER_WIDTH); ! 66: y = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH); ! 67: ! 68: if (win->flipped) { ! 69: y = SIZE - y - 1; ! 70: x = SIZE - x - 1; ! 71: } ! 72: ! 73: if ((x < 0) || (x >= SIZE) || (y < 0) || (y >= SIZE)) { ! 74: fprintf(stderr, "Bad coords (%d, %d)\n", x, y); ! 75: return; ! 76: } ! 77: ! 78: if (oneboard && (chessboard->square[y][x].color != nexttomove)) { ! 79: message_add(win, "Wrong player!\n", true); ! 80: return; ! 81: } else if (!oneboard && (chessboard->square[y][x].color != ! 82: win->color)) { ! 83: message_add(win, "Can't move that\n", true); ! 84: return; ! 85: } ! 86: ! 87: thismove = alloc(move); ! 88: thismove->fromx = x; ! 89: thismove->fromy = y; ! 90: thismove->piece.color = chessboard->square[y][x].color; ! 91: thismove->piece.type = chessboard->square[y][x].type; ! 92: ! 93: if (debug) ! 94: fprintf(stderr, "%s selected his %s at (%d, %d)...\n", ! 95: colornames[(int) thismove->piece.color], ! 96: piecenames[(int) thismove->piece.type], ! 97: thismove->fromy, thismove->fromx); ! 98: return; ! 99: } ! 100: ! 101: void ! 102: button_released(event, win) ! 103: XEvent *event; ! 104: windata *win; ! 105: { ! 106: int x, y; ! 107: XKeyEvent *ev = (XKeyEvent *) event; ! 108: ! 109: if (!thismove) { ! 110: /* fprintf(stderr, "Error: button hasn't been pressed\n"); */ ! 111: return; ! 112: } ! 113: if (loading_flag) ! 114: return; ! 115: ! 116: /* Figure out what piece he is pointing at. */ ! 117: x = ev->x / (SQUARE_WIDTH + BORDER_WIDTH); ! 118: y = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH); ! 119: ! 120: if (win->flipped) { ! 121: y = SIZE - y - 1; ! 122: x = SIZE - x - 1; ! 123: } ! 124: ! 125: if ((x < 0) || (x >= SIZE) || (y < 0) || (y >= SIZE)) { ! 126: fprintf(stderr, "Bad coords (%d, %d)\n", x, y); ! 127: return; ! 128: } ! 129: ! 130: if ((thismove->fromx == x) && (thismove->fromy == y)) { ! 131: message_add(win, "Hey, you touch it, you move it, buddy.\n", ! 132: true); ! 133: return; ! 134: } ! 135: if (chessboard->square[y][x].color == thismove->piece.color) { ! 136: message_add(win, "Can't put one piece on top of another\n", ! 137: true); ! 138: return; ! 139: } ! 140: ! 141: thismove->tox = x; ! 142: thismove->toy = y; ! 143: thismove->taken.color = chessboard->square[y][x].color; ! 144: thismove->taken.type = chessboard->square[y][x].type; ! 145: if (thismove->taken.color != NONE) ! 146: thismove->type = CAPTURE; ! 147: else if ((thismove->piece.type == KING) && (thismove->fromx == 4) && ! 148: (thismove->tox == 6) && ! 149: (thismove->toy == thismove->fromy)) ! 150: thismove->type = KCASTLE; ! 151: else if ((thismove->piece.type == KING) && (thismove->tox == 2) && ! 152: (thismove->fromx == 4) && ! 153: (thismove->toy == thismove->fromy)) ! 154: thismove->type = QCASTLE; ! 155: else ! 156: thismove->type = MOVE; ! 157: ! 158: /* Now check the en-passant case... */ ! 159: if ((thismove->type == MOVE) && ((thismove->tox == thismove->fromx + 1) ! 160: || (thismove->tox == thismove->fromx - 1)) && ! 161: (thismove->piece.type == PAWN) && lastmove && ! 162: (lastmove->tox == lastmove->fromx) && (lastmove->fromx ! 163: == thismove->tox) && ((lastmove->fromy + lastmove->toy) ! 164: / 2 == thismove->toy)) { ! 165: thismove->type = CAPTURE; ! 166: thismove->enpassant = true; ! 167: thismove->taken = lastmove->piece; ! 168: } ! 169: ! 170: if (!valid_move(thismove, chessboard)) { ! 171: message_add(win, "Invalid move.\n", true); ! 172: return; ! 173: } ! 174: ! 175: if (debug) ! 176: fprintf(stderr, "\t... and moved it to (%d, %d), type %s\n", ! 177: thismove->toy, thismove->tox, ! 178: movetypenames[(int) thismove->type]); ! 179: move_piece(thismove); ! 180: ! 181: if (thismove->check) { ! 182: message_add(win1, "Check.\n", true); ! 183: if (!oneboard) { ! 184: message_add(win2, "Check.\n", true); ! 185: } ! 186: } ! 187: ! 188: if (!moves) ! 189: moves = lastmove = thismove; ! 190: else ! 191: lastmove = lastmove->next = thismove; ! 192: ! 193: if (progflag) ! 194: program_send(thismove); ! 195: ! 196: thismove = NULL; ! 197: nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE); ! 198: clock_switch(); ! 199: ! 200: return; ! 201: } ! 202: ! 203: void ! 204: prog_move(m) ! 205: move *m; ! 206: { ! 207: if (debug) ! 208: fprintf(stderr, "program moves from (%d, %d) to (%d, %d)\n", ! 209: m->fromy, m->fromx, m->toy, m->tox); ! 210: move_piece(m); ! 211: ! 212: if (!moves) ! 213: moves = lastmove = m; ! 214: else ! 215: lastmove = lastmove->next = m; ! 216: ! 217: nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE); ! 218: clock_switch(); ! 219: ! 220: return; ! 221: } ! 222: ! 223: void ! 224: move_piece(m) ! 225: move *m; ! 226: { ! 227: /* Update the screen... */ ! 228: screen_move(m); ! 229: ! 230: /* Move the piece on the board... */ ! 231: board_move(chessboard, m); ! 232: ! 233: /* And record it... */ ! 234: record_move(m); ! 235: ! 236: if (noisyflag) { ! 237: XBell(win1->display, 50); ! 238: XBell(win2->display, 50); ! 239: } ! 240: return; ! 241: } ! 242: ! 243: static void ! 244: screen_move(m) ! 245: move *m; ! 246: { ! 247: piece pp; ! 248: ! 249: switch (m->type) { ! 250: case CAPTURE: ! 251: jail_add(&m->taken); ! 252: /* FALLTHRU */ ! 253: ! 254: case MOVE: ! 255: win_erasepiece(m->fromy, m->fromx, WHITE); ! 256: if (win_flashmove) ! 257: win_flash(m, WHITE); ! 258: win_drawpiece(&m->piece, m->toy, m->tox, WHITE); ! 259: if (m->enpassant) ! 260: win_erasepiece(m->toy + ((m->piece.color == WHITE) ? ! 261: 1 : -1), m->tox, WHITE); ! 262: if (!oneboard) { ! 263: win_erasepiece(m->fromy, m->fromx, BLACK); ! 264: if (win_flashmove) ! 265: win_flash(m, BLACK); ! 266: win_drawpiece(&m->piece, m->toy, m->tox, BLACK); ! 267: if (m->enpassant) ! 268: win_erasepiece(m->toy + ((m->piece.color == ! 269: WHITE) ? 1 : -1), m->tox, WHITE); ! 270: } ! 271: if ((m->piece.type == PAWN) && (((m->piece.color == BLACK) && ! 272: (m->toy == 7)) || ((m->piece.color == WHITE) && ! 273: (m->toy == 0)))) { ! 274: pp.color = m->piece.color; ! 275: pp.type = QUEEN; ! 276: win_drawpiece(&pp, m->toy, m->tox, WHITE); ! 277: if (!oneboard) ! 278: win_drawpiece(&m->piece, m->toy, m->tox, BLACK); ! 279: } ! 280: break; ! 281: ! 282: case KCASTLE: ! 283: if (m->piece.color == WHITE) { ! 284: win_erasepiece(7, 4, WHITE); ! 285: win_erasepiece(7, 7, WHITE); ! 286: if (win_flashmove) ! 287: win_flash(m, WHITE); ! 288: win_drawpiece(&m->piece, 7, 6, WHITE); ! 289: win_drawpiece(&chessboard->square[7][7], 7, 5, WHITE); ! 290: if (!oneboard) { ! 291: win_erasepiece(7, 4, BLACK); ! 292: win_erasepiece(7, 7, BLACK); ! 293: if (win_flashmove) ! 294: win_flash(m, BLACK); ! 295: win_drawpiece(&m->piece, 7, 6, BLACK); ! 296: win_drawpiece(&chessboard->square[7][7], 7, 5, ! 297: BLACK); ! 298: } ! 299: } else { ! 300: win_erasepiece(0, 4, WHITE); ! 301: win_erasepiece(0, 7, WHITE); ! 302: if (win_flashmove) ! 303: win_flash(m, WHITE); ! 304: win_drawpiece(&m->piece, 0, 6, WHITE); ! 305: win_drawpiece(&chessboard->square[0][7], 0, 5, WHITE); ! 306: if (!oneboard) { ! 307: win_erasepiece(0, 4, BLACK); ! 308: win_erasepiece(0, 7, BLACK); ! 309: if (win_flashmove) ! 310: win_flash(m, BLACK); ! 311: win_drawpiece(&m->piece, 0, 6, BLACK); ! 312: win_drawpiece(&chessboard->square[0][7], 0, 5, ! 313: BLACK); ! 314: } ! 315: } ! 316: break; ! 317: ! 318: case QCASTLE: ! 319: if (m->piece.color == WHITE) { ! 320: win_erasepiece(7, 4, WHITE); ! 321: win_erasepiece(7, 0, WHITE); ! 322: if (win_flashmove) ! 323: win_flash(m, WHITE); ! 324: win_drawpiece(&m->piece, 7, 2, WHITE); ! 325: win_drawpiece(&chessboard->square[7][0], 7, 3, WHITE); ! 326: if (!oneboard) { ! 327: win_erasepiece(7, 4, BLACK); ! 328: win_erasepiece(7, 0, BLACK); ! 329: if (win_flashmove) ! 330: win_flash(m, BLACK); ! 331: win_drawpiece(&m->piece, 7, 2, BLACK); ! 332: win_drawpiece(&chessboard->square[7][7], 7, 3, ! 333: BLACK); ! 334: } ! 335: } else { ! 336: win_erasepiece(0, 4, WHITE); ! 337: win_erasepiece(0, 0, WHITE); ! 338: if (win_flashmove) ! 339: win_flash(m, WHITE); ! 340: win_drawpiece(&m->piece, 0, 2, WHITE); ! 341: win_drawpiece(&chessboard->square[0][0], 0, 3, WHITE); ! 342: if (!oneboard) { ! 343: win_erasepiece(0, 4, BLACK); ! 344: win_erasepiece(0, 0, BLACK); ! 345: if (win_flashmove) ! 346: win_flash(m, BLACK); ! 347: win_drawpiece(&m->piece, 0, 2, BLACK); ! 348: win_drawpiece(&chessboard->square[0][7], 0, 3, ! 349: BLACK); ! 350: } ! 351: } ! 352: break; ! 353: ! 354: default: ! 355: fprintf(stderr, "Bad move type %d\n", m->type); ! 356: } ! 357: return; ! 358: } ! 359: ! 360: /* Retract the last move made... */ ! 361: ! 362: void ! 363: replay() ! 364: { ! 365: move *m = lastmove, bm; ! 366: ! 367: memset(&bm, 0, sizeof(bm)); ! 368: switch (m->type) { ! 369: case MOVE: ! 370: bm.type = MOVE; ! 371: bm.piece = m->piece; ! 372: bm.fromx = m->tox; ! 373: bm.fromy = m->toy; ! 374: bm.tox = m->fromx; ! 375: bm.toy = m->fromy; ! 376: board_move(chessboard, &bm); ! 377: screen_move(&bm); ! 378: break; ! 379: ! 380: case CAPTURE: ! 381: bm.type = MOVE; ! 382: bm.piece = m->piece; ! 383: bm.fromx = m->tox; ! 384: bm.fromy = m->toy; ! 385: bm.tox = m->fromx; ! 386: bm.toy = m->fromy; ! 387: board_move(chessboard, &bm); ! 388: screen_move(&bm); ! 389: chessboard->square[m->toy][m->tox] = m->taken; ! 390: bm.piece = m->taken; ! 391: bm.fromx = bm.tox = m->tox; ! 392: bm.fromy = bm.toy = m->toy; ! 393: screen_move(&bm); ! 394: jail_remove(&m->taken); ! 395: break; ! 396: ! 397: case KCASTLE: ! 398: bm.type = MOVE; ! 399: bm.piece.type = KING; ! 400: bm.piece.color = m->piece.color; ! 401: bm.fromx = 6; ! 402: bm.tox = 4; ! 403: bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0; ! 404: board_move(chessboard, &bm); ! 405: screen_move(&bm); ! 406: bm.type = MOVE; ! 407: bm.piece.type = ROOK; ! 408: bm.piece.color = m->piece.color; ! 409: bm.fromx = 5; ! 410: bm.tox = 7; ! 411: bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0; ! 412: board_move(chessboard, &bm); ! 413: screen_move(&bm); ! 414: if (m->piece.color == WHITE) ! 415: chessboard->white_cant_castle_k = false; ! 416: else ! 417: chessboard->black_cant_castle_k = false; ! 418: break; ! 419: ! 420: case QCASTLE: ! 421: bm.type = MOVE; ! 422: bm.piece.type = KING; ! 423: bm.piece.color = m->piece.color; ! 424: bm.fromx = 2; ! 425: bm.tox = 4; ! 426: bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0; ! 427: board_move(chessboard, &bm); ! 428: screen_move(&bm); ! 429: bm.type = MOVE; ! 430: bm.piece.type = ROOK; ! 431: bm.piece.color = m->piece.color; ! 432: bm.fromx = 3; ! 433: bm.tox = 0; ! 434: bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0; ! 435: board_move(chessboard, &bm); ! 436: screen_move(&bm); ! 437: if (m->piece.color == WHITE) ! 438: chessboard->white_cant_castle_q = false; ! 439: else ! 440: chessboard->black_cant_castle_q = false; ! 441: break; ! 442: } ! 443: record_back(); ! 444: ! 445: nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE); ! 446: clock_switch(); ! 447: ! 448: if (!moves->next) { ! 449: moves->next = foremoves; ! 450: foremoves = moves; ! 451: moves = lastmove = NULL; ! 452: } else { ! 453: for (m = moves; m->next; m = m->next) ! 454: lastmove = m; ! 455: lastmove->next->next = foremoves; ! 456: foremoves = lastmove->next; ! 457: lastmove->next = NULL; ! 458: } ! 459: ! 460: if (progflag) ! 461: program_undo(); ! 462: ! 463: return; ! 464: } ! 465: ! 466: /* Put back the last move undone. */ ! 467: ! 468: void ! 469: forward() ! 470: { ! 471: prog_move(foremoves); ! 472: foremoves = foremoves->next; ! 473: return; ! 474: } ! 475: ! 476: /* End the game. */ ! 477: ! 478: void ! 479: cleanup(s) ! 480: char *s; ! 481: { ! 482: if (progflag) ! 483: program_end(); ! 484: record_end(s); ! 485: XSync(win1->display, 0); ! 486: if (!oneboard) { ! 487: XSync(win2->display, 0); ! 488: } ! 489: exit(0); ! 490: } ! 491: ! 492: void ! 493: restart() ! 494: { ! 495: moves = lastmove = thismove = NULL; ! 496: nexttomove = WHITE; ! 497: ! 498: clock_init(win1, WHITE); ! 499: clock_init(win1, BLACK); ! 500: jail_init(win1); ! 501: if (!oneboard) { ! 502: clock_init(win2, WHITE); ! 503: clock_init(win2, BLACK); ! 504: jail_init(win2); ! 505: } ! 506: board_init(chessboard); ! 507: win_restart(); ! 508: record_reset(); ! 509: if (progflag) { ! 510: program_end(); ! 511: program_init(progname); ! 512: } ! 513: return; ! 514: } ! 515:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.