1 #include "chess.h"
2 #include "data.h"
3 /* last modified 05/08/14 */
4 /*
5 *******************************************************************************
6 * *
7 * Edit() is used to edit (alter) the current board position. It clears the *
8 * board and then allows the operator to enter a position using the syntax *
9 * defined by the xboard/winboard "edit" command. *
10 * *
11 * White sets the color of pieces added to white. This color will stay in *
12 * effect until specifically changed. *
13 * *
14 * Black sets the color of pieces added to black. This color will stay in *
15 * effect until specifically changed. *
16 * *
17 * # clears the chessboard completely. *
18 * *
19 * C changes (toggles) the color of pieces being placed on the board. *
20 * *
21 * End (or . for ICS/Xboard) terminates Edit(). *
22 * *
23 * Pieces are placed on the board by three character "commands" of the form *
24 * [piece][square] where piece is a member of the normal set of pieces *
25 * {P,N,B,R,Q,K} and [square] is algebraic square notation (a1-h8). Ex: Ke8 *
26 * puts a king (of the current "color") on square e8. *
27 * *
28 *******************************************************************************
29 */
Edit(void)30 void Edit(void) {
31 int athome = 1, i, piece, readstat, square, tfile, trank, wtm = 1, error =
32 0;
33 static const char pieces[] =
34 { 'x', 'X', 'P', 'p', 'N', 'n', 'B', 'b', 'R', 'r',
35 'Q', 'q', 'K', 'k', '\0'
36 };
37 TREE *const tree = block[0];
38
39 /*
40 ************************************************************
41 * *
42 * Process the commands to set the board[n] form of the *
43 * chess position. *
44 * *
45 ************************************************************
46 */
47 while (FOREVER) {
48 if ((input_stream == stdin) && !xboard) {
49 if (wtm)
50 printf("edit(white): ");
51 else
52 printf("edit(black): ");
53 }
54 fflush(stdout);
55 readstat = Read(1, buffer);
56 if (readstat < 0)
57 return;
58 nargs = ReadParse(buffer, args, " \t;");
59 if (xboard)
60 Print(32, "edit.command:%s\n", args[0]);
61 if (!strcmp(args[0], "white"))
62 wtm = 1;
63 else if (!strcmp(args[0], "black"))
64 wtm = 0;
65 if (!strcmp(args[0], "#"))
66 for (i = 0; i < 64; i++)
67 PcOnSq(i) = 0;
68 else if (!strcmp(args[0], "c"))
69 wtm = Flip(wtm);
70 else if (!strcmp(args[0], "end") || (!strcmp(args[0], ".")))
71 break;
72 else if (!strcmp(args[0], "d"))
73 DisplayChessBoard(stdout, tree->position);
74 else if (strlen(args[0]) == 3) {
75 if (strchr(pieces, args[0][0])) {
76 piece = (strchr(pieces, args[0][0]) - pieces) >> 1;
77 tfile = args[0][1] - 'a';
78 trank = args[0][2] - '1';
79 square = (trank << 3) + tfile;
80 if ((square < 0) || (square > 63))
81 printf("unrecognized square %s\n", args[0]);
82 if (wtm)
83 PcOnSq(square) = piece;
84 else
85 PcOnSq(square) = -piece;
86 }
87 } else if (strlen(args[0]) == 2) {
88 piece = pawn;
89 tfile = args[0][0] - 'a';
90 trank = args[0][1] - '1';
91 square = (trank << 3) + tfile;
92 if ((square < 0) || (square > 63))
93 printf("unrecognized square %s\n", args[0]);
94 if (wtm)
95 PcOnSq(square) = piece;
96 else
97 PcOnSq(square) = -piece;
98 } else
99 printf("unrecognized piece %s\n", args[0]);
100 }
101 /*
102 ************************************************************
103 * *
104 * Now, if a king is on its original square, check the *
105 * rooks to see if they are and set the castle status *
106 * accordingly. Note that this checks for pieces on the *
107 * original rank, but not their original squares (ICS *
108 * "wild" games) and doesn't set castling if true. *
109 * *
110 * The winboard/xboard "edit" command does not give us a *
111 * way of setting castling status, so we have to guess. *
112 * *
113 ************************************************************
114 */
115 Castle(0, white) = 0;
116 Castle(0, black) = 0;
117 EnPassant(0) = 0;
118 for (i = 0; i < 16; i++)
119 if (PcOnSq(i) == 0 || PcOnSq(i + 48) == 0)
120 athome = 0;
121 if (!athome || (PcOnSq(A1) == rook && PcOnSq(B1) == knight &&
122 PcOnSq(C1) == bishop && PcOnSq(D1) == queen && PcOnSq(E1) == king &&
123 PcOnSq(F1) == bishop && PcOnSq(G1) == knight && PcOnSq(H1) == rook
124 && PcOnSq(A8) == -rook && PcOnSq(B8) == -knight &&
125 PcOnSq(C8) == -bishop && PcOnSq(D8) == -queen && PcOnSq(E8) == -king
126 && PcOnSq(F8) == -bishop && PcOnSq(G8) == -knight &&
127 PcOnSq(H8) == -rook)) {
128 if (PcOnSq(E1) == king) {
129 if (PcOnSq(A1) == rook)
130 Castle(0, white) = Castle(0, white) | 2;
131 if (PcOnSq(H1) == rook)
132 Castle(0, white) = Castle(0, white) | 1;
133 }
134 if (PcOnSq(E8) == -king) {
135 if (PcOnSq(A8) == -rook)
136 Castle(0, black) = Castle(0, black) | 2;
137 if (PcOnSq(H8) == -rook)
138 Castle(0, black) = Castle(0, black) | 1;
139 }
140 }
141 /*
142 ************************************************************
143 * *
144 * Basic board is now set. Now it's time to set the bit *
145 * board representation correctly. *
146 * *
147 ************************************************************
148 */
149 SetChessBitBoards(tree);
150 error += InvalidPosition(tree);
151 if (!error) {
152 if (log_file)
153 DisplayChessBoard(log_file, tree->position);
154 wtm = 1;
155 move_number = 1;
156 rep_index = 0;
157 tree->rep_list[0] = HashKey;
158 Reversible(0) = 0;
159 moves_out_of_book = 0;
160 } else {
161 InitializeChessBoard(tree);
162 Print(4095, "Illegal position, using normal initial chess position\n");
163 }
164 }
165