src/game.c

changeset 26
e0a76ee1bb2b
parent 25
3ab0c2e1a4e2
child 27
efeb98bc69c9
     1.1 --- a/src/game.c	Tue Apr 01 12:30:25 2014 +0200
     1.2 +++ b/src/game.c	Tue Apr 01 14:04:00 2014 +0200
     1.3 @@ -112,6 +112,78 @@
     1.4      }
     1.5  }
     1.6  
     1.7 +static void eval_move_failed_msg(int code) {
     1.8 +    switch (code) {
     1.9 +    case AMBIGUOUS_MOVE:
    1.10 +        printw("Ambiguous move - please specify the piece to move.");
    1.11 +        break;
    1.12 +    case INVALID_POSITION:
    1.13 +        printw("Cannot find the piece that shall be moved.");
    1.14 +        break;
    1.15 +    case NEED_PROMOTION:
    1.16 +        printw("You need to promote the pawn (append \"=Q\" e.g.)!");
    1.17 +        break;
    1.18 +    default:
    1.19 +        printw("Can't interpret move - please use algebraic notation.");
    1.20 +    }
    1.21 +}
    1.22 +
    1.23 +static int domove_singlemachine(GameState *gamestate) {
    1.24 +    
    1.25 +    const size_t buflen = 8;
    1.26 +    char movestr[buflen];
    1.27 +    
    1.28 +    int inputy = getmaxy(stdscr) - 6;
    1.29 +    while (1) {
    1.30 +        move(inputy, 0);
    1.31 +        printw(
    1.32 +            "Use chess notation to enter your move.\n"
    1.33 +            "Or type 'surr' to surrender or 'remis' to end with remis.\n\n"
    1.34 +            "Type your move: ");
    1.35 +        clrtoeol();
    1.36 +        refresh();
    1.37 +        getnstr(movestr, buflen);
    1.38 +
    1.39 +        if (strncmp(movestr, "surr", buflen) == 0) {
    1.40 +            printw("%s surrendered!",
    1.41 +                gamestate->mycolor==WHITE?"White":"Black");
    1.42 +            clrtoeol();
    1.43 +            refresh();
    1.44 +            return 1;
    1.45 +        } else if (strncmp(movestr, "remis", buflen) == 0) {
    1.46 +            printw("Game ends remis.");
    1.47 +            clrtoeol();
    1.48 +            refresh();
    1.49 +            return 1;
    1.50 +        } else {
    1.51 +            Move move;
    1.52 +            int eval_result = eval_move(gamestate, movestr, &move);
    1.53 +            switch (eval_result) {
    1.54 +            case VALID_MOVE_SYNTAX:
    1.55 +                if (validate_move(gamestate, &move)) {
    1.56 +                    apply_move(gamestate, &move);
    1.57 +                    if (move.checkmate) {
    1.58 +                        printw("Checkmate!");
    1.59 +                        clrtoeol();
    1.60 +                        return 1;
    1.61 +                    } else if (move.stalemate) {
    1.62 +                        printw("Stalemate!");
    1.63 +                        clrtoeol();
    1.64 +                        return 1;
    1.65 +                    } else {
    1.66 +                        return 0;
    1.67 +                    }
    1.68 +                } else {
    1.69 +                    printw("Invalid move.");
    1.70 +                }
    1.71 +                break;
    1.72 +            default:
    1.73 +                eval_move_failed_msg(eval_result);
    1.74 +            }
    1.75 +            clrtoeol();
    1.76 +        }
    1.77 +    }
    1.78 +}
    1.79  
    1.80  static int sendmove(GameState *gamestate, int opponent) {
    1.81      
    1.82 @@ -167,6 +239,7 @@
    1.83                  code = net_recieve_code(opponent);
    1.84                  move.check = code == NETCODE_CHECK;
    1.85                  move.checkmate = code == NETCODE_CHECKMATE;
    1.86 +                move.stalemate = code == NETCODE_STALEMATE;
    1.87                  if (code == NETCODE_DECLINE) {
    1.88                      printw("Invalid move.");
    1.89                  } else {
    1.90 @@ -175,22 +248,17 @@
    1.91                          printw("Checkmate!");
    1.92                          clrtoeol();
    1.93                          return 1;
    1.94 +                    } else if (move.stalemate) {
    1.95 +                        printw("Stalemate!");
    1.96 +                        clrtoeol();
    1.97 +                        return 1;
    1.98                      } else {
    1.99                          return 0;
   1.100                      }
   1.101                  }
   1.102                  break;
   1.103 -            case AMBIGUOUS_MOVE:
   1.104 -                printw("Ambiguous move - please specify the piece to move.");
   1.105 -                break;
   1.106 -            case INVALID_POSITION:
   1.107 -                printw("Cannot find the piece that shall be moved.");
   1.108 -                break;
   1.109 -            case NEED_PROMOTION:
   1.110 -                printw("You need to promote the pawn (append \"=Q\" e.g.)!");
   1.111 -                break;
   1.112              default:
   1.113 -                printw("Can't interpret move - please use algebraic notation.");
   1.114 +                eval_move_failed_msg(eval_result);
   1.115              }
   1.116              clrtoeol();
   1.117          }
   1.118 @@ -234,6 +302,14 @@
   1.119                          net_send_code(opponent, NETCODE_CHECK);
   1.120                      } else if (move.checkmate) {
   1.121                          net_send_code(opponent, NETCODE_CHECKMATE);
   1.122 +                        printw("\rCheckmate!");
   1.123 +                        clrtoeol();
   1.124 +                        return 1;
   1.125 +                    } else if (move.stalemate) {
   1.126 +                        net_send_code(opponent, NETCODE_STALEMATE);
   1.127 +                        printw("\rStalemate!");
   1.128 +                        clrtoeol();
   1.129 +                        return 1;
   1.130                      } else {
   1.131                          net_send_code(opponent, NETCODE_ACCEPT);
   1.132                      }
   1.133 @@ -245,22 +321,49 @@
   1.134      }
   1.135  }
   1.136  
   1.137 +static void init_board(GameState *gamestate) {
   1.138 +    Board initboard = {
   1.139 +        {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
   1.140 +        {WPAWN, WPAWN,   WPAWN,   WPAWN,  WPAWN, WPAWN,   WPAWN,   WPAWN},
   1.141 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.142 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.143 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.144 +        {0,     0,       0,       0,      0,     0,       0,       0},
   1.145 +        {BPAWN, BPAWN,   BPAWN,   BPAWN,  BPAWN, BPAWN,   BPAWN,   BPAWN},
   1.146 +        {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
   1.147 +    };
   1.148 +    memcpy(gamestate->board, initboard, sizeof(Board));
   1.149 +}
   1.150 +
   1.151 +void game_start_singlemachine(Settings *settings) {
   1.152 +    GameState gamestate;
   1.153 +    init_board(&gamestate);
   1.154 +    gamestate.mycolor = WHITE;
   1.155 +    gamestate.movelist = gamestate.lastmove = NULL;
   1.156 +    // TODO: time limit
   1.157 +    _Bool running;
   1.158 +    do {
   1.159 +        clear();
   1.160 +        draw_board(&gamestate);
   1.161 +        running = !domove_singlemachine(&gamestate);
   1.162 +        gamestate.mycolor = opponent_color(gamestate.mycolor);
   1.163 +    }  while (running);
   1.164 +    
   1.165 +    gamestate_cleanup(&gamestate);
   1.166 +    
   1.167 +    mvaddstr(getmaxy(stdscr)-1, 0,
   1.168 +        "Game has ended. Press any key to leave...");
   1.169 +    refresh();
   1.170 +    getch();
   1.171 +}
   1.172 +
   1.173  void game_start(Settings *settings, int opponent) {
   1.174      _Bool myturn = is_server(settings) ==
   1.175          (settings->gameinfo.servercolor == WHITE);
   1.176      
   1.177 +    // TODO: time limit
   1.178      GameState gamestate;
   1.179 -    Board initboard = {
   1.180 -        {WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK},
   1.181 -        {WPAWN, WPAWN,   WPAWN,   WPAWN,  WPAWN, WPAWN,   WPAWN,   WPAWN},
   1.182 -        {0,     0,       0,       0,      0,     0,       0,       0},
   1.183 -        {0,     0,       0,       0,      0,     0,       0,       0},
   1.184 -        {0,     0,       0,       0,      0,     0,       0,       0},
   1.185 -        {0,     0,       0,       0,      0,     0,       0,       0},
   1.186 -        {BPAWN, BPAWN,   BPAWN,   BPAWN,  BPAWN, BPAWN,   BPAWN,   BPAWN},
   1.187 -        {BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK}
   1.188 -    };
   1.189 -    memcpy(gamestate.board, initboard, sizeof(Board));
   1.190 +    init_board(&gamestate);
   1.191      gamestate.mycolor = myturn ? WHITE:BLACK;
   1.192      gamestate.movelist = gamestate.lastmove = NULL;
   1.193      
   1.194 @@ -281,5 +384,6 @@
   1.195      
   1.196      mvaddstr(getmaxy(stdscr)-1, 0,
   1.197          "Game has ended. Press any key to leave...");
   1.198 +    refresh();
   1.199      getch();
   1.200  }

mercurial