1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/chess/knight.c Mon Mar 31 11:16:32 2014 +0200 1.3 @@ -0,0 +1,133 @@ 1.4 +/* 1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 + * 1.7 + * Copyright 2014 Mike Becker. All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions are met: 1.11 + * 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 1.15 + * 2. Redistributions in binary form must reproduce the above copyright 1.16 + * notice, this list of conditions and the following disclaimer in the 1.17 + * documentation and/or other materials provided with the distribution. 1.18 + * 1.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.29 + * POSSIBILITY OF SUCH DAMAGE. 1.30 + * 1.31 + */ 1.32 + 1.33 +#include "knight.h" 1.34 +#include "rules.h" 1.35 +#include <stdlib.h> 1.36 + 1.37 +_Bool knight_chkrules(Move *move) { 1.38 + int dx = abs(move->fromfile - move->tofile); 1.39 + int dy = abs(move->fromrow - move->torow); 1.40 + 1.41 + return (dx == 2 && dy == 1) || (dx == 1 && dy == 2); 1.42 +} 1.43 + 1.44 +static int knight_getloc_fixedrow(Board board, Move *move) { 1.45 + int d = 3 - abs(move->fromrow - move->torow); 1.46 + 1.47 + if (d == 1 || d == 2) { 1.48 + if (move->tofile < 6 && 1.49 + board[move->fromrow][move->tofile + d] == move->piece) { 1.50 + if (move->fromfile == POS_UNSPECIFIED) { 1.51 + move->fromfile = move->tofile + d; 1.52 + return VALID_MOVE_SYNTAX; 1.53 + } else { 1.54 + return AMBIGUOUS_MOVE; 1.55 + } 1.56 + } 1.57 + if (move->tofile > 1 && 1.58 + board[move->fromrow][move->tofile - d] == move->piece) { 1.59 + if (move->fromfile == POS_UNSPECIFIED) { 1.60 + move->fromfile = move->tofile - d; 1.61 + return VALID_MOVE_SYNTAX; 1.62 + } else { 1.63 + return AMBIGUOUS_MOVE; 1.64 + } 1.65 + } 1.66 + } 1.67 + 1.68 + return INVALID_POSITION; 1.69 +} 1.70 + 1.71 +static int knight_getloc_fixedfile(Board board, Move *move) { 1.72 + int d = 3 - abs(move->fromfile - move->tofile); 1.73 + 1.74 + if (d == 1 || d == 2) { 1.75 + if (move->torow < 6 && 1.76 + board[move->torow + d][move->fromfile] == move->piece) { 1.77 + if (move->fromrow == POS_UNSPECIFIED) { 1.78 + move->fromrow = move->torow + d; 1.79 + return VALID_MOVE_SYNTAX; 1.80 + } else { 1.81 + return AMBIGUOUS_MOVE; 1.82 + } 1.83 + } 1.84 + if (move->torow > 1 && 1.85 + board[move->torow - d][move->fromfile] == move->piece) { 1.86 + if (move->fromrow == POS_UNSPECIFIED) { 1.87 + move->fromrow = move->torow - d; 1.88 + return VALID_MOVE_SYNTAX; 1.89 + } else { 1.90 + return AMBIGUOUS_MOVE; 1.91 + } 1.92 + } 1.93 + } 1.94 + 1.95 + return INVALID_POSITION; 1.96 +} 1.97 + 1.98 +int knight_getlocation(Board board, Move *move) { 1.99 + 1.100 + if (move->fromfile != POS_UNSPECIFIED) { 1.101 + return knight_getloc_fixedfile(board, move); 1.102 + } 1.103 + 1.104 + if (move->fromrow != POS_UNSPECIFIED) { 1.105 + return knight_getloc_fixedrow(board, move); 1.106 + } 1.107 + 1.108 + for (int x = -2 ; x <= 2 ; x++) { 1.109 + if (x == 0) { 1.110 + continue; 1.111 + } 1.112 + for (int y = -2 ; y <= 2 ; y++) { 1.113 + if (y == 0 || y == x) { 1.114 + continue; 1.115 + } 1.116 + uint8_t cx = move->tofile + x; 1.117 + uint8_t cy = move->torow + y; 1.118 + 1.119 + if (isidx(cx) && isidx(cy) && board[cy][cx] == move->piece) { 1.120 + if (move->fromfile == POS_UNSPECIFIED 1.121 + && move->fromrow == POS_UNSPECIFIED) { 1.122 + move->fromfile = cx; 1.123 + move->fromrow = cy; 1.124 + } else { 1.125 + return AMBIGUOUS_MOVE; 1.126 + } 1.127 + } 1.128 + } 1.129 + } 1.130 + 1.131 + if (move->fromfile == POS_UNSPECIFIED || move->fromrow == POS_UNSPECIFIED) { 1.132 + return INVALID_POSITION; 1.133 + } else { 1.134 + return VALID_MOVE_SYNTAX; 1.135 + } 1.136 +}