implemented bishop rules

Sat, 29 Mar 2014 14:46:33 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 29 Mar 2014 14:46:33 +0100
changeset 17
2aed5418e142
parent 16
a298c6637c30
child 18
6008840b859e

implemented bishop rules

src/game.c file | annotate | diff | comparison | revisions
src/rules/bishop.c file | annotate | diff | comparison | revisions
--- a/src/game.c	Fri Mar 28 14:32:52 2014 +0100
+++ b/src/game.c	Sat Mar 29 14:46:33 2014 +0100
@@ -232,7 +232,7 @@
     memset(move, 0, sizeof(Move));
     move->fromfile = POS_UNSPECIFIED;
     move->fromrow = POS_UNSPECIFIED;
-    
+    // TODO: promotion
     size_t len = strlen(mstr);
     
     /* evaluate check/checkmate flags */
--- a/src/rules/bishop.c	Fri Mar 28 14:32:52 2014 +0100
+++ b/src/rules/bishop.c	Sat Mar 29 14:46:33 2014 +0100
@@ -29,18 +29,100 @@
 
 #include "bishop.h"
 #include "rules.h"
+#include <math.h>
 
 _Bool bishop_chkrules(Move* move) {
-    // TODO: implement
-    return FALSE;
+    return abs(move->torow-move->fromrow) == abs(move->tofile-move->fromfile);
 }
 
 _Bool bishop_isblocked(Board board, Move *move) {
-    // TODO: implement
-    return TRUE;
+    int dy = move->torow > move->fromrow ? 1 : -1;
+    int dx = move->tofile > move->fromfile ? 1 : -1;
+    
+    uint8_t y = move->fromrow;
+    uint8_t x = move->fromfile;
+    
+    do {
+        x += dx;
+        y += dy;
+        if (board[y][x]) {
+            return TRUE;
+        }
+    } while (x != move->tofile && y != move->torow);
+    
+    return FALSE;
+}
+
+static int bishop_getloc_fixedfile(Board board, Move *move) {
+    uint8_t d = abs(move->fromfile - move->tofile);
+    if (board[move->torow - d][move->fromfile] == move->piece) {
+        move->fromrow = move->torow - d;
+    }
+    if (board[move->torow + d][move->fromfile] == move->piece) {
+        if (move->fromrow == POS_UNSPECIFIED) {
+            move->fromrow = move->torow + d;
+        } else {
+            return AMBIGUOUS_MOVE; /* rare situation after promotion */
+        }
+    }
+    return move->fromrow == POS_UNSPECIFIED ?
+        INVALID_POSITION : VALID_MOVE_SYNTAX;
+}
+
+static int bishop_getloc_fixedrow(Board board, Move *move) {
+    uint8_t d = abs(move->fromrow - move->torow);
+    if (board[move->fromrow][move->tofile - d] == move->piece) {
+        move->fromfile = move->tofile - d;
+    }
+    if (board[move->fromrow][move->tofile + d] == move->piece) {
+        if (move->fromfile == POS_UNSPECIFIED) {
+            move->fromfile = move->tofile + d;
+        } else {
+            return AMBIGUOUS_MOVE; /* rare situation after promotion */
+        }
+    }
+    return move->fromfile == POS_UNSPECIFIED ?
+        INVALID_POSITION : VALID_MOVE_SYNTAX;
 }
 
 int bishop_getlocation(Board board, Move *move) {
-    // TODO: implement
-    return INVALID_MOVE_SYNTAX;
+    
+    if (move->fromfile != POS_UNSPECIFIED) {
+        return bishop_getloc_fixedfile(board, move);
+    }
+    
+    if (move->fromrow != POS_UNSPECIFIED) {
+        return bishop_getloc_fixedrow(board, move);
+    }
+    
+    _Bool amb = FALSE;
+    for (int d = -7 ; d < 8  ; d++) {
+        uint8_t row = move->torow + d;
+        if (isidx(row)) {
+            uint8_t file = move->tofile + d;
+            if (isidx(file) && board[row][file] == move->piece) {
+                if (amb) {
+                    return AMBIGUOUS_MOVE;
+                }
+                amb = TRUE;
+                move->fromrow = row;
+                move->fromfile = file;
+            }
+            file = move->tofile - d;
+            if (isfile(file) && board[row][file] == move->piece) {
+                if (amb) {
+                    return AMBIGUOUS_MOVE;
+                }
+                amb = TRUE;
+                move->fromrow = row;
+                move->fromfile = file;
+            }
+        }
+    }
+    
+    if (move->fromrow == POS_UNSPECIFIED || move->fromfile == POS_UNSPECIFIED) {
+        return INVALID_POSITION;
+    } else {
+        return VALID_MOVE_SYNTAX;
+    }
 }

mercurial