src/game.c

changeset 7
41468077b5bb
parent 6
daaf6e5b3501
child 8
52d742aee695
     1.1 --- a/src/game.c	Wed Mar 19 10:08:25 2014 +0100
     1.2 +++ b/src/game.c	Wed Mar 19 15:36:54 2014 +0100
     1.3 @@ -28,7 +28,153 @@
     1.4   */
     1.5  
     1.6  #include "game.h"
     1.7 +#include "input.h"
     1.8 +#include <ncurses.h>
     1.9 +#include <string.h>
    1.10 +
    1.11 +static const uint8_t boardx = 10, boardy = 10;
    1.12 +
    1.13 +static void draw_board(Board board) {
    1.14 +    
    1.15 +    for (uint8_t y = 0 ; y < 8 ; y++) {
    1.16 +        for (uint8_t x = 0 ; x < 8 ; x++) {
    1.17 +            uint8_t col = board[y][x] & COLOR_MASK;
    1.18 +            uint8_t piece = board[y][x] & PIECE_MASK;
    1.19 +            char piecec = ' ';
    1.20 +            switch (piece) {
    1.21 +                case PAWN: piecec = 'P'; break;
    1.22 +                case ROOK: piecec = 'R'; break;
    1.23 +                case KNIGHT: piecec = 'N'; break;
    1.24 +                case BISHOP: piecec = 'B'; break;
    1.25 +                case QUEEN: piecec = 'Q'; break;
    1.26 +                case KING: piecec = 'K'; break;
    1.27 +            }
    1.28 +            
    1.29 +            attrset((col == WHITE ? A_BOLD : A_DIM) |
    1.30 +                COLOR_PAIR((y&1)==(x&1) ? COL_WB : COL_BW));
    1.31 +            
    1.32 +            mvaddch(boardy-y, boardx+x*3, ' ');
    1.33 +            mvaddch(boardy-y, boardx+x*3+1, piecec);
    1.34 +            mvaddch(boardy-y, boardx+x*3+2, ' ');
    1.35 +        }
    1.36 +    }
    1.37 +    
    1.38 +    attrset(A_NORMAL);
    1.39 +    for (uint8_t i = 0 ; i < 8 ; i++) {
    1.40 +        mvaddch(boardy+1, boardx+i*3+1, 'a'+i);
    1.41 +        mvaddch(boardy-i, boardx-2, '1'+i);
    1.42 +    }
    1.43 +}
    1.44 +
    1.45 +static int sendmove(int opponent) {
    1.46 +    const size_t buflen = 8;
    1.47 +    char move[buflen];
    1.48 +    _Bool remisrejected = FALSE;
    1.49 +    
    1.50 +    while (1) {
    1.51 +        move(boardy+3, 0);
    1.52 +        if (remisrejected) {
    1.53 +            printw(
    1.54 +                "Use chess notation to enter your move.\n"
    1.55 +                "Remis offer rejected - type 'surr' to surrender.      \n\n"
    1.56 +                "Type your move: ");
    1.57 +        } else {
    1.58 +            printw(
    1.59 +                "Use chess notation to enter your move.\n"
    1.60 +                "Or type 'surr' to surrender or 'remis' to offer remis.\n\n"
    1.61 +                "Type your move: ");
    1.62 +        }
    1.63 +        clrtoeol();
    1.64 +        refresh();
    1.65 +        getnstr(move, buflen);
    1.66 +
    1.67 +        if (strncmp(move, "surr", buflen) == 0) {
    1.68 +            printw("You surrendered!");
    1.69 +            net_send_code(opponent, NETCODE_SURRENDER);
    1.70 +            return 1;
    1.71 +        } else if (strncmp(move, "remis", buflen) == 0) {
    1.72 +            if (!remisrejected) {
    1.73 +                net_send_code(opponent, NETCODE_REMIS);
    1.74 +                printw("Remis offer sent - waiting for acceptance...");
    1.75 +                refresh();
    1.76 +                if (net_recieve_code(opponent) == NETCODE_ACCEPT) {
    1.77 +                    printw("\rRemis accepted!");
    1.78 +                    clrtoeol();
    1.79 +                    return 1;
    1.80 +                } else {
    1.81 +                    remisrejected = TRUE;
    1.82 +                }
    1.83 +            }
    1.84 +        } else {
    1.85 +            // TODO: validate move syntactically
    1.86 +            // TODO: send move and await acceptance
    1.87 +        }
    1.88 +    }
    1.89 +}
    1.90 +
    1.91 +static int recvmove(int opponent) {
    1.92 +    
    1.93 +    while (1) {
    1.94 +        move(boardy+3, 0);
    1.95 +        printw("Awaiting opponent move...");
    1.96 +        clrtoeol();
    1.97 +        refresh();
    1.98 +
    1.99 +        // TODO: nonblocking
   1.100 +        uint32_t code = net_recieve_code(opponent);
   1.101 +        switch (code) {
   1.102 +            case NETCODE_SURRENDER:
   1.103 +                printw("\rYour opponent surrendered!");
   1.104 +                clrtoeol();
   1.105 +                return 1;
   1.106 +            case NETCODE_REMIS:
   1.107 +                if (prompt_yesno(
   1.108 +                    "\rYour opponent offers remis - do you accept")) {
   1.109 +                    printw("\rRemis accepted!");
   1.110 +                    clrtoeol();
   1.111 +                    net_send_code(opponent, NETCODE_ACCEPT);
   1.112 +                    return 1;
   1.113 +                } else {
   1.114 +                    net_send_code(opponent, NETCODE_DECLINE);
   1.115 +                }
   1.116 +                break;
   1.117 +            case NETCODE_MOVE:
   1.118 +                // TODO: receive move
   1.119 +                // TODO: validate move and accept/reject
   1.120 +                return 0;
   1.121 +        }
   1.122 +    }
   1.123 +}
   1.124  
   1.125  void game_start(Settings *settings, int opponent) {
   1.126 +    _Bool myturn = is_server(settings) ==
   1.127 +        (settings->gameinfo.servercolor == WHITE);
   1.128 +    _Bool running;
   1.129      
   1.130 +    Board board = {
   1.131 +        {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
   1.132 +        {WPAWN, WPAWN,   WPAWN,   WPAWN,  WPAWN, WPAWN,   WPAWN,   WPAWN},
   1.133 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.134 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.135 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.136 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.137 +        {BPAWN, BPAWN,   BPAWN,   BPAWN,  BPAWN, BPAWN,   BPAWN,   BPAWN},
   1.138 +        {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
   1.139 +    };
   1.140 +    
   1.141 +    do {
   1.142 +        clear();
   1.143 +        draw_board(board);
   1.144 +        if (myturn) {
   1.145 +            running = !sendmove(opponent);
   1.146 +        } else {
   1.147 +            running = !recvmove(opponent);
   1.148 +            flushinp(); // flush any input the user hacked in while waiting
   1.149 +        }
   1.150 +        myturn ^= 1;
   1.151 +    }  while (running);
   1.152 +    
   1.153 +    mvaddstr(getmaxy(tchess_window)-1, 0,
   1.154 +        "Game has ended. Press any key to leave...");
   1.155 +    getch();
   1.156  }

mercurial