summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2023-03-20 02:19:02 -0700
committerKai Stevenson <kai@kaistevenson.com>2023-03-20 02:19:02 -0700
commit1a3b3fb05f86e357b099812c0a09a084934fd111 (patch)
treef3d4c0b9961d70b672e9e2220ae5d17a20e77eb3
parente33dc4755fb08ed08f30b5e1af65457556d5bcb7 (diff)
minimum viable implementation of fscomch works now
-rw-r--r--src/chess.c162
-rw-r--r--src/fscomch.c32
-rw-r--r--src/fscomch.h4
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