src/game.c

changeset 13
faec61c4901f
parent 12
84880c7e1ea6
child 14
970748b9a73b
     1.1 --- a/src/game.c	Wed Mar 26 13:16:49 2014 +0100
     1.2 +++ b/src/game.c	Wed Mar 26 14:12:59 2014 +0100
     1.3 @@ -71,6 +71,12 @@
     1.4      }
     1.5  }
     1.6  
     1.7 +/**
     1.8 + * Applies a move and deletes captured pieces.
     1.9 + * 
    1.10 + * @param board the current board state
    1.11 + * @param move the move to apply
    1.12 + */
    1.13  static void apply_move(Board board, Move *move) {
    1.14      board[move->fromrow][move->fromfile] = 0;
    1.15      // TODO: care for en passant capture
    1.16 @@ -91,9 +97,20 @@
    1.17      }
    1.18  }
    1.19  
    1.20 +/**
    1.21 + * Validates move by applying chess rules.
    1.22 + * @param board the current board state
    1.23 + * @param move the move to validate
    1.24 + * @return TRUE, if the move complies to chess rules, FALSE otherwise
    1.25 + */
    1.26  static _Bool validate_move(Board board, Move *move) {
    1.27      _Bool result;
    1.28      
    1.29 +    /* validate indices (don't trust opponent) */
    1.30 +    if (!chkidx(move)) {
    1.31 +        return FALSE;
    1.32 +    }
    1.33 +    
    1.34      /* does piece exist */
    1.35      result = board[move->fromrow][move->fromfile] == move->piece;
    1.36      
    1.37 @@ -162,7 +179,7 @@
    1.38   * @return TRUE if the location could be retrieved, FALSE if the location is
    1.39   * ambiguous
    1.40   */
    1.41 -static _Bool getlocation(Board board, Move *move) {
    1.42 +static _Bool getlocation(Board board, Move *move) {   
    1.43      uint8_t piece = move->piece & PIECE_MASK;
    1.44      switch (piece) {
    1.45          case PAWN: return pawn_getlocation(board, move);
    1.46 @@ -203,11 +220,9 @@
    1.47      
    1.48      if (len == 2) {
    1.49          /* pawn move (e.g. "e4") */
    1.50 -        if (isfile(mstr[0]) && isrow(mstr[1])) {
    1.51 -            move->piece = PAWN;
    1.52 -            move->tofile = fileidx(mstr[0]);
    1.53 -            move->torow = rowidx(mstr[1]);
    1.54 -        }
    1.55 +        move->piece = PAWN;
    1.56 +        move->tofile = fileidx(mstr[0]);
    1.57 +        move->torow = rowidx(mstr[1]);
    1.58      } else if (len == 3) {
    1.59          if (strcmp(mstr, "O-O") == 0) {
    1.60              /* king side castling */
    1.61 @@ -216,17 +231,27 @@
    1.62              move->tofile = fileidx('g');
    1.63              move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
    1.64          } else {
    1.65 -            /* unambiguous move (e.g. "Nf3") */
    1.66 +            /* move (e.g. "Nf3") */
    1.67              move->piece = getpiece(mstr[0]);
    1.68 -            move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED;
    1.69 -            move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED;
    1.70 +            move->tofile = fileidx(mstr[1]);
    1.71 +            move->torow = rowidx(mstr[2]);
    1.72          }
    1.73          
    1.74      } else if (len == 4) {
    1.75 -        /* ambiguous move (e.g. "Ndf3") */
    1.76 -        
    1.77 -        /* unambiguous capture (e.g. "Nxf3", "dxe5") */
    1.78 -        
    1.79 +        move->piece = getpiece(mstr[0]);
    1.80 +        if (mstr[1] == 'x') {
    1.81 +            /* capture (e.g. "Nxf3", "dxe5") */
    1.82 +            move->capture = TRUE;
    1.83 +            if (!move->piece) {
    1.84 +                move->piece = PAWN;
    1.85 +                move->fromfile = fileidx(mstr[0]);
    1.86 +            }
    1.87 +        } else {
    1.88 +            /* move (e.g. "Ndf3") */
    1.89 +            move->fromfile = fileidx(mstr[1]);
    1.90 +        }
    1.91 +        move->tofile = fileidx(mstr[2]);
    1.92 +        move->torow = rowidx(mstr[3]);
    1.93      } else if (len == 5) {
    1.94          if (strcmp(mstr, "O-O-O") == 0) {
    1.95              /* queen side castling "O-O-O" */
    1.96 @@ -235,26 +260,51 @@
    1.97              move->tofile = fileidx('c');
    1.98              move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
    1.99          } else {
   1.100 -            /* ambiguous capture (e.g. "Ndxf3") */
   1.101 -
   1.102 -            /* long notation move (e.g. "Nc5a4") */
   1.103 -
   1.104 -            /* long notation capture (e.g. "e5xf6") */
   1.105 +            move->piece = getpiece(mstr[0]);
   1.106 +            if (mstr[2] == 'x') {
   1.107 +                move->capture = TRUE;
   1.108 +                if (move->piece) {
   1.109 +                    /* capture (e.g. "Ndxf3") */
   1.110 +                    move->fromfile = fileidx(mstr[1]);
   1.111 +                } else {
   1.112 +                    /* long notation capture (e.g. "e5xf6") */
   1.113 +                    move->piece = PAWN;
   1.114 +                    move->fromfile = fileidx(mstr[0]);
   1.115 +                    move->fromrow = rowidx(mstr[1]);
   1.116 +                }
   1.117 +            } else {
   1.118 +                /* long notation move (e.g. "Nc5a4") */
   1.119 +                move->fromfile = fileidx(mstr[1]);
   1.120 +                move->fromrow = rowidx(mstr[2]);
   1.121 +            }
   1.122 +            move->tofile = fileidx(mstr[3]);
   1.123 +            move->torow = rowidx(mstr[4]);
   1.124          }
   1.125      } else if (len == 6) {
   1.126          /* long notation capture (e.g. "Nc5xf3") */
   1.127 +        if (mstr[3] == 'x') {
   1.128 +            move->capture = TRUE;
   1.129 +            move->piece = getpiece(mstr[0]);
   1.130 +            move->fromfile = fileidx(mstr[1]);
   1.131 +            move->fromrow = rowidx(mstr[2]);
   1.132 +            move->tofile = fileidx(mstr[4]);
   1.133 +            move->torow = rowidx(mstr[5]);
   1.134 +        }
   1.135      }
   1.136  
   1.137 +    
   1.138      if (move->piece) {
   1.139          move->piece |= mycolor;
   1.140 +        if (move->fromfile == POS_UNSPECIFIED
   1.141 +            || move->fromrow == POS_UNSPECIFIED) {
   1.142 +            return getlocation(board, move) && chkidx(move);
   1.143 +        } else {
   1.144 +            return chkidx(move);
   1.145 +        }
   1.146 +    } else {
   1.147 +        return FALSE;
   1.148      }
   1.149 -    
   1.150 -    if (!getlocation(board, move)) {
   1.151 -        // TODO: return status code to indicate the error type
   1.152 -        move->piece = 0;
   1.153 -    }
   1.154 -    
   1.155 -    return move->piece != 0;
   1.156 +    // TODO: return status code to indicate the error type
   1.157  }
   1.158  
   1.159  static int sendmove(Board board, uint8_t mycolor, int opponent) {

mercurial