Annotation of 43BSDReno/games/chess/Xchess/control.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.