src/game.c

changeset 34
c4d4b8a8f902
parent 33
866025982aa9
child 35
6c64b7a073af
     1.1 --- a/src/game.c	Wed Apr 09 11:12:04 2014 +0200
     1.2 +++ b/src/game.c	Wed Apr 09 12:07:47 2014 +0200
     1.3 @@ -33,6 +33,7 @@
     1.4  #include <ncurses.h>
     1.5  #include <string.h>
     1.6  #include <inttypes.h>
     1.7 +#include <sys/select.h>
     1.8  
     1.9  static const uint8_t boardx = 10, boardy = 10;
    1.10  static int inputy = 21; /* should be overridden on game startup */
    1.11 @@ -315,6 +316,13 @@
    1.12  
    1.13  static int recvmove(GameState *gamestate, GameInfo *gameinfo, int opponent) {
    1.14      
    1.15 +    if (net_setnonblocking(opponent, 1)) {
    1.16 +        printw("Cannot setup nonblocking IO on network socket");
    1.17 +        cbreak(); getch();
    1.18 +        exit(EXIT_FAILURE);
    1.19 +    }
    1.20 +    
    1.21 +    struct timeval timeout;
    1.22      while (1) {
    1.23          timecontrol(gamestate, gameinfo);
    1.24          
    1.25 @@ -323,52 +331,66 @@
    1.26          clrtoeol();
    1.27          refresh();
    1.28  
    1.29 -        // TODO: nonblocking
    1.30 -        uint32_t code = net_recieve_code(opponent);
    1.31 +        fd_set readfds;
    1.32          
    1.33 -        Move move;
    1.34 -        switch (code) {
    1.35 -        case NETCODE_TIMEOVER:
    1.36 -            printw("\rYour opponent's time ran out - you win!");
    1.37 -            clrtoeol();
    1.38 -            return 1;
    1.39 -        case NETCODE_SURRENDER:
    1.40 -            printw("\rYour opponent surrendered!");
    1.41 -            clrtoeol();
    1.42 -            return 1;
    1.43 -        case NETCODE_REMIS:
    1.44 -            if (prompt_yesno(
    1.45 -                "\rYour opponent offers remis - do you accept")) {
    1.46 -                printw("\rRemis accepted!");
    1.47 +        FD_ZERO(&readfds);
    1.48 +        FD_SET(opponent, &readfds);
    1.49 +        timeout.tv_sec = 0;
    1.50 +        timeout.tv_usec = 1e5;
    1.51 +        
    1.52 +        int result = select(opponent+1, &readfds, NULL, NULL, &timeout);
    1.53 +        if (result == -1) {
    1.54 +            printw("\rCannot perform asynchronous network IO");
    1.55 +            cbreak(); getch();
    1.56 +            exit(EXIT_FAILURE);
    1.57 +        }
    1.58 +        if (result > 0) {
    1.59 +            uint32_t code = net_recieve_code(opponent);
    1.60 +
    1.61 +            Move move;
    1.62 +            switch (code) {
    1.63 +            case NETCODE_TIMEOVER:
    1.64 +                printw("\rYour opponent's time ran out - you win!");
    1.65                  clrtoeol();
    1.66 -                net_send_code(opponent, NETCODE_ACCEPT);
    1.67                  return 1;
    1.68 -            } else {
    1.69 -                net_send_code(opponent, NETCODE_DECLINE);
    1.70 -            }
    1.71 -            break;
    1.72 -        case NETCODE_MOVE:
    1.73 -            net_recieve_data(opponent, &move, sizeof(Move));
    1.74 -            if (validate_move(gamestate, &move)) {
    1.75 -                apply_move(gamestate, &move);
    1.76 -                if (move.check) {
    1.77 -                    net_send_code(opponent, NETCODE_CHECK);
    1.78 -                } else if (gamestate->checkmate) {
    1.79 -                    net_send_code(opponent, NETCODE_CHECKMATE);
    1.80 -                    printw("\rCheckmate!");
    1.81 +            case NETCODE_SURRENDER:
    1.82 +                printw("\rYour opponent surrendered!");
    1.83 +                clrtoeol();
    1.84 +                return 1;
    1.85 +            case NETCODE_REMIS:
    1.86 +                if (prompt_yesno(
    1.87 +                    "\rYour opponent offers remis - do you accept")) {
    1.88 +                    printw("\rRemis accepted!");
    1.89                      clrtoeol();
    1.90 -                    return 1;
    1.91 -                } else if (gamestate->stalemate) {
    1.92 -                    net_send_code(opponent, NETCODE_STALEMATE);
    1.93 -                    printw("\rStalemate!");
    1.94 -                    clrtoeol();
    1.95 +                    net_send_code(opponent, NETCODE_ACCEPT);
    1.96                      return 1;
    1.97                  } else {
    1.98 -                    net_send_code(opponent, NETCODE_ACCEPT);
    1.99 +                    net_send_code(opponent, NETCODE_DECLINE);
   1.100                  }
   1.101 -                return 0;
   1.102 -            } else {
   1.103 -                net_send_code(opponent, NETCODE_DECLINE);
   1.104 +                break;
   1.105 +            case NETCODE_MOVE:
   1.106 +                net_recieve_data(opponent, &move, sizeof(Move));
   1.107 +                if (validate_move(gamestate, &move)) {
   1.108 +                    apply_move(gamestate, &move);
   1.109 +                    if (move.check) {
   1.110 +                        net_send_code(opponent, NETCODE_CHECK);
   1.111 +                    } else if (gamestate->checkmate) {
   1.112 +                        net_send_code(opponent, NETCODE_CHECKMATE);
   1.113 +                        printw("\rCheckmate!");
   1.114 +                        clrtoeol();
   1.115 +                        return 1;
   1.116 +                    } else if (gamestate->stalemate) {
   1.117 +                        net_send_code(opponent, NETCODE_STALEMATE);
   1.118 +                        printw("\rStalemate!");
   1.119 +                        clrtoeol();
   1.120 +                        return 1;
   1.121 +                    } else {
   1.122 +                        net_send_code(opponent, NETCODE_ACCEPT);
   1.123 +                    }
   1.124 +                    return 0;
   1.125 +                } else {
   1.126 +                    net_send_code(opponent, NETCODE_DECLINE);
   1.127 +                }
   1.128              }
   1.129          }
   1.130      }

mercurial