123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- /* This file contains code for X-CHESS.
- Copyright (C) 1986 Free Software Foundation, Inc.
- This file is part of X-CHESS.
- X-CHESS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the X-CHESS General Public
- License for full details.
- Everyone is granted permission to copy, modify and redistribute
- X-CHESS, but only under the conditions described in the
- X-CHESS General Public License. A copy of this license is
- supposed to have been given to you along with X-CHESS so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies. */
- /* RCS Info: $Revision: 1.4 $ on $Date: 86/11/23 17:17:32 $
- * $Source: /users/faustus/xchess/RCS/control.c,v $
- * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
- * Permission is granted to do anything with this code except sell it
- * or remove this message.
- *
- * Deal with input from the user.
- */
- #include "xchess.h"
- move *moves;
- move *foremoves;
- color nexttomove = WHITE;
- bool noisyflag = false;
- static move *lastmove;
- static move *thismove;
- static void screen_move();
- void
- button_pressed(event, win)
- XEvent *event;
- windata *win;
- {
- int x, y;
- XKeyOrButtonEvent *ev = (XKeyOrButtonEvent *) event;
- if (!oneboard && (win->color != nexttomove)) {
- message_add(win, "Wrong player!\n", true);
- return;
- }
- if (progflag && (nexttomove == (blackflag ? WHITE : BLACK))) {
- message_add(win, "Wait for the computer...\n", true);
- return;
- }
- if (loading_flag) {
- message_add(win, "You'd better not do that now...\n", true);
- return;
- }
- /* Figure out what piece he is pointing at. */
- x = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
- y = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
- if (win->flipped) {
- y = SIZE - y - 1;
- x = SIZE - x - 1;
- }
- if ((x < 0) || (x >= SIZE) || (y < 0) || (y >= SIZE)) {
- fprintf(stderr, "Bad coords (%d, %d)\n", x, y);
- return;
- }
- if (oneboard && (chessboard->square[y][x].color != nexttomove)) {
- message_add(win, "Wrong player!\n", true);
- return;
- } else if (!oneboard && (chessboard->square[y][x].color !=
- win->color)) {
- message_add(win, "Can't move that\n", true);
- return;
- }
- thismove = alloc(move);
- thismove->fromx = x;
- thismove->fromy = y;
- thismove->piece.color = chessboard->square[y][x].color;
- thismove->piece.type = chessboard->square[y][x].type;
- if (debug)
- fprintf(stderr, "%s selected his %s at (%d, %d)...\n",
- colornames[(int) thismove->piece.color],
- piecenames[(int) thismove->piece.type],
- thismove->fromy, thismove->fromx);
- return;
- }
- void
- button_released(event, win)
- XEvent *event;
- windata *win;
- {
- int x, y;
- XKeyOrButtonEvent *ev = (XKeyOrButtonEvent *) event;
- if (!thismove) {
- /* fprintf(stderr, "Error: button hasn't been pressed\n"); */
- return;
- }
- if (loading_flag)
- return;
- /* Figure out what piece he is pointing at. */
- x = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
- y = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
- if (win->flipped) {
- y = SIZE - y - 1;
- x = SIZE - x - 1;
- }
- if ((x < 0) || (x >= SIZE) || (y < 0) || (y >= SIZE)) {
- fprintf(stderr, "Bad coords (%d, %d)\n", x, y);
- return;
- }
- if ((thismove->fromx == x) && (thismove->fromy == y)) {
- message_add(win, "Hey, you touch it, you move it, buddy.\n",
- true);
- return;
- }
- if (chessboard->square[y][x].color == thismove->piece.color) {
- message_add(win, "Can't put one piece on top of another\n",
- true);
- return;
- }
- thismove->tox = x;
- thismove->toy = y;
- thismove->taken.color = chessboard->square[y][x].color;
- thismove->taken.type = chessboard->square[y][x].type;
- if (thismove->taken.color != NONE)
- thismove->type = CAPTURE;
- else if ((thismove->piece.type == KING) && (thismove->fromx == 4) &&
- (thismove->tox == 6) &&
- (thismove->toy == thismove->fromy))
- thismove->type = KCASTLE;
- else if ((thismove->piece.type == KING) && (thismove->tox == 2) &&
- (thismove->fromx == 4) &&
- (thismove->toy == thismove->fromy))
- thismove->type = QCASTLE;
- else
- thismove->type = MOVE;
-
- /* Now check the en-passant case... */
- if ((thismove->type == MOVE) && ((thismove->tox == thismove->fromx + 1)
- || (thismove->tox == thismove->fromx - 1)) &&
- (thismove->piece.type == PAWN) && lastmove &&
- (lastmove->tox == lastmove->fromx) && (lastmove->fromx
- == thismove->tox) && ((lastmove->fromy + lastmove->toy)
- / 2 == thismove->toy)) {
- thismove->type = CAPTURE;
- thismove->enpassant = true;
- thismove->taken = lastmove->piece;
- }
- if (!valid_move(thismove, chessboard)) {
- message_add(win, "Invalid move.\n", true);
- return;
- }
- if (debug)
- fprintf(stderr, "\t... and moved it to (%d, %d), type %s\n",
- thismove->toy, thismove->tox,
- movetypenames[(int) thismove->type]);
- move_piece(thismove);
- if (thismove->check) {
- message_add(win1, "Check.\n", true);
- if (!oneboard) {
- message_add(win2, "Check.\n", true);
- }
- }
- if (!moves)
- moves = lastmove = thismove;
- else
- lastmove = lastmove->next = thismove;
- if (progflag)
- program_send(thismove);
- thismove = NULL;
- nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE);
- clock_switch();
- return;
- }
- void
- prog_move(m)
- move *m;
- {
- if (debug)
- fprintf(stderr, "program moves from (%d, %d) to (%d, %d)\n",
- m->fromy, m->fromx, m->toy, m->tox);
- move_piece(m);
- if (!moves)
- moves = lastmove = m;
- else
- lastmove = lastmove->next = m;
- nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE);
- clock_switch();
- return;
- }
- void
- move_piece(m)
- move *m;
- {
- /* Update the screen... */
- screen_move(m);
- /* Move the piece on the board... */
- board_move(chessboard, m);
- /* And record it... */
- record_move(m);
- if (noisyflag)
- XFeep(-4);
- return;
- }
- static void
- screen_move(m)
- move *m;
- {
- piece pp;
- switch (m->type) {
- case CAPTURE:
- jail_add(&m->taken);
- /* FALLTHRU */
- case MOVE:
- win_erasepiece(m->fromy, m->fromx, WHITE);
- if (win_flashmove)
- win_flash(m, WHITE);
- win_drawpiece(&m->piece, m->toy, m->tox, WHITE);
- if (m->enpassant)
- win_erasepiece(m->toy + ((m->piece.color == WHITE) ?
- 1 : -1), m->tox, WHITE);
- if (!oneboard) {
- win_erasepiece(m->fromy, m->fromx, BLACK);
- if (win_flashmove)
- win_flash(m, BLACK);
- win_drawpiece(&m->piece, m->toy, m->tox, BLACK);
- if (m->enpassant)
- win_erasepiece(m->toy + ((m->piece.color ==
- WHITE) ? 1 : -1), m->tox, WHITE);
- }
- if ((m->piece.type == PAWN) && (((m->piece.color == BLACK) &&
- (m->toy == 7)) || ((m->piece.color == WHITE) &&
- (m->toy == 0)))) {
- pp.color = m->piece.color;
- pp.type = QUEEN;
- win_drawpiece(&pp, m->toy, m->tox, WHITE);
- if (!oneboard)
- win_drawpiece(&m->piece, m->toy, m->tox, BLACK);
- }
- break;
-
- case KCASTLE:
- if (m->piece.color == WHITE) {
- win_erasepiece(7, 4, WHITE);
- win_erasepiece(7, 7, WHITE);
- if (win_flashmove)
- win_flash(m, WHITE);
- win_drawpiece(&m->piece, 7, 6, WHITE);
- win_drawpiece(&chessboard->square[7][7], 7, 5, WHITE);
- if (!oneboard) {
- win_erasepiece(7, 4, BLACK);
- win_erasepiece(7, 7, BLACK);
- if (win_flashmove)
- win_flash(m, BLACK);
- win_drawpiece(&m->piece, 7, 6, BLACK);
- win_drawpiece(&chessboard->square[7][7], 7, 5,
- BLACK);
- }
- } else {
- win_erasepiece(0, 4, WHITE);
- win_erasepiece(0, 7, WHITE);
- if (win_flashmove)
- win_flash(m, WHITE);
- win_drawpiece(&m->piece, 0, 6, WHITE);
- win_drawpiece(&chessboard->square[0][7], 0, 5, WHITE);
- if (!oneboard) {
- win_erasepiece(0, 4, BLACK);
- win_erasepiece(0, 7, BLACK);
- if (win_flashmove)
- win_flash(m, BLACK);
- win_drawpiece(&m->piece, 0, 6, BLACK);
- win_drawpiece(&chessboard->square[0][7], 0, 5,
- BLACK);
- }
- }
- break;
- case QCASTLE:
- if (m->piece.color == WHITE) {
- win_erasepiece(7, 4, WHITE);
- win_erasepiece(7, 0, WHITE);
- if (win_flashmove)
- win_flash(m, WHITE);
- win_drawpiece(&m->piece, 7, 2, WHITE);
- win_drawpiece(&chessboard->square[7][0], 7, 3, WHITE);
- if (!oneboard) {
- win_erasepiece(7, 4, BLACK);
- win_erasepiece(7, 0, BLACK);
- if (win_flashmove)
- win_flash(m, BLACK);
- win_drawpiece(&m->piece, 7, 2, BLACK);
- win_drawpiece(&chessboard->square[7][7], 7, 3,
- BLACK);
- }
- } else {
- win_erasepiece(0, 4, WHITE);
- win_erasepiece(0, 0, WHITE);
- if (win_flashmove)
- win_flash(m, WHITE);
- win_drawpiece(&m->piece, 0, 2, WHITE);
- win_drawpiece(&chessboard->square[0][0], 0, 3, WHITE);
- if (!oneboard) {
- win_erasepiece(0, 4, BLACK);
- win_erasepiece(0, 0, BLACK);
- if (win_flashmove)
- win_flash(m, BLACK);
- win_drawpiece(&m->piece, 0, 2, BLACK);
- win_drawpiece(&chessboard->square[0][7], 0, 3,
- BLACK);
- }
- }
- break;
- default:
- fprintf(stderr, "Bad move type %d\n", m->type);
- }
- return;
- }
- /* Retract the last move made... */
- void
- replay()
- {
- move *m = lastmove, bm;
- switch (m->type) {
- case MOVE:
- bm.type = MOVE;
- bm.piece = m->piece;
- bm.fromx = m->tox;
- bm.fromy = m->toy;
- bm.tox = m->fromx;
- bm.toy = m->fromy;
- board_move(chessboard, &bm);
- screen_move(&bm);
- break;
- case CAPTURE:
- bm.type = MOVE;
- bm.piece = m->piece;
- bm.fromx = m->tox;
- bm.fromy = m->toy;
- bm.tox = m->fromx;
- bm.toy = m->fromy;
- board_move(chessboard, &bm);
- screen_move(&bm);
- chessboard->square[m->toy][m->tox] = m->taken;
- bm.piece = m->taken;
- bm.fromx = bm.tox = m->tox;
- bm.fromy = bm.toy = m->toy;
- screen_move(&bm);
- jail_remove(&m->taken);
- break;
- case KCASTLE:
- bm.type = MOVE;
- bm.piece.type = KING;
- bm.piece.color = m->piece.color;
- bm.fromx = 6;
- bm.tox = 4;
- bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
- board_move(chessboard, &bm);
- screen_move(&bm);
- bm.type = MOVE;
- bm.piece.type = ROOK;
- bm.piece.color = m->piece.color;
- bm.fromx = 5;
- bm.tox = 7;
- bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
- board_move(chessboard, &bm);
- screen_move(&bm);
- if (m->piece.color == WHITE)
- chessboard->white_cant_castle_k = false;
- else
- chessboard->black_cant_castle_k = false;
- break;
- case QCASTLE:
- bm.type = MOVE;
- bm.piece.type = KING;
- bm.piece.color = m->piece.color;
- bm.fromx = 2;
- bm.tox = 4;
- bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
- board_move(chessboard, &bm);
- screen_move(&bm);
- bm.type = MOVE;
- bm.piece.type = ROOK;
- bm.piece.color = m->piece.color;
- bm.fromx = 3;
- bm.tox = 0;
- bm.fromy = bm.toy = (m->piece.color == WHITE) ? 7 : 0;
- board_move(chessboard, &bm);
- screen_move(&bm);
- if (m->piece.color == WHITE)
- chessboard->white_cant_castle_q = false;
- else
- chessboard->black_cant_castle_q = false;
- break;
- }
- record_back();
- nexttomove = ((nexttomove == WHITE) ? BLACK : WHITE);
- clock_switch();
- if (!moves->next) {
- moves->next = foremoves;
- foremoves = moves;
- moves = lastmove = NULL;
- } else {
- for (m = moves; m->next; m = m->next)
- lastmove = m;
- lastmove->next->next = foremoves;
- foremoves = lastmove->next;
- lastmove->next = NULL;
- }
- if (progflag)
- program_undo();
- return;
- }
- /* Put back the last move undone. */
- void
- forward()
- {
- prog_move(foremoves);
- foremoves = foremoves->next;
- return;
- }
- /* End the game. */
- void
- cleanup(s)
- char *s;
- {
- if (progflag)
- program_end();
- record_end(s);
- XSync(0);
- exit(0);
- }
- void
- restart()
- {
- moves = lastmove = thismove = NULL;
- nexttomove = WHITE;
- clock_init(win1, WHITE);
- clock_init(win1, BLACK);
- jail_init(win1);
- if (!oneboard) {
- clock_init(win2, WHITE);
- clock_init(win2, BLACK);
- jail_init(win2);
- }
- board_init(chessboard);
- win_restart();
- record_reset();
- if (progflag) {
- program_end();
- program_init(progname);
- }
- return;
- }
|