diff --git a/assignment1-18/chessboard.c b/assignment1-18/chessboard.c index be63ea9..c7e3e3a 100644 --- a/assignment1-18/chessboard.c +++ b/assignment1-18/chessboard.c @@ -1,5 +1,10 @@ +// vim: set ts=4 sw=4 et tw=80: + #include #include "./chessboard.h" +#include +#include +#include void init_chessboard(struct chessboard * cb) { int i; @@ -37,7 +42,7 @@ void init_chessboard(struct chessboard * cb) { void print_chessboard(struct chessboard * cb) { printf(" a b c d e f g h\n" - " ┌───┬───┬───┬───┬───┬───┬───┬───┐\n"); + " ┌───┬───┬───┬───┬───┬───┬───┬───┐\n"); int i; for (i = 7; i >= 0; i--) { @@ -56,13 +61,93 @@ void print_chessboard(struct chessboard * cb) { } printf(" └───┴───┴───┴───┴───┴───┴───┴───┘\n" - " a b c d e f g h\n"); + " a b c d e f g h\n"); } +void cb_move(struct chessboard* cb, int from_row, int from_col, int to_row, + int to_col) { + cb->position[to_row][to_col] = cb->position[from_row][from_col]; + cb->position[from_row][from_col] = EMPTY; +} + +bool is_empty(struct chessboard* cb, int row, int col) { + return cb->position[row][col] == EMPTY; +} + +inline enum player player(struct chessboard* cb, int row, int col) { + return cb->position[row][col] < 7 ? WHITE : BLACK; +} + +enum mstatus move_pawn(struct chessboard* cb, enum player p, int from_row, + int from_col, int to_row, int to_col) { + // two forward if in the starting position, no capture is valid + if (((p == WHITE && from_row == 1 && to_row == 3 && + is_empty(cb, 2, from_col)) || + (p == BLACK && from_row == 7 && to_row == 5 && + is_empty(cb, 6, from_col))) && + from_col == to_col && + is_empty(cb, to_row, to_col)) { + cb_move(cb, from_row, from_col, to_row, to_col); + return VALID; + // one forward, no capture is valid + } else if (((p == WHITE && to_row - from_row == 1) || + (p == BLACK && from_row - to_row == 1)) && + from_col == to_col && + is_empty(cb, to_row, to_col)) { + cb_move(cb, from_row, from_col, to_row, to_col); + return VALID; + // one forward, one left or right, with capture, is valid + } else if (to_row = from_row + (p == WHITE ? 1 : -1) && + abs(from_col - to_col) == 1 && + !is_empty(cb, to_row, to_col) && + player(cb, to_row, to_col) != p) { + cb_move(cb, from_row, from_col, to_row, to_col); + return VALID; + } else { + return INVALID; + } +} + enum mstatus move( - struct chessboard * cb, enum player p, - const char * from, const char * to) + struct chessboard * cb, enum player p, + const char * from, const char * to) { - + // if you are giving us garbage, we behave like Rome's municipal services + if (strlen(from) != 2 || strlen(to) != 2 || from[0] < 'a' || from[0] > 'h' + || to[0] < 'a' || to[0] > 'h' || from[1] < '1' || from[1] > '8' + || to[1] < '1' || to[1] > '8') { + return INVALID; + } + + int from_row = from[0] - 'a', to_row = to[0] - 'a'; + int from_col = from[1] - '1', to_col = to[0] - '1'; + + // if you are moving thin air, EH VOLEVIH + if (cb->position[from_row][from_col] == EMPTY) { + return INVALID; + } + + // if you are moving someone else's pieces, "thou shall not steal" + if (cb->position[from_row][from_col] / 7 != p) { + return INVALID; + } + + // if you are trying to suicide (capture your piecies), sorry but assisted + // suicide is not legal in italy + if (cb->position[to_row][to_col] != EMPTY && + cb->position[from_row][from_col] / 7 == + cb->position[to_row][to_col] / 7) { + return INVALID; + } + + // try to understand which piece we are moving + switch (cb->position[from_row][from_col]) { + case WHITE_PAWN: + case BLACK_PAWN: + return move_pawn(cb, p, from_row, from_col, to_row, to_col); + default: + return INVALID; + } } +