src/main.c

changeset 2
0a08f79c320d
parent 1
e5fbb8f9edbe
child 3
3693fd2eb0e9
--- a/src/main.c	Wed Feb 05 14:07:43 2014 +0100
+++ b/src/main.c	Sun Feb 23 21:03:35 2014 +0100
@@ -29,26 +29,58 @@
 
 #include "terminal-chess.h"
 #include <string.h>
+#include <time.h>
 
 int get_settings(int argc, char **argv, Settings *settings) {
     char *valid;
+    unsigned long int time, port;
+    uint8_t timeunit = 60;
+    size_t len;
     
-    for (char opt ; (opt = getopt(argc, argv, "hp:")) != -1 ;) {
+    for (char opt ; (opt = getopt(argc, argv, "a:bhp:rt:")) != -1 ;) {
         switch (opt) {
-            case 'p':
-                if (strtol(optarg, &valid, 10) < 1025 || *valid != '\0') {
-                    fprintf(stderr,
-                        "Invalid port number (%s) - choose a number > 1024\n",
-                        optarg);
-                    return 1;
+        case 'b':
+            settings->gameinfo.servercolor = BLACK;
+            break;
+        case 'r':
+            settings->gameinfo.servercolor = (rand()>>5) & 1 ? WHITE : BLACK;
+            break;
+        case 't':
+        case 'a':
+            len = strlen(optarg);
+            if (optarg[len-1] == 's') {
+                optarg[len-1] = '\0';
+                timeunit = 1;
+            }
+            
+            if ((time = strtoul(optarg, &valid, 10)) > TIME_MAX
+                || *valid != '\0') {
+                fprintf(stderr, "Specified time is invalid (%s)\n", optarg);
+                return 1;
+            } else {
+                if (opt=='t') {
+                    settings->gameinfo.time = timeunit * time;
                 } else {
-                    settings->port = optarg;
+                    settings->gameinfo.addtime = time;
                 }
-                break;
-            case 'h':
-            case '?':
-                settings->printhelp = 1;
-                break;
+            }
+            break;
+        case 'p':
+            port = strtol(optarg, &valid, 10);
+            if (port < 1025 || port > 65535 || *valid != '\0') {
+                fprintf(stderr,
+                    "Invalid port number (%s) - choose a number between "
+                    "1025 and 65535\n",
+                    optarg);
+                return 1;
+            } else {
+                settings->port = optarg;
+            }
+            break;
+        case 'h':
+        case '?':
+            settings->printhelp = 1;
+            break;
         }
     }
     
@@ -65,10 +97,31 @@
 Settings default_settings() {
     Settings settings;
     memset(&settings, 0, sizeof(Settings));
+    settings.gameinfo.servercolor = WHITE;
     settings.port = "27015";
     return settings;
 }
 
+void dump_gameinfo(Gameinfo *gameinfo) {
+    int serverwhite = gameinfo->servercolor == WHITE;
+    printf(
+        "Game details:\n"
+        "  Server plays %s  -  Client plays %s\n",
+        serverwhite?"white":"black", serverwhite?"black":"White"
+    );
+    if (gameinfo->time > 0) {
+        if (gameinfo->time % 60) {
+            printf("  Time limit: %ds + %ds\n",
+                gameinfo->time, gameinfo->addtime);
+        } else {
+            printf("  Time limit: %dm + %ds\n",
+                gameinfo->time/60, gameinfo->addtime);
+        }
+    } else {
+        printf("  No time limit\n");
+    }
+}
+
 int cleanup(Settings *settings, int exitcode) {
     if (settings->server) {
         if (net_destroy(settings->server)) {
@@ -80,17 +133,32 @@
 }
 
 int main(int argc, char **argv) {
+    srand(time(NULL));
     
     Settings settings = default_settings();
-    get_settings(argc, argv, &settings);
+    if (get_settings(argc, argv, &settings)) {
+        return 1;
+    }
     
     if (settings.printhelp) {
         printf(
-            "Usage: %s [OPTION]... [HOST]\n"
-            "Starts/joins a network chess game\n\n"
+            "Usage: terminal-chess [OPTION]... [HOST]\n"
+            "Starts/joins a network chess game\n"
+            "\nGeneral options\n"
             "  -h            This help page\n"
-            "  -p            TCP port to use (default: 27015)\n",
-            argv[0]);
+            "  -p            TCP port to use (default: 27015)\n"
+            "\nServer options\n"
+            "  -a <time>     Specifies the time to add after each move\n"
+            "  -b            Server plays black pieces (default: white)\n"
+            "  -r            Distribute color randomly\n"
+            "  -t <time>     Specifies time limit (default: no limit)\n"
+            "\nNotes\n"
+            "White pieces are displayed as uppercase and black pieces as "
+            "lowercase letters.\n"
+            "The time unit for -a is seconds and for -t minutes by default. To "
+            "specify\nseconds for the -t option, use the s suffix.\n"
+            "Example: -t 150s\n"
+        );
         return EXIT_SUCCESS;
     }
     
@@ -98,6 +166,22 @@
     settings.server = &server;
     
     if (is_server(&settings)) {
+        dump_gameinfo(&(settings.gameinfo));
+        printf("\nListening for client...\n");
+        if (net_create(&server, settings.port)) {
+            perror("Server creation failed");
+            return cleanup(&settings, EXIT_FAILURE);
+        }
+        
+        if (net_listen(&server)) {
+            perror("Listening for client failed");
+            return cleanup(&settings, EXIT_FAILURE);
+        }
+        
+        printf("Client connected - transmitting gameinfo...\n");
+        net_send(server.client->fd, NETCODE_GAMEINFO,
+            &(settings.gameinfo), sizeof(settings.gameinfo));
+    } else {
         if (net_find(&server, settings.serverhost, settings.port)) {
             perror("Can't find server");
             return cleanup(&settings, EXIT_FAILURE);
@@ -107,15 +191,14 @@
             perror("Can't connect to server");
             return cleanup(&settings, EXIT_FAILURE);
         }
-    } else {
-        if (net_create(&server, settings.port)) {
-            perror("Server creation failed");
-            return cleanup(&settings, EXIT_FAILURE);
-        }
-        
-        if (net_listen(&server)) {
-            perror("Listening for client failed");
-            return cleanup(&settings, EXIT_FAILURE);
+
+        printf("Connection established!\n\n");
+        if (net_recieve_code(server.fd) == NETCODE_GAMEINFO) {
+            net_recieve_data(server.fd, &(settings.gameinfo),
+                sizeof(settings.gameinfo));
+            dump_gameinfo(&(settings.gameinfo));
+        } else {
+            fprintf(stderr, "Server sent invalid gameinfo.\n");
         }
     }
     

mercurial