src/main.c

changeset 2
0a08f79c320d
parent 1
e5fbb8f9edbe
child 3
3693fd2eb0e9
     1.1 --- a/src/main.c	Wed Feb 05 14:07:43 2014 +0100
     1.2 +++ b/src/main.c	Sun Feb 23 21:03:35 2014 +0100
     1.3 @@ -29,26 +29,58 @@
     1.4  
     1.5  #include "terminal-chess.h"
     1.6  #include <string.h>
     1.7 +#include <time.h>
     1.8  
     1.9  int get_settings(int argc, char **argv, Settings *settings) {
    1.10      char *valid;
    1.11 +    unsigned long int time, port;
    1.12 +    uint8_t timeunit = 60;
    1.13 +    size_t len;
    1.14      
    1.15 -    for (char opt ; (opt = getopt(argc, argv, "hp:")) != -1 ;) {
    1.16 +    for (char opt ; (opt = getopt(argc, argv, "a:bhp:rt:")) != -1 ;) {
    1.17          switch (opt) {
    1.18 -            case 'p':
    1.19 -                if (strtol(optarg, &valid, 10) < 1025 || *valid != '\0') {
    1.20 -                    fprintf(stderr,
    1.21 -                        "Invalid port number (%s) - choose a number > 1024\n",
    1.22 -                        optarg);
    1.23 -                    return 1;
    1.24 +        case 'b':
    1.25 +            settings->gameinfo.servercolor = BLACK;
    1.26 +            break;
    1.27 +        case 'r':
    1.28 +            settings->gameinfo.servercolor = (rand()>>5) & 1 ? WHITE : BLACK;
    1.29 +            break;
    1.30 +        case 't':
    1.31 +        case 'a':
    1.32 +            len = strlen(optarg);
    1.33 +            if (optarg[len-1] == 's') {
    1.34 +                optarg[len-1] = '\0';
    1.35 +                timeunit = 1;
    1.36 +            }
    1.37 +            
    1.38 +            if ((time = strtoul(optarg, &valid, 10)) > TIME_MAX
    1.39 +                || *valid != '\0') {
    1.40 +                fprintf(stderr, "Specified time is invalid (%s)\n", optarg);
    1.41 +                return 1;
    1.42 +            } else {
    1.43 +                if (opt=='t') {
    1.44 +                    settings->gameinfo.time = timeunit * time;
    1.45                  } else {
    1.46 -                    settings->port = optarg;
    1.47 +                    settings->gameinfo.addtime = time;
    1.48                  }
    1.49 -                break;
    1.50 -            case 'h':
    1.51 -            case '?':
    1.52 -                settings->printhelp = 1;
    1.53 -                break;
    1.54 +            }
    1.55 +            break;
    1.56 +        case 'p':
    1.57 +            port = strtol(optarg, &valid, 10);
    1.58 +            if (port < 1025 || port > 65535 || *valid != '\0') {
    1.59 +                fprintf(stderr,
    1.60 +                    "Invalid port number (%s) - choose a number between "
    1.61 +                    "1025 and 65535\n",
    1.62 +                    optarg);
    1.63 +                return 1;
    1.64 +            } else {
    1.65 +                settings->port = optarg;
    1.66 +            }
    1.67 +            break;
    1.68 +        case 'h':
    1.69 +        case '?':
    1.70 +            settings->printhelp = 1;
    1.71 +            break;
    1.72          }
    1.73      }
    1.74      
    1.75 @@ -65,10 +97,31 @@
    1.76  Settings default_settings() {
    1.77      Settings settings;
    1.78      memset(&settings, 0, sizeof(Settings));
    1.79 +    settings.gameinfo.servercolor = WHITE;
    1.80      settings.port = "27015";
    1.81      return settings;
    1.82  }
    1.83  
    1.84 +void dump_gameinfo(Gameinfo *gameinfo) {
    1.85 +    int serverwhite = gameinfo->servercolor == WHITE;
    1.86 +    printf(
    1.87 +        "Game details:\n"
    1.88 +        "  Server plays %s  -  Client plays %s\n",
    1.89 +        serverwhite?"white":"black", serverwhite?"black":"White"
    1.90 +    );
    1.91 +    if (gameinfo->time > 0) {
    1.92 +        if (gameinfo->time % 60) {
    1.93 +            printf("  Time limit: %ds + %ds\n",
    1.94 +                gameinfo->time, gameinfo->addtime);
    1.95 +        } else {
    1.96 +            printf("  Time limit: %dm + %ds\n",
    1.97 +                gameinfo->time/60, gameinfo->addtime);
    1.98 +        }
    1.99 +    } else {
   1.100 +        printf("  No time limit\n");
   1.101 +    }
   1.102 +}
   1.103 +
   1.104  int cleanup(Settings *settings, int exitcode) {
   1.105      if (settings->server) {
   1.106          if (net_destroy(settings->server)) {
   1.107 @@ -80,17 +133,32 @@
   1.108  }
   1.109  
   1.110  int main(int argc, char **argv) {
   1.111 +    srand(time(NULL));
   1.112      
   1.113      Settings settings = default_settings();
   1.114 -    get_settings(argc, argv, &settings);
   1.115 +    if (get_settings(argc, argv, &settings)) {
   1.116 +        return 1;
   1.117 +    }
   1.118      
   1.119      if (settings.printhelp) {
   1.120          printf(
   1.121 -            "Usage: %s [OPTION]... [HOST]\n"
   1.122 -            "Starts/joins a network chess game\n\n"
   1.123 +            "Usage: terminal-chess [OPTION]... [HOST]\n"
   1.124 +            "Starts/joins a network chess game\n"
   1.125 +            "\nGeneral options\n"
   1.126              "  -h            This help page\n"
   1.127 -            "  -p            TCP port to use (default: 27015)\n",
   1.128 -            argv[0]);
   1.129 +            "  -p            TCP port to use (default: 27015)\n"
   1.130 +            "\nServer options\n"
   1.131 +            "  -a <time>     Specifies the time to add after each move\n"
   1.132 +            "  -b            Server plays black pieces (default: white)\n"
   1.133 +            "  -r            Distribute color randomly\n"
   1.134 +            "  -t <time>     Specifies time limit (default: no limit)\n"
   1.135 +            "\nNotes\n"
   1.136 +            "White pieces are displayed as uppercase and black pieces as "
   1.137 +            "lowercase letters.\n"
   1.138 +            "The time unit for -a is seconds and for -t minutes by default. To "
   1.139 +            "specify\nseconds for the -t option, use the s suffix.\n"
   1.140 +            "Example: -t 150s\n"
   1.141 +        );
   1.142          return EXIT_SUCCESS;
   1.143      }
   1.144      
   1.145 @@ -98,6 +166,22 @@
   1.146      settings.server = &server;
   1.147      
   1.148      if (is_server(&settings)) {
   1.149 +        dump_gameinfo(&(settings.gameinfo));
   1.150 +        printf("\nListening for client...\n");
   1.151 +        if (net_create(&server, settings.port)) {
   1.152 +            perror("Server creation failed");
   1.153 +            return cleanup(&settings, EXIT_FAILURE);
   1.154 +        }
   1.155 +        
   1.156 +        if (net_listen(&server)) {
   1.157 +            perror("Listening for client failed");
   1.158 +            return cleanup(&settings, EXIT_FAILURE);
   1.159 +        }
   1.160 +        
   1.161 +        printf("Client connected - transmitting gameinfo...\n");
   1.162 +        net_send(server.client->fd, NETCODE_GAMEINFO,
   1.163 +            &(settings.gameinfo), sizeof(settings.gameinfo));
   1.164 +    } else {
   1.165          if (net_find(&server, settings.serverhost, settings.port)) {
   1.166              perror("Can't find server");
   1.167              return cleanup(&settings, EXIT_FAILURE);
   1.168 @@ -107,15 +191,14 @@
   1.169              perror("Can't connect to server");
   1.170              return cleanup(&settings, EXIT_FAILURE);
   1.171          }
   1.172 -    } else {
   1.173 -        if (net_create(&server, settings.port)) {
   1.174 -            perror("Server creation failed");
   1.175 -            return cleanup(&settings, EXIT_FAILURE);
   1.176 -        }
   1.177 -        
   1.178 -        if (net_listen(&server)) {
   1.179 -            perror("Listening for client failed");
   1.180 -            return cleanup(&settings, EXIT_FAILURE);
   1.181 +
   1.182 +        printf("Connection established!\n\n");
   1.183 +        if (net_recieve_code(server.fd) == NETCODE_GAMEINFO) {
   1.184 +            net_recieve_data(server.fd, &(settings.gameinfo),
   1.185 +                sizeof(settings.gameinfo));
   1.186 +            dump_gameinfo(&(settings.gameinfo));
   1.187 +        } else {
   1.188 +            fprintf(stderr, "Server sent invalid gameinfo.\n");
   1.189          }
   1.190      }
   1.191      

mercurial