src/chess/king.c

changeset 25
3ab0c2e1a4e2
parent 23
824c9522ce66
child 47
d726e4b46c33
     1.1 --- a/src/chess/king.c	Tue Apr 01 10:28:08 2014 +0200
     1.2 +++ b/src/chess/king.c	Tue Apr 01 12:30:25 2014 +0200
     1.3 @@ -29,18 +29,88 @@
     1.4  
     1.5  #include "rules.h"
     1.6  #include "king.h"
     1.7 +#include <stdlib.h>
     1.8  
     1.9 -_Bool king_chkrules(GameState *gamestate, Move* move) {
    1.10 -    // TODO: implement
    1.11 +static _Bool king_castling_chkmoved(GameState *gamestate,
    1.12 +    uint8_t row, uint8_t file) {
    1.13 +    
    1.14 +    MoveList *ml = gamestate->movelist;
    1.15 +    while (ml) {
    1.16 +        if (ml->move.fromfile == file && ml->move.fromrow == row) {
    1.17 +            return 1;
    1.18 +        }
    1.19 +        ml = ml->next;
    1.20 +    }
    1.21 +    
    1.22      return 0;
    1.23  }
    1.24  
    1.25 +_Bool king_chkrules(GameState *gamestate, Move* move) {
    1.26 +    if (abs(move->torow - move->fromrow) <= 1 &&
    1.27 +        abs(move->tofile - move->fromfile) <= 1) {
    1.28 +        return 1;
    1.29 +    } else {
    1.30 +        /* castling */
    1.31 +        if (move->fromrow == move->torow &&
    1.32 +            move->fromrow == ((move->piece&COLOR_MASK) == WHITE ? 0 : 7) &&
    1.33 +            move->fromfile == fileidx('e') &&
    1.34 +            (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) {
    1.35 +            
    1.36 +            return !king_castling_chkmoved(gamestate,
    1.37 +                move->fromrow, move->fromfile) &&
    1.38 +                !king_castling_chkmoved(gamestate, move->fromrow,
    1.39 +                move->tofile == fileidx('c') ? 0 : 7);
    1.40 +        } else {
    1.41 +            return 0;
    1.42 +        }
    1.43 +    }
    1.44 +}
    1.45 +
    1.46  _Bool king_isblocked(GameState *gamestate, Move *move) {
    1.47 -    // TODO: implement
    1.48 -    return 1;
    1.49 +    
    1.50 +    uint8_t opponent_color = opponent_color(move->piece&COLOR_MASK);
    1.51 +    _Bool blocked = is_covered(gamestate, move->torow, move->tofile,
    1.52 +        opponent_color);
    1.53 +    
    1.54 +    if (abs(move->tofile - move->fromfile) == 2) {
    1.55 +        if (move->tofile == fileidx('c')) {
    1.56 +            blocked |= gamestate->board[move->torow][fileidx('b')];
    1.57 +        }
    1.58 +        uint8_t midfile = (move->tofile+move->fromfile)/2;
    1.59 +        blocked |= gamestate->lastmove->move.check ||
    1.60 +            gamestate->board[move->torow][midfile] ||
    1.61 +            is_covered(gamestate, move->torow, midfile, opponent_color);
    1.62 +    }
    1.63 +    
    1.64 +    return blocked;
    1.65  }
    1.66  
    1.67  int king_getlocation(GameState *gamestate, Move *move) {
    1.68 -    // TODO: implement
    1.69 -    return INVALID_MOVE_SYNTAX;
    1.70 +    
    1.71 +    uint8_t file, row;
    1.72 +    
    1.73 +    for (int f = -1 ; f <= 1 ; f++) {
    1.74 +        for (int r = -1 ; r <= 1 ; r++) {
    1.75 +            if (f == 0 && r == 0) {
    1.76 +                continue;
    1.77 +            }
    1.78 +            file = move->tofile + f;
    1.79 +            row = move->torow + r;
    1.80 +            if (isidx(file) && isidx(row)) {
    1.81 +                if (gamestate->board[row][file] == move->piece) {
    1.82 +                    if ((move->fromfile != POS_UNSPECIFIED
    1.83 +                        && move->fromfile != file) ||
    1.84 +                        (move->fromrow != POS_UNSPECIFIED
    1.85 +                        && move->fromrow != row)) {
    1.86 +                        return INVALID_POSITION;
    1.87 +                    }
    1.88 +                    move->fromfile = file;
    1.89 +                    move->fromrow = row;
    1.90 +                    return VALID_MOVE_SYNTAX;
    1.91 +                }
    1.92 +            }
    1.93 +        }
    1.94 +    }
    1.95 +    
    1.96 +    return INVALID_POSITION;
    1.97  }

mercurial