move history
このコミットが含まれているのは:
コミット
c0849f47b3
82
uttt.c
82
uttt.c
|
@ -32,6 +32,11 @@ struct ut_move
|
|||
{
|
||||
char r, c;
|
||||
};
|
||||
struct ut_game
|
||||
{
|
||||
char l;
|
||||
struct ut_move moves[81];
|
||||
};
|
||||
|
||||
const char HELP_TEXT[] = "\
|
||||
Usage: uttt (--local | --host | --join)\n\
|
||||
|
@ -280,25 +285,46 @@ void ut_bmvch(void *arg, int y, int x, char c)
|
|||
}
|
||||
|
||||
int dtiles_line;
|
||||
void ut_cursdraw(const struct ut_state *state)
|
||||
void ut_cursdraw(const struct ut_state *state, const struct ut_game *game)
|
||||
{
|
||||
ut_cursprintf("Turn: %c Play board: %s\n", (int)state->player, PLAY_BOARDS[(state->playBoard + 10) % 10]);
|
||||
dtiles_line = curs_line;
|
||||
ut_drawTiles(ut_cursmvchc, NULL, state, false, (struct ut_move){-1, -1}); // TODO some kind of move history to know the last move
|
||||
ut_drawTiles(ut_cursmvchc, NULL, state, false, (game && game->l > 0) ? game->moves[game->l - 1] : (struct ut_move){-1, -1});
|
||||
curs_line += DTILES_Y;
|
||||
//ut_drawBoards(ut_cursmvchc, NULL, state);
|
||||
}
|
||||
void ut_sockdraw(const struct ut_state *state, int fd)
|
||||
void ut_sockdraw(const struct ut_state *state, const struct ut_game *game, int fd)
|
||||
{
|
||||
ut_dprintf(fd, "Turn: %c\nPlay board: %s\n", (int)state->player, PLAY_BOARDS[(state->playBoard + 10) % 10]);
|
||||
char dtiles[DTILES_Y][DTILES_X];
|
||||
ut_drawTiles(ut_tmvch, dtiles, state, true, (struct ut_move){-1, -1});
|
||||
ut_drawTiles(ut_tmvch, dtiles, state, true, (game && game->l > 0) ? game->moves[game->l - 1] : (struct ut_move){-1, -1});
|
||||
for(int r = 0; r < DTILES_Y; r++)
|
||||
{
|
||||
ut_dprintf(fd, "%.*s\n", DTILES_X, dtiles[r]);
|
||||
}
|
||||
}
|
||||
|
||||
void ut_cursmove(const struct ut_move m)
|
||||
{
|
||||
ut_cursprintf("%d,%d", (int)m.c, (int)m.r);
|
||||
}
|
||||
void ut_cursgame(const struct ut_game *game)
|
||||
{
|
||||
for(int i = 0; i < game->l; i++)
|
||||
{
|
||||
ut_cursmove(game->moves[i]);
|
||||
if(i + 1 < game->l)
|
||||
{
|
||||
ut_cursprintf(" ");
|
||||
}
|
||||
}
|
||||
ut_cursprintf("\n");
|
||||
}
|
||||
void ut_sockmove(const struct ut_move m, int fd)
|
||||
{
|
||||
ut_dprintf(fd, "%d,%d\n", (int)m.c, (int)m.r);
|
||||
}
|
||||
|
||||
int ut_readfill(int fd, char *x, size_t l)
|
||||
{
|
||||
while(l > 0)
|
||||
|
@ -316,7 +342,7 @@ int ut_readfill(int fd, char *x, size_t l)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ut_cursgetpos(const struct ut_state *state, struct ut_move *m)
|
||||
int ut_cursgetmove(const struct ut_state *state, struct ut_move *m)
|
||||
{
|
||||
#define P(r, c, d) ((state->playBoard == -1 || state->playBoard == 3 * (r / 3) + (c / 3)) && \
|
||||
(state->boards[r / 3][c / 3] == '\0' || d % 3 == 1))
|
||||
|
@ -425,7 +451,7 @@ int ut_ignore_line(int sock) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
int ut_sockgetpos(const struct ut_state *state, int sock, struct ut_move *m, bool readable) {
|
||||
int ut_sockgetmove(const struct ut_state *state, int sock, struct ut_move *m, bool readable) {
|
||||
int index = 0;
|
||||
char byte;
|
||||
while (true) {
|
||||
|
@ -456,12 +482,12 @@ int ut_sockgetpos(const struct ut_state *state, int sock, struct ut_move *m, boo
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ut_local_game(struct ut_state *state) {
|
||||
int ut_local_game(struct ut_state *state, struct ut_game *game) {
|
||||
for(;;)
|
||||
{
|
||||
struct ut_move m = {4, 4};
|
||||
ut_curserase();
|
||||
ut_cursdraw(state);
|
||||
ut_cursdraw(state, game);
|
||||
char w = ut_winner(state);
|
||||
if(w)
|
||||
{
|
||||
|
@ -475,18 +501,19 @@ int ut_local_game(struct ut_state *state) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
if(ut_cursgetpos(state, &m)) {continue;}
|
||||
if(ut_cursgetmove(state, &m)) {continue;}
|
||||
if(ut_move(state, state, m)) {continue;}
|
||||
game->moves[game->l++] = m;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ut_network_game(struct ut_state *state, int sock, char player, bool readable) {
|
||||
int ut_network_game(struct ut_state *state, struct ut_game *game, int sock, char player, bool readable) {
|
||||
while (true) {
|
||||
struct ut_move m = {4, 4};
|
||||
ut_curserase();
|
||||
ut_cursdraw(state);
|
||||
if (readable) ut_sockdraw(state, sock);
|
||||
ut_cursdraw(state, game);
|
||||
if (readable) ut_sockdraw(state, game, sock);
|
||||
char w = ut_winner(state);
|
||||
if(w)
|
||||
{
|
||||
|
@ -506,8 +533,8 @@ int ut_network_game(struct ut_state *state, int sock, char player, bool readable
|
|||
}
|
||||
if (state->player == player) {
|
||||
if (readable) {ut_dprintf(sock, "Waiting for game partner ...\n");}
|
||||
if(ut_cursgetpos(state, &m)) {continue;}
|
||||
ut_dprintf(sock, "%d,%d\n", (int)m.c, (int)m.r);
|
||||
if(ut_cursgetmove(state, &m)) {continue;}
|
||||
ut_sockmove(m, sock);
|
||||
} else {
|
||||
ut_cursprintf("Waiting for game partner ...\n");
|
||||
refresh();
|
||||
|
@ -515,8 +542,13 @@ int ut_network_game(struct ut_state *state, int sock, char player, bool readable
|
|||
// line feed aligns game board each turn
|
||||
ut_dprintf(sock, "\nPlace token %c in position x,y: ", (int)ut_turn(player));
|
||||
}
|
||||
int err = ut_sockgetpos(state, sock, &m, readable);
|
||||
ut_cursprintf("received row=%d col=%d\n", (int)m.r, (int)m.c);
|
||||
int err = ut_sockgetmove(state, sock, &m, readable);
|
||||
if(err != 0)
|
||||
{
|
||||
ut_cursprintf("received ");
|
||||
ut_cursmove(m);
|
||||
ut_cursprintf("\n");
|
||||
}
|
||||
if (err == 1) {
|
||||
ut_cursprintf("Connection closed.\n");
|
||||
return 1;
|
||||
|
@ -526,8 +558,9 @@ int ut_network_game(struct ut_state *state, int sock, char player, bool readable
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
if (ut_move(state, state, m)) {continue;}
|
||||
if (readable) {ut_dprintf(sock, "\n");}
|
||||
if (ut_move(state, state, m)) {continue;}
|
||||
game->moves[game->l++] = m;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -540,7 +573,7 @@ char ut_random_player(void) {
|
|||
return player;
|
||||
}
|
||||
|
||||
int ut_host_game(struct ut_state *state) {
|
||||
int ut_host_game(struct ut_state *state, struct ut_game *game) {
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == -1) {
|
||||
ut_cursprintf("error %d\n", errno);
|
||||
|
@ -598,10 +631,10 @@ int ut_host_game(struct ut_state *state) {
|
|||
ut_dprintf(conn, "You play as: %c\n\n", ut_turn(player));
|
||||
}
|
||||
|
||||
return ut_network_game(state, conn, player, readable);
|
||||
return ut_network_game(state, game, conn, player, readable);
|
||||
}
|
||||
|
||||
int ut_join_game(struct ut_state *state) {
|
||||
int ut_join_game(struct ut_state *state, struct ut_game *game) {
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == -1) {
|
||||
ut_cursprintf("error %d\n", errno);
|
||||
|
@ -640,7 +673,7 @@ int ut_join_game(struct ut_state *state) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
return ut_network_game(state, sock, *player, false);
|
||||
return ut_network_game(state, game, sock, *player, false);
|
||||
}
|
||||
|
||||
void finish(int sig)
|
||||
|
@ -678,18 +711,19 @@ void begin(void)
|
|||
int main(int argc, char **argv) {
|
||||
|
||||
struct ut_state state = ut_initial;
|
||||
struct ut_game game = {0};
|
||||
if (argc != 2) {
|
||||
printf(HELP_TEXT);
|
||||
return 1;
|
||||
} else if (strncmp(argv[1], arg_local, sizeof(arg_local)) == 0) {
|
||||
begin();
|
||||
waitfinish(ut_local_game(&state));
|
||||
waitfinish(ut_local_game(&state, &game));
|
||||
} else if (strncmp(argv[1], arg_host, sizeof(arg_host)) == 0) {
|
||||
begin();
|
||||
waitfinish(ut_host_game(&state));
|
||||
waitfinish(ut_host_game(&state, &game));
|
||||
} else if (strncmp(argv[1], arg_join, sizeof(arg_join)) == 0) {
|
||||
begin();
|
||||
waitfinish(ut_join_game(&state));
|
||||
waitfinish(ut_join_game(&state, &game));
|
||||
} else {
|
||||
printf(HELP_TEXT);
|
||||
return 1;
|
||||
|
|
読み込み中…
新しいイシューから参照