/* * Othello engine. * * This program keeps track of the current state of the board and renders it * appropriately. It calls the respective players, validates and implements * their moves. It furthermore keeps track of the players' move time limits. */ #include #include #include #include #include // mode_t #include // mkfifo() #include // unlink(), fork() #include // signal() #include "board.h" #include "mcp.h" bool serialize_state(int fd, const game_state *state) { return state->dump_to_fd(fd); } void initialize_state(game_state *state, char const *init) { if (init[0] == 'O') state->player(0); else state->player(1); for (unsigned r = 0; r < state->rows(); ++r) { for (unsigned c = 0; c < state->columns(); ++c) { char field = init[r * state->columns() + c + 1]; FieldType t; switch(field) { case '.': t = EMPTY; break; case 'O': t = PLAYER_1; break; case 'X': t = PLAYER_2; break; default: t = OUT_OF_BOUNDS; break; } state->set(r+1,c+1,t); } } } bool is_final_state(game_state const *state) { return state->finished(); } bool deserialize_move(int fd, game_move *move) { char buf[128]; memset(buf,0,128); ssize_t r = read(fd, buf, 128); if (r != 3) return false; int res = sscanf(buf, "%u,%u", &move->row, &move->col); if (res != 2) return false; return true; } bool apply_move(game_state *state, const game_move *move) { // skip move only if it's really impossible if ((move->row == 0) && (move->col == 0) && !state->can_move()) { state->skipped(); return true; } return state->move(move->row, move->col); }