73 lines
1.7 KiB
C++
73 lines
1.7 KiB
C++
/*
|
|
* 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 <cstdio>
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
#include <sys/types.h> // mode_t
|
|
#include <sys/stat.h> // mkfifo()
|
|
#include <unistd.h> // unlink(), fork()
|
|
#include <signal.h> // 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);
|
|
}
|