fixed crucial bug where both players could move at the same time + added pawn rules (TODO: en passant)

Wed, 26 Mar 2014 14:53:15 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 26 Mar 2014 14:53:15 +0100
changeset 14
970748b9a73b
parent 13
faec61c4901f
child 15
7ffd66591afe

fixed crucial bug where both players could move at the same time + added pawn rules (TODO: en passant)

src/game.c file | annotate | diff | comparison | revisions
src/game.h file | annotate | diff | comparison | revisions
src/rules/pawn.c file | annotate | diff | comparison | revisions
     1.1 --- a/src/game.c	Wed Mar 26 14:12:59 2014 +0100
     1.2 +++ b/src/game.c	Wed Mar 26 14:53:15 2014 +0100
     1.3 @@ -78,9 +78,9 @@
     1.4   * @param move the move to apply
     1.5   */
     1.6  static void apply_move(Board board, Move *move) {
     1.7 -    board[move->fromrow][move->fromfile] = 0;
     1.8 +    msrc(board, move) = 0;
     1.9      // TODO: care for en passant capture
    1.10 -    board[move->torow][move->tofile] = move->piece;
    1.11 +    mdst(board, move) = move->piece;
    1.12      
    1.13      /* castling */
    1.14      if ((move->piece & PIECE_MASK) == KING &&
    1.15 @@ -112,8 +112,14 @@
    1.16      }
    1.17      
    1.18      /* does piece exist */
    1.19 -    result = board[move->fromrow][move->fromfile] == move->piece;
    1.20 +    result = msrc(board, move) == move->piece;
    1.21      
    1.22 +    /* can't capture own pieces */
    1.23 +    if ((mdst(board, move) & COLOR_MASK) == (move->piece & COLOR_MASK)) {
    1.24 +        return FALSE;
    1.25 +    }
    1.26 +    
    1.27 +    /* validate individual rules */
    1.28      switch (move->piece & PIECE_MASK) {
    1.29      case PAWN:
    1.30          result = result && pawn_chkrules(board, move);
    1.31 @@ -247,8 +253,9 @@
    1.32                  move->fromfile = fileidx(mstr[0]);
    1.33              }
    1.34          } else {
    1.35 -            /* move (e.g. "Ndf3") */
    1.36 -            move->fromfile = fileidx(mstr[1]);
    1.37 +            /* move (e.g. "Ndf3", "N2c3") */
    1.38 +            move->fromfile = isfile(mstr[1]) ?
    1.39 +                fileidx(mstr[1]) : rowidx(mstr[1]);
    1.40          }
    1.41          move->tofile = fileidx(mstr[2]);
    1.42          move->torow = rowidx(mstr[3]);
    1.43 @@ -366,6 +373,8 @@
    1.44                      if (move.checkmate) {
    1.45                          printw("Checkmate!");
    1.46                          return 1;
    1.47 +                    } else {
    1.48 +                        return 0;
    1.49                      }
    1.50                  }
    1.51              } else {
     2.1 --- a/src/game.h	Wed Mar 26 14:12:59 2014 +0100
     2.2 +++ b/src/game.h	Wed Mar 26 14:53:15 2014 +0100
     2.3 @@ -37,8 +37,9 @@
     2.4  extern "C" {
     2.5  #endif
     2.6  
     2.7 -#define PIECE_MASK 0x0F
     2.8 -#define COLOR_MASK 0xF0
     2.9 +#define PIECE_MASK       0x0F
    2.10 +#define COLOR_MASK       0x30
    2.11 +#define ENPASSANT_THREAT 0x40
    2.12  
    2.13  #define WHITE 0x10
    2.14  #define BLACK 0x20
    2.15 @@ -77,6 +78,8 @@
    2.16  } Move;
    2.17  
    2.18  #define POS_UNSPECIFIED UINT8_MAX
    2.19 +#define mdst(b,m) b[m->torow][m->tofile]
    2.20 +#define msrc(b,m) b[m->fromrow][m->fromfile]
    2.21  
    2.22  #define isidx(idx) ((uint8_t)idx < 8)
    2.23  
     3.1 --- a/src/rules/pawn.c	Wed Mar 26 14:12:59 2014 +0100
     3.2 +++ b/src/rules/pawn.c	Wed Mar 26 14:53:15 2014 +0100
     3.3 @@ -30,28 +30,44 @@
     3.4  #include "pawn.h"
     3.5  
     3.6  _Bool pawn_chkrules(Board board, Move *move) {
     3.7 -    // TODO: implement
     3.8 -    return TRUE;
     3.9 +    int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1);
    3.10 +    if (move->capture) {
    3.11 +        if (move->fromrow == move->torow + d && (
    3.12 +            move->fromfile == move->tofile + 1 ||
    3.13 +            move->fromfile == move->tofile - 1)) {
    3.14 +            // TODO: en passant
    3.15 +            return mdst(board,move) != 0; /* color has been checked */
    3.16 +        } else {
    3.17 +            return FALSE;
    3.18 +        }
    3.19 +    } else {
    3.20 +        if (move->fromfile == move->tofile) {
    3.21 +            return (move->fromrow == move->torow + d) ||
    3.22 +                (move->fromrow == (d < 0 ? 1 : 6) && /* advanced first move */
    3.23 +                move->fromrow == move->torow + d*2);
    3.24 +        } else {
    3.25 +            return FALSE;
    3.26 +        }
    3.27 +    }
    3.28  }
    3.29  
    3.30  _Bool pawn_isblocked(Board board, Move *move) {
    3.31 -    // TODO: implement
    3.32 -    return FALSE;
    3.33 +    return mdst(board,move) && !move->capture;
    3.34  }
    3.35  
    3.36  _Bool pawn_getlocation(Board board, Move *move) {
    3.37      int8_t d = ((move->piece & COLOR_MASK) == WHITE ? -1 : 1);
    3.38      
    3.39 -    // TODO: battle moves
    3.40 -    
    3.41 -    move->fromfile = move->tofile;
    3.42 +    if (move->fromfile == POS_UNSPECIFIED) {
    3.43 +        move->fromfile = move->tofile;
    3.44 +    }
    3.45      move->fromrow = move->torow + d;
    3.46      if (move->fromrow > 6) {
    3.47          return FALSE;
    3.48      } else {
    3.49          /* advanced first move */
    3.50          if (move->fromrow == (d < 0 ? 2 : 5) &&
    3.51 -            board[move->fromrow][move->fromfile] != move->piece) {
    3.52 +            msrc(board,move) != move->piece) {
    3.53  
    3.54              move->fromrow += d;
    3.55              if (move->fromrow > 6) {

mercurial