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