#endif
typedef enum {
- PLAYER_BLACK,
- PLAYER_WHITE
-} player_t;
+ LOA_PLAYER_BLACK,
+ LOA_PLAYER_WHITE
+} loa_player_t;
typedef enum {
- CELL_BLACK = PLAYER_BLACK,
- CELL_WHITE = PLAYER_WHITE,
- CELL_EMPTY
-} cell_t;
+ LOA_CELL_BLACK = LOA_PLAYER_BLACK,
+ LOA_CELL_WHITE = LOA_PLAYER_WHITE,
+ LOA_CELL_EMPTY
+} loa_cell_t;
/* The implementation of board_group_size depends on the square of
* BOARD_SIZE being less than or equal to 64. */
-#define BOARD_SIZE 8
-#define DIAG_ARRAY_SIZE (2 * BOARD_SIZE - 1)
+#define LOA_BOARD_SIZE 8
+#define LOA_DIAG_ARRAY_SIZE (2 * LOA_BOARD_SIZE - 1)
typedef struct {
- cell_t cells[BOARD_SIZE][BOARD_SIZE];
+ loa_cell_t cells[LOA_BOARD_SIZE][LOA_BOARD_SIZE];
/* Number of black and white pieces */
int num_pieces[2];
/* Number of pieces (of either color) in each row, column, and
* diagonal. */
- int row_pieces[BOARD_SIZE];
- int col_pieces[BOARD_SIZE];
- int diag_grave_pieces[DIAG_ARRAY_SIZE];
- int diag_acute_pieces[DIAG_ARRAY_SIZE];
-} board_t;
+ int row_pieces[LOA_BOARD_SIZE];
+ int col_pieces[LOA_BOARD_SIZE];
+ int diag_grave_pieces[LOA_DIAG_ARRAY_SIZE];
+ int diag_acute_pieces[LOA_DIAG_ARRAY_SIZE];
+
+ loa_player_t player;
+} loa_board_t;
typedef struct _loa_game {
loudgame_t lg;
- board_t board;
- player_t current;
+ loa_board_t board;
} loa_game_t;
+static void
+loa_board_next_player (loa_board_t *board)
+{
+ if (board->player == LOA_PLAYER_BLACK)
+ board->player = LOA_PLAYER_WHITE;
+ else
+ board->player = LOA_PLAYER_BLACK;
+}
+
static int
-board_group_size_recursive (board_t *board, int x, int y,
- cell_t cell,
- uint64_t *visited)
+loa_board_group_size_recursive (loa_board_t *board, int x, int y,
+ loa_cell_t cell,
+ uint64_t *visited)
{
uint64_t bit;
if (x < 0 || y < 0)
return 0;
- if (x >= BOARD_SIZE || y >= BOARD_SIZE)
+ if (x >= LOA_BOARD_SIZE || y >= LOA_BOARD_SIZE)
return 0;
- bit = 1ll << (x * BOARD_SIZE + y);
+ bit = 1ll << (x * LOA_BOARD_SIZE + y);
if (*visited & bit)
return 0;
return 0;
return 1 +
- board_group_size_recursive (board, x-1, y-1, cell, visited) +
- board_group_size_recursive (board, x-1, y , cell, visited) +
- board_group_size_recursive (board, x-1, y+1, cell, visited) +
- board_group_size_recursive (board, x , y-1, cell, visited) +
- board_group_size_recursive (board, x , y , cell, visited) +
- board_group_size_recursive (board, x , y+1, cell, visited) +
- board_group_size_recursive (board, x+1, y-1, cell, visited) +
- board_group_size_recursive (board, x+1, y , cell, visited) +
- board_group_size_recursive (board, x+1, y+1, cell, visited);
+ loa_board_group_size_recursive (board, x-1, y-1, cell, visited) +
+ loa_board_group_size_recursive (board, x-1, y , cell, visited) +
+ loa_board_group_size_recursive (board, x-1, y+1, cell, visited) +
+ loa_board_group_size_recursive (board, x , y-1, cell, visited) +
+ loa_board_group_size_recursive (board, x , y , cell, visited) +
+ loa_board_group_size_recursive (board, x , y+1, cell, visited) +
+ loa_board_group_size_recursive (board, x+1, y-1, cell, visited) +
+ loa_board_group_size_recursive (board, x+1, y , cell, visited) +
+ loa_board_group_size_recursive (board, x+1, y+1, cell, visited);
}
static int
-board_group_size (board_t *board, int x, int y)
+loa_board_group_size (loa_board_t *board, int x, int y)
{
uint64_t visited = 0ll;
- cell_t cell = board->cells[x][y];
+ loa_cell_t cell = board->cells[x][y];
- return board_group_size_recursive (board, x, y, cell, &visited);
+ return loa_board_group_size_recursive (board, x, y, cell, &visited);
}
static int
-board_is_won (board_t *board, int x, int y)
+loa_board_is_won (loa_board_t *board, int x, int y)
{
- cell_t cell = board->cells[x][y];
+ loa_cell_t cell = board->cells[x][y];
- if (cell == CELL_EMPTY)
+ if (cell == LOA_CELL_EMPTY)
return 0;
- if (board_group_size (board, x, y) == board->num_pieces[cell])
+ if (loa_board_group_size (board, x, y) == board->num_pieces[cell])
return 1;
return 0;
static int
_grave_index (int x, int y)
{
- return x - y + BOARD_SIZE - 1;
+ return x - y + LOA_BOARD_SIZE - 1;
}
/* Given an (x,y) position on the board, return the index of the array
}
static loa_bool_t
-board_move_legal (board_t *board, int x1, int y1, int x2, int y2, char **error)
+loa_board_move_legal (loa_board_t *board,
+ int x1, int y1,
+ int x2, int y2,
+ char **error)
{
int x, y;
int dx, dy;
int step_x, step_y;
- if (board->cells[x1][y1] == CELL_EMPTY) {
+ if (board->cells[x1][y1] == LOA_CELL_EMPTY) {
*error = "There is no piece there to move";
return FALSE;
}
x != x2 || y != y2;
x += step_x, y += step_y)
{
- if (board->cells[x][y] != CELL_EMPTY &&
+ if (board->cells[x][y] != LOA_CELL_EMPTY &&
board->cells[x][y] != board->cells[x1][y1])
{
*error = "You cannot jump an opponent's piece";
}
static void
-board_add_piece (board_t *board, int x, int y, cell_t cell)
+loa_board_add_piece (loa_board_t *board, int x, int y, loa_cell_t cell)
{
- assert (cell == CELL_BLACK || cell == CELL_WHITE);
- assert (board->cells[x][y] == CELL_EMPTY);
+ assert (cell == LOA_CELL_BLACK || cell == LOA_CELL_WHITE);
+ assert (board->cells[x][y] == LOA_CELL_EMPTY);
board->col_pieces[x]++;
board->row_pieces[y]++;
board->cells[x][y] = cell;
}
-static cell_t
-board_remove_piece (board_t *board, int x, int y)
+static loa_cell_t
+loa_board_remove_piece (loa_board_t *board, int x, int y)
{
- cell_t cell;
+ loa_cell_t cell;
cell = board->cells[x][y];
- if (cell == CELL_EMPTY)
- return CELL_EMPTY;
+ if (cell == LOA_CELL_EMPTY)
+ return LOA_CELL_EMPTY;
board->col_pieces[x]--;
board->row_pieces[y]--;
board->num_pieces[cell]--;
- board->cells[x][y] = CELL_EMPTY;
+ board->cells[x][y] = LOA_CELL_EMPTY;
return cell;
}
static void
-board_init (board_t *board)
+loa_board_init (loa_board_t *board)
{
int i, x, y;
- for (x = 0; x < BOARD_SIZE; x++)
- for (y = 0; y < BOARD_SIZE; y++)
- board->cells[x][y] = CELL_EMPTY;
+ for (x = 0; x < LOA_BOARD_SIZE; x++)
+ for (y = 0; y < LOA_BOARD_SIZE; y++)
+ board->cells[x][y] = LOA_CELL_EMPTY;
- board->num_pieces[CELL_BLACK] = 0;
- board->num_pieces[CELL_WHITE] = 0;
+ board->num_pieces[LOA_CELL_BLACK] = 0;
+ board->num_pieces[LOA_CELL_WHITE] = 0;
- for (i = 0; i < BOARD_SIZE; i++) {
+ for (i = 0; i < LOA_BOARD_SIZE; i++) {
board->row_pieces[i] = 0;
board->col_pieces[i] = 0;
}
- for (i = 0; i < DIAG_ARRAY_SIZE; i++) {
+ for (i = 0; i < LOA_DIAG_ARRAY_SIZE; i++) {
board->diag_grave_pieces[i] = 0;
board->diag_acute_pieces[i] = 0;
}
- for (i = 1; i < BOARD_SIZE - 1; i++) {
- board_add_piece (board, i, 0, CELL_BLACK);
- board_add_piece (board, i, BOARD_SIZE - 1, CELL_BLACK);
- board_add_piece (board, 0, i, CELL_WHITE);
- board_add_piece (board, BOARD_SIZE - 1, i, CELL_WHITE);
+ for (i = 1; i < LOA_BOARD_SIZE - 1; i++) {
+ loa_board_add_piece (board, i, 0, LOA_CELL_BLACK);
+ loa_board_add_piece (board, i, LOA_BOARD_SIZE - 1, LOA_CELL_BLACK);
+ loa_board_add_piece (board, 0, i, LOA_CELL_WHITE);
+ loa_board_add_piece (board, LOA_BOARD_SIZE - 1, i, LOA_CELL_WHITE);
}
+
+ board->player = LOA_PLAYER_BLACK;
}
/* A few different ideas for displaying boards:
* A B C D E F G H A B C D E F G H
*/
static char *
-board_to_string (board_t *board)
+loa_board_to_string (loa_board_t *board)
{
int x, y;
/* In order of BLACK, WHITE, EMPTY */
} while (0)
APPENDF (" %s\n", board_header);
- for (y = 0; y < BOARD_SIZE; y++) {
- APPENDF ("%d%s", BOARD_SIZE - y, row_header);
- for (x = 0; x < BOARD_SIZE; x++) {
+ for (y = 0; y < LOA_BOARD_SIZE; y++) {
+ APPENDF ("%d%s", LOA_BOARD_SIZE - y, row_header);
+ for (x = 0; x < LOA_BOARD_SIZE; x++) {
APPENDF ("%s", cell_strings[board->cells[x][y]]);
- if (x != BOARD_SIZE - 1)
+ if (x != LOA_BOARD_SIZE - 1)
APPENDF ("%s", cell_separator);
}
APPENDF ("%s\n", row_footer);
- if (y != BOARD_SIZE -1)
+ if (y != LOA_BOARD_SIZE -1)
APPENDF (" %s\n", row_separator);
}
APPENDF (" %s\n", board_footer);
APPENDF (" ");
- for (x = 0; x < BOARD_SIZE; x++) {
+ for (x = 0; x < LOA_BOARD_SIZE; x++) {
APPENDF ("%c", 'A' + x);
- if (x != BOARD_SIZE - 1)
+ if (x != LOA_BOARD_SIZE - 1)
APPENDF (" ");
}
APPENDF ("\n");
static void
loa_game_new_game (loa_game_t *game)
{
- board_init (&game->board);
- game->current = PLAYER_BLACK;
-}
-
-static void
-loa_game_next_player (loa_game_t *game)
-{
- if (game->current == PLAYER_BLACK)
- game->current = PLAYER_WHITE;
- else
- game->current = PLAYER_BLACK;
+ loa_board_init (&game->board);
}
static loa_bool_t
loa_game_move (loa_game_t *game, const char * peer,
int x1, int y1, int x2, int y2)
{
- board_t *board = &game->board;
- cell_t cell;
+ loa_board_t *board = &game->board;
+ loa_cell_t cell;
char *error;
- if (x1 < 0 || y1 < 0 || x1 >= BOARD_SIZE || y1 >= BOARD_SIZE) {
+ if (x1 < 0 || y1 < 0 || x1 >= LOA_BOARD_SIZE || y1 >= LOA_BOARD_SIZE) {
loudgame_sendf (&game->lg, peer, "Invalid coordinates (not on board).");
return FALSE;
}
- if (board->cells[x1][y1] != game->current) {
+ if (board->cells[x1][y1] != board->player) {
loudgame_sendf (&game->lg, peer, "Cell at (%d,%d) does not belong to current player.",
x1, y1);
return FALSE;
}
- if (! board_move_legal (&game->board, x1, y1, x2, y2, &error)) {
+ if (! loa_board_move_legal (&game->board, x1, y1, x2, y2, &error)) {
loudgame_sendf (&game->lg, peer, "Illegal move: %c%d%c%d",
- 'a' + x1, BOARD_SIZE - y1,
- 'a' + x2, BOARD_SIZE - y2);
+ 'a' + x1, LOA_BOARD_SIZE - y1,
+ 'a' + x2, LOA_BOARD_SIZE - y2);
return FALSE;
}
- cell = board_remove_piece (board, x1, y1);
- board_remove_piece (board, x2, y2);
- board_add_piece (board, x2, y2, cell);
+ cell = loa_board_remove_piece (board, x1, y1);
+ loa_board_remove_piece (board, x2, y2);
+ loa_board_add_piece (board, x2, y2, cell);
- loa_game_next_player (game);
+ loa_board_next_player (board);
return TRUE;
}
"xmlns",
"http://www.w3.org/1999/xhtml");
- if (game->current == PLAYER_BLACK)
+ if (game->board.player == LOA_PLAYER_BLACK)
lm_message_node_add_child (body, "span", "Black to move:");
else
lm_message_node_add_child (body, "span", "White to move:");
- board_string = board_to_string (&game->board);
+ board_string = loa_board_to_string (&game->board);
line = board_string;
while (1) {
x1 = tolower (xc1) - 'a';
x2 = tolower (xc2) - 'a';
/* We use an upper-left origin internally. */
- y1 = BOARD_SIZE - y1;
- y2 = BOARD_SIZE - y2;
+ y1 = LOA_BOARD_SIZE - y1;
+ y2 = LOA_BOARD_SIZE - y2;
if (! loa_game_move (game, peer, x1, y1, x2, y2))
return;
loudgame_broadcastf (&game->lg, "%c%d%c%d",
- 'a' + x1, BOARD_SIZE - y1,
- 'a' + x2, BOARD_SIZE - y2);
+ 'a' + x1, LOA_BOARD_SIZE - y1,
+ 'a' + x2, LOA_BOARD_SIZE - y2);
- if (board_is_won (&game->board, x2, y2))
+ if (loa_board_is_won (&game->board, x2, y2))
loudgame_broadcastf (&game->lg, "%s wins", peer);
}
{
loudgame_broadcastf (&game->lg, "%s passes", peer);
- loa_game_next_player (game);
+ loa_board_next_player (&game->board);
}
static void