implemented simple pawn movement

Sat, 22 Mar 2014 16:04:02 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 22 Mar 2014 16:04:02 +0100
changeset 8
52d742aee695
parent 7
41468077b5bb
child 9
4e4f156bba58

implemented simple pawn movement

src/game.c file | annotate | diff | comparison | revisions
src/game.h file | annotate | diff | comparison | revisions
     1.1 --- a/src/game.c	Wed Mar 19 15:36:54 2014 +0100
     1.2 +++ b/src/game.c	Sat Mar 22 16:04:02 2014 +0100
     1.3 @@ -34,7 +34,7 @@
     1.4  
     1.5  static const uint8_t boardx = 10, boardy = 10;
     1.6  
     1.7 -static void draw_board(Board board) {
     1.8 +static void draw_board(Board board, uint8_t mycolor) {
     1.9      
    1.10      for (uint8_t y = 0 ; y < 8 ; y++) {
    1.11          for (uint8_t x = 0 ; x < 8 ; x++) {
    1.12 @@ -53,22 +53,118 @@
    1.13              attrset((col == WHITE ? A_BOLD : A_DIM) |
    1.14                  COLOR_PAIR((y&1)==(x&1) ? COL_WB : COL_BW));
    1.15              
    1.16 -            mvaddch(boardy-y, boardx+x*3, ' ');
    1.17 -            mvaddch(boardy-y, boardx+x*3+1, piecec);
    1.18 -            mvaddch(boardy-y, boardx+x*3+2, ' ');
    1.19 +            int cy = mycolor == WHITE ? boardy-y : boardy-7+y;
    1.20 +            int cx = mycolor == WHITE ? boardx+x*3 : boardx+21-x*3;
    1.21 +            mvaddch(cy, cx, ' ');
    1.22 +            mvaddch(cy, cx+1, piecec);
    1.23 +            mvaddch(cy, cx+2, ' ');
    1.24          }
    1.25      }
    1.26      
    1.27      attrset(A_NORMAL);
    1.28      for (uint8_t i = 0 ; i < 8 ; i++) {
    1.29 -        mvaddch(boardy+1, boardx+i*3+1, 'a'+i);
    1.30 -        mvaddch(boardy-i, boardx-2, '1'+i);
    1.31 +        int x = mycolor == WHITE ? boardx+i*3+1 : boardx+22-i*3;
    1.32 +        int y = mycolor == WHITE ? boardy-i : boardy-7+i;
    1.33 +        mvaddch(boardy+1, x, 'a'+i);
    1.34 +        mvaddch(y, boardx-2, '1'+i);
    1.35      }
    1.36  }
    1.37  
    1.38 -static int sendmove(int opponent) {
    1.39 +static void apply_move(Board board, Move *move) {
    1.40 +    board[move->fromrow][move->fromfile] = 0;
    1.41 +    // TODO: care for en passant capture
    1.42 +    board[move->torow][move->tofile] = move->piece;
    1.43 +}
    1.44 +
    1.45 +static _Bool validate_move(Board board, uint8_t mycolor, Move *move) {
    1.46 +    _Bool result = TRUE;
    1.47 +    
    1.48 +    /* does piece exist */
    1.49 +    result &= board[move->fromrow][move->fromfile] == move->piece;
    1.50 +    
    1.51 +    /* is move rule conform */
    1.52 +    // TODO: make it so
    1.53 +    
    1.54 +    /* is piece blocked */
    1.55 +    // TODO: make it so
    1.56 +    
    1.57 +    /* is piece pinned */
    1.58 +    // TODO: make it so
    1.59 +    
    1.60 +    return result;
    1.61 +}
    1.62 +
    1.63 +static _Bool eval_move(Board board, uint8_t mycolor, char *movestr, Move *move) {
    1.64 +    memset(move, 0, sizeof(Move));
    1.65 +    
    1.66 +    size_t len = strlen(movestr);
    1.67 +    
    1.68 +    /* remove check */
    1.69 +    if (movestr[len-1] == '+') {
    1.70 +        len--; movestr[len] = '\0';
    1.71 +        move->check = TRUE;
    1.72 +    }
    1.73 +    
    1.74 +    if (len == 2) {
    1.75 +        /* pawn move (e.g. "e4") */
    1.76 +        if (isfile(movestr[0]) && isrow(movestr[1])) {
    1.77 +            move->piece = PAWN;
    1.78 +            move->fromfile = move->tofile = fileidx(movestr[0]);
    1.79 +            move->torow = rowidx(movestr[1]);
    1.80 +            move->fromrow = rowidx(movestr[1]) + (mycolor == WHITE ? -1 : 1);
    1.81 +            if (move->fromrow > 6) {
    1.82 +                move->piece = 0;
    1.83 +            } else {
    1.84 +                /* advanced first move */
    1.85 +                if (move->fromrow == (mycolor == WHITE ? 2 : 5) &&
    1.86 +                    board[move->fromrow][move->fromfile] != (mycolor|PAWN)) {
    1.87 +                    
    1.88 +                    move->fromrow += (mycolor == WHITE ? -1 : 1);
    1.89 +                    if (move->fromrow > 6) {
    1.90 +                        move->piece = 0;
    1.91 +                    }
    1.92 +                }
    1.93 +            }
    1.94 +        }
    1.95 +    } else if (len == 3) {
    1.96 +        if (strcmp(movestr, "0-0") == 0) {
    1.97 +            /* king side castling */
    1.98 +            move->piece = KING;
    1.99 +            move->fromfile = fileidx('e');
   1.100 +            move->fromfile = fileidx('g');
   1.101 +            move->fromrow = move->torow = mycolor == WHITE ? 0 : 7;
   1.102 +        } else {
   1.103 +            /* unambiguous move (e.g. "Nf3") */
   1.104 +        }
   1.105 +        
   1.106 +    } else if (len == 4) {
   1.107 +        /* ambiguous move (e.g. "Ndf3") */
   1.108 +        
   1.109 +        /* unambiguous capture (e.g. "Nxf3", "dxe5") */
   1.110 +        
   1.111 +    } else if (len == 5) {
   1.112 +        /* queen side castling "O-O-O" */
   1.113 +        
   1.114 +        /* ambiguous capture (e.g. "Ndxf3") */
   1.115 +        
   1.116 +        /* long notation move (e.g. "Nc5a4") */
   1.117 +        
   1.118 +        /* long notation capture (e.g. "e5xf6") */
   1.119 +    } else if (len == 6) {
   1.120 +        /* long notation capture (e.g. "Nc5xf3") */
   1.121 +    }
   1.122 +    
   1.123 +    if (move->piece) {
   1.124 +        move->piece |= mycolor;
   1.125 +        return TRUE;
   1.126 +    } else {
   1.127 +        return FALSE;
   1.128 +    }
   1.129 +}
   1.130 +
   1.131 +static int sendmove(Board board, uint8_t mycolor, int opponent) {
   1.132      const size_t buflen = 8;
   1.133 -    char move[buflen];
   1.134 +    char movestr[buflen];
   1.135      _Bool remisrejected = FALSE;
   1.136      
   1.137      while (1) {
   1.138 @@ -86,13 +182,14 @@
   1.139          }
   1.140          clrtoeol();
   1.141          refresh();
   1.142 -        getnstr(move, buflen);
   1.143 +        getnstr(movestr, buflen);
   1.144  
   1.145 -        if (strncmp(move, "surr", buflen) == 0) {
   1.146 +        if (strncmp(movestr, "surr", buflen) == 0) {
   1.147              printw("You surrendered!");
   1.148 +            refresh();
   1.149              net_send_code(opponent, NETCODE_SURRENDER);
   1.150              return 1;
   1.151 -        } else if (strncmp(move, "remis", buflen) == 0) {
   1.152 +        } else if (strncmp(movestr, "remis", buflen) == 0) {
   1.153              if (!remisrejected) {
   1.154                  net_send_code(opponent, NETCODE_REMIS);
   1.155                  printw("Remis offer sent - waiting for acceptance...");
   1.156 @@ -100,19 +197,32 @@
   1.157                  if (net_recieve_code(opponent) == NETCODE_ACCEPT) {
   1.158                      printw("\rRemis accepted!");
   1.159                      clrtoeol();
   1.160 +                    refresh();
   1.161                      return 1;
   1.162                  } else {
   1.163                      remisrejected = TRUE;
   1.164                  }
   1.165              }
   1.166          } else {
   1.167 -            // TODO: validate move syntactically
   1.168 -            // TODO: send move and await acceptance
   1.169 +            Move move;
   1.170 +            if (eval_move(board, mycolor, movestr, &move)) {
   1.171 +                net_send_code(opponent, NETCODE_MOVE);
   1.172 +                net_send_data(opponent, &move, sizeof(Move));
   1.173 +                if (net_recieve_code(opponent) == NETCODE_ACCEPT) {
   1.174 +                    apply_move(board, &move);
   1.175 +                    return 0;
   1.176 +                } else {
   1.177 +                    printw("Invalid move.");
   1.178 +                    clrtoeol();
   1.179 +                }
   1.180 +            } else {
   1.181 +                printw("Can't interpret move - please use algebraic notation.");
   1.182 +            }
   1.183          }
   1.184      }
   1.185  }
   1.186  
   1.187 -static int recvmove(int opponent) {
   1.188 +static int recvmove(Board board, uint8_t mycolor, int opponent) {
   1.189      
   1.190      while (1) {
   1.191          move(boardy+3, 0);
   1.192 @@ -122,6 +232,8 @@
   1.193  
   1.194          // TODO: nonblocking
   1.195          uint32_t code = net_recieve_code(opponent);
   1.196 +        
   1.197 +        Move move;
   1.198          switch (code) {
   1.199              case NETCODE_SURRENDER:
   1.200                  printw("\rYour opponent surrendered!");
   1.201 @@ -139,9 +251,14 @@
   1.202                  }
   1.203                  break;
   1.204              case NETCODE_MOVE:
   1.205 -                // TODO: receive move
   1.206 -                // TODO: validate move and accept/reject
   1.207 -                return 0;
   1.208 +                net_recieve_data(opponent, &move, sizeof(Move));
   1.209 +                if (validate_move(board, mycolor, &move)) {
   1.210 +                    apply_move(board, &move);
   1.211 +                    net_send_code(opponent, NETCODE_ACCEPT);
   1.212 +                    return 0;
   1.213 +                } else {
   1.214 +                    net_send_code(opponent, NETCODE_DECLINE);
   1.215 +                }
   1.216          }
   1.217      }
   1.218  }
   1.219 @@ -149,6 +266,8 @@
   1.220  void game_start(Settings *settings, int opponent) {
   1.221      _Bool myturn = is_server(settings) ==
   1.222          (settings->gameinfo.servercolor == WHITE);
   1.223 +    uint8_t mycolor = myturn ? WHITE:BLACK;
   1.224 +    
   1.225      _Bool running;
   1.226      
   1.227      Board board = {
   1.228 @@ -164,11 +283,11 @@
   1.229      
   1.230      do {
   1.231          clear();
   1.232 -        draw_board(board);
   1.233 +        draw_board(board, mycolor);
   1.234          if (myturn) {
   1.235 -            running = !sendmove(opponent);
   1.236 +            running = !sendmove(board, mycolor, opponent);
   1.237          } else {
   1.238 -            running = !recvmove(opponent);
   1.239 +            running = !recvmove(board, mycolor, opponent);
   1.240              flushinp(); // flush any input the user hacked in while waiting
   1.241          }
   1.242          myturn ^= 1;
     2.1 --- a/src/game.h	Wed Mar 19 15:36:54 2014 +0100
     2.2 +++ b/src/game.h	Sat Mar 22 16:04:02 2014 +0100
     2.3 @@ -65,6 +65,21 @@
     2.4  
     2.5  typedef uint8_t Board[8][8];
     2.6  
     2.7 +typedef struct {
     2.8 +    uint8_t piece;
     2.9 +    uint8_t fromfile;
    2.10 +    uint8_t fromrow;
    2.11 +    uint8_t tofile;
    2.12 +    uint8_t torow;
    2.13 +    _Bool check;
    2.14 +    _Bool capture;
    2.15 +} Move;
    2.16 +
    2.17 +#define isfile(file) (file >= 'a' && file <= 'h')
    2.18 +#define isrow(row) (row >= '1' && row <= '8')
    2.19 +#define rowidx(row) (row-'1')
    2.20 +#define fileidx(file) (file-'a')
    2.21 +
    2.22  void game_start(Settings *settings, int opponent);
    2.23  
    2.24  #ifdef	__cplusplus

mercurial