src/game.c

Wed, 19 Mar 2014 15:36:54 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 19 Mar 2014 15:36:54 +0100
changeset 7
41468077b5bb
parent 6
daaf6e5b3501
child 8
52d742aee695
permissions
-rw-r--r--

implemented chess board and remis/surrender messages

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2014 Mike Becker. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  *
    28  */
    30 #include "game.h"
    31 #include "input.h"
    32 #include <ncurses.h>
    33 #include <string.h>
    35 static const uint8_t boardx = 10, boardy = 10;
    37 static void draw_board(Board board) {
    39     for (uint8_t y = 0 ; y < 8 ; y++) {
    40         for (uint8_t x = 0 ; x < 8 ; x++) {
    41             uint8_t col = board[y][x] & COLOR_MASK;
    42             uint8_t piece = board[y][x] & PIECE_MASK;
    43             char piecec = ' ';
    44             switch (piece) {
    45                 case PAWN: piecec = 'P'; break;
    46                 case ROOK: piecec = 'R'; break;
    47                 case KNIGHT: piecec = 'N'; break;
    48                 case BISHOP: piecec = 'B'; break;
    49                 case QUEEN: piecec = 'Q'; break;
    50                 case KING: piecec = 'K'; break;
    51             }
    53             attrset((col == WHITE ? A_BOLD : A_DIM) |
    54                 COLOR_PAIR((y&1)==(x&1) ? COL_WB : COL_BW));
    56             mvaddch(boardy-y, boardx+x*3, ' ');
    57             mvaddch(boardy-y, boardx+x*3+1, piecec);
    58             mvaddch(boardy-y, boardx+x*3+2, ' ');
    59         }
    60     }
    62     attrset(A_NORMAL);
    63     for (uint8_t i = 0 ; i < 8 ; i++) {
    64         mvaddch(boardy+1, boardx+i*3+1, 'a'+i);
    65         mvaddch(boardy-i, boardx-2, '1'+i);
    66     }
    67 }
    69 static int sendmove(int opponent) {
    70     const size_t buflen = 8;
    71     char move[buflen];
    72     _Bool remisrejected = FALSE;
    74     while (1) {
    75         move(boardy+3, 0);
    76         if (remisrejected) {
    77             printw(
    78                 "Use chess notation to enter your move.\n"
    79                 "Remis offer rejected - type 'surr' to surrender.      \n\n"
    80                 "Type your move: ");
    81         } else {
    82             printw(
    83                 "Use chess notation to enter your move.\n"
    84                 "Or type 'surr' to surrender or 'remis' to offer remis.\n\n"
    85                 "Type your move: ");
    86         }
    87         clrtoeol();
    88         refresh();
    89         getnstr(move, buflen);
    91         if (strncmp(move, "surr", buflen) == 0) {
    92             printw("You surrendered!");
    93             net_send_code(opponent, NETCODE_SURRENDER);
    94             return 1;
    95         } else if (strncmp(move, "remis", buflen) == 0) {
    96             if (!remisrejected) {
    97                 net_send_code(opponent, NETCODE_REMIS);
    98                 printw("Remis offer sent - waiting for acceptance...");
    99                 refresh();
   100                 if (net_recieve_code(opponent) == NETCODE_ACCEPT) {
   101                     printw("\rRemis accepted!");
   102                     clrtoeol();
   103                     return 1;
   104                 } else {
   105                     remisrejected = TRUE;
   106                 }
   107             }
   108         } else {
   109             // TODO: validate move syntactically
   110             // TODO: send move and await acceptance
   111         }
   112     }
   113 }
   115 static int recvmove(int opponent) {
   117     while (1) {
   118         move(boardy+3, 0);
   119         printw("Awaiting opponent move...");
   120         clrtoeol();
   121         refresh();
   123         // TODO: nonblocking
   124         uint32_t code = net_recieve_code(opponent);
   125         switch (code) {
   126             case NETCODE_SURRENDER:
   127                 printw("\rYour opponent surrendered!");
   128                 clrtoeol();
   129                 return 1;
   130             case NETCODE_REMIS:
   131                 if (prompt_yesno(
   132                     "\rYour opponent offers remis - do you accept")) {
   133                     printw("\rRemis accepted!");
   134                     clrtoeol();
   135                     net_send_code(opponent, NETCODE_ACCEPT);
   136                     return 1;
   137                 } else {
   138                     net_send_code(opponent, NETCODE_DECLINE);
   139                 }
   140                 break;
   141             case NETCODE_MOVE:
   142                 // TODO: receive move
   143                 // TODO: validate move and accept/reject
   144                 return 0;
   145         }
   146     }
   147 }
   149 void game_start(Settings *settings, int opponent) {
   150     _Bool myturn = is_server(settings) ==
   151         (settings->gameinfo.servercolor == WHITE);
   152     _Bool running;
   154     Board board = {
   155         {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
   156         {WPAWN, WPAWN,   WPAWN,   WPAWN,  WPAWN, WPAWN,   WPAWN,   WPAWN},
   157         {0,     0,       0,       0,      0,     0,       0,       0},
   158         {0,     0,       0,       0,      0,     0,       0,       0},
   159         {0,     0,       0,       0,      0,     0,       0,       0},
   160         {0,     0,       0,       0,      0,     0,       0,       0},
   161         {BPAWN, BPAWN,   BPAWN,   BPAWN,  BPAWN, BPAWN,   BPAWN,   BPAWN},
   162         {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
   163     };
   165     do {
   166         clear();
   167         draw_board(board);
   168         if (myturn) {
   169             running = !sendmove(opponent);
   170         } else {
   171             running = !recvmove(opponent);
   172             flushinp(); // flush any input the user hacked in while waiting
   173         }
   174         myturn ^= 1;
   175     }  while (running);
   177     mvaddstr(getmaxy(tchess_window)-1, 0,
   178         "Game has ended. Press any key to leave...");
   179     getch();
   180 }

mercurial