diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/board.c | 62 | ||||
-rw-r--r-- | lib/coordinate.c | 109 | ||||
-rw-r--r-- | lib/print.c | 67 |
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; + } + } } |