universe@10: /* universe@10: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@10: * universe@10: * Copyright 2014 Mike Becker. All rights reserved. universe@10: * universe@10: * Redistribution and use in source and binary forms, with or without universe@10: * modification, are permitted provided that the following conditions are met: universe@10: * universe@10: * 1. Redistributions of source code must retain the above copyright universe@10: * notice, this list of conditions and the following disclaimer. universe@10: * universe@10: * 2. Redistributions in binary form must reproduce the above copyright universe@10: * notice, this list of conditions and the following disclaimer in the universe@10: * documentation and/or other materials provided with the distribution. universe@10: * universe@10: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@10: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@10: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@10: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@10: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@10: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@10: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@10: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@10: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@10: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@10: * POSSIBILITY OF SUCH DAMAGE. universe@10: * universe@10: */ universe@10: universe@10: #ifndef RULES_H universe@10: #define RULES_H universe@10: universe@19: #include universe@10: universe@16: #define VALID_MOVE_SYNTAX 0 universe@16: #define INVALID_MOVE_SYNTAX 1 universe@16: #define INVALID_POSITION 2 universe@16: #define AMBIGUOUS_MOVE 3 universe@18: #define NEED_PROMOTION 4 universe@16: universe@19: universe@19: #define PIECE_MASK 0x0F universe@19: #define COLOR_MASK 0x30 universe@19: #define ENPASSANT_THREAT 0x40 universe@19: universe@19: #define WHITE 0x10 universe@19: #define BLACK 0x20 universe@19: universe@19: #define PAWN 0x01 universe@19: #define ROOK 0x02 universe@19: #define KNIGHT 0x03 universe@19: #define BISHOP 0x04 universe@19: #define QUEEN 0x05 universe@19: #define KING 0x06 universe@19: universe@19: #define WPAWN (WHITE|PAWN) universe@19: #define WROOK (WHITE|ROOK) universe@19: #define WKNIGHT (WHITE|KNIGHT) universe@19: #define WBISHOP (WHITE|BISHOP) universe@19: #define WQUEEN (WHITE|QUEEN) universe@19: #define WKING (WHITE|KING) universe@19: #define BPAWN (BLACK|PAWN) universe@19: #define BROOK (BLACK|ROOK) universe@19: #define BKNIGHT (BLACK|KNIGHT) universe@19: #define BBISHOP (BLACK|BISHOP) universe@19: #define BQUEEN (BLACK|QUEEN) universe@19: #define BKING (BLACK|KING) universe@19: universe@19: typedef uint8_t Board[8][8]; universe@19: universe@23: universe@19: typedef struct { universe@19: uint8_t piece; universe@19: uint8_t fromfile; universe@19: uint8_t fromrow; universe@19: uint8_t tofile; universe@19: uint8_t torow; universe@19: uint8_t promotion; universe@19: _Bool check; universe@19: _Bool checkmate; universe@19: _Bool capture; universe@19: } Move; universe@19: universe@23: typedef struct MoveList MoveList; universe@23: universe@23: struct MoveList { universe@23: Move move; universe@23: MoveList* next; universe@23: }; universe@23: universe@23: typedef struct { universe@23: Board board; universe@23: uint8_t mycolor; universe@23: MoveList* movelist; universe@23: MoveList* lastmove; universe@23: } GameState; universe@23: universe@19: #define POS_UNSPECIFIED UINT8_MAX universe@19: #define mdst(b,m) b[(m)->torow][(m)->tofile] universe@19: #define msrc(b,m) b[(m)->fromrow][(m)->fromfile] universe@19: universe@19: #define isidx(idx) ((uint8_t)idx < 8) universe@19: universe@19: #define isfile(file) (file >= 'a' && file <= 'h') universe@19: #define isrow(row) (row >= '1' && row <= '8') universe@19: universe@19: #define rowidx(row) (row-'1') universe@19: #define fileidx(file) (file-'a') universe@19: universe@19: #define rowchr(row) (row+'1') universe@19: #define filechr(file) (file+'a') universe@19: universe@19: #define chkidx(move) (isidx((move)->fromfile) && isidx((move)->fromrow) && \ universe@19: isidx((move)->tofile) && isidx((move)->torow)) universe@19: universe@19: /* secure versions - use, if index is not checked with isidx() */ universe@19: #define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED) universe@19: #define rowidx_s(c) (isrow(c)?rowidx(c):POS_UNSPECIFIED) universe@19: universe@23: void gamestate_cleanup(GameState *gamestate); universe@23: universe@19: /** universe@19: * Maps a character to a piece. universe@19: * universe@19: * Does not work for pawns, since they don't have a character. universe@19: * universe@19: * @param c one of R,N,B,Q,K universe@19: * @return numeric value for the specified piece universe@19: */ universe@19: uint8_t getpiece(char c); universe@19: universe@19: /** universe@19: * Maps a piece to a character. universe@19: * universe@19: * Does not work for pawns, scince they don't have a character. universe@19: * universe@19: * @param piece one of ROOK, KNIGHT, BISHOP, QUEEN, KING universe@19: * @return character value for the specified piece universe@19: */ universe@19: char getpiecechr(uint8_t piece); universe@19: universe@19: /** universe@19: * Evaluates a move syntactically and stores the move data in the specified universe@19: * object. universe@19: * universe@23: * @param gamestate the current game state universe@19: * @param mstr the input string to parse universe@19: * @param move a pointer to object where the move data shall be stored universe@19: * @return status code (see rules/rules.h for the list of codes) universe@19: */ universe@23: int eval_move(GameState *gamestate, char *mstr, Move *move); universe@19: universe@19: /** universe@19: * Validates move by applying chess rules. universe@23: * @param gamestate the current game state universe@19: * @param move the move to validate universe@19: * @return TRUE, if the move complies to chess rules, FALSE otherwise universe@19: */ universe@23: _Bool validate_move(GameState *gamestate, Move *move); universe@19: universe@19: /** universe@19: * Applies a move and deletes captured pieces. universe@19: * universe@23: * @param gamestate the current game state universe@19: * @param move the move to apply universe@19: */ universe@23: void apply_move(GameState *gamestate, Move *move); universe@19: universe@10: #endif /* RULES_H */ universe@10: