implemented king

Tue, 01 Apr 2014 12:30:25 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 01 Apr 2014 12:30:25 +0200
changeset 25
3ab0c2e1a4e2
parent 24
4d030da07c88
child 26
e0a76ee1bb2b

implemented king

src/chess/king.c file | annotate | diff | comparison | revisions
src/chess/rules.c file | annotate | diff | comparison | revisions
src/chess/rules.h file | annotate | diff | comparison | revisions
src/game.c file | annotate | diff | comparison | revisions
src/network.h file | annotate | diff | comparison | revisions
--- a/src/chess/king.c	Tue Apr 01 10:28:08 2014 +0200
+++ b/src/chess/king.c	Tue Apr 01 12:30:25 2014 +0200
@@ -29,18 +29,88 @@
 
 #include "rules.h"
 #include "king.h"
+#include <stdlib.h>
+
+static _Bool king_castling_chkmoved(GameState *gamestate,
+    uint8_t row, uint8_t file) {
+    
+    MoveList *ml = gamestate->movelist;
+    while (ml) {
+        if (ml->move.fromfile == file && ml->move.fromrow == row) {
+            return 1;
+        }
+        ml = ml->next;
+    }
+    
+    return 0;
+}
 
 _Bool king_chkrules(GameState *gamestate, Move* move) {
-    // TODO: implement
-    return 0;
+    if (abs(move->torow - move->fromrow) <= 1 &&
+        abs(move->tofile - move->fromfile) <= 1) {
+        return 1;
+    } else {
+        /* castling */
+        if (move->fromrow == move->torow &&
+            move->fromrow == ((move->piece&COLOR_MASK) == WHITE ? 0 : 7) &&
+            move->fromfile == fileidx('e') &&
+            (move->tofile == fileidx('c') || move->tofile == fileidx('g'))) {
+            
+            return !king_castling_chkmoved(gamestate,
+                move->fromrow, move->fromfile) &&
+                !king_castling_chkmoved(gamestate, move->fromrow,
+                move->tofile == fileidx('c') ? 0 : 7);
+        } else {
+            return 0;
+        }
+    }
 }
 
 _Bool king_isblocked(GameState *gamestate, Move *move) {
-    // TODO: implement
-    return 1;
+    
+    uint8_t opponent_color = opponent_color(move->piece&COLOR_MASK);
+    _Bool blocked = is_covered(gamestate, move->torow, move->tofile,
+        opponent_color);
+    
+    if (abs(move->tofile - move->fromfile) == 2) {
+        if (move->tofile == fileidx('c')) {
+            blocked |= gamestate->board[move->torow][fileidx('b')];
+        }
+        uint8_t midfile = (move->tofile+move->fromfile)/2;
+        blocked |= gamestate->lastmove->move.check ||
+            gamestate->board[move->torow][midfile] ||
+            is_covered(gamestate, move->torow, midfile, opponent_color);
+    }
+    
+    return blocked;
 }
 
 int king_getlocation(GameState *gamestate, Move *move) {
-    // TODO: implement
-    return INVALID_MOVE_SYNTAX;
+    
+    uint8_t file, row;
+    
+    for (int f = -1 ; f <= 1 ; f++) {
+        for (int r = -1 ; r <= 1 ; r++) {
+            if (f == 0 && r == 0) {
+                continue;
+            }
+            file = move->tofile + f;
+            row = move->torow + r;
+            if (isidx(file) && isidx(row)) {
+                if (gamestate->board[row][file] == move->piece) {
+                    if ((move->fromfile != POS_UNSPECIFIED
+                        && move->fromfile != file) ||
+                        (move->fromrow != POS_UNSPECIFIED
+                        && move->fromrow != row)) {
+                        return INVALID_POSITION;
+                    }
+                    move->fromfile = file;
+                    move->fromrow = row;
+                    return VALID_MOVE_SYNTAX;
+                }
+            }
+        }
+    }
+    
+    return INVALID_POSITION;
 }
--- a/src/chess/rules.c	Tue Apr 01 10:28:08 2014 +0200
+++ b/src/chess/rules.c	Tue Apr 01 12:30:25 2014 +0200
@@ -90,6 +90,30 @@
     }
 }
 
+_Bool is_covered(GameState *gamestate,uint8_t row,uint8_t file,uint8_t color) {
+    Move threats[16];
+    int threatcount = 0;
+    for (uint8_t r = 0 ; r < 8 ; r++) {
+        for (uint8_t f = 0 ; f < 8 ; f++) {
+            if ((gamestate->board[r][f] & COLOR_MASK) == color) {
+                threats[threatcount].piece = gamestate->board[r][f];
+                threats[threatcount].fromrow = r;
+                threats[threatcount].fromfile = f;
+                threats[threatcount].torow = row;
+                threats[threatcount].tofile = file;
+                threatcount++;
+            }
+        }
+    }
+    
+    for (int i = 0 ; i < threatcount ; i++) {
+        if (validate_move(gamestate, &(threats[i]))) {
+            return 1;
+        }
+    }
+    
+    return 0;
+}
 
 void apply_move(GameState *gamestate, Move *move) {
     uint8_t piece = move->piece & PIECE_MASK;
@@ -190,10 +214,15 @@
         result = 0;
     }
     
+    /* cancel processing to avoid recursion overflow with is_covered() */
+    if (!result) {
+        return 0;
+    }
+    
     /* is piece pinned */
     // TODO: make it so
     
-    /* correct check and checkmate flags */
+    /* correct check and checkmate flags (move is still valid) */
     // TODO: make it so
     
     return result;
--- a/src/chess/rules.h	Tue Apr 01 10:28:08 2014 +0200
+++ b/src/chess/rules.h	Tue Apr 01 12:30:25 2014 +0200
@@ -95,6 +95,8 @@
     MoveList* lastmove;
 } GameState;
 
+#define opponent_color(color) ((color)==WHITE?BLACK:WHITE)
+
 #define POS_UNSPECIFIED UINT8_MAX
 #define mdst(b,m) b[(m)->torow][(m)->tofile]
 #define msrc(b,m) b[(m)->fromrow][(m)->fromfile]
@@ -140,6 +142,18 @@
 char getpiecechr(uint8_t piece);
 
 /**
+ * Checks, if a specified field is covered by a piece of a certain color.
+ * 
+ * @param gamestate the current game state
+ * @param row row of the field to check
+ * @param file file of the field to check
+ * @param color the color of the piece that should cover the field
+ * @return TRUE, if any piece of the specified color threatens the specified
+ * field (i.e. could capture an opponent piece)
+ */
+_Bool is_covered(GameState *gamestate,uint8_t row,uint8_t file,uint8_t color);
+
+/**
  * Evaluates a move syntactically and stores the move data in the specified
  * object.
  * 
--- a/src/game.c	Tue Apr 01 10:28:08 2014 +0200
+++ b/src/game.c	Tue Apr 01 12:30:25 2014 +0200
@@ -86,21 +86,26 @@
 
         if (logelem) {
             Move move = logelem->move;
-            char logstr[] = {
-                getpiecechr(move.piece),
-                filechr(move.fromfile), rowchr(move.fromrow),
-                move.capture ? 'x':'\0',
-                filechr(move.tofile), rowchr(move.torow),
-                move.check ? '+' : (move.checkmate ? '#' : 
-                    (move.promotion ? '=' : '\0')),
-                move.promotion ? getpiecechr(move.promotion) : '\0',
-                ' '
-            };
-            for (int stri = 0 ; stri < sizeof(logstr) ; stri++) {
-                if (logstr[stri]) {
-                    addch(logstr[stri]);
+            if ((move.piece&PIECE_MASK) == KING &&
+                abs(move.tofile-move.fromfile) == 2) {
+                addstr(move.tofile==fileidx('c')?"O-O-O":"O-O");
+            } else {
+                char logstr[] = {
+                    getpiecechr(move.piece),
+                    filechr(move.fromfile), rowchr(move.fromrow),
+                    move.capture ? 'x':'\0',
+                    filechr(move.tofile), rowchr(move.torow),
+                    move.check ? '+' : (move.checkmate ? '#' : 
+                        (move.promotion ? '=' : '\0')),
+                    move.promotion ? getpiecechr(move.promotion) : '\0'
+                };
+                for (int stri = 0 ; stri < sizeof(logstr) ; stri++) {
+                    if (logstr[stri]) {
+                        addch(logstr[stri]);
+                    }
                 }
             }
+            addch(' ');
             
             logelem = logelem->next;
         }
--- a/src/network.h	Tue Apr 01 10:28:08 2014 +0200
+++ b/src/network.h	Tue Apr 01 12:30:25 2014 +0200
@@ -45,8 +45,9 @@
 #define NETCODE_REMIS 0x22
 #define NETCODE_CHECK 0x23
 #define NETCODE_CHECKMATE 0x24
-    
-#define NETCODE_VERSION 6
+#define NETCODE_STALEMATE 0x25
+
+#define NETCODE_VERSION 7
 
 typedef struct {
     int fd; /* -1, if we are the client */

mercurial