src/chess/rules.h

changeset 160
f87832cba8b8
parent 157
07cbfc477b22
--- a/src/chess/rules.h	Tue Jul 28 13:44:10 2026 +0200
+++ b/src/chess/rules.h	Wed Jul 29 13:45:51 2026 +0200
@@ -30,6 +30,7 @@
 #ifndef RULES_H
 #define	RULES_H
 
+#include <stdlib.h>
 #include <stdint.h>
 #include <stdbool.h>
 
@@ -44,21 +45,21 @@
 #define KING_MOVES_INTO_CHECK  7
 #define RULES_VIOLATED        10
 
-#define ENPASSANT_THREAT 0x40
+#define ENPASSANT_THREAT 0x40u
 
-#define WHITE 0x10
-#define BLACK 0x20
+#define WHITE 0x10u
+#define BLACK 0x20u
 #define opponent_color(color) ((color)==WHITE?BLACK:WHITE)
 
-#define PIECE_MASK 0x0F
-#define COLOR_MASK 0x30
+#define PIECE_MASK 0x0Fu
+#define COLOR_MASK 0x30u
 
-#define PAWN   0x01
-#define ROOK   0x02
-#define KNIGHT 0x03
-#define BISHOP 0x04
-#define QUEEN  0x05
-#define KING   0x06
+#define PAWN   0x01u
+#define ROOK   0x02u
+#define KNIGHT 0x03u
+#define BISHOP 0x04u
+#define QUEEN  0x05u
+#define KING   0x06u
 
 #define WPAWN   (WHITE|PAWN)
 #define WROOK   (WHITE|ROOK)
@@ -74,6 +75,11 @@
 #define BKING   (BLACK|KING)
 
 typedef uint8_t Board[8][8];
+typedef uint8_t BoardIndex;
+typedef BoardIndex Row;
+typedef BoardIndex File;
+typedef uint8_t Piece;
+typedef uint8_t Color;
 
 struct movetimeval {
     uint64_t tv_sec;
@@ -81,11 +87,11 @@
 };
 
 typedef struct {
-    uint8_t piece;
-    uint8_t fromfile;
-    uint8_t fromrow;
-    uint8_t tofile;
-    uint8_t torow;
+    Piece piece;
+    File fromfile;
+    Row fromrow;
+    File tofile;
+    Row torow;
     uint8_t promotion;
     uint8_t check;
     uint8_t capture;
@@ -140,6 +146,17 @@
     bool review;
 } GameState;
 
+#define piece_type(piece) ((piece)&PIECE_MASK)
+#define piece_color(piece) ((piece)&COLOR_MASK)
+#define mkpiece(type,color) ((type)|(color))
+
+#define enpassant_threat_add(gamestate, row, file) \
+    (gamestate->board[row][file] |= ENPASSANT_THREAT)
+#define enpassant_threat_remove(gamestate, row, file) \
+    (gamestate->board[row][file] &= ~ENPASSANT_THREAT)
+#define enpassant_threat_exists(gamestate, row, file) \
+    (gamestate->board[row][file] & ENPASSANT_THREAT)
+
 #define is_game_running(gamestate) !((gamestate)->checkmate || \
     (gamestate)->wresign || (gamestate)->bresign || (gamestate)->threefold || \
     (gamestate)->stalemate || (gamestate)->remis || (gamestate)->review)
@@ -148,13 +165,13 @@
     ((gamestate)->moves[(gamestate)->movecount-1])
 
 #define POS_UNSPECIFIED UINT8_MAX
-#define mdst(b,m) b[(m)->torow][(m)->tofile]
-#define msrc(b,m) b[(m)->fromrow][(m)->fromfile]
+#define mdst(m) (m)->torow, (m)->tofile
+#define msrc(m) (m)->fromrow, (m)->fromfile
 
 /** Checks if the index is specified and valid. */
-#define isidx(idx) ((uint8_t)(idx) < 8)
+#define isidx(idx) ((BoardIndex)(idx) < 8)
 /** Checks if the index is unspecified or valid. */
-#define isidxr(idx) ((idx) == POS_UNSPECIFIED || (uint8_t)(idx) < 8)
+#define isidxr(idx) ((idx) == POS_UNSPECIFIED || (BoardIndex)(idx) < 8)
 
 #define isfile(file) (file >= 'a' && file <= 'h')
 #define isrow(row) (row >= '1' && row <= '8')
@@ -169,7 +186,6 @@
 #define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED)
 #define rowidx_s(c) (isrow(c)?rowidx(c):POS_UNSPECIFIED)
 
-
 /**
  * Initializes a game state and prepares the chess board.
  * @param gamestate the game state to initialize
@@ -186,21 +202,22 @@
  * Maps a character to a piece.
  * 
  * Does not work for pawns, since they don't have a character.
- * 
+ *
  * @param c one of R,N,B,Q,K
- * @return numeric value for the specified piece
+ * @param color the piece color
+ * @return the specified piece or zero when the character is invalid
  */
