コミットを比較
4 コミット
1b427181a2
...
61cfc2db1c
作成者 | SHA1 | 日付 |
---|---|---|
ninya9k | 61cfc2db1c | |
ninya9k | 012d16c55c | |
ninya9k | 00d635bea9 | |
ninya9k | 77fb778d0b |
156
uttt.c
156
uttt.c
|
@ -89,6 +89,9 @@ int ut_move(struct ut_state *new_state, const struct ut_state *old_state, int ro
|
||||||
// bad move - tile is occupied
|
// bad move - tile is occupied
|
||||||
if(old_state->tiles[row][col] != '\0') {return 1;} // replace with ' ' maybe
|
if(old_state->tiles[row][col] != '\0') {return 1;} // replace with ' ' maybe
|
||||||
|
|
||||||
|
// bad move - board is not playable
|
||||||
|
if(old_state->boards[row / 3][col / 3] != '\0') {return 1;} // replace with ' ' maybe
|
||||||
|
|
||||||
// copy old_state->{tiles,boards} to new_state->{tiles,boards}
|
// copy old_state->{tiles,boards} to new_state->{tiles,boards}
|
||||||
memmove(new_state->tiles, old_state->tiles, sizeof(old_state->tiles));
|
memmove(new_state->tiles, old_state->tiles, sizeof(old_state->tiles));
|
||||||
memmove(new_state->boards, old_state->boards, sizeof(old_state->boards));
|
memmove(new_state->boards, old_state->boards, sizeof(old_state->boards));
|
||||||
|
@ -104,51 +107,51 @@ int ut_move(struct ut_state *new_state, const struct ut_state *old_state, int ro
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ut_show(const struct ut_state *state) {
|
void ut_show(const struct ut_state *state, FILE *file) {
|
||||||
#define tiles state->tiles
|
#define tiles state->tiles
|
||||||
printf("Turn: %c\nPlay board: %d\n", (int)state->player, state->playBoard);
|
printf("Turn: %c\nPlay board: %d\n", (int)state->player, state->playBoard);
|
||||||
int play_board_row = -1;
|
int play_board_row = -1;
|
||||||
int play_board_col = -1;
|
int play_board_col = -1;
|
||||||
if (state->playBoard != -1) {
|
if (state->playBoard != -1) {
|
||||||
play_board_row = state->playBoard / 3;
|
play_board_row = state->playBoard / 3;
|
||||||
play_board_col = state->playBoard % 3;
|
play_board_col = state->playBoard % 3;
|
||||||
}
|
}
|
||||||
printf(" 012 345 678\n");
|
fprintf(file, " 012 345 678\n");
|
||||||
for(int y = 0; y < 9; y++)
|
for(int y = 0; y < 9; y++)
|
||||||
{
|
{
|
||||||
if (y == 3 || y == 6) {
|
if (y == 3 || y == 6) {
|
||||||
printf(" ---+---+---\n");
|
fprintf(file, " ---+---+---\n");
|
||||||
}
|
}
|
||||||
printf("%d ", y);
|
fprintf(file, "%d ", y);
|
||||||
for(int x = 0; x < 9; x++)
|
for(int x = 0; x < 9; x++)
|
||||||
{
|
{
|
||||||
if (x == 3 || x == 6) {
|
if (x == 3 || x == 6) {
|
||||||
putchar('|');
|
fputc('|', file);
|
||||||
}
|
}
|
||||||
putchar(tiles[y][x] ? tiles[y][x] : ' ');
|
fputc(tiles[y][x] ? tiles[y][x] : ' ', file);
|
||||||
}
|
}
|
||||||
if (y / 3 == play_board_row || play_board_row == -1) {
|
if (y / 3 == play_board_row || play_board_row == -1) {
|
||||||
printf("<");
|
fputc('<', file);
|
||||||
}
|
}
|
||||||
putchar('\n');
|
fputc('\n', file);
|
||||||
}
|
|
||||||
if (play_board_col == -1) {
|
|
||||||
printf(" ^^^ ^^^ ^^^");
|
|
||||||
} else {
|
|
||||||
printf(" ");
|
|
||||||
for (int i = 0; i < play_board_col; i++) {
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
printf("^^^");
|
|
||||||
}
|
}
|
||||||
putchar('\n');
|
if (play_board_col == -1) {
|
||||||
#undef tiles
|
fprintf(file, " ^^^ ^^^ ^^^");
|
||||||
|
} else {
|
||||||
|
fprintf(file, " ");
|
||||||
|
for (int i = 0; i < play_board_col; i++) {
|
||||||
|
fprintf(file, " ");
|
||||||
|
}
|
||||||
|
fprintf(file, "^^^");
|
||||||
|
}
|
||||||
|
fputc('\n', file);
|
||||||
|
#undef tiles
|
||||||
}
|
}
|
||||||
|
|
||||||
void ut_show_boards(const struct ut_state *state) {
|
void ut_show_boards(const struct ut_state *state) {
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
putchar(state->boards[j][i]);
|
putchar(state->boards[j][i] ? state->boards[j][i] : ' ');
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
@ -185,18 +188,78 @@ bool getpos(const struct ut_state *state, int *x, int *y) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getpos_net(const struct ut_state *state, int conn, int *x, int *y) {
|
void getpos_net(const struct ut_state *state, int conn, FILE* conn_file, int *x, int *y) {
|
||||||
char buf[4];
|
const int MAX_LINE_LEN = 120;
|
||||||
int n = recv(conn, &buf, 4, 0); // lazy way but idc
|
char byte;
|
||||||
printf("bytes received: %d\n", n);
|
int n;
|
||||||
printf("buf=%s\n", buf);
|
while (true) {
|
||||||
*x = buf[0] - 0x30;
|
n = recv(conn, &byte, 1, 0);
|
||||||
*y = buf[2] - 0x30;
|
if (n == 0) {goto conn_closed;}
|
||||||
printf("x=%d y=%d\n", *x, *y);
|
if (byte == '|') {
|
||||||
if (buf[1] != ',' || buf[3] != '\n' || *x >= 9 || *y >= 9 || *x < 0 || *y < 0) {
|
// ignore this line
|
||||||
printf("protocol not followed perfectly by partner - exiting\n");
|
for (int i = 0; i < MAX_LINE_LEN; i++) {
|
||||||
exit(1);
|
n = recv(conn, &byte, 1, 0);
|
||||||
|
if (n == 0) {goto conn_closed;}
|
||||||
|
if (byte == '\n') {break;}
|
||||||
|
}
|
||||||
|
if (byte != '\n') {
|
||||||
|
printf("Partner sent too much data in one comment line - exiting\n");
|
||||||
|
close(conn);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (byte == '\n') {
|
||||||
|
printf("Partner ended line before coords were complete - retrying\n");
|
||||||
|
fprintf(conn_file, "Invalid coordinates. Try again: ");
|
||||||
|
fflush(conn_file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*x = byte - 0x30;
|
||||||
|
n = recv(conn, &byte, 1, 0);
|
||||||
|
if (n == 0) {goto conn_closed;}
|
||||||
|
if (byte == '\n') {
|
||||||
|
printf("Partner ended line before coords were complete - retrying\n");
|
||||||
|
fprintf(conn_file, "Invalid coordinates. Try again: ");
|
||||||
|
fflush(conn_file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
n = recv(conn, &byte, 1, 0);
|
||||||
|
if (n == 0) {goto conn_closed;}
|
||||||
|
if (byte == '\n') {
|
||||||
|
printf("Partner ended line before coords were complete - retrying\n");
|
||||||
|
fprintf(conn_file, "Invalid coordinates. Try again: ");
|
||||||
|
fflush(conn_file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*y = byte - 0x30;
|
||||||
|
n = recv(conn, &byte, 1, 0);
|
||||||
|
if (n == 0) {goto conn_closed;}
|
||||||
|
if (byte != '\n') {
|
||||||
|
printf("Partner sent extra data after coords were complete - ignoring and retrying\n");
|
||||||
|
fprintf(conn_file, "Invalid coordinates. Try again: ");
|
||||||
|
fflush(conn_file);
|
||||||
|
// ignore the rest of this line
|
||||||
|
for (int i = 0; i < MAX_LINE_LEN; i++) {
|
||||||
|
n = recv(conn, &byte, 1, 0);
|
||||||
|
if (n == 0) {goto conn_closed;}
|
||||||
|
if (byte == '\n') {break;}
|
||||||
|
}
|
||||||
|
if (byte != '\n') {
|
||||||
|
printf("Partner sent too much extra data - exiting\n");
|
||||||
|
close(conn);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
printf("x=%d y=%d\n", *x, *y);
|
||||||
|
return;
|
||||||
|
|
||||||
|
conn_closed:
|
||||||
|
printf("Connection closed.\n");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void finish(int sig)
|
void finish(int sig)
|
||||||
|
@ -210,7 +273,7 @@ void finish(int sig)
|
||||||
void ut_local_game(struct ut_state *state) {
|
void ut_local_game(struct ut_state *state) {
|
||||||
int x, y;
|
int x, y;
|
||||||
while (true) {
|
while (true) {
|
||||||
ut_show(state);
|
ut_show(state, stdout);
|
||||||
ut_show_boards(state);
|
ut_show_boards(state);
|
||||||
bool ok = getpos(state, &x, &y);
|
bool ok = getpos(state, &x, &y);
|
||||||
if (!ok) {continue;}
|
if (!ok) {continue;}
|
||||||
|
@ -234,18 +297,25 @@ void ut_local_game(struct ut_state *state) {
|
||||||
void ut_host_game(struct ut_state *state, int conn, char host_player) {
|
void ut_host_game(struct ut_state *state, int conn, char host_player) {
|
||||||
int x, y;
|
int x, y;
|
||||||
printf("You play as %c.\n", host_player);
|
printf("You play as %c.\n", host_player);
|
||||||
|
FILE* conn_file = fdopen(conn, "w");
|
||||||
while (true) {
|
while (true) {
|
||||||
ut_show(state);
|
ut_show(state, stdout);
|
||||||
ut_show_boards(state);
|
ut_show_boards(state);
|
||||||
|
ut_show(state, conn_file);
|
||||||
if (state->player == host_player) {
|
if (state->player == host_player) {
|
||||||
|
fprintf(conn_file, "Waiting for game partner ...\n");
|
||||||
|
fflush(conn_file);
|
||||||
bool ok = getpos(state, &x, &y);
|
bool ok = getpos(state, &x, &y);
|
||||||
if (!ok) {continue;}
|
if (!ok) {continue;}
|
||||||
} else {
|
} else {
|
||||||
printf("Waiting for game parter ...\n");
|
printf("Waiting for game partner ...\n");
|
||||||
getpos_net(state, conn, &x, &y);
|
fprintf(conn_file, "Place token %c in position x,y: ", ut_turn(host_player));
|
||||||
|
fflush(conn_file);
|
||||||
|
getpos_net(state, conn, conn_file, &x, &y);
|
||||||
}
|
}
|
||||||
int err = ut_move(state, state, x, y);
|
int err = ut_move(state, state, y, x);
|
||||||
if (err) {continue;}
|
if (err) {continue;}
|
||||||
|
fputc('\n', conn_file);
|
||||||
char w = ut_winner((char *)state->boards, 0, 3);
|
char w = ut_winner((char *)state->boards, 0, 3);
|
||||||
if(w)
|
if(w)
|
||||||
{
|
{
|
||||||
|
|
読み込み中…
新しいイシューから参照