summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/board.c62
-rw-r--r--lib/coordinate.c109
-rw-r--r--lib/print.c67
3 files changed, 173 insertions, 65 deletions
diff --git a/lib/board.c b/lib/board.c
index c4a4f2d..774bfd5 100644
--- a/lib/board.c
+++ b/lib/board.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include "board.h"
+#include "coordinate.h"
#include "piece.h"
static Board _setup_colors(Board b) {
@@ -9,69 +10,78 @@ static Board _setup_colors(Board b) {
for (i = 0; i < SIZE; i++)
for (j = 0; j < SIZE; j++)
- if (i % 2) // Odd rows start with white
+ if (i % 2)
if (j % 2)
- b[i][j].color = WHITE;
- else
b[i][j].color = BLACK;
+ else
+ b[i][j].color = WHITE;
else
if (j % 2)
- b[i][j].color = BLACK;
- else
b[i][j].color = WHITE;
+ else
+ b[i][j].color = BLACK;
return b;
}
+static Board _set_new_piece(Board b, Coord c, Color color, PieceType t) {
+ Square s = board_get_square(b, c);
+ s.piece = new_piece(color, t);
+
+ return board_set_square(b, c, s);
+}
+
static Board _pawns(Board b) {
- short white_pawns_row = 1, black_pawns_row = 6, i;
+ Coord c = coord_set_row(coord_null(), '2');
+ char col;
- for (i = 0; i < SIZE; i++)
- b[white_pawns_row][i].piece = new_piece(WHITE, PAWN);
+ for (col = 'a'; col <= 'h'; col++)
+ _set_new_piece(b, coord_set_col(c, col), WHITE, PAWN);
- for (i = 0; i < SIZE; i++)
- b[black_pawns_row][i].piece = new_piece(BLACK, PAWN);
+ c = coord_set_row(coord_null(), '7');
+ for (col = 'a'; col <= 'h'; col++)
+ _set_new_piece(b, coord_set_col(c, col), BLACK, PAWN);
return b;
}
static Board _rocks(Board b) {
- b[0][0].piece = new_piece(WHITE, ROCK);
- b[0][7].piece = new_piece(WHITE, ROCK);
- b[7][0].piece = new_piece(BLACK, ROCK);
- b[7][7].piece = new_piece(BLACK, ROCK);
+ _set_new_piece(b, coord_init("a1"), WHITE, ROCK);
+ _set_new_piece(b, coord_init("h1"), WHITE, ROCK);
+ _set_new_piece(b, coord_init("a8"), BLACK, ROCK);
+ _set_new_piece(b, coord_init("h8"), BLACK, ROCK);
return b;
}
static Board _knights(Board b) {
- b[0][1].piece = new_piece(WHITE, KNIGHT);
- b[0][6].piece = new_piece(WHITE, KNIGHT);
- b[7][1].piece = new_piece(BLACK, KNIGHT);
- b[7][6].piece = new_piece(BLACK, KNIGHT);
+ _set_new_piece(b, coord_init("b1"), WHITE, KNIGHT);
+ _set_new_piece(b, coord_init("g1"), WHITE, KNIGHT);
+ _set_new_piece(b, coord_init("b8"), BLACK, KNIGHT);
+ _set_new_piece(b, coord_init("g8"), BLACK, KNIGHT);
return b;
}
static Board _bishops(Board b) {
- b[0][2].piece = new_piece(WHITE, BISHOP);
- b[0][5].piece = new_piece(WHITE, BISHOP);
- b[7][2].piece = new_piece(BLACK, BISHOP);
- b[7][5].piece = new_piece(BLACK, BISHOP);
+ _set_new_piece(b, coord_init("c1"), WHITE, BISHOP);
+ _set_new_piece(b, coord_init("f1"), WHITE, BISHOP);
+ _set_new_piece(b, coord_init("c8"), BLACK, BISHOP);
+ _set_new_piece(b, coord_init("f8"), BLACK, BISHOP);
return b;
}
static Board _queens(Board b) {
- b[0][4].piece = new_piece(WHITE, QUEEN);
- b[7][4].piece = new_piece(BLACK, QUEEN);
+ _set_new_piece(b, coord_init("d1"), WHITE, QUEEN);
+ _set_new_piece(b, coord_init("d8"), BLACK, QUEEN);
return b;
}
static Board _kings(Board b) {
- b[0][3].piece = new_piece(WHITE, KING);
- b[7][3].piece = new_piece(BLACK, KING);
+ _set_new_piece(b, coord_init("e1"), WHITE, KING);
+ _set_new_piece(b, coord_init("e8"), BLACK, KING);
return b;
}
diff --git a/lib/coordinate.c b/lib/coordinate.c
index 2dc0215..7518a78 100644
--- a/lib/coordinate.c
+++ b/lib/coordinate.c
@@ -3,29 +3,110 @@
#include "coordinate.h"
-static int _valid_coord(char col, char row) {
+/*
+ * Returns 0 if the coordinate is between a1 and h8.
+ */
+int coord_is_valid(char *s) {
+ if (strnlen(s, 3) != 2)
+ return 1;
+
+ char col = tolower(s[0]);
+ char row = tolower(s[1]);
+
if (col >= 'a' && col <= 'h' && row >= '1' && row <= '8')
return 0;
- return 1;
+ return 2;
}
-int coord_init(Coord* c, char col, char row) {
- char lower_col = tolower(col);
- char lower_row = tolower(row);
+/*
+ * Does not check if s is a valid string representing. If input is
+ * untrusted, use coord_is_valid(char*) to check it.
+ */
+Coord coord_init(char* s) {
+ Coord c;
+ char col = tolower(s[0]);
+ char row = tolower(s[1]);
- if (! _valid_coord(lower_col, lower_row))
- return 1;
+ c.col = col;
+ c.row = row;
+
+ return c;
+}
+
+/*
+ * Returns 0 if c is the null coordinate
+ */
+int coord_is_null(Coord c) {
+ return (c.col == 0 && c.row == 0);
+}
- c->row = row;
- c->col = col;
+/*
+ * Returns the null coordinate
+ */
+Coord coord_null() {
+ Coord c;
- return 0;
+ c.col = 0;
+ c.row = 0;
+
+ return c;
}
-int coord_init_from_str(Coord* c, char* s) {
- if (strlen(s) != 2)
- return 1;
+/*
+ * Set Coord row
+ */
+Coord coord_set_row(Coord c, char row) {
+ c.row = row;
+
+ return c;
+}
+
+/*
+ * Set Coord column
+ */
+Coord coord_set_col(Coord c, char col) {
+ c.col = col;
+
+ return c;
+}
+
+/*
+ * Returns the next coordinate. Useful for traversing the board forwards.
+ */
+Coord coord_next(Coord c) {
+ if (coord_is_null(c))
+ c = coord_init("a8");
+ else
+ if (c.col == 'h')
+ if (c.row == '1')
+ c = coord_null();
+ else {
+ c.row -= 1;
+ c.col = 'a';
+ }
+ else
+ c.col += 1;
+
+ return c;
+}
+
+/*
+ * Returns the previous coordinate. Useful for traversing the board backwards.
+ */
+Coord coord_prev(Coord c) {
+ if (coord_is_null(c))
+ c = coord_init("h1");
+ else
+ if (c.col == 'a')
+ if (c.row == '8')
+ c = coord_null();
+ else {
+ c.row += 1;
+ c.col = 'h';
+ }
+ else
+ c.col -= 1;
- return coord_init(c, s[0], s[1]);
+ return c;
}
diff --git a/lib/print.c b/lib/print.c
index 249e486..9282581 100644
--- a/lib/print.c
+++ b/lib/print.c
@@ -2,8 +2,26 @@
#include <stdlib.h>
#include "print.h"
+#include "board.h"
+#include "coordinate.h"
#include "piece.h"
+static void _print_row_separator() {
+ int j;
+
+ for (j = 0; j < SIZE; j++)
+ printf("+---");
+
+ printf("+\n");
+}
+
+static Coord _next_coord(Coord c, Color side) {
+ if (side == WHITE)
+ return coord_next(c);
+ else
+ return coord_prev(c);
+}
+
/* Printing related functions */
void print_piece(Piece p) {
putchar(piece_character(p));
@@ -11,39 +29,38 @@ void print_piece(Piece p) {
void print_square(Square s) {
if (s.piece == NULL)
- switch (s.color) {
- case WHITE:
+ if (s.color == WHITE)
putchar(' ');
- break;;
- case BLACK:
+ else
putchar('/');
- break;
- default:
- perror("Wait... what?\n");
- exit(EXIT_FAILURE);
- }
else
print_piece(*s.piece);
}
-void print_board(Board b) {
- int i, j;
+/*
+ * Pretty print the board. The "side" parameter lets you choose the
+ * orientation. Use WHITE for a white player perspective, BLACK otherwise.
+ */
+void print_board(Board b, Color side) {
+ Coord c = _next_coord(coord_null(), side);
+ char current_row = c.row;
- for (i = 0; i < SIZE; i++) {
- for (j = 0; j < SIZE; j++)
- printf("+---");
- printf("+\n");
+ _print_row_separator();
+ while (!coord_is_null(c)) {
+ // Print the square
+ printf("| ");
+ print_square(board_get_square(b, c));
+ putchar(' ');
- for (j = 0; j < SIZE; j++) {
- printf("| ");
- print_square(b[i][j]);
- putchar(' ');
- }
- printf("|\n");
- }
+ // Shall we move forward or backwards?
+ c = _next_coord(c, side);
- for (j = 0; j < SIZE; j++)
- printf("+---");
- printf("+\n");
+ // If the row changed then we must start a new line
+ if (c.row != current_row) {
+ printf("|\n");
+ _print_row_separator();
+ current_row = c.row;
+ }
+ }
}
nihil fit ex nihilo