summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2021-06-14 16:33:59 +0300
committereug-vs <eug-vs@keemail.me>2021-06-14 16:33:59 +0300
commit50ffb304f0d4098ccbcc7e2fb286b2d3cc56e66c (patch)
tree166dade91166cbe1463393d956c710b55298ae66 /src
parent78c966ef9c0a3451aecb4abcc48f9e0944757990 (diff)
downloadc-chess-50ffb304f0d4098ccbcc7e2fb286b2d3cc56e66c.tar.gz
feat: pass turn between players and validate moves
Diffstat (limited to 'src')
-rw-r--r--src/main.c71
-rw-r--r--src/pieces.h6
2 files changed, 53 insertions, 24 deletions
diff --git a/src/main.c b/src/main.c
index cbdd862..40bdba4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -110,51 +110,70 @@ void input_move(int move[2]) {
move[1] = notation_to_index(file_destination, rank_destination);
};
-int generate_legal_moves(int origin, int* board) {
+int validate_move(int move[2], int color, int* board) {
+ int origin = move[0];
+ int destination = move[1];
+
+ if ((origin & 0x88) || (destination & 0x88)) return -1;
+
int piece = board[origin];
- int* move;
+ int* legal_move;
+
+ if (piece % 2 != color) return -3;
switch (piece & NO_COLOR) {
case KNIGHT:
- move = knightMoves;
+ legal_move = knightMoves;
break;
case BISHOP:
- move = bishopMoves;
+ legal_move = bishopMoves;
break;
case ROOK:
- move = rookMoves;
+ legal_move = rookMoves;
break;
case QUEEN:
- move = queenMoves;
+ legal_move = queenMoves;
break;
case KING:
- move = kingMoves;
+ legal_move = kingMoves;
break;
case PAWN:
- if (piece & BLACK) move = blackPawnMoves;
- else move = pawnMoves;
+ if (piece & BLACK) legal_move = blackPawnMoves;
+ else legal_move = pawnMoves;
break;
default:
- puts("No piece found!");
- move = NULL;
+ return -2;
}
- while(*move) {
- for (int square = origin + *move; !(square & 0x88); square += *move) {
- if (board[square] != EMPTY) break;
- board[square] = VISUAL;
+ while(*legal_move) {
+ for (int square = origin + *legal_move; !(square & 0x88); square += *legal_move) {
+ int target_piece = board[square];
+
+ if (square == destination) {
+ if (target_piece & color) return -4;
+ return target_piece;
+ }
+
+ if (target_piece != EMPTY) break;
if ((piece & NO_COLOR) == PAWN || piece == KNIGHT || piece == KING) break;
}
- move++;
+ legal_move++;
}
+
+ return -5;
}
+char* VALIDATION_ERRORS[] = {
+ "trying to access off-board square",
+ "no piece on origin square",
+ "opponent piece on origin square",
+ "trying to capture your own piece",
+ "move is not allowed",
+};
+
int apply_move(int move[2], int* board) {
int origin = move[0];
int destination = move[1];
-
- if ((origin & 0x88) || (destination & 0x88)) return 0;
-
int piece = board[origin];
board[destination] = piece;
@@ -168,14 +187,22 @@ int main() {
parse_FEN(DEFAULT_FEN, board);
print_board(board);
+
int move[2];
+ int color = 0;
+
while (1) {
+ printf("Enter a move for %s:\n", COLORS[color]);
input_move(move);
- if (apply_move(move, board)) {
- generate_legal_moves(move[1], board);
+
+ int error = validate_move(move, color, board);
+ if (error < 0) {
+ printf("Invalid move: %s!\n", VALIDATION_ERRORS[-1 - error]);
+ } else {
+ apply_move(move, board);
print_board(board);
+ color ^= 1;
}
- else puts("Invalid move!");
}
return 0;
diff --git a/src/pieces.h b/src/pieces.h
index 2289f2c..5689bb7 100644
--- a/src/pieces.h
+++ b/src/pieces.h
@@ -2,6 +2,8 @@
#define BLACK 0b0001
#define NO_COLOR 0b1110
+char* COLORS[] = { "white", "black" };
+
#define EMPTY 0b0000
#define VISUAL 0b0001
@@ -29,8 +31,8 @@ int rookMoves[] = { 16, 1, -1, -16, 0 };
int queenMoves[] = { 17, 16, 15, 1, -1, -15, -16, -17, 0 };
int knightMoves[] = { 33, 31, 18, 14, -33, -31, -18, -14, 0 };
int kingMoves[] = { 17, 16, 15, 1, -1, -15, -16, -17, 0 };
-int pawnMoves[] = { 17, 16, 15, 0 };
-int blackPawnMoves[] = { -17, -16, -15, 0 };
+int pawnMoves[] = { 32, 17, 16, 15, 0 };
+int blackPawnMoves[] = { -32, -17, -16, -15, 0 };
#define FILE_MASK 0b1111