コミットを比較

...

9 コミット

作成者 SHA1 メッセージ 日付
woosh 6314045855 Merge remote-tracking branch 'refs/remotes/origin/cleaner' into cleaner 2023-11-15 08:17:59 +00:00
woosh d5b5220c8b fixed initial r,c 2023-11-15 08:16:45 +00:00
ninya9k a98459b46e lol 2023-11-15 08:09:16 +00:00
ninya9k 194825db5a Merge remote-tracking branch 'origin/cleaner' into cleaner 2023-11-15 08:07:35 +00:00
ninya9k 771b1e9ba8 readable socket niceties 2023-11-15 08:05:54 +00:00
woosh 8c83ddcba4 fixing input and curses board - still broken 2023-11-15 08:05:29 +00:00
ninya9k 573ae23c48 send board over socket 2023-11-15 08:04:45 +00:00
ninya9k 6a669af1cd ignore | lines 2023-11-15 07:48:05 +00:00
ninya9k 6fad23c17d readable iff game<->game session 2023-11-15 07:40:24 +00:00
1個のファイルの変更98行の追加96行の削除

194
uttt.c
ファイルの表示

@ -41,6 +41,12 @@ const char arg_local[] = "--local";
const char arg_host[] = "--host";
const char arg_join[] = "--join";
const char PLAY_BOARDS[][14] = {
"top left", "top middle", "top right",
"middle left", "middle", "middle right",
"bottom left", "bottom middle", "bottom right",
"all boards",
};
char ut_turn(char player)
{
@ -183,17 +189,17 @@ void ut_drawBoard(void (*mvch)(void*, int, int, char), void *arg, const char *ti
*/
for(int r = 0; r < 3; r++) // tiles
for(int c = 0; c < 3; c++)
mvch(arg, iy + 2 * r, ix + 2 * c, T(r, c) != '\0' ? T(r, c) : ' ');
mvch(arg, iy + 2 * r + 1, ix + 2 * c + 1, T(r, c) != '\0' ? T(r, c) : ' ');
//char info = winner != '\0' ? winner : highlight ? '*' : ' ';
for(int r = 0; r < 3; r++) // |
for(int c = 0; c < 2; c++)
mvch(arg, iy + 2 * r, ix + 2 * c + 1, winner != '\0' ? winner : '|');
mvch(arg, iy + 2 * r + 1, ix + 2 * c + 1 + 1, winner != '\0' ? winner : '|');
for(int r = 0; r < 2; r++) // -
for(int c = 0; c < 3; c++)
mvch(arg, iy + 2 * r + 1, ix + 2 * c, winner != '\0' ? winner : '-');
mvch(arg, iy + 2 * r + 1 + 1, ix + 2 * c + 1, winner != '\0' ? winner : '-');
for(int r = 0; r < 2; r++) // +
for(int c = 0; c < 2; c++)
mvch(arg, iy + 2 * r + 1, ix + 2 * c + 1, winner != '\0' ? winner : highlight ? '*' : '+');
mvch(arg, iy + 2 * r + 1 + 1, ix + 2 * c + 1 + 1, winner != '\0' ? winner : highlight ? '*' : '+');
for(int r = 0; r < 7; r++) // | boundary
for(int c = 0; c < 2; c++)
mvch(arg, iy + r, ix + 6 * c, ' ');
@ -209,7 +215,7 @@ void ut_drawTiles(void (*mvch)(void*, int, int, char), void *arg, const struct u
for(int c = 0; c < 3; c++)
ut_drawBoard(mvch, arg, (char *)state->tiles,
27 * r + 3 * c, 9,
7 * r + 1, 7 * c + 1,
7 * r, 7 * c,
state->boards[r][c],
state->playBoard == -1 || state->playBoard == 3 * r + c);
if(numbers)
@ -245,6 +251,7 @@ void ut_bmvch(void *arg, int y, int x, char c)
((char (*)[DBOARDS_X])arg)[y][x] = c;
}
#define DTILES_LINE 1
void ut_cursdraw(const struct ut_state *state)
{
ut_cursprintf("Turn: %c Play board: %d\n", (int)state->player, state->playBoard);
@ -264,22 +271,22 @@ void ut_sockdraw(const struct ut_state *state, int fd)
}
}
/*void ut_show(const struct ut_state *state, int fd, bool as_comment) {
void ut_show(const struct ut_state *state, int fd) {
#define tiles state->tiles
ut_dprintf(fd, "%sTurn: %c\n%sPlay board: %d\n", as_comment ? "| " : "", (int)state->player, as_comment ? "| " : "", state->playBoard);
ut_dprintf(fd, "Turn: %c\nPlay board: %s\n", (int)state->player, PLAY_BOARDS[(state->playBoard + 10) % 10]);
int play_board_row = -1;
int play_board_col = -1;
if (state->playBoard != -1) {
play_board_row = state->playBoard / 3;
play_board_col = state->playBoard % 3;
}
ut_dprintf(fd, "%s 012 345 678\n", as_comment ? "| " : "");
ut_dprintf(fd, " 012 345 678\n");
for(int y = 0; y < 9; y++)
{
if (y == 3 || y == 6) {
ut_dprintf(fd, "%s ---+---+---\n", as_comment ? "| " : "");
ut_dprintf(fd, " ---+---+---\n");
}
ut_dprintf(fd, "%s%d ", as_comment ? "| " : "", y);
ut_dprintf(fd, "%d ", y);
for(int x = 0; x < 9; x++)
{
if (x == 3 || x == 6) {
@ -293,9 +300,9 @@ void ut_sockdraw(const struct ut_state *state, int fd)
ut_writefill(fd, "\n", 1);
}
if (play_board_col == -1) {
ut_dprintf(fd, "%s ^^^ ^^^ ^^^", as_comment ? "| " : "");
ut_dprintf(fd, " ^^^ ^^^ ^^^");
} else {
ut_dprintf(fd, "%s ", as_comment ? "| " : "");
ut_dprintf(fd, " ");
for (int i = 0; i < play_board_col; i++) {
ut_dprintf(fd, " ");
}
@ -303,7 +310,7 @@ void ut_sockdraw(const struct ut_state *state, int fd)
}
ut_writefill(fd, "\n", 1);
#undef tiles
}*/
}
/*void ut_show_boards(const struct ut_state *state) {
for (int j = 0; j < 3; j++) {
@ -337,7 +344,11 @@ int ut_cursgetpos(const struct ut_state *state, int *r, int *c)
(state->boards[r / 3][c / 3] == '\0' || d % 3 == 1))
MEVENT event;
ut_cursprintf("Select move with arrow keys or mouse.\n");
if(state->playBoard == -1)
if(*r < 0 || *r >= 9 || *c < 0 || *c >= 9)
{
*r = 4; *c = 4;
}
else if(state->playBoard == -1)
{
*r = 3 * (*r / 3) + 1;
*c = 3 * (*c / 3) + 1;
@ -354,7 +365,7 @@ int ut_cursgetpos(const struct ut_state *state, int *r, int *c)
*r = 3 * (*r / 3) + 1;
*c = 3 * (*c / 3) + 1;
}*/
move((7 * (*r / 3) + 1) + (2 * (*r % 3)),
move(DTILES_LINE + (7 * (*r / 3) + 1) + (2 * (*r % 3)),
(7 * (*c / 3) + 1) + (2 * (*c % 3)));
refresh();
switch(getch())
@ -362,6 +373,7 @@ int ut_cursgetpos(const struct ut_state *state, int *r, int *c)
case KEY_MOUSE:
if(getmouse(&event) == OK && (event.bstate & BUTTON1_CLICKED))
{
event.y -= DTILES_LINE;
if(event.y < 0 || event.y >= 21) {break;}
if(event.x < 0 || event.x >= 21) {break;}
*r = (event.y % 7 - 1) / 2 + 3 * (event.y / 7);
@ -454,35 +466,54 @@ int ut_cursgetpos(const struct ut_state *state, int *r, int *c)
return true;
}*/
int ut_sockgetpos(const struct ut_state *state, int sock, int *x, int *y) { // TODO
const int MAX_LINE_LEN = 128;
int ut_ignore_line(int sock) {
char byte;
for (int i = 0; i < 128; i++) {
if (ut_readfill(sock, &byte, 1)) {
return 1;
}
if (byte == '\n') {return 0;}
}
return 2;
}
int ut_sockgetpos(const struct ut_state *state, int sock, int *x, int *y, bool readable) { // TODO
int index = 0;
char byte;
int n;
while (true) {
char line[MAX_LINE_LEN];
int len = ut_readline(sock, line, MAX_LINE_LEN);
if (len < 0) {return len;}
if (len == 0) {printf("sex\n");return -1;}
line[len] = 0;
printf("got >>>>>> line: '%s'\n", line);
if (line[0] == '|') {continue;}
if (len != 3) {return -3;}
if (line[1] != ',') {return -3;}
*x = line[0] - 0x30;
*y = line[2] - 0x30;
break;
int r = ut_readfill(sock, &byte, 1);
if (r < 0) {return r;}
if (r == 0) {
printf("Connection closed.\n");
return -1;
}
if (index == 0 && byte == '|') {
if (ut_ignore_line(sock)) {return -1;}
} else if (index == 0) {
*x = byte - 0x30;
} else if (index == 2) {
*y = byte - 0x30;
} else if (index == 1 && byte != ',' || index == 3 && byte != '\n') {
printf("Partner sent malformed coords - retrying\n");
if (ut_ignore_line(sock)) {return -1;}
if (readable) {
ut_dprintf(sock, "Invalid coordinates. Try again: ");
}
index = 0;
continue;
}
index++;
if (index == 4) {break;}
}
printf("x=%d y=%d\n", *x, *y);
return 0;
}
int ut_local_game(struct ut_state *state) {
int x, y;
for(;;)
{
int r, c, err;
int r = 4, c = 4;
ut_curserase();
ut_cursdraw(state);
char w = ut_winner((char *)state->boards, 0, 3);
@ -498,10 +529,8 @@ int ut_local_game(struct ut_state *state) {
}
break;
}
err = ut_cursgetpos(state, &r, &c);
if (err) {continue;}
err = ut_move(state, state, r, c);
if (err) {continue;}
if(ut_cursgetpos(state, &r, &c)) {continue;}
if(ut_move(state, state, r, c)) {continue;}
}
return 0;
}
@ -510,12 +539,12 @@ int ut_network_game(struct ut_state *state, int sock, char player, bool readable
int x, y;
//printf("You play as %c.\n", player);
while (true) {
ut_show(state, 1, false);
ut_show_boards(state);
ut_show(state, sock, true);
//ut_show(state, 1, false);
//ut_show_boards(state);
ut_show(state, sock);
if (state->player == player) {
if (readable) {ut_dprintf(sock, "Waiting for game partner ...\n");}
bool ok = getpos(state, &x, &y);
bool ok = ut_cursgetpos(state, &x, &y);
if (!ok) {continue;}
ut_dprintf(sock, "%d,%d\n", x, y);
} else {
@ -524,16 +553,10 @@ 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: ", ut_turn(player));
}
int err = ut_sockgetpos(state, sock, &x, &y);
int err = ut_sockgetpos(state, sock, &x, &y, readable);
if (err == -1) {
printf("Connection closed.\n");
return 1;
} else if (err == -2) {
printf("Partner sent too much data - exiting\n");
return 1;
} else if (err == -3) {
printf("Partner sent malformed data - retrying ...\n");
continue;
}
}
int err = ut_move(state, state, y, x);
@ -600,12 +623,32 @@ int ut_host_game(struct ut_state *state) {
char player;
if ((player = ut_random_player()) < 0) {return 1;}
// check to determine readable
char byte;
ut_dprintf(conn, "| Press enter to start: ");
if (ut_readfill(conn, &byte, 1)) {
printf("Connection closed.\n");
return 1;
}
bool readable = byte != '\0';
if (byte != '\n') {
int err = ut_ignore_line(sock);
if (err == 1) {
printf("Connection closed.\n");
return 1;
} else if (err == 2) {
printf("Partner sent too much data - exiting\n");
return 1;
}
}
// tell partner X or O
ut_dprintf(conn, "%c\n", ut_turn(player));
if (readable) {
ut_dprintf(conn, "You play as: %c\n\n", ut_turn(player));
}
// TODO check to determine readable
return ut_network_game(state, conn, player);
return ut_network_game(state, conn, player, readable);
}
int ut_join_game(struct ut_state *state) {
@ -626,17 +669,17 @@ int ut_join_game(struct ut_state *state) {
return 1;
}
// tell host to deactivate readable
ut_dprintf(sock, "\0\n");
// host decides X or O
char player_buf[2];
char *player = (char*)&player_buf;
int r = ut_readfill(sock, player_buf, 2);
if (r == 2) {printf("Connection closed.\n");}
if (r != 0) {return 1;}
state->host_player = ut_turn(*player);
// TODO send '\0' to deactivate readable
return ut_network_game(state, sock, *player);
return ut_network_game(state, sock, *player, false);
}
void finish(int sig)
@ -665,47 +708,6 @@ void begin(void)
mousemask(BUTTON1_CLICKED, NULL);
}
/*int main(int argc, char *argv[]) {
signal(SIGINT, finish);
initscr();
keypad(stdscr, TRUE);
nonl(); // \r instead of \r\n
cbreak();
noecho();
mousemask(BUTTON1_CLICKED, NULL);
struct ut_state state = ut_initial;
while (true) {
int r, c, err;
erase();
ut_draw(&state);
char w = ut_winner((char *)state.boards, 0, 3);
if(w)
{
if(w == ' ')
{
mvaddstr(21, 0, "Draw!");
}
else
{
mvaddch(21, 0, w);
mvaddstr(21, 1, " Wins!");
}
mvaddstr(22, 0, "Press any key to exit.");
refresh();
mousemask(0, NULL);
getch();
break;
}
err = ut_click(&state, &r, &c);
if (err) {continue;}
err = ut_move(&state, &state, r, c);
if (err) {continue;}
}
finish(0);
return 0;
}*/
int main(int argc, char **argv) {
struct ut_state state = ut_initial;