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

1.1       root        1: 
                      2: /* This file contains code for X-CHESS.
                      3:    Copyright (C) 1986 Free Software Foundation, Inc.
                      4: 
                      5: This file is part of X-CHESS.
                      6: 
                      7: X-CHESS is distributed in the hope that it will be useful,
                      8: but WITHOUT ANY WARRANTY.  No author or distributor
                      9: accepts responsibility to anyone for the consequences of using it
                     10: or for whether it serves any particular purpose or works at all,
                     11: unless he says so in writing.  Refer to the X-CHESS General Public
                     12: License for full details.
                     13: 
                     14: Everyone is granted permission to copy, modify and redistribute
                     15: X-CHESS, but only under the conditions described in the
                     16: X-CHESS General Public License.   A copy of this license is
                     17: supposed to have been given to you along with X-CHESS so you
                     18: can know your rights and responsibilities.  It should be in a
                     19: file named COPYING.  Among other things, the copyright notice
                     20: and this notice must be preserved on all copies.  */
                     21: 
                     22: 
                     23: /* RCS Info: $Revision: 1.3 $ on $Date: 86/11/23 17:18:35 $
                     24:  *           $Source: /users/faustus/xchess/RCS/valid.c,v $
                     25:  * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
                     26:  *     Permission is granted to do anything with this code except sell it
                     27:  *     or remove this message.
                     28:  *
                     29:  * Validate a move.
                     30:  */
                     31: 
                     32: #include "xchess.h"
                     33: 
                     34: extern bool ischeck(), couldmove();
                     35: 
                     36: bool
                     37: valid_move(m, b)
                     38:        move *m;
                     39:        board *b;
                     40: {
                     41:        board tb;
                     42: 
                     43:        /* First check that the piece can make the move at all... */
                     44:        if (!couldmove(m, b))
                     45:                return (false);
                     46: 
                     47:        /* Now see if the king is in check now. */
                     48:        bcopy((char *) b, (char *) &tb, sizeof (board));
                     49:        board_move(&tb, m);
                     50:        if (ischeck(&tb, m->piece.color))
                     51:                return (false);
                     52:        
                     53:        if (ischeck(&tb, ((m->piece.color == WHITE) ? BLACK : WHITE)))
                     54:                m->check = true;
                     55:        
                     56:        return (true);
                     57: }
                     58: 
                     59: static bool
                     60: couldmove(m, b)
                     61:        move *m;
                     62:        board *b;
                     63: {
                     64:        int x, y;
                     65: 
                     66:        switch (m->type) {
                     67:            case KCASTLE:
                     68:                if ((m->piece.color == WHITE) && (b->white_cant_castle_k) ||
                     69:                                (m->piece.color == BLACK) && 
                     70:                                (b->black_cant_castle_k))
                     71:                        return (false);
                     72:                if ((b->square[m->fromy][5].color != NONE) ||
                     73:                                (b->square[m->fromy][6].color != NONE))
                     74:                        return (false);
                     75:                if (ischeck(b, m->piece.color))
                     76:                        return (false);
                     77:                break;
                     78: 
                     79:            case QCASTLE:
                     80:                if ((m->piece.color == WHITE) && (b->white_cant_castle_q) ||
                     81:                                (m->piece.color == BLACK) && 
                     82:                                (b->black_cant_castle_q))
                     83:                        return (false);
                     84:                if ((b->square[m->fromy][1].color != NONE) ||
                     85:                                (b->square[m->fromy][2].color != NONE) ||
                     86:                                (b->square[m->fromy][3].color != NONE))
                     87:                        return (false);
                     88:                if (ischeck(b, m->piece.color))
                     89:                        return (false);
                     90:                break;
                     91: 
                     92:            case MOVE:
                     93:            case CAPTURE:
                     94:                /* There is one special case here, that of taking a pawn
                     95:                 * en passant.  In this case we change the move field to
                     96:                 * CAPTURE if it's ok.
                     97:                 */
                     98:                switch (m->piece.type) {
                     99:                    case PAWN:
                    100:                        if ((m->type == MOVE) && (m->fromx == m->tox)) {
                    101:                                /* A normal move. */
                    102:                                if ((m->piece.color == WHITE) && (m->fromy ==
                    103:                                                m->toy + 1))
                    104:                                        break;
                    105:                                if ((m->piece.color == WHITE) && (m->fromy ==
                    106:                                                6) && (m->toy == 4) &&
                    107:                                                (b->square[5][m->fromx].color
                    108:                                                == NONE))
                    109:                                        break;
                    110:                                if ((m->piece.color == BLACK) && (m->fromy ==
                    111:                                                m->toy - 1))
                    112:                                        break;
                    113:                                if ((m->piece.color == BLACK) && (m->fromy ==
                    114:                                                1) && (m->toy == 3) &&
                    115:                                                (b->square[2][m->fromx].color
                    116:                                                == NONE))
                    117:                                        break;
                    118:                                return (false);
                    119:                        } else if (m->type == CAPTURE) {
                    120:                                if ((((m->piece.color == WHITE) && (m->fromy ==
                    121:                                            m->toy + 1)) || ((m->piece.color ==
                    122:                                            BLACK) && (m->fromy == m->toy -
                    123:                                            1))) && ((m->fromx == m->tox + 1) ||
                    124:                                            (m->fromx == m->tox - 1)))
                    125:                                        break;
                    126:                                /* Now maybe it's enpassant...  We've already
                    127:                                 * checked for some of these things in the
                    128:                                 * calling routine.
                    129:                                 */
                    130:                                if (m->enpassant) {
                    131:                                        if (b->square[(m->piece.color == WHITE)
                    132:                                                    ? 3 : 4][m->tox].color == 
                    133:                                                    ((m->piece.color == WHITE) ?
                    134:                                                    BLACK : WHITE))
                    135:                                                break;
                    136:                                }
                    137:                                return (false);
                    138:                        }
                    139:                        return (false);
                    140: 
                    141:                    case ROOK:
                    142:                        if (m->fromx == m->tox) {
                    143:                                for (y = m->fromy + ((m->fromy > m->toy) ? -1 :
                    144:                                                1); y != m->toy; y += ((m->fromy
                    145:                                                > m->toy) ? -1 : 1))
                    146:                                        if (b->square[y][m->tox].color != NONE)
                    147:                                                return (false);
                    148:                                break;
                    149:                        }
                    150:                        if (m->fromy == m->toy) {
                    151:                                for (x = m->fromx + ((m->fromx > m->tox) ? -1 :
                    152:                                                1); x != m->tox; x += ((m->fromx
                    153:                                                > m->tox) ? -1 : 1))
                    154:                                        if (b->square[m->toy][x].color != NONE)
                    155:                                                return (false);
                    156:                                break;
                    157:                        }
                    158:                        return (false);
                    159: 
                    160:                    case KNIGHT:
                    161:                        x = m->fromx - m->tox;
                    162:                        y = m->fromy - m->toy;
                    163:                        if ((((x == 2) || (x == -2)) &&
                    164:                                        ((y == 1) || (y == -1))) ||
                    165:                                        (((x == 1) || (x == -1)) &&
                    166:                                        ((y == 2) || (y == -2))))
                    167:                                break;
                    168:                        return (false);
                    169: 
                    170:                    case BISHOP:
                    171:                        x = m->fromx - m->tox;
                    172:                        y = m->fromy - m->toy;
                    173:                        if ((x != y) && (x != - y))
                    174:                                return (false);
                    175:                        for (x = m->fromx + ((m->fromx > m->tox) ? -1 : 1), y =
                    176:                                        m->fromy + ((m->fromy > m->toy) ? -1 :
                    177:                                        1); x != m->tox;
                    178:                                        x += ((m->fromx > m->tox) ? -1 : 1),
                    179:                                        y += ((m->fromy > m->toy) ? -1 : 1))
                    180:                                if (b->square[y][x].color != NONE)
                    181:                                        return (false);
                    182:                        break;
                    183: 
                    184:                    case QUEEN:
                    185:                        if (m->fromx == m->tox) {
                    186:                                for (y = m->fromy + ((m->fromy > m->toy) ? -1 :
                    187:                                                1); y != m->toy; y += ((m->fromy
                    188:                                                > m->toy) ? -1 : 1))
                    189:                                        if (b->square[y][m->tox].color != NONE)
                    190:                                                return (false);
                    191:                                break;
                    192:                        }
                    193:                        if (m->fromy == m->toy) {
                    194:                                for (x = m->fromx + ((m->fromx > m->tox) ? -1 :
                    195:                                                1); x != m->tox; x += ((m->fromx
                    196:                                                > m->tox) ? -1 : 1))
                    197:                                        if (b->square[m->toy][x].color != NONE)
                    198:                                                return (false);
                    199:                                break;
                    200:                        }
                    201:                        x = m->fromx - m->tox;
                    202:                        y = m->fromy - m->toy;
                    203:                        if ((x != y) && (x != - y))
                    204:                                return (false);
                    205:                        for (x = m->fromx + ((m->fromx > m->tox) ? -1 : 1), y =
                    206:                                        m->fromy + ((m->fromy > m->toy) ? -1 :
                    207:                                        1); x != m->tox;
                    208:                                        x += ((m->fromx > m->tox) ? -1 : 1),
                    209:                                        y += ((m->fromy > m->toy) ? -1 : 1))
                    210:                                if (b->square[y][x].color != NONE)
                    211:                                        return (false);
                    212:                        break;
                    213: 
                    214:                    case KING:
                    215:                        x = m->fromx - m->tox;
                    216:                        y = m->fromy - m->toy;
                    217:                        if ((x >= -1) && (x <= 1) && (y >= -1) && (y <= 1))
                    218:                                break;
                    219:                        return (false);
                    220:                }
                    221:                break;
                    222:        }
                    223:        return (true);
                    224: }
                    225: 
                    226: /* Say whether either king is in check...  If move is non-NULL, say whether he
                    227:  * in in check after the move takes place.  We do this in a rather stupid way.
                    228:  */
                    229: 
                    230: static bool
                    231: ischeck(b, col)
                    232:        board *b;
                    233:        color col;
                    234: {
                    235:        int x, y, kx, ky;
                    236:        move ch;
                    237: 
                    238:        for (x = 0; x < SIZE; x++)
                    239:                for (y = 0; y < SIZE; y++)
                    240:                        if ((b->square[y][x].color == col) &&
                    241:                                    (b->square[y][x].type == KING)) {
                    242:                                kx = x;
                    243:                                ky = y;
                    244:                        }
                    245: 
                    246:        for (x = 0; x < SIZE; x++)
                    247:                for (y = 0; y < SIZE; y++)
                    248:                        if (b->square[y][x].color == ((col == WHITE) ?
                    249:                                        BLACK : WHITE)) {
                    250:                                ch.type = CAPTURE;
                    251:                                ch.piece.color = b->square[y][x].color;
                    252:                                ch.piece.type = b->square[y][x].type;
                    253:                                ch.fromx = x;
                    254:                                ch.fromy = y;
                    255:                                ch.tox = kx;
                    256:                                ch.toy = ky;
                    257:                                ch.enpassant = false;
                    258:                                if (couldmove(&ch, b))
                    259:                                        return (true);
                    260:                        }
                    261: 
                    262:        return (false);
                    263: }
                    264: 

unix.superglobalmegacorp.com

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