-uint8_t getpiece(char c);
+Piece getpiece(char c, Color color);
 
 /**
  * Maps a piece to a character.
  * 
- * Does not work for pawns, scince they don't have a character.
+ * Does not work for pawns, since they don't have a character.
  * 
  * @param piece may have color or additional flags
  * @return character value for the specified piece
  */
-char getpiecechr(uint8_t piece);
+char getpiecechr(Piece piece);
 
 /**
  * Maps a piece to a unicode character sequence.
@@ -208,10 +225,10 @@
  * The returned unicode is for black pieces.
  * You may colorize the output by setting the terminal foreground color.
  * 
- * @param piece the piece to dispaly
+ * @param piece the piece to display
  * @return unicode character sequence for the specified piece
  */
-char* getpieceunicode(uint8_t piece);
+char* getpieceunicode(Piece piece);
 
 /**
  * Returns the color of the player who is next to move.
@@ -219,7 +236,38 @@
  * @param gamestate the current game state
  * @return the color of the player who is next to move
  */
-uint8_t current_color(GameState *gamestate);
+Color current_color(GameState *gamestate);
+
+/**
+ * Returns the piece at the specified position.
+ *
+ * @param gamestate the current game state
+ * @param row the row
+ * @param file the file
+ * @return the piece at the specified position
+ */
+Piece piece_at(const GameState *gamestate, Row row, File file);
+
+/**
+ * Places a piece at the specified position in the current game state.
+ *
+ * @param gamestate the current game state
+ * @param row the row
+ * @param file the file
+ * @param piece the piece to place at the specified position
+ */
+void piece_set(GameState *gamestate, Row row, File file, Piece piece);
+
+/**
+ * Removes the piece at the specified position in the current game state.
+ *
+ * @param gamestate the current game state
+ * @param row the row
+ * @param file the file
+ */
+static inline void piece_remove(GameState *gamestate, Row row, File file) {
+    piece_set(gamestate, row, file, 0);
+}
 
 /**
  * Checks, if a specified field is covered by a piece of a certain color.
@@ -233,13 +281,12 @@
  * @param color the color of the piece that should threaten the field
  * @param threats the array where to store the threats (should be able to hold
  * the rare maximum of 16 elements)
- * @param threatcount a pointer to an uint8_t where the count of threats is
- * stored
+ * @param threatcount a pointer where the count of threats is stored
  * @return true, if any piece of the specified color threatens the specified
  * field (i.e. could capture an opponent piece)
  */
-bool get_threats(GameState *gamestate, uint8_t row, uint8_t file,
-        uint8_t color, Move* threats, uint8_t* threatcount);
+bool get_threats(GameState *gamestate, Row row, File file,
+        Color color, Move* threats, size_t* threatcount);
 
 /**
  * Checks, if a specified field is covered by a piece of a certain color AND
@@ -254,13 +301,12 @@
  * @param color the color of the piece that should threaten the field
  * @param threats the array where to store the threats (should be able to hold
  * the rare maximum of 16 elements)
- * @param threatcount a pointer to an uint8_t where the count of threats is
- * stored
+ * @param threatcount a pointer where the count of threats is stored
  * @return true, if any piece of the specified color threatens the specified
  * field (i.e. could capture an opponent piece)
  */
-bool get_real_threats(GameState *gamestate, uint8_t row, uint8_t file,
-        uint8_t color, Move* threats, uint8_t* threatcount);
+bool get_real_threats(GameState *gamestate, Row row, File file,
+        Color color, Move* threats, size_t* threatcount);
 
 /**
  * Checks, if a specified field is covered by a piece of a certain color.
@@ -304,8 +350,7 @@
  * @return true, if any piece (excluding the king) of the specified color
  * threatens the specified field and could capture an opponent piece
  */
-bool is_protected(GameState *gamestate, uint8_t row, uint8_t file,
-        uint8_t color);
+bool is_protected(GameState *gamestate, Row row, File file, Color color);
 
 /**
  * Checks, if the specified move cannot be performed, because the piece is
@@ -339,8 +384,7 @@
  * @param color the color of the player to evaluate the move for
  * @return status code (see macros in this file for the list of codes)
  */
-int eval_move(GameState *gamestate, const char *mstr,
-        Move *move, uint8_t color);
+int eval_move(GameState *gamestate, const char *mstr, Move *move, Color color);
 
 /**
  * Syntactically checks a move without verifying that a piece exists that is
@@ -350,7 +394,7 @@
  * @param color the color of the player to evaluate the move for
  * @return status code (see macros in this file for the list of codes)
  */
-int check_move(const char *mstr, uint8_t color);
+int check_move(const char *mstr, Color color);
 
 /**
  * Validates move by applying chess rules.
@@ -399,7 +443,7 @@
  * @return the remaining time - if time control is disabled, this function
  * always returns zero
  */
-uint16_t remaining_movetime(GameState *gamestate, uint8_t color);
+uint16_t remaining_movetime(GameState *gamestate, Color color);
 
 /**
  * Converts clock time to string.

mercurial