src/game.c

changeset 19
6a26114297a1
parent 18
6008840b859e
child 21
2e5846019b4f
     1.1 --- a/src/game.c	Sat Mar 29 16:53:58 2014 +0100
     1.2 +++ b/src/game.c	Mon Mar 31 11:16:32 2014 +0200
     1.3 @@ -28,64 +28,13 @@
     1.4   */
     1.5  
     1.6  #include "game.h"
     1.7 +#include "network.h"
     1.8  #include "input.h"
     1.9 -#include "rules/rules.h"
    1.10  #include <ncurses.h>
    1.11  #include <string.h>
    1.12  
    1.13  static const uint8_t boardx = 10, boardy = 10;
    1.14  
    1.15 -static uint8_t getpiecechr(uint8_t piece) {
    1.16 -    switch (piece & PIECE_MASK) {
    1.17 -    case ROOK: return 'R';
    1.18 -    case KNIGHT: return 'N';
    1.19 -    case BISHOP: return 'B';
    1.20 -    case QUEEN: return 'Q';
    1.21 -    case KING: return 'K';
    1.22 -    default: return '\0';
    1.23 -    }
    1.24 -}
    1.25 -
    1.26 -/**
    1.27 - * Maps a character to a piece.
    1.28 - * 
    1.29 - * Does not work for pawns, since they don't have a character.
    1.30 - * 
    1.31 - * @param c one of R,N,B,Q,K
    1.32 - * @return numeric value for the specified piece
    1.33 - */
    1.34 -static uint8_t getpiece(char c) {
    1.35 -    switch (c) {
    1.36 -        case 'R': return ROOK;
    1.37 -        case 'N': return KNIGHT;
    1.38 -        case 'B': return BISHOP;
    1.39 -        case 'Q': return QUEEN;
    1.40 -        case 'K': return KING;
    1.41 -        default: return 0;
    1.42 -    }
    1.43 -}
    1.44 -
    1.45 -/**
    1.46 - * Guesses the location of a piece for short algebraic notation.
    1.47 - * 
    1.48 - * @param board the current state of the board
    1.49 - * @param move the move date to operate on
    1.50 - * @return status code (see rules/rules.h for the codes)
    1.51 - */
    1.52 -static int getlocation(Board board, Move *move) {   
    1.53 -    uint8_t piece = move->piece & PIECE_MASK;
    1.54 -    switch (piece) {
    1.55 -        case PAWN: return pawn_getlocation(board, move);
    1.56 -        case ROOK: return rook_getlocation(board, move);
    1.57 -        case KNIGHT: return knight_getlocation(board, move);
    1.58 -        case BISHOP: return bishop_getlocation(board, move);
    1.59 -        case QUEEN: return queen_getlocation(board, move);
    1.60 -        case KING: return king_getlocation(board, move);
    1.61 -        default: return INVALID_MOVE_SYNTAX;
    1.62 -    }
    1.63 -}
    1.64 -
    1.65 -
    1.66  static void draw_board(Board board, MoveListRoot *movelist, uint8_t mycolor) {
    1.67      
    1.68      for (uint8_t y = 0 ; y < 8 ; y++) {
    1.69 @@ -158,255 +107,6 @@
    1.70      }
    1.71  }
    1.72  
    1.73 -/**
    1.74 - * Applies a move and deletes captured pieces.
    1.75 - * 
    1.76 - * @param board the current board state
    1.77 - * @param move the move to apply
    1.78 - */
    1.79 -static void apply_move(Board board, Move *move) {
    1.80 -    uint8_t piece = move->piece & PIECE_MASK;
    1.81 -    uint8_t color = move->piece & COLOR_MASK;
    1.82 -    
    1.83 -    /* en passant capture */
    1.84 -    if (move->capture && piece == PAWN &&
    1.85 -        mdst(board, move) == 0) {
    1.86 -        board[move->fromrow][move->tofile] = 0;
    1.87 -    }
    1.88 -    
    1.89 -    /* remove old en passant threats */
    1.90 -    for (uint8_t file = 0 ; file < 8 ; file++) {
    1.91 -        board[3][file] &= ~ENPASSANT_THREAT;
    1.92 -        board[4][file] &= ~ENPASSANT_THREAT;
    1.93 -    }
    1.94 -    
    1.95 -    /* add new en passant threat */
    1.96 -    if (piece == PAWN && (
    1.97 -        (move->fromrow == 1 && move->torow == 3) ||
    1.98 -        (move->fromrow == 6 && move->torow == 4))) {
    1.99 -        move->piece |= ENPASSANT_THREAT;
   1.100 -    }
   1.101 -    
   1.102 -    /* move (and maybe capture or promote) */
   1.103 -    msrc(board, move) = 0;
   1.104 -    if (move->promotion) {
   1.105 -        mdst(board, move) = move->promotion;
   1.106 -    } else {
   1.107 -        mdst(board, move) = move->piece;
   1.108 -    }
   1.109 -    
   1.110 -    /* castling */
   1.111 -    if (piece == KING &&
   1.112 -        move->fromfile == fileidx('e')) {
   1.113 -        
   1.114 -        if (move->tofile == fileidx('g')) {
   1.115 -            board[move->torow][fileidx('h')] = 0;
   1.116 -            board[move->torow][fileidx('f')] = color|ROOK;
   1.117 -        } else if (move->tofile == fileidx('c')) {
   1.118 -            board[move->torow][fileidx('a')] = 0;
   1.119 -            board[move->torow][fileidx('d')] = color|ROOK;
   1.120 -        }
   1.121 -    }
   1.122 -}
   1.123 -
   1.124 -/**
   1.125 - * Validates move by applying chess rules.
   1.126 - * @param board the current board state
   1.127 - * @param move the move to validate
   1.128 - * @return TRUE, if the move complies to chess rules, FALSE otherwise
   1.129 - */
   1.130 -static _Bool validate_move(Board board, Move *move) {
   1.131 -    _Bool result;
   1.132 -    
   1.133 -    /* validate indices (don't trust opponent) */
   1.134 -    if (!chkidx(move)) {
   1.135 -        return FALSE;
   1.136 -    }
   1.137 -    
   1.138 -    /* does piece exist */
   1.139 -    result = msrc(board, move) == move->piece;
   1.140 -    
   1.141 -    /* can't capture own pieces */
   1.142 -    if ((mdst(board, move) & COLOR_MASK) == (move->piece & COLOR_MASK)) {
   1.143 -        return FALSE;
   1.144 -    }
   1.145 -    
   1.146 -    /* validate individual rules */
   1.147 -    switch (move->piece & PIECE_MASK) {
   1.148 -    case PAWN:
   1.149 -        result = result && pawn_chkrules(board, move);
   1.150 -        result = result && !pawn_isblocked(board, move);
   1.151 -        break;
   1.152 -    case ROOK:
   1.153 -        result = result && rook_chkrules(move);
   1.154 -        result = result && !rook_isblocked(board, move);
   1.155 -        break;
   1.156 -    case KNIGHT:
   1.157 -        result = result && knight_chkrules(move);
   1.158 -        result = result && !knight_isblocked(board, move);
   1.159 -        break;
   1.160 -    case BISHOP:
   1.161 -        result = result && bishop_chkrules(move);
   1.162 -        result = result && !bishop_isblocked(board, move);
   1.163 -        break;
   1.164 -    case QUEEN:
   1.165 -        result = result && queen_chkrules(move);
   1.166 -        result = result && !queen_isblocked(board, move);
   1.167 -        break;
   1.168 -    case KING:
   1.169 -        result = result && king_chkrules(board, move);
   1.170 -        result = result && !king_isblocked(board, move);
   1.171 -        break;
   1.172 -    default:
   1.173 -        result = FALSE;
   1.174 -    }
   1.175 -    
   1.176 -    /* is piece pinned */
   1.177 -    // TODO: make it so
   1.178 -    
   1.179 -    /* correct check and checkmate flags */
   1.180 -    // TODO: make it so
   1.181 -    
   1.182 -    return result;
   1.183 -}
   1.184 -
   1.185 -/**
   1.186 - * Evaluates a move syntactically and stores the move data in the specified
   1.187 - * object.
   1.188 - * 
   1.189 - * @param board the current state of the board
   1.190 - * @param mycolor the color of the current player
   1.191 - * @param mstr the input string to parse
   1.192 - * @param move a pointer to object where the move data shall be stored
   1.193 - * @return status code (see rules/rules.h for the list of codes)
   1.194 - */
   1.195 -static int eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) {
   1.196 -    memset(move, 0, sizeof(Move));
   1.197 -    move->fromfile = POS_UNSPECIFIED;
   1.198 -    move->fromrow = POS_UNSPECIFIED;
   1.199 -
   1.200 -    size_t len = strlen(mstr);
   1.201 -    
   1.202 -    /* evaluate check/checkmate flags */
   1.203 -    if (mstr[len-1] == '+') {
   1.204 -        len--; mstr[len] = '\0';
   1.205 -        move->check = TRUE;
   1.206 -    } else if (mstr[len-1] == '#') {
   1.207 -        len--; mstr[len] = '\0';
   1.208 -        move->checkmate = TRUE;
   1.209 -    }
   1.210 -    
   1.211 -    /* evaluate promotion */
   1.212 -    if (len > 3 && mstr[len-2] == '=') {
   1.213 -        move->promotion = getpiece(mstr[len-1]);
   1.214 -        if (!move->promotion) {
   1.215 -            return INVALID_MOVE_SYNTAX;
   1.216 -        } else {
   1.217 -            move->promotion |= mycolor;
   1.218 -            len -= 2;
   1.219 -            mstr[len] = 0;
   1.220 -        }
   1.221 -    }
   1.222 -    
   1.223 -    if (len == 2) {
   1.224 -        /* pawn move (e.g. "e4") */
   1.225 -        move->piece = PAWN;
   1.226 -        move->tofile = fileidx(mstr[0]);
   1.227 -        move->torow = rowidx(mstr[1]);
   1.228 -    } else if (len == 3) {
   1.229 -        if (strcmp(mstr, "O-O") == 0) {
   1.230 -            /* king side castling */
   1.231 -            move->piece = KING;
   1.232 -            move->fromfile = fileidx('e');
   1.233 -            move->tofile = fileidx('g');
   1.234 -            move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
   1.235 -        } else {
   1.236 -            /* move (e.g. "Nf3") */
   1.237 -            move->piece = getpiece(mstr[0]);
   1.238 -            move->tofile = fileidx(mstr[1]);
   1.239 -            move->torow = rowidx(mstr[2]);
   1.240 -        }
   1.241 -        
   1.242 -    } else if (len == 4) {
   1.243 -        move->piece = getpiece(mstr[0]);
   1.244 -        if (!move->piece) {
   1.245 -            move->piece = PAWN;
   1.246 -            move->fromfile = fileidx(mstr[0]);
   1.247 -        }
   1.248 -        if (mstr[1] == 'x') {
   1.249 -            /* capture (e.g. "Nxf3", "dxe5") */
   1.250 -            move->capture = TRUE;
   1.251 -        } else {
   1.252 -            /* move (e.g. "Ndf3", "N2c3", "e2e4") */
   1.253 -            if (isfile(mstr[1])) {
   1.254 -                move->fromfile = fileidx(mstr[1]);
   1.255 -                if (move->piece == PAWN) {
   1.256 -                    move->piece = 0;
   1.257 -                }
   1.258 -            } else {
   1.259 -                move->fromrow = rowidx(mstr[1]);
   1.260 -            }
   1.261 -        }
   1.262 -        move->tofile = fileidx(mstr[2]);
   1.263 -        move->torow = rowidx(mstr[3]);
   1.264 -    } else if (len == 5) {
   1.265 -        if (strcmp(mstr, "O-O-O") == 0) {
   1.266 -            /* queen side castling "O-O-O" */
   1.267 -            move->piece = KING;
   1.268 -            move->fromfile = fileidx('e');
   1.269 -            move->tofile = fileidx('c');
   1.270 -            move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
   1.271 -        } else {
   1.272 -            move->piece = getpiece(mstr[0]);
   1.273 -            if (mstr[2] == 'x') {
   1.274 -                move->capture = TRUE;
   1.275 -                if (move->piece) {
   1.276 -                    /* capture (e.g. "Ndxf3") */
   1.277 -                    move->fromfile = fileidx(mstr[1]);
   1.278 -                } else {
   1.279 -                    /* long notation capture (e.g. "e5xf6") */
   1.280 -                    move->piece = PAWN;
   1.281 -                    move->fromfile = fileidx(mstr[0]);
   1.282 -                    move->fromrow = rowidx(mstr[1]);
   1.283 -                }
   1.284 -            } else {
   1.285 -                /* long notation move (e.g. "Nc5a4") */
   1.286 -                move->fromfile = fileidx(mstr[1]);
   1.287 -                move->fromrow = rowidx(mstr[2]);
   1.288 -            }
   1.289 -            move->tofile = fileidx(mstr[3]);
   1.290 -            move->torow = rowidx(mstr[4]);
   1.291 -        }
   1.292 -    } else if (len == 6) {
   1.293 -        /* long notation capture (e.g. "Nc5xf3") */
   1.294 -        if (mstr[3] == 'x') {
   1.295 -            move->capture = TRUE;
   1.296 -            move->piece = getpiece(mstr[0]);
   1.297 -            move->fromfile = fileidx(mstr[1]);
   1.298 -            move->fromrow = rowidx(mstr[2]);
   1.299 -            move->tofile = fileidx(mstr[4]);
   1.300 -            move->torow = rowidx(mstr[5]);
   1.301 -        }
   1.302 -    }
   1.303 -
   1.304 -    
   1.305 -    if (move->piece) {
   1.306 -        if (move->piece == PAWN && move->torow == (mycolor==WHITE?7:0)
   1.307 -            && !move->promotion) {
   1.308 -            return NEED_PROMOTION;
   1.309 -        }
   1.310 -        
   1.311 -        move->piece |= mycolor;
   1.312 -        if (move->fromfile == POS_UNSPECIFIED
   1.313 -            || move->fromrow == POS_UNSPECIFIED) {
   1.314 -            return getlocation(board, move);
   1.315 -        } else {
   1.316 -            return chkidx(move) ? VALID_MOVE_SYNTAX : INVALID_POSITION;
   1.317 -        }
   1.318 -    } else {
   1.319 -        return INVALID_MOVE_SYNTAX;
   1.320 -    }
   1.321 -}
   1.322  
   1.323  static int sendmove(Board board, MoveListRoot *movelist,
   1.324      uint8_t mycolor, int opponent) {

mercurial