このコミットが含まれているのは:
woosh 2023-11-16 02:32:45 +00:00
コミット c0849f47b3
1個のファイルの変更58行の追加24行の削除

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;