Skip to content

Instantly share code, notes, and snippets.

@gjain-7
Last active June 23, 2024 14:23
Show Gist options
  • Select an option

  • Save gjain-7/84d507054e28353f8166665d731e2091 to your computer and use it in GitHub Desktop.

Select an option

Save gjain-7/84d507054e28353f8166665d731e2091 to your computer and use it in GitHub Desktop.
Chess implementation in C. Does not work, some error in code.
// borrwed from https://codereview.stackexchange.com/questions/234619/chess-game-in-c
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
void drawMoves();
enum Type {
NONE = 0,
PAWN,
ROOK,
BISHOP,
KNIGHT,
QUEEN,
KING,
};
enum Color {
BLACK = 0,
WHITE,
};
struct Piece {
enum Type type;
enum Color color;
};
// struct Piece board[8][8] = {{{ROOK, BLACK},
// {KNIGHT, BLACK},
// {BISHOP, BLACK},
// {QUEEN, BLACK},
// {KING, BLACK},
// {BISHOP, BLACK},
// {KNIGHT, BLACK},
// {ROOK, BLACK}},
// {{PAWN, BLACK},
// {PAWN, BLACK},
// {PAWN, BLACK},
// {PAWN, BLACK},
// {PAWN, BLACK},
// {PAWN, BLACK},
// {PAWN, BLACK},
// {PAWN, BLACK}},
// {{NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK}},
// {{NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK}},
// {{NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK}},
// {{NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK},
// {NONE, BLACK}},
// {{PAWN, WHITE},
// {PAWN, WHITE},
// {PAWN, WHITE},
// {PAWN, WHITE},
// {PAWN, WHITE},
// {PAWN, WHITE},
// {PAWN, WHITE},
// {PAWN, WHITE}},
// {{ROOK, WHITE},
// {KNIGHT, WHITE},
// {BISHOP, WHITE},
// {QUEEN, WHITE},
// {KING, WHITE},
// {BISHOP, WHITE},
// {KNIGHT, WHITE},
// {ROOK, WHITE}}};
struct Piece board[8][8] = {
{{ROOK, BLACK}, {KNIGHT, BLACK}, {BISHOP, BLACK}, {QUEEN, BLACK},
{KING, BLACK}, {NONE, BLACK}, {NONE, BLACK}, {ROOK, BLACK}},
{{NONE, BLACK}, {PAWN, BLACK}, {PAWN, BLACK}, {PAWN, BLACK},
{NONE, BLACK}, {PAWN, BLACK}, {PAWN, BLACK}, {PAWN, BLACK}},
{{PAWN, BLACK}, {NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK},
{NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK}, {KNIGHT, BLACK}},
{{NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK},
{QUEEN, WHITE}, {NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK}},
{{NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK},
{PAWN, WHITE}, {NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK}},
{{KNIGHT, WHITE}, {NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK},
{NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK}, {NONE, BLACK}},
{{PAWN, WHITE}, {PAWN, WHITE}, {PAWN, WHITE}, {NONE, BLACK},
{NONE, BLACK}, {PAWN, WHITE}, {PAWN, BLACK}, {PAWN, WHITE}},
{{ROOK, WHITE}, {NONE, WHITE}, {BISHOP, WHITE}, {NONE, BLACK},
{KING, WHITE}, {BISHOP, WHITE}, {KNIGHT, WHITE}, {ROOK, WHITE}}
};
int moves[8][8];
enum Color currentTurn;
int findKing(enum Color col) {
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (board[i][j].type == KING && board[i][j].color == col)
return i * 8 + j;
return -1;
}
int getValidBishopMoves(int x, int y, enum Color color) {
int canMove = 1;
for (int xDir = -1; xDir < 2; xDir += 2) {
for (int yDir = -1; yDir < 2; yDir += 2) {
int count = 1;
while (1) {
if (x + (count * xDir) <= 7 && x + (count * xDir) >= 0 &&
y + (count * yDir) <= 7 && y + (count * yDir) >= 0) {
struct Piece p =
board[y + (count * yDir)][x + (count * xDir)];
if (p.type != NONE) {
if (p.color != color) {
moves[y + (count * yDir)][x + (count * xDir)] = 3;
canMove = 0;
}
break;
} else {
moves[y + (count * yDir)][x + (count * xDir)] = 1;
canMove = 0;
}
} else {
break;
}
count++;
}
}
}
return canMove;
}
int getValidRookMoves(int x, int y, enum Color color) {
int canMove = 1;
for (int dir = -1; dir < 2; dir += 2) {
for (int tx = x + dir; tx >= 0 && tx <= 7; tx += dir) {
if (board[y][tx].type != NONE) {
if (board[y][tx].color != color) {
moves[y][tx] = 3;
canMove = 0;
}
break;
} else {
moves[y][tx] = 1;
canMove = 0;
}
}
for (int ty = y + dir; ty >= 0 && ty <= 7; ty += dir) {
if (board[ty][x].type != NONE) {
if (board[ty][x].color != color) {
moves[ty][x] = 3;
canMove = 0;
}
break;
} else {
moves[ty][x] = 1;
canMove = 0;
}
}
}
return canMove;
}
int getValidPawnMoves(int x, int y, enum Color color) {
int canMove = 1;
if (color == WHITE) {
if (y == 6 && board[y - 2][x].type == NONE) {
moves[y - 2][x] = 1;
canMove = 0;
}
if (y - 1 >= 0) {
if (board[y - 1][x].type == NONE) {
moves[y - 1][x] = 1;
canMove = 0;
}
if (x + 1 <= 7 && board[y - 1][x + 1].color == BLACK &&
board[y - 1][x + 1].type != NONE) {
moves[y - 1][x + 1] = 3;
canMove = 0;
}
if (x - 1 >= 0 && board[y - 1][x - 1].color == BLACK &&
board[y - 1][x - 1].type != NONE) {
moves[y - 1][x - 1] = 3;
canMove = 0;
}
}
} else {
if (y == 1 && board[y + 2][x].type == NONE) {
moves[y + 2][x] = 1;
canMove = 0;
}
if (y + 1 <= 7) {
if (board[y + 1][x].type == NONE) {
moves[y + 1][x] = 1;
canMove = 0;
}
if (x + 1 <= 7 && board[y + 1][x + 1].color == WHITE &&
board[y + 1][x + 1].type != NONE) {
moves[y + 1][x + 1] = 3;
canMove = 0;
}
if (x - 1 >= 0 && board[y + 1][x - 1].color == WHITE &&
board[y + 1][x - 1].type != NONE) {
moves[y + 1][x - 1] = 3;
canMove = 0;
}
}
}
return canMove;
}
int getValidKnightMoves(int x, int y, enum Color color) {
// define a knight move in xdir and ydir
int xdir[] = {1, 2, 2, 1, -1, -2, -2, -1};
int ydir[] = {2, 1, -1, -2, -2, -1, 1, 2};
int canMove = 1;
for (int i = 0; i < 8; i++) {
// out of bounds check
if (x + xdir[i] > 7 || x + xdir[i] < 0 || y + ydir[i] > 7 ||
y + ydir[i] < 0)
continue;
// move to empty square
if (board[y + ydir[i]][x + xdir[i]].type == NONE) {
moves[y + ydir[i]][x + xdir[i]] = 1;
canMove = 0;
}
// capture
else if (board[y + ydir[i]][x + xdir[i]].color != color) {
moves[y + ydir[i]][x + xdir[i]] = 3;
canMove = 0;
}
}
return canMove;
}
int getValidKingMoves(int x, int y, enum Color col) {
int canMove = 1;
for (int xDir = -1; xDir < 2; xDir++) {
for (int yDir = -1; yDir < 2; yDir++) {
if (xDir + x <= 7 && xDir + x >= 0 && y + yDir >= 0 &&
yDir + y <= 7 && !(xDir == 0 && yDir == 0)) {
if (board[yDir + y][xDir + x].type != NONE) {
if (board[yDir + y][xDir + x].color != col)
moves[yDir + y][xDir + x] = 3;
canMove = 0;
} else {
moves[yDir + y][xDir + x] = 1;
canMove = 0;
}
}
}
}
return canMove;
}
int getValidMoves(int x, int y) {
if (x > 7 || x < 0 || y > 7 || y < 0) return 1;
// clear the board
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++) moves[i][j] = 0;
struct Piece piece = board[y][x];
moves[y][x] = 2;
if (piece.type == NONE) {
return 1;
}
if (piece.type == PAWN) {
return getValidPawnMoves(x, y, piece.color);
}
if (piece.type == KNIGHT) {
return getValidKnightMoves(x, y, piece.color);
}
if (piece.type == BISHOP) {
return getValidBishopMoves(x, y, piece.color);
}
if (piece.type == ROOK) {
return getValidRookMoves(x, y, piece.color);
}
if (piece.type == QUEEN) {
int rk = getValidRookMoves(x, y, piece.color);
int bs = getValidBishopMoves(x, y, piece.color);
return rk && bs;
}
if (piece.type == KING) {
return getValidKingMoves(x, y, piece.color);
}
return 1;
}
bool isCheck(enum Color currerntTurn) {
int kingX, kingY;
kingX = findKing(currentTurn);
kingY = kingX % 8;
kingX /= 8;
printf("king is here %d %d\n", kingY+1, kingX+1);
printf("%d\n", getValidMoves(5-1,4-1));
printf("%d\n", moves[kingX][kingY]);
drawMoves();
// exit(0);
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
// if (board[x][y].color != currentTurn && getValidMoves(x, y) == 0 &&
// ((moves[kingX][kingY] == 1 || moves[kingX][kingY] == 3))) {
// printf("here i am\n");
// return 1;
// }
}
}
return 0;
}
/**
* @brief if the king is in check, and for each valid move of king, there is a
* check then its a check mate
* @param currentTurn
* @return true if the king is in checkmate otherwise false
*/
bool isCheckmate(enum Color currentTurn) {
if (!isCheck(currentTurn)) return false;
// find king
int kingX, kingY;
kingX = findKing(currentTurn);
kingY = kingX % 8;
kingX /= 8;
getValidMoves(kingX, kingY);
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (moves[i][j] == 1 || moves[i][j] == 3) {
struct Piece temp = board[i][j];
board[i][j] = board[kingX][kingY];
board[kingX][kingY].type = NONE,
board[kingX][kingY].color = BLACK;
bool result = isCheck(currentTurn);
board[kingX][kingY] = board[i][j];
board[i][j] = temp;
if (!result) return false;
}
}
}
return true;
}
void drawBoard() {
printf(" ");
for (int y = 0; y < 8; y++) {
printf("%d: ", y + 1);
}
printf("\n");
for (int x = 0; x < 8; x++) {
printf("%d: ", x + 1);
for (int y = 0; y < 8; y++) {
if (board[x][y].type != NONE) {
printf("%d%d", board[x][y].type, board[x][y].color);
} else {
printf("--");
}
printf(" ");
}
printf("\n");
}
}
void drawMoves() {
printf(" ");
for (int y = 0; y < 8; y++) {
printf("%d: ", y + 1);
}
printf("\n");
for (int x = 0; x < 8; x++) {
printf("%d: ", x + 1);
for (int y = 0; y < 8; y++) {
if (moves[x][y] == 0) {
printf("--");
} else {
printf("%d%d", moves[x][y], moves[x][y]);
}
printf(" ");
}
printf("\n");
}
}
void play() {
currentTurn = WHITE;
while (1) {
system("@cls||clear");
// if current state is checkmate then end game
if (isCheckmate(currentTurn)) {
printf("Checkmate\n");
if (currentTurn == WHITE)
printf("Black wins\n");
else
printf("White wins\n");
return;
}
if (currentTurn == WHITE)
printf("White's turn\n\n");
else
printf("Black's turn\n\n");
drawBoard();
// take input for selecting piece
int x, y;
scanf("%d %d", &x, &y);
x--, y--;
if (board[y][x].type == NONE || board[y][x].color != currentTurn ||
getValidMoves(x, y) == 1 || isCheck(currentTurn))
continue;
system("@cls||clear");
drawBoard();
printf("\n");
drawMoves();
// take input for selecting move
int x1, y1;
scanf("%d %d", &x1, &y1);
x1--, y1--;
// How to check if the move is valid
// if the piece is of self (checking while 1st input)
// its is running the correct move and likewise capturing in right
// square (move matrix) move does not result in check (add check
// condition)
// if the move is valid then make the move and change the turn
if ((moves[y1][x1] == 1 || moves[y1][x1] == 3) &&
!isCheck(currentTurn)) {
board[y1][x1] = board[y][x];
board[y][x].type = NONE, board[y][x].color = BLACK;
currentTurn = (enum Color)((currentTurn + 1) % 2);
}
}
}
int main() {
drawBoard();
int res = isCheck(BLACK);
printf("%d\n", res);
// printf()
// play();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment