summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chess.c168
1 files changed, 145 insertions, 23 deletions
diff --git a/chess.c b/chess.c
index 3657f63..7464497 100644
--- a/chess.c
+++ b/chess.c
@@ -1,5 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+
+#define ANSI_COLOR_RED "\x1b[31m"
+#define ANSI_COLOR_GREEN "\x1b[32m"
+#define ANSI_COLOR_YELLOW "\x1b[33m"
+#define ANSI_COLOR_BLUE "\x1b[34m"
+#define ANSI_COLOR_MAGENTA "\x1b[35m"
+#define ANSI_COLOR_CYAN "\x1b[36m"
+#define ANSI_COLOR_RESET "\x1b[0m"
+
typedef enum {
pawn = 1,
knight = 2,
@@ -29,65 +39,66 @@ vectorp_t init_vectorp(vector_t* vectors, int length) {
return vectorP;
}
void draw_board(int board[8][8]) {
- printf(" ABCDEFGH\n");
+ printf(" A B C D E F G H\n");
+ int tileColor = 1;
for(int r = 0; r < 8; r++) {
- char* line = calloc(10, sizeof(char));
+ tileColor = !tileColor;
+ char* line = calloc(2 + (8 * 10), sizeof(char));
line[0] = '8' - r;
line[1] = ' ';
for(int c = 0; c < 8; c++) {
+ tileColor = !tileColor;
+ strcat(line, tileColor == 0 ? ANSI_COLOR_RED : ANSI_COLOR_RESET);
if(board[c][r] <= 6) {
switch(board[c][r]) {
case 0:
- line[c + 2] = ' ';
+ strcat(line, "# ");
break;
case pawn:
- line[c + 2] = 'P';
+ strcat(line, "P ");
break;
case knight:
- line[c + 2] = 'N';
+ strcat(line, "N ");
break;
case bishop:
- line[c + 2] = 'B';
+ strcat(line, "B ");
break;
case rook:
- line[c + 2] = 'R';
+ strcat(line, "R ");
break;
case queen:
- line[c + 2] = 'Q';
+ strcat(line, "Q ");
break;
case king:
- line[c + 2] = 'K';
+ strcat(line, "K ");
break;
}
}
else {
switch(board[c][r] - 6) {
- case 0:
- line[c + 2] = ' ';
- break;
case pawn:
- line[c + 2] = 'p';
+ strcat(line, "p ");
break;
case knight:
- line[c + 2] = 'n';
+ strcat(line, "n ");
break;
case bishop:
- line[c + 2] = 'b';
+ strcat(line, "b ");
break;
case rook:
- line[c + 2] = 'r';
+ strcat(line, "r ");
break;
case queen:
- line[c + 2] = 'q';
+ strcat(line, "q ");
break;
case king:
- line[c + 2] = 'k';
+ strcat(line, "k ");
break;
}
}
}
printf(line);
- printf("\n");
+ printf("\n" ANSI_COLOR_RESET);
free(line);
}
}
@@ -105,7 +116,6 @@ int is_color(int board[8][8], vector_t position, int color) {
return board[position.mx][position.my] >= 7;
}
}
-//0 is white, 1 is black
vectorp_t get_pawn_moves(int board[8][8], vector_t position, int color) {
vector_t* moves = malloc(6 * sizeof(vector_t));
int moveCount = 0;
@@ -149,7 +159,7 @@ vectorp_t get_knight_moves(int board[8][8], vector_t position, int color) {
return init_vectorp(moves, moveCount);
}
vectorp_t get_bishop_moves(int board[8][8], vector_t position, int color) {
- vector_t* moves = malloc(13 * sizeof(vector_t));
+ vector_t* moves = malloc(14 * sizeof(vector_t));
int moveCount = 0;
for(int i = 0; i < 4; i++) {
int h = i < 2 ? 1 : -1;
@@ -179,6 +189,78 @@ vectorp_t get_bishop_moves(int board[8][8], vector_t position, int color) {
}
return init_vectorp(moves, moveCount);
}
+vectorp_t get_rook_moves(int board[8][8], vector_t position, int color) {
+ vector_t* moves = malloc(14 * sizeof(vector_t));
+ int moveCount = 0;
+ for(int i = 0; i < 4; i++) {
+ int h = (i == 0 || i == 2) ? 0 : i == 1 ? 1 : -1;
+ int v = (i == 1 || i == 3) ? 0 : i == 2 ? 1 : -1;
+ vector_t checkPos = init_vector(position.mx, position.my);
+ for(int d = 0; d < 7; d++) {
+ checkPos.mx += h;
+ checkPos.my += v;
+ if(in_board(checkPos)) {
+ if(is_empty(board, checkPos)) {
+ moves[moveCount] = init_vector(checkPos.mx, checkPos.my);
+ moveCount++;
+ }
+ else if(is_color(board, checkPos, !color)) {
+ moves[moveCount] = init_vector(checkPos.mx, checkPos.my);
+ moveCount++;
+ break;
+ }
+ else {
+ break;
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ return init_vectorp(moves, moveCount);
+}
+vectorp_t get_queen_moves(int board[8][8], vector_t position, int color) {
+ vector_t* moves = malloc(28 * sizeof(vector_t));
+ int moveCount = 0;
+ for(int i = 0; i < 8; i++) {
+ int h;
+ int v;
+ //diagonal moves
+ if(i < 4) {
+ h = i < 2 ? 1 : -1;
+ v = (i == 0 || i == 2) ? 1 : -1;
+ }
+ //straight moves
+ else {
+ h = (i == 4 || i == 6) ? 0 : i == 5 ? 1 : -1;
+ v = (i == 5 || i == 7) ? 0 : i == 6 ? 1 : -1;
+ }
+ vector_t checkPos = init_vector(position.mx, position.my);
+ for(int d = 0; d < 7; d++) {
+ checkPos.mx += h;
+ checkPos.my += v;
+ if(in_board(checkPos)) {
+ if(is_empty(board, checkPos)) {
+ moves[moveCount] = init_vector(checkPos.mx, checkPos.my);
+ moveCount++;
+ }
+ else if(is_color(board, checkPos, !color)) {
+ moves[moveCount] = init_vector(checkPos.mx, checkPos.my);
+ moveCount++;
+ break;
+ }
+ else {
+ break;
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ return init_vectorp(moves, moveCount);
+}
vectorp_t get_moves(int board[8][8], vector_t position, piece_t piece) {
int color = 0;
if(piece > 6) {
@@ -194,6 +276,12 @@ vectorp_t get_moves(int board[8][8], vector_t position, piece_t piece) {
else if(piece == bishop) {
return get_bishop_moves(board, position, color);
}
+ else if(piece == rook) {
+ return get_rook_moves(board, position, color);
+ }
+ else if(piece == queen) {
+ return get_queen_moves(board, position, color);
+ }
}
vector_t user_input_pos() {
char* inputString = malloc(3 * sizeof(char));
@@ -220,11 +308,45 @@ vector_t user_input_pos() {
//converts board coordinates into algebraic notation
char* get_readable_coords(vector_t position) {
char* output = malloc(3 * sizeof(char));
- output[0] = 'A' + position.mx;
+ output[0] = 'a' + position.mx;
output[1] = '8' - position.my;
output[2] = '\0';
return output;
}
+//gets the proper algebraic notation for the move
+char* get_move_name(int board[8][8], vector_t origin, vector_t end) {
+ int piece = board[origin.mx][origin.my];
+ if(piece > 6) {
+ piece -= 6;
+ }
+ if(piece != 1) {
+ char cPiece = piece == pawn ? 'P' : piece == knight ? 'N' : piece == bishop ? 'B' : piece == rook ? 'R' : piece == queen ? 'Q' : 'K';
+ int isCapture = board[end.mx][end.my] != 0;
+ char* output = calloc(isCapture ? 5 : 4, sizeof(char));
+ output[0] = cPiece;
+ if(isCapture) {
+ output[1] = 'x';
+ }
+ char* rEnd = get_readable_coords(end);
+ strcat(output, rEnd);
+ free(rEnd);
+ output[isCapture ? 4 : 3] = '\0';
+ return output;
+ }
+ else {
+ int isCapture = board[end.mx][end.my] != 0;
+ char* output = calloc(isCapture ? 5 : 3, sizeof(char));
+ if(isCapture) {
+ output[0] = 'a' + origin.mx;
+ output[1] = 'x';
+ }
+ char* rEnd = get_readable_coords(end);
+ strcat(output, rEnd);
+ free(rEnd);
+ output[isCapture ? 4 : 2] = '\0';
+ return output;
+ }
+}
void clear_screen() {
system("@cls||clear");
}
@@ -273,7 +395,7 @@ int main() {
printf("Valid moves: ");
//write all the valid moves
for(int i = 0; i < moves.length; i++) {
- char* readable_coords = get_readable_coords(moves.vectors[i]);
+ char* readable_coords = get_move_name(board, selection, moves.vectors[i]);
printf(readable_coords);
free(readable_coords);
printf("; ");