src/chess/knight.c

changeset 19
6a26114297a1
parent 16
a298c6637c30
child 23
824c9522ce66
equal deleted inserted replaced
18:6008840b859e 19:6a26114297a1
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2014 Mike Becker. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #include "knight.h"
31 #include "rules.h"
32 #include <stdlib.h>
33
34 _Bool knight_chkrules(Move *move) {
35 int dx = abs(move->fromfile - move->tofile);
36 int dy = abs(move->fromrow - move->torow);
37
38 return (dx == 2 && dy == 1) || (dx == 1 && dy == 2);
39 }
40
41 static int knight_getloc_fixedrow(Board board, Move *move) {
42 int d = 3 - abs(move->fromrow - move->torow);
43
44 if (d == 1 || d == 2) {
45 if (move->tofile < 6 &&
46 board[move->fromrow][move->tofile + d] == move->piece) {
47 if (move->fromfile == POS_UNSPECIFIED) {
48 move->fromfile = move->tofile + d;
49 return VALID_MOVE_SYNTAX;
50 } else {
51 return AMBIGUOUS_MOVE;
52 }
53 }
54 if (move->tofile > 1 &&
55 board[move->fromrow][move->tofile - d] == move->piece) {
56 if (move->fromfile == POS_UNSPECIFIED) {
57 move->fromfile = move->tofile - d;
58 return VALID_MOVE_SYNTAX;
59 } else {
60 return AMBIGUOUS_MOVE;
61 }
62 }
63 }
64
65 return INVALID_POSITION;
66 }
67
68 static int knight_getloc_fixedfile(Board board, Move *move) {
69 int d = 3 - abs(move->fromfile - move->tofile);
70
71 if (d == 1 || d == 2) {
72 if (move->torow < 6 &&
73 board[move->torow + d][move->fromfile] == move->piece) {
74 if (move->fromrow == POS_UNSPECIFIED) {
75 move->fromrow = move->torow + d;
76 return VALID_MOVE_SYNTAX;
77 } else {
78 return AMBIGUOUS_MOVE;
79 }
80 }
81 if (move->torow > 1 &&
82 board[move->torow - d][move->fromfile] == move->piece) {
83 if (move->fromrow == POS_UNSPECIFIED) {
84 move->fromrow = move->torow - d;
85 return VALID_MOVE_SYNTAX;
86 } else {
87 return AMBIGUOUS_MOVE;
88 }
89 }
90 }
91
92 return INVALID_POSITION;
93 }
94
95 int knight_getlocation(Board board, Move *move) {
96
97 if (move->fromfile != POS_UNSPECIFIED) {
98 return knight_getloc_fixedfile(board, move);
99 }
100
101 if (move->fromrow != POS_UNSPECIFIED) {
102 return knight_getloc_fixedrow(board, move);
103 }
104
105 for (int x = -2 ; x <= 2 ; x++) {
106 if (x == 0) {
107 continue;
108 }
109 for (int y = -2 ; y <= 2 ; y++) {
110 if (y == 0 || y == x) {
111 continue;
112 }
113 uint8_t cx = move->tofile + x;
114 uint8_t cy = move->torow + y;
115
116 if (isidx(cx) && isidx(cy) && board[cy][cx] == move->piece) {
117 if (move->fromfile == POS_UNSPECIFIED
118 && move->fromrow == POS_UNSPECIFIED) {
119 move->fromfile = cx;
120 move->fromrow = cy;
121 } else {
122 return AMBIGUOUS_MOVE;
123 }
124 }
125 }
126 }
127
128 if (move->fromfile == POS_UNSPECIFIED || move->fromrow == POS_UNSPECIFIED) {
129 return INVALID_POSITION;
130 } else {
131 return VALID_MOVE_SYNTAX;
132 }
133 }

mercurial