--- a/src/chess/rules.c Tue Aug 25 18:35:18 2026 +0200 +++ b/src/chess/rules.c Tue Aug 25 18:59:18 2026 +0200 @@ -126,7 +126,7 @@ } size_t piece_moves_allowed(const GameState *gamestate, - Row r, File f, Move *moves) { + Rank r, File f, Move *moves) { Piece p = piece_at(gamestate, r, f); Color c = piece_color(p); switch (piece_type(p)) { @@ -152,7 +152,7 @@ /* scan the board for pieces of the next player's color */ Move moves[QUEEN_MOVES_MAX]; - for (Row r = 0; r < 8; r++) { + for (Rank r = 0; r < 8; r++) { for (File f = 0; f < 8; f++) { if (piece_color(piece_at(gamestate, r, f)) == next_player && piece_moves_allowed(gamestate, r, f, moves) > 0) { @@ -203,7 +203,7 @@ unsigned op_piece_count[7] = {0}; bool has_bbishop = false, has_wbishop = false; bool op_has_bbishop = false, op_has_wbishop = false; - for (Row r = 0 ; r < 8 ; r++) { + for (Rank r = 0 ; r < 8 ; r++) { for (File f = 0 ; f < 8 ; f++) { Piece p = piece_at(gamestate, r, f); if (piece_color(p) == color) { @@ -320,8 +320,8 @@ static void apply_move_internal(GameState *gamestate, Move *move) { /* en passant capture */ if (move->capture && piece_type(move->piece) == PAWN && - piece_at(gamestate, mdst(move)) == 0) { - piece_remove(gamestate, move->fromrow, move->tofile); + piece_at(gamestate, move->torank, move->tofile) == 0) { + piece_remove(gamestate, move->fromrank, move->tofile); } /* remove old en passant threats */ @@ -331,29 +331,29 @@ } /* move (and maybe capture or promote) */ - piece_remove(gamestate, msrc(move)); + piece_remove(gamestate, move->fromrank, move->fromfile); if (move->promotion) { - piece_set(gamestate, mdst(move), move->promotion); + piece_set(gamestate, move->torank, move->tofile, move->promotion); } else { - piece_set(gamestate, mdst(move), move->piece); + piece_set(gamestate, move->torank, move->tofile, move->piece); } /* add new en passant threat */ if (piece_type(move->piece) == PAWN && ( - (move->fromrow == 1 && move->torow == 3) || - (move->fromrow == 6 && move->torow == 4))) { - enpassant_threat_add(gamestate, move->torow, move->tofile); + (move->fromrank == 1 && move->torank == 3) || + (move->fromrank == 6 && move->torank == 4))) { + enpassant_threat_add(gamestate, move->torank, move->tofile); } /* castling */ if (piece_type(move->piece) == KING && move->fromfile == fileidx('e')) { const Color color = piece_color(move->piece); if (move->tofile == fileidx('g')) { - gamestate->board[move->torow][fileidx('h')] = 0; - gamestate->board[move->torow][fileidx('f')] = mkpiece(ROOK, color); + gamestate->board[move->torank][fileidx('h')] = 0; + gamestate->board[move->torank][fileidx('f')] = mkpiece(ROOK, color); } else if (move->tofile == fileidx('c')) { - gamestate->board[move->torow][fileidx('a')] = 0; - gamestate->board[move->torow][fileidx('d')] = mkpiece(ROOK, color); + gamestate->board[move->torank][fileidx('a')] = 0; + gamestate->board[move->torank][fileidx('d')] = mkpiece(ROOK, color); } } @@ -421,13 +421,13 @@ Color piececolor = piece_color(move->piece); Color oppcolor = opponent_color(piececolor); File opkingfile = 0; - Row opkingrow = 0; - for (Row row = 0 ; row < 8 ; row++) { + Rank opkingrank = 0; + for (Rank rank = 0 ; rank < 8 ; rank++) { for (File file = 0 ; file < 8 ; file++) { - Piece p = piece_at(&simulation, row, file); + Piece p = piece_at(&simulation, rank, file); if (p == mkpiece(KING, oppcolor)) { opkingfile = file; - opkingrow = row; + opkingrank = rank; } } } @@ -435,7 +435,7 @@ /* determine if the opposing king is now threatened */ Move threats[16]; size_t threatcount; - bool incheck = get_threats(&simulation, opkingrow, opkingfile, + bool incheck = get_threats(&simulation, opkingrank, opkingfile, piececolor, threats, &threatcount); if (!incheck) { @@ -448,7 +448,7 @@ for (int dr = -1 ; dr <= 1 && !canescape ; dr++) { for (int df = -1 ; df <= 1 && !canescape ; df++) { if (dr == 0 && df == 0) continue; - Row er = opkingrow + dr; + Rank er = opkingrank + dr; File ef = opkingfile + df; if (!isidx(er) || !isidx(ef)) continue; @@ -466,9 +466,9 @@ GameState sim_retaliate = gamestate_copy_sim(&simulation); Move move_retaliate = {0}; move_retaliate.piece = mkpiece(KING, oppcolor); - move_retaliate.fromrow = opkingrow; + move_retaliate.fromrank = opkingrank; move_retaliate.fromfile = opkingfile; - move_retaliate.torow = er; + move_retaliate.torank = er; move_retaliate.tofile = ef; move_retaliate.capture = true; apply_move_internal(&sim_retaliate, &move_retaliate); @@ -485,7 +485,7 @@ /* can't escape, can the king be rescued? */ if (!canescape && threatcount == 1) { canescape = is_protected(&simulation, - threats[0].fromrow, threats[0].fromfile, oppcolor); + threats[0].fromrank, threats[0].fromfile, oppcolor); } /* can't capture, can he block? */ @@ -495,36 +495,36 @@ /* knight, pawns and the king cannot be blocked */ if (tptype == BISHOP || tptype == ROOK || tptype == QUEEN) { - if (threat->fromrow == threat->torow) { - /* rook aspect (on row) */ + if (threat->fromrank == threat->torank) { + /* rook aspect (on rank) */ int d = threat->tofile > threat->fromfile ? 1 : -1; File file = threat->fromfile; while (!canescape && file != threat->tofile - d) { file += d; canescape |= is_protected(&simulation, - threat->torow, file, oppcolor); + threat->torank, file, oppcolor); } } else if (threat->fromfile == threat->tofile) { /* rook aspect (on file) */ - int d = threat->torow > threat->fromrow ? 1 : -1; - Row row = threat->fromrow; - while (!canescape && row != threat->torow - d) { - row += d; + int d = threat->torank > threat->fromrank ? 1 : -1; + Rank rank = threat->fromrank; + while (!canescape && rank != threat->torank - d) { + rank += d; canescape |= is_protected(&simulation, - row, threat->tofile, oppcolor); + rank, threat->tofile, oppcolor); } } else { /* bishop aspect */ - int dr = threat->torow > threat->fromrow ? 1 : -1; + int dr = threat->torank > threat->fromrank ? 1 : -1; int df = threat->tofile > threat->fromfile ? 1 : -1; - Row row = threat->fromrow; + Rank rank = threat->fromrank; File file = threat->fromfile; while (!canescape && file != threat->tofile - df - && row != threat->torow - dr) { - row += dr; + && rank != threat->torank - dr) { + rank += dr; file += df; - canescape |= is_protected(&simulation, row, file, + canescape |= is_protected(&simulation, rank, file, oppcolor); } } @@ -566,33 +566,33 @@ /* resolve ambiguities, if any */ Move candidates[16]; size_t ccount; - if (get_real_candidates(gamestate, move->torow, move->tofile, + if (get_real_candidates(gamestate, move->torank, move->tofile, piece_color(move->piece), candidates, &ccount)) { - unsigned int ambrows = 0, ambfiles = 0, ambpiece = 0; + unsigned int ambranks = 0, ambfiles = 0, ambpiece = 0; for (size_t i = 0 ; i < ccount ; i++) { if (candidates[i].piece == move->piece) { ambpiece++; - if (candidates[i].fromrow == move->fromrow) { - ambrows++; + if (candidates[i].fromrank == move->fromrank) { + ambranks++; } if (candidates[i].fromfile == move->fromfile) { ambfiles++; } } } - /* neither file, nor row are ambiguous, name file */ - if (ambpiece > 1 && ambrows == 1 && ambfiles == 1) { + /* neither file, nor rank are ambiguous, name file */ + if (ambpiece > 1 && ambranks == 1 && ambfiles == 1) { /* this is most likely the case with Knights * in diagonal opposition */ string[idx++] = filechr(move->fromfile); } else { - /* ambiguous row, name file */ - if (ambrows > 1) { + /* ambiguous rank, name file */ + if (ambranks > 1) { string[idx++] = filechr(move->fromfile); } - /* ambiguous file, name row */ + /* ambiguous file, name rank */ if (ambfiles > 1) { - string[idx++] = rowchr(move->fromrow); + string[idx++] = rankchr(move->fromrank); } } } @@ -605,7 +605,7 @@ /* destination */ string[idx++] = filechr(move->tofile); - string[idx++] = rowchr(move->torow); + string[idx++] = rankchr(move->torank); /* promotion? */ if (move->promotion) { @@ -626,23 +626,23 @@ assert((move->piece & ~(PIECE_MASK|COLOR_MASK)) == 0); /* validate indices (don't trust opponent) */ - if (!isidx(move->fromrow) || !isidx(move->fromfile) || - !isidx(move->torow) || !isidx(move->tofile)) { + if (!isidx(move->fromrank) || !isidx(move->fromfile) || + !isidx(move->torank) || !isidx(move->tofile)) { return INVALID_MOVE_SYNTAX; } /* must move */ - if (move->fromfile == move->tofile && move->fromrow == move->torow) { + if (move->fromfile == move->tofile && move->fromrank == move->torank) { return RULES_VIOLATED; } /* does piece exist */ - if (piece_at(gamestate, msrc(move)) != move->piece) { + if (piece_at(gamestate, move->fromrank, move->fromfile) != move->piece) { return PIECE_NOT_FOUND; } /* is there any piece at the destination? */ - Piece piece_at_dst = piece_at(gamestate, mdst(move)); + Piece piece_at_dst = piece_at(gamestate, move->torank, move->tofile); /* can't capture own pieces */ if (piece_color(piece_at_dst) == piece_color(move->piece)) { @@ -654,7 +654,7 @@ /* ... or the capture happens en passant */ if (!move->capture || piece_type(move->piece) != PAWN || !enpassant_threat_exists(gamestate, - move->fromrow, move->tofile)) { + move->fromrank, move->tofile)) { return RULES_VIOLATED; } } @@ -706,17 +706,17 @@ Color piececolor = piece_color(move->piece); Color oppcolor = opponent_color(piececolor); File kingfile = 0; - Row kingrow = 0; - for (Row row = 0 ; row < 8 ; row++) { + Rank kingrank = 0; + for (Rank rank = 0 ; rank < 8 ; rank++) { for (File file = 0 ; file < 8 ; file++) { - Piece p = piece_at(&simulation, row, file); + Piece p = piece_at(&simulation, rank, file); if (p == mkpiece(KING, piececolor)) { kingfile = file; - kingrow = row; + kingrank = rank; } } } - if (is_covered(&simulation, kingrow, kingfile, oppcolor)) { + if (is_covered(&simulation, kingrank, kingfile, oppcolor)) { if (piece_type(move->piece) == KING) { result = KING_MOVES_INTO_CHECK; } else { @@ -752,30 +752,30 @@ return VALID_MOVE_SEMANTICS; } -Piece piece_at(const GameState *gamestate, Row row, File file) { - return gamestate->board[row][file] & (PIECE_MASK|COLOR_MASK); +Piece piece_at(const GameState *gamestate, Rank rank, File file) { + return gamestate->board[rank][file] & (PIECE_MASK|COLOR_MASK); } -void piece_set(GameState *gamestate, Row row, File file, Piece piece) { - gamestate->board[row][file] = piece; +void piece_set(GameState *gamestate, Rank rank, File file, Piece piece) { + gamestate->board[rank][file] = piece; } -bool get_candidates(const GameState *gamestate, Row row, File file, +bool get_candidates(const GameState *gamestate, Rank rank, File file, Color color, Move *moves, size_t *movecount) { Move candidates[32]; size_t ccount = 0; - for (Row r = 0 ; r < 8 ; r++) { + for (Rank r = 0 ; r < 8 ; r++) { for (File f = 0 ; f < 8 ; f++) { Piece p = piece_at(gamestate, r, f); if (piece_color(p) == color) { /* non-capturing move */ memset(&(candidates[ccount]), 0, sizeof(Move)); candidates[ccount].piece = p; - candidates[ccount].fromrow = r; + candidates[ccount].fromrank = r; candidates[ccount].fromfile = f; - candidates[ccount].torow = row; + candidates[ccount].torank = rank; candidates[ccount].tofile = file; - if (piece_type(p) == PAWN && (row == 0 || row == 7)) { + if (piece_type(p) == PAWN && (rank == 0 || rank == 7)) { /* the exact piece for promotion does not matter */ candidates[ccount].promotion = mkpiece(QUEEN, color); } @@ -809,31 +809,31 @@ return result; } -bool get_threats(const GameState *gamestate, Row row, File file, +bool get_threats(const GameState *gamestate, Rank rank, File file, Color color, Move *threats, size_t *threatcount) { /* simulate a capturing move on the target position */ Color opcolor = opponent_color(color); GameState simulation = gamestate_copy_sim(gamestate); - if (piece_color(piece_at(&simulation, row, file)) != opcolor) { + if (piece_color(piece_at(&simulation, rank, file)) != opcolor) { /* set a fake pawn if the field is not occupied by the opponent */ - piece_set(&simulation, row, file, mkpiece(PAWN, opcolor)); + piece_set(&simulation, rank, file, mkpiece(PAWN, opcolor)); } Move candidates[16]; size_t ccount = 0; - for (Row r = 0 ; r < 8 ; r++) { + for (Rank r = 0 ; r < 8 ; r++) { for (File f = 0 ; f < 8 ; f++) { Piece p = piece_at(&simulation, r, f); if (piece_color(p) == color) { memset(&(candidates[ccount]), 0, sizeof(Move)); candidates[ccount].piece = p; - candidates[ccount].fromrow = r; + candidates[ccount].fromrank = r; candidates[ccount].fromfile = f; - candidates[ccount].torow = row; + candidates[ccount].torank = rank; candidates[ccount].tofile = file; candidates[ccount].capture = true; - if (piece_type(p) == PAWN && (row == 0 || row == 7)) { + if (piece_type(p) == PAWN && (rank == 0 || rank == 7)) { /* the exact piece for promotion does not matter */ candidates[ccount].promotion = mkpiece(QUEEN, color); } @@ -871,24 +871,24 @@ apply_move_internal(&simulation, &simmove); File kingfile = 0; - Row kingrow = 0; - for (Row row = 0 ; row < 8 ; row++) { + Rank kingrank = 0; + for (Rank rank = 0 ; rank < 8 ; rank++) { for (File file = 0 ; file < 8 ; file++) { - if (piece_at(&simulation, row, file) == mkpiece(KING, color)) { + if (piece_at(&simulation, rank, file) == mkpiece(KING, color)) { kingfile = file; - kingrow = row; + kingrank = rank; } } } bool covered = is_covered(&simulation, - kingrow, kingfile, opponent_color(color)); + kingrank, kingfile, opponent_color(color)); gamestate_cleanup(&simulation); return covered; } -bool get_real_candidates(const GameState *gamestate, Row row, File file, +bool get_real_candidates(const GameState *gamestate, Rank rank, File file, Color color, Move *moves, size_t *movecount) { if (movecount) { @@ -897,7 +897,7 @@ Move candidates[16]; size_t ccount; - if (get_candidates(gamestate, row, file, color, candidates, &ccount)) { + if (get_candidates(gamestate, rank, file, color, candidates, &ccount)) { bool result = false; for (size_t i = 0 ; i < ccount ; i++) { if (!is_pinned(gamestate, &candidates[i])) { @@ -913,7 +913,7 @@ } } -bool get_real_threats(const GameState *gamestate, Row row, File file, +bool get_real_threats(const GameState *gamestate, Rank rank, File file, Color color, Move *threats, size_t *threatcount) { if (threatcount) { @@ -922,7 +922,7 @@ Move candidates[16]; size_t ccount; - if (get_threats(gamestate, row, file, color, candidates, &ccount)) { + if (get_threats(gamestate, rank, file, color, candidates, &ccount)) { bool result = false; for (size_t i = 0 ; i < ccount ; i++) { if (!is_pinned(gamestate, &candidates[i])) { @@ -950,16 +950,16 @@ size_t candidatecount; /* determine all candidate moves and sort out the invalid ones */ - if (get_candidates(gamestate, move->torow, move->tofile, color, + if (get_candidates(gamestate, move->torank, move->tofile, color, candidates, &candidatecount)) { bool found = false; for (size_t i = 0 ; i < candidatecount ; i++) { - /* filter by partial fromrow/fromfile information */ + /* filter by partial fromrank/fromfile information */ if (candidates[i].piece == move->piece && - (move->fromrow == POS_UNSPECIFIED || - move->fromrow == candidates[i].fromrow) && + (move->fromrank == POS_UNSPECIFIED || + move->fromrank == candidates[i].fromrank) && (move->fromfile == POS_UNSPECIFIED || move->fromfile == candidates[i].fromfile)) { @@ -994,7 +994,7 @@ } /* found a candidate, copy the source location */ - move->fromrow = candidate->fromrow; + move->fromrank = candidate->fromrank; move->fromfile = candidate->fromfile; return VALID_MOVE_SYNTAX; } else { @@ -1005,7 +1005,7 @@ static int eval_move1(const char *pstr, Move *move, Color color) { memset(move, 0, sizeof(Move)); move->fromfile = POS_UNSPECIFIED; - move->fromrow = POS_UNSPECIFIED; + move->fromrank = POS_UNSPECIFIED; size_t len = strlen(pstr); if (len < 1 || len > 6) { @@ -1037,19 +1037,19 @@ /* pawn move (e.g. "e4") */ move->piece = mkpiece(PAWN, color); move->tofile = fileidx(mstr[0]); - move->torow = rowidx(mstr[1]); + move->torank = rankidx(mstr[1]); } else if (len == 3) { if (strcmp(mstr, "O-O") == 0) { /* king side castling */ move->piece = mkpiece(KING, color); move->fromfile = fileidx('e'); move->tofile = fileidx('g'); - move->fromrow = move->torow = color == WHITE ? 0 : 7; + move->fromrank = move->torank = color == WHITE ? 0 : 7; } else { /* move (e.g. "Nf3") */ move->piece = getpiece(mstr[0], color); move->tofile = fileidx(mstr[1]); - move->torow = rowidx(mstr[2]); + move->torank = rankidx(mstr[2]); } } else if (len == 4) { move->piece = getpiece(mstr[0], color); @@ -1070,18 +1070,18 @@ move->piece = 0; } } else { - move->fromrow = rowidx(mstr[1]); + move->fromrank = rankidx(mstr[1]); } } move->tofile = fileidx(mstr[2]); - move->torow = rowidx(mstr[3]); + move->torank = rankidx(mstr[3]); } else if (len == 5) { if (strcmp(mstr, "O-O-O") == 0) { /* queen side castling "O-O-O" */ move->piece = mkpiece(KING, color); move->fromfile = fileidx('e'); move->tofile = fileidx('c'); - move->fromrow = move->torow = color == WHITE ? 0 : 7; + move->fromrank = move->torank = color == WHITE ? 0 : 7; } else { move->piece = getpiece(mstr[0], color); if (mstr[2] == 'x') { @@ -1090,8 +1090,8 @@ /* capture (e.g. "Ndxf3" or "R1xh3") */ if (isfile(mstr[1])) { move->fromfile = fileidx(mstr[1]); - } else if (isrow(mstr[1])) { - move->fromrow = rowidx(mstr[1]); + } else if (isrank(mstr[1])) { + move->fromrank = rankidx(mstr[1]); } else { return INVALID_MOVE_SYNTAX; } @@ -1099,15 +1099,15 @@ /* long notation capture (e.g. "e5xf6") */ move->piece = mkpiece(PAWN, color); move->fromfile = fileidx(mstr[0]); - move->fromrow = rowidx(mstr[1]); + move->fromrank = rankidx(mstr[1]); } } else { /* long notation move (e.g. "Nc5a4") */ move->fromfile = fileidx(mstr[1]); - move->fromrow = rowidx(mstr[2]); + move->fromrank = rankidx(mstr[2]); } move->tofile = fileidx(mstr[3]); - move->torow = rowidx(mstr[4]); + move->torank = rankidx(mstr[4]); } } else if (len == 6) { /* long notation capture (e.g. "Nc5xf3") */ @@ -1115,9 +1115,9 @@ move->capture = true; move->piece = getpiece(mstr[0], color); move->fromfile = fileidx(mstr[1]); - move->fromrow = rowidx(mstr[2]); + move->fromrank = rankidx(mstr[2]); move->tofile = fileidx(mstr[4]); - move->torow = rowidx(mstr[5]); + move->torank = rankidx(mstr[5]); } } @@ -1127,7 +1127,7 @@ } if (piece_type(move->piece) == PAWN - && move->torow == (color==WHITE?7:0) + && move->torank == (color==WHITE?7:0) && !move->promotion) { return NEED_PROMOTION; } @@ -1136,8 +1136,8 @@ * destination indices must be specified and valid * source indices must either be valid or unspecified */ - if (!isidxr(move->fromrow) || !isidxr(move->fromfile) || - !isidx(move->torow) || !isidx(move->tofile)) { + if (!isidxr(move->fromrank) || !isidxr(move->fromfile) || + !isidx(move->torank) || !isidx(move->tofile)) { return INVALID_MOVE_SYNTAX; } @@ -1149,7 +1149,7 @@ int result = eval_move1(mstr, move, color); if (result == VALID_MOVE_SYNTAX) { if (move->fromfile == POS_UNSPECIFIED - || move->fromrow == POS_UNSPECIFIED) { + || move->fromrank == POS_UNSPECIFIED) { result = getlocation(gamestate, move); } if (result == VALID_MOVE_SYNTAX) { @@ -1186,11 +1186,11 @@ return eval_move1(mstr, &move, color); } -bool is_protected(const GameState *gamestate, Row row, File file, Color color) { +bool is_protected(const GameState *gamestate, Rank rank, File file, Color color) { Move candidates[16]; size_t ccount; /* we need all candidates - not only threats! */ - if (get_candidates(gamestate, row, file, color, candidates, &ccount)) { + if (get_candidates(gamestate, rank, file, color, candidates, &ccount)) { for (size_t i = 0 ; i < ccount ; i++) { /* skip the king */ if (piece_type(candidates[i].piece) == KING) continue; @@ -1273,7 +1273,7 @@ } size_t filter_moves_allowed(const GameState *gamestate, - Color c, Row r, File f, Move *moves, moves_generator_func func) { + Color c, Rank r, File f, Move *moves, moves_generator_func func) { /* worst case: the queen has the most moves */ Move candidates[QUEEN_MOVES_MAX];