1/*
2    Sjeng - a chess variants playing program
3    Copyright (C) 2000 Gian-Carlo Pascutto
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19    File: crazy.c
20    Purpose: bughouse/crazyhouse specific functions
21
22*/
23
24#include <assert.h>
25#include "sjeng.h"
26#include "protos.h"
27#include "extvars.h"
28
29int holding[2][16];
30int num_holding[2];
31
32char realholdings[255];
33int userealholdings;
34
35int drop_piece;
36
37int white_hand_eval;
38int black_hand_eval;
39
40uint32_t hold_hash;
41
42#define HHash(x,y)  (hold_hash ^= zobrist[(x)][(y)])
43
44/* input example : holding [BPPP] [QR] */
45/* based on db's parser */
46void ProcessHoldings(char str[])
47{
48  int c, i;
49
50  i = 0;
51
52  memset(holding, 0, sizeof(holding));
53  hold_hash = 0xC0FFEE00;
54
55  white_hand_eval = 0;
56  black_hand_eval = 0;
57  reset_ecache();
58
59  num_holding[WHITE] = 0;
60  num_holding[BLACK] = 0;
61
62  for(c = WHITE; c <= BLACK; c++)
63    {
64      while(str[i++] != '[')
65	if(str[i] == 0) return;
66
67      while(str[i] != ']') {
68	switch(str[i++]) {
69	case 'p':
70	case 'P':
71	  holding[c][c == WHITE ? wpawn : bpawn]++;
72	  num_holding[c]++;
73	  HHash((c == WHITE ? wpawn : bpawn),
74		holding[c][(c == WHITE ? wpawn : bpawn)]);
75	  break;
76	case 'q':
77	case 'Q':
78	  holding[c][c == WHITE ? wqueen : bqueen]++;
79	  num_holding[c]++;
80	  HHash((c == WHITE ? wqueen : bqueen),
81		holding[c][(c == WHITE ? wqueen : bqueen)]);
82	  break;
83	case 'r':
84	case 'R':
85	  holding[c][c == WHITE ? wrook : brook]++;
86	  num_holding[c]++;
87	  HHash((c == WHITE ? wrook : brook),
88		holding[c][(c == WHITE ? wrook : brook)]);
89	  break;
90	case 'b':
91	case 'B':
92	  holding[c][c == WHITE ? wbishop : bbishop]++;
93	  num_holding[c]++;
94	  HHash((c == WHITE ? wbishop : bbishop),
95		holding[c][(c == WHITE ? wbishop : bbishop)]);
96	  break;
97	case 'n':
98	case 'N':
99	  holding[c][c == WHITE ? wknight : bknight]++;
100	  num_holding[c]++;
101	  HHash((c == WHITE ? wknight : bknight),
102		holding[c][(c == WHITE ? wknight : bknight)]);
103	  break;
104	default:
105	  return;
106	}
107      }
108    }
109
110  /* no fake pieces in crazyhouse! */
111  if (Variant == Bughouse && !userealholdings)
112    {
113      strncpy(realholdings, str, 200);
114
115      if (comp_color == 1)
116	{
117	  /* computer is white*/
118	  if (holding[BLACK][bpawn] == 0)
119	    {
120	      holding[BLACK][bpawn]++;
121	      num_holding[BLACK]++;
122	      HHash(bpawn, holding[BLACK][bpawn]);
123	    }
124	  if (holding[BLACK][bbishop] == 0)
125	    {
126	      holding[BLACK][bbishop]++;
127	      num_holding[BLACK]++;
128	      HHash(bpawn, holding[BLACK][bbishop]);
129	    }
130	  if (holding[BLACK][bknight] == 0)
131	  {
132	    holding[BLACK][bknight]++;
133	    num_holding[BLACK]++;
134	    HHash(bknight, holding[BLACK][bknight]);
135	  }
136	  if (holding[BLACK][brook] == 0)
137	  {
138	    holding[BLACK][brook]++;
139	    num_holding[BLACK]++;
140	    HHash(bknight, holding[BLACK][brook]);
141	  }
142	  if (holding[BLACK][bqueen] == 0)
143	  {
144	    holding[BLACK][bqueen]++;
145	    num_holding[BLACK]++;
146	    HHash(bknight, holding[BLACK][bqueen]);
147	  }
148	}
149      else
150	{
151	  /* computer is black*/
152	  if (holding[WHITE][wqueen] == 0)
153	  {
154	    holding[WHITE][wqueen]++;
155	    num_holding[WHITE]++;
156	    HHash(wqueen, holding[WHITE][wqueen]);
157	  }
158	  if (holding[WHITE][wrook] == 0)
159	  {
160	    holding[WHITE][wrook]++;
161	    num_holding[WHITE]++;
162	    HHash(wqueen, holding[WHITE][wrook]);
163	  }
164	  if (holding[WHITE][wbishop] == 0)
165	  {
166	    holding[WHITE][wbishop]++;
167	    num_holding[WHITE]++;
168	    HHash(wqueen, holding[WHITE][wbishop]);
169	  }
170	  if (holding[WHITE][wknight] == 0)
171	  {
172	    holding[WHITE][wknight]++;
173	    num_holding[WHITE]++;
174	    HHash(wqueen, holding[WHITE][wknight]);
175	  }
176	  if (holding[WHITE][wpawn] == 0)
177	  {
178	    holding[WHITE][wpawn]++;
179	    num_holding[WHITE]++;
180	    HHash(wqueen, holding[WHITE][wpawn]);
181	  }
182	}
183    }
184}
185
186int text_to_piece(char txt, int who)
187{
188  switch(txt)
189    {
190    case 'p':
191    case 'P':
192      return (who == WHITE ? wpawn : bpawn);
193    case 'b':
194    case 'B':
195      return (who == WHITE ? wbishop : bbishop);
196    case 'n':
197    case 'N':
198      return (who == WHITE ? wknight : bknight);
199    case 'r':
200    case 'R':
201      return (who == WHITE ? wrook : brook);
202    case 'q':
203    case 'Q':
204      return (who == WHITE ? wqueen : bqueen);
205    };
206
207  return npiece;
208}
209
210int SwitchColor(int piece)
211{
212  int t[] = { 0, bpawn, wpawn, bknight, wknight, 0, 0, brook, wrook, bqueen, wqueen, bbishop, wbishop };
213
214  assert(piece > frame  && piece < npiece);
215
216  return(t[piece]);
217}
218
219int SwitchPromoted(int piece)
220{
221  int t[] = { 0, bpawn, wpawn, bpawn, wpawn, 0, 0, bpawn, wpawn, bpawn, wpawn, bpawn, wpawn };
222
223  assert(piece > frame && piece < npiece);
224
225  return(t[piece]);
226}
227
228void addHolding(int what, int who)
229{
230
231  if (Variant == Crazyhouse)
232    {
233
234      holding[who][what]++;
235
236      num_holding[who]++;
237
238      HHash(what, holding[who][what]);
239
240    };
241
242  if (who == WHITE)
243    white_hand_eval += hand_value[what];
244  else
245    black_hand_eval += hand_value[what];
246
247  Material += material[what];
248
249  return;
250
251}
252
253void removeHolding(int what, int who)
254{
255
256  if (Variant == Crazyhouse)
257    {
258
259      assert(holding[who][what] > 0);
260      assert(holding[who][what] < 20);
261
262      HHash(what, holding[who][what]);
263
264      holding[who][what]--;
265
266      num_holding[who]--;
267
268    }
269
270  if (who == WHITE)
271  	white_hand_eval -= hand_value[what];
272  else
273    	black_hand_eval -= hand_value[what];
274
275  Material -= material[what];
276
277  return;
278
279}
280
281void DropaddHolding(int what, int who)
282{
283  holding[who][what]++;
284
285  num_holding[who]++;
286
287  HHash(what, holding[who][what]);
288
289  if (who == WHITE)
290    white_hand_eval += hand_value[what];
291  else
292    black_hand_eval += hand_value[what];
293
294  Material += material[what];
295
296  return;
297}
298
299void DropremoveHolding(int what, int who)
300{
301  assert(holding[who][what] > 0);
302
303  assert(holding[who][what] < 20);
304
305  HHash(what, holding[who][what]);
306
307  holding[who][what]--;
308
309  num_holding[who]--;
310
311  if (who == WHITE)
312      white_hand_eval -= hand_value[what];
313  else
314      black_hand_eval -= hand_value[what];
315
316  Material -= material[what];
317
318  return;
319}
320
321void printHolding(void)
322{
323
324  printf("WP: %d WR: %d WB: %d WN: %d WQ: %d\n",
325	 holding[WHITE][wpawn], holding[WHITE][wrook],
326	 holding[WHITE][wbishop],
327	 holding[WHITE][wknight], holding[WHITE][wqueen]);
328
329  printf("BP: %d BR: %d BB: %d BN: %d BQ: %d\n",
330	 holding[BLACK][bpawn], holding[BLACK][brook],
331	 holding[BLACK][bbishop],
332	 holding[BLACK][bknight], holding[BLACK][bqueen]);
333
334}
335