diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2023-03-20 02:19:02 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2023-03-20 02:19:02 -0700 |
| commit | 1a3b3fb05f86e357b099812c0a09a084934fd111 (patch) | |
| tree | f3d4c0b9961d70b672e9e2220ae5d17a20e77eb3 | |
| parent | e33dc4755fb08ed08f30b5e1af65457556d5bcb7 (diff) | |
minimum viable implementation of fscomch works now
| -rw-r--r-- | src/chess.c | 162 | ||||
| -rw-r--r-- | src/fscomch.c | 32 | ||||
| -rw-r--r-- | src/fscomch.h | 4 |
3 files changed, 127 insertions, 71 deletions
diff --git a/src/chess.c b/src/chess.c index 530bc79..adb5ce2 100644 --- a/src/chess.c +++ b/src/chess.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <string.h> #include "vector.h" #include "console.h" @@ -37,96 +38,125 @@ int main(int argc, char **argv) { /* try to acquire a lock on the local matchfile */ FILE* matchFile = try_lock_match(); match_t match; + char isHost; + char isWhite; if (matchFile != NULL) { + isHost = 1; /* we are acting as the host--await a connection */ - printf("awaiting connection\n"); + printf("Awaiting connection\n"); match = await_match(matchFile, NULL); - printf("connection completed. match is %s\n", match.uuid); + printf("Connection completed. Match is %s\n", match.uuid); } else { + isHost = 0; /* we are joining an existing match */ - printf("attempting to join existing match\n"); + printf("Attempting to join existing match\n"); match = join_match(); if (match.uuid != NULL) { - printf("joined match %s\n", match.uuid); + printf("Joined match %s\n", match.uuid); } else { - printf("error joining match. reload the program\n"); + printf("Error joining match. reload the program\n"); } } - exit(0); - int turn = 0; - while(1) { + sleep(2); + /* host plays white */ + isWhite = isHost; + char turn = 0; + while (1) { //draw the board, write some info clear_screen(); draw_board(board.pieces); - printf(turn == 0 ? "\nWhite's turn\n" : "\nBlack's turn\n"); - if(is_in_check(board, turn)) { - vectorpp_t allMoves = get_all_moves(board, turn, 0); - int checkmate = 0; - for(int i = 0; i < allMoves.length; i++) { - if(allMoves.vectorps[i].length > 0) { - checkmate = 0; + if (turn == isWhite) { + /* awaiting the remote player */ + printf("Waiting for %s's move\n", turn ? "black" : "white"); + while (1) { + char* message = read_message(match, NULL); + /* try to parse the message as a move */ + if (strncmp(message, "move=", 5) == 0) { + vector_t rOrigin = init_vector(message[5] - '0', message[6] - '0'); + vector_t rDest = init_vector(message[7] - '0', message[8] - '0'); + board = make_move(board, rOrigin, rDest); + break; + } + free(message); + } + } + else { + /* get local move */ + printf(turn == 0 ? "\nWhite's turn\n" : "\nBlack's turn\n"); + if(is_in_check(board, turn)) { + vectorpp_t allMoves = get_all_moves(board, turn, 0); + char checkmate = 0; + for(int i = 0; i < allMoves.length; i++) { + if(allMoves.vectorps[i].length > 0) { + checkmate = 0; + break; + } + else { + checkmate = 1; + } + } + if(checkmate) { + printf("You've been checkmated!\n"); break; } else { - checkmate = 1; + printf("You're in check!\n"); } } - if(checkmate) { - printf("You've been checkmated!\n"); - break; + printf("Enter the coordinates of the piece you want to move\n"); + //get the selection for the piece to be moved + vector_t selection = user_input_pos(); + int selectedPiece = board.pieces[selection.mx][selection.my]; + //check if the piece is of the right colour, and that there is a piece there + if(selectedPiece == 0 || (selectedPiece > 6 && turn == 0) || (selectedPiece <= 6 && turn == 1)) { + warn_user("Invalid selection!"); + continue; } - else { - printf("You're in check!\n"); + printf("Selected piece: "); + printf("%d", selectedPiece); + printf("\n"); + vectorp_t moves = get_moves_final(board, selection, selectedPiece); + if(moves.length == 0) { + warn_user("That piece has no valid moves!"); + continue; } - } - printf("Enter the coordinates of the piece you want to move\n"); - //get the selection for the piece to be moved - vector_t selection = user_input_pos(); - int selectedPiece = board.pieces[selection.mx][selection.my]; - //check if the piece is of the right colour, and that there is a piece there - if(selectedPiece == 0 || (selectedPiece > 6 && turn == 0) || (selectedPiece <= 6 && turn == 1)) { - warn_user("Invalid selection!"); - continue; - } - printf("Selected piece: "); - printf("%d", selectedPiece); - printf("\n"); - vectorp_t moves = get_moves_final(board, selection, selectedPiece); - if(moves.length == 0) { - warn_user("That piece has no valid moves!"); - continue; - } - printf("Valid moves: "); - //write all the valid moves - for(int i = 0; i < moves.length; i++) { - char* readable_coords = get_move_name(board, selection, moves.vectors[i]); - printf(readable_coords); - free(readable_coords); - printf("; "); - } - printf("\nEnter the coordinates you would like to move that piece to, or enter < to go back\n"); - //get the selection for the location to move the piece to - vector_t target = user_input_pos(); - if(target.mx == -1) { - continue; - } - //check if target is in list of valid moves - int match = 0; - for(int i = 0; i < moves.length; i++) { - if(moves.vectors[i].mx == target.mx && moves.vectors[i].my == target.my) { - match = 1; - break; + printf("Valid moves: "); + //write all the valid moves + for(int i = 0; i < moves.length; i++) { + char* readable_coords = get_move_name(board, selection, moves.vectors[i]); + printf(readable_coords); + free(readable_coords); + printf("; "); } + printf("\nEnter the coordinates you would like to move that piece to, or enter < to go back\n"); + //get the selection for the location to move the piece to + vector_t target = user_input_pos(); + if(target.mx == -1) { + continue; + } + //check if target is in list of valid moves + int moveMatch = 0; + for(int i = 0; i < moves.length; i++) { + if(moves.vectors[i].mx == target.mx && moves.vectors[i].my == target.my) { + moveMatch = 1; + break; + } + } + if(!moveMatch) { + warn_user("Invalid move"); + continue; + } + board = make_move(board, selection, target); + free(moves.vectors); + printf("\n"); + /* send move to remote player */ + char move[10]; + strcpy(move, "move="); + snprintf(move + 5, 5, "%d%d%d%d", selection.mx, selection.my, target.mx, target.my); + send_message(move, match); } - if(!match) { - warn_user("Invalid move"); - continue; - } - board = make_move(board, selection, target); - free(moves.vectors); - printf("\n"); turn = !turn; } return 0; diff --git a/src/fscomch.c b/src/fscomch.c index a9fc27b..412f9cf 100644 --- a/src/fscomch.c +++ b/src/fscomch.c @@ -4,6 +4,7 @@ #include <unistd.h> #include <time.h> #include <sys/stat.h> +#include <string.h> #include "fscomch.h" match_t init_match(char* uuid, FILE* streamIn, FILE* streamOut) { @@ -38,16 +39,15 @@ match_t await_match(FILE* matchFile, char* cancelToken) { struct timespec req; req.tv_sec = 0; req.tv_nsec = awaitMatchNs; - printf("sleeping\n"); nanosleep(&req, NULL); } - /* connect to files created by joining player */ + /* connect to streams */ char aName[256]; char bName[256]; snprintf(aName, 256, "/tmp/chess/%s.a", uuid); snprintf(bName, 256, "/tmp/chess/%s.b", uuid); FILE* streamIn = fopen(aName, "r"); - FILE* streamOut = fopen(bName, "w"); + FILE* streamOut = fopen(bName, "a"); /* connection complete, delete the match file and the join lock */ remove("/tmp/chess/match"); remove("/tmp/chess/matchjoin"); @@ -65,21 +65,43 @@ match_t join_match() { /* this is definitely the only process joining the game proceed to generate a uuid */ char* uuid = make_uuid(); - /* make the .a and .b files based on the uuid */ + /* create and connect to streams */ char aName[256]; char bName[256]; snprintf(aName, 256, "/tmp/chess/%s.a", uuid); snprintf(bName, 256, "/tmp/chess/%s.b", uuid); FILE* streamIn = fopen(bName, "w+"); - FILE* streamOut = fopen(aName, "w"); + FILE* streamOut = fopen(aName, "a"); match_t match = init_match(uuid, streamIn, streamOut); /* send uuid to the host */ FILE* matchFile = fopen("/tmp/chess/match", "a"); fputs(uuid, matchFile); + fclose(matchFile); /* joining match complete, close the descriptor */ close(fd); return match; } +void send_message(char* content, match_t match) { + fprintf(match.streamOut, "%s\n", content); + fflush(match.streamOut); +} +char* read_message(match_t match, char* cancelToken) { + char* buffer = calloc(256, sizeof(char)); + while (cancelToken == NULL || *cancelToken) { + if (fgets(buffer, 256, match.streamIn) != NULL) { + break; + } + /* wtf? */ + fseek(match.streamIn, ftell(match.streamIn), SEEK_SET); + struct timespec req; + req.tv_sec = 0; + req.tv_nsec = awaitMoveNs; + nanosleep(&req, NULL); + } + /* overwrite potential newline */ + buffer[strlen(buffer) - 1] = '\0'; + return buffer; +} char* make_uuid() { char sym[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f'}; char* out = calloc(37, sizeof(char)); diff --git a/src/fscomch.h b/src/fscomch.h index b7900e3..bc92467 100644 --- a/src/fscomch.h +++ b/src/fscomch.h @@ -20,5 +20,9 @@ FILE* try_lock_match(); match_t await_match(FILE* matchFile, char* cancelToken); /* joins an existing match */ match_t join_match(); +void send_message(char* content, match_t match); +/* blocks */ +char* read_message(match_t match, char* cancelToken); char* make_uuid(); + #endif |
