khetai 0.2.3 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,33 +1,50 @@
1
- #include <stdio.h>
1
+ #include "khetai_lib.h"
2
2
  #include <ctype.h>
3
+ #include <stdio.h>
3
4
  #include <stdlib.h>
4
- #include <time.h>
5
- #include "khetai_lib.h"
6
5
 
7
6
  int max_time;
8
7
  time_t start_time;
9
8
 
10
- Square board[120] = {0};
11
- int pharaoh_loc[2] = {0};
12
- enum Player whose_turn;
13
- enum Player starter;
14
- int initial_depth = 0;
9
+ static Square board[120] = {0};
10
+ static int pharaoh_loc[2] = {0};
11
+ static enum Player whose_turn;
12
+ static enum Player starter;
13
+ static int initial_depth = 0;
15
14
 
16
- Move undo_moves[MAX_DEPTH] = {0};
17
- int undo_capture_indices[MAX_DEPTH] = {0};
18
- Square undo_capture_squares[MAX_DEPTH] = {0};
15
+ static Move undo_moves[MAX_DEPTH] = {0};
16
+ static int undo_capture_indices[MAX_DEPTH] = {0};
17
+ static Square undo_capture_squares[MAX_DEPTH] = {0};
19
18
 
20
- HashEntry table[TABLE_SIZE] = {0};
21
- uint64_t hashes[MAX_DEPTH] = {0};
22
- uint64_t keys[0xFF][120] = {0};
23
- uint64_t turn_key = 0;
24
-
25
- int undo_index = 0;
26
- int move_num = 0;
27
- bool checkmate = false;
19
+ PieceTracker piece_trackers[2] = {0};
28
20
 
29
- Move alphabeta_root(int depth, enum Player player)
30
- {
21
+ HashEntry table[TABLE_SIZE] = {0};
22
+ static uint64_t hashes[MAX_DEPTH] = {0};
23
+ static uint64_t keys[0xFF][120] = {0};
24
+ static uint64_t turn_key = 0;
25
+
26
+ static int undo_index = 0;
27
+ static int hashes_index = 0;
28
+ static bool checkmate = false;
29
+
30
+ static int alphabeta(int depth, enum Player player, int alpha, int beta);
31
+ static void insert_table(HashEntry *entry, uint64_t key, int depth, int flag, int score, Move move);
32
+ static int calculate_score(void);
33
+ static int distance_from_pharaoh(int i, int p);
34
+ static void fire_laser(uint64_t *hash);
35
+ static void undo_move();
36
+ static void find_valid_moves(Move *valid_moves, int *vi);
37
+ static void find_valid_anubis_pyramid_moves(int i, Move *valid_moves, int *vi);
38
+ static void find_valid_scarab_moves(int i, Move *valid_moves, int *vi);
39
+ static void find_valid_pharaoh_moves(int i, Move *valid_moves, int *vi);
40
+ static void find_valid_sphinx_moves(int i, Move *valid_moves, int *vi);
41
+ static uint64_t get_board_hash();
42
+ static void init_piece_trackers();
43
+ static bool is_move_legal(Move move);
44
+ static Square str_to_square(char *str);
45
+ static void print_piece(Square s);
46
+
47
+ Move alphabeta_root(int depth, enum Player player) {
31
48
  whose_turn = player;
32
49
  starter = player;
33
50
  initial_depth = depth;
@@ -38,16 +55,14 @@ Move alphabeta_root(int depth, enum Player player)
38
55
  Move valid_moves[NUM_VALID_MOVES] = {0};
39
56
  int vi = 0;
40
57
  find_valid_moves(valid_moves, &vi);
41
- for (int i = 0; i < NUM_VALID_MOVES; i++)
42
- {
58
+ for (int i = 0; i < NUM_VALID_MOVES; i++) {
43
59
  if (valid_moves[i] == 0)
44
60
  break;
45
61
  make_move(valid_moves[i]);
46
62
  int score = -alphabeta(depth - 1, opposite_player(player), -beta, -alpha);
47
63
  undo_move();
48
64
  whose_turn = player;
49
- if (score > best_score)
50
- {
65
+ if (score > best_score) {
51
66
  best_score = score;
52
67
  best_move = valid_moves[i];
53
68
  }
@@ -62,12 +77,10 @@ Move alphabeta_root(int depth, enum Player player)
62
77
  return best_move;
63
78
  }
64
79
 
65
- int alphabeta(int depth, enum Player player, int alpha, int beta)
66
- {
80
+ int alphabeta(int depth, enum Player player, int alpha, int beta) {
67
81
  whose_turn = player;
68
- if (depth == 0 || checkmate)
69
- {
70
- return player == Red ? calculate_score() : -calculate_score();
82
+ if (depth == 0 || checkmate) {
83
+ return player == RED ? calculate_score() : -calculate_score();
71
84
  }
72
85
 
73
86
  int alpha_orig = alpha;
@@ -75,43 +88,33 @@ int alphabeta(int depth, enum Player player, int alpha, int beta)
75
88
  int vi = 0;
76
89
 
77
90
  int table_depth = initial_depth - depth;
78
- HashEntry *entry = search_table(hashes[move_num]);
79
- if (entry->key == hashes[move_num] && entry->depth > table_depth)
80
- {
91
+ HashEntry *entry = search_table(hashes[hashes_index]);
92
+ if (entry->key == hashes[hashes_index] && entry->depth > table_depth && is_move_legal(entry->move)) {
93
+ valid_moves[vi++] = entry->move;
94
+
81
95
  if (entry->flag == EXACT)
82
96
  return entry->score;
83
- else if (entry->flag == ALPHA)
84
- {
85
- if (entry->score > alpha)
86
- alpha = entry->score;
87
- }
88
- else
89
- {
90
- if (entry->score < beta)
91
- beta = entry->score;
92
- }
97
+ else if (entry->flag == LOWERBOUND && entry->score > alpha)
98
+ alpha = entry->score;
99
+ else if (entry->flag == UPPERBOUND && entry->score < beta)
100
+ beta = entry->score;
93
101
 
94
102
  if (alpha >= beta)
95
103
  return entry->score;
96
-
97
- if (is_move_legal(entry->move))
98
- valid_moves[vi++] = entry->move;
99
104
  }
100
105
 
101
106
  find_valid_moves(valid_moves, &vi);
102
107
  int best_score = -MAX_SCORE;
103
108
  Move best_move = (Move)0;
104
109
 
105
- for (int i = 0; (i < NUM_VALID_MOVES && (time(NULL) - start_time < max_time)); i++)
106
- {
110
+ for (int i = 0; (i < NUM_VALID_MOVES && (time(NULL) - start_time < max_time)); i++) {
107
111
  if (valid_moves[i] == 0)
108
112
  break;
109
113
  make_move(valid_moves[i]);
110
114
  int score = -alphabeta(depth - 1, opposite_player(player), -beta, -alpha);
111
115
  undo_move();
112
116
  whose_turn = player;
113
- if (score > best_score)
114
- {
117
+ if (score > best_score) {
115
118
  best_score = score;
116
119
  best_move = valid_moves[i];
117
120
  }
@@ -123,30 +126,16 @@ int alphabeta(int depth, enum Player player, int alpha, int beta)
123
126
 
124
127
  int flag = EXACT;
125
128
  if (best_score <= alpha_orig)
126
- flag = BETA;
129
+ flag = UPPERBOUND;
127
130
  else if (best_score >= beta)
128
- flag = ALPHA;
131
+ flag = LOWERBOUND;
129
132
 
130
-
131
- insert_table(entry, hashes[move_num], table_depth, flag, best_score, best_move);
133
+ insert_table(entry, hashes[hashes_index], table_depth, flag, best_score, best_move);
132
134
  return best_score;
133
135
  }
134
136
 
135
- void insert_table(HashEntry *entry, uint64_t key, int table_depth, int flag, int score, Move move)
136
- {
137
- if (entry->key != 0)
138
- {
139
- if (table_depth > entry->depth)
140
- {
141
- entry->key = key;
142
- entry->depth = table_depth;
143
- entry->flag = flag;
144
- entry->score = score;
145
- entry->move = move;
146
- }
147
- }
148
- else
149
- {
137
+ void insert_table(HashEntry *entry, uint64_t key, int table_depth, int flag, int score, Move move) {
138
+ if (entry->key == 0 || table_depth > entry->depth) {
150
139
  entry->key = key;
151
140
  entry->depth = table_depth;
152
141
  entry->flag = flag;
@@ -155,47 +144,47 @@ void insert_table(HashEntry *entry, uint64_t key, int table_depth, int flag, int
155
144
  }
156
145
  }
157
146
 
158
- int calculate_score()
159
- {
147
+ int calculate_score() {
160
148
  int score = 0;
161
149
  int anubis_score = 800;
162
150
  int pyramid_score = 1000;
163
151
  int pharaoh_score = 100000;
164
- for (int i = 0; i < 120; i++)
165
- {
166
- Square s = board[i];
167
- if (is_piece(s))
168
- {
169
- int value = 0;
170
- switch (get_piece(s))
171
- {
172
- case Anubis:
173
- value += anubis_score;
174
- value -= distance_from_pharaoh(i, pharaoh_loc[get_owner(s)]) * 10;
175
- break;
176
- case Pyramid:
177
- value += pyramid_score;
178
- value += rand() % 20;
179
- break;
180
- case Scarab:
181
- int max_distance = 16;
182
- int base_score = 1000;
183
- value += (max_distance - distance_from_pharaoh(i, pharaoh_loc[opposite_player(get_owner(s))])) * base_score / max_distance;
184
- break;
185
- case Pharaoh:
186
- value += pharaoh_score;
187
- break;
188
- default:
189
- break;
152
+
153
+ for (int j = 0; j < 2; j++) {
154
+ enum Player player = j;
155
+ for (int k = 0; k < 13; k++) {
156
+ int i = get_board_index(player, k);
157
+ if (i != EPT) {
158
+ Square s = board[i];
159
+ int value = 0;
160
+ switch (get_piece(s)) {
161
+ case ANUBIS:
162
+ value += anubis_score;
163
+ value -= distance_from_pharaoh(i, pharaoh_loc[player]) * 10;
164
+ break;
165
+ case PYRAMID:
166
+ value += pyramid_score;
167
+ value += (rand() % 51) - 25;
168
+ break;
169
+ case SCARAB:
170
+ int max_distance = 16;
171
+ int base_score = 1000;
172
+ value += (max_distance - distance_from_pharaoh(i, pharaoh_loc[opposite_player(player)])) * base_score / max_distance;
173
+ break;
174
+ case PHARAOH:
175
+ value += pharaoh_score;
176
+ break;
177
+ default:
178
+ break;
179
+ }
180
+ score += get_owner(s) == RED ? value : -value;
190
181
  }
191
- score += get_owner(s) == Red ? value : -value;
192
182
  }
193
183
  }
194
184
  return score;
195
185
  }
196
186
 
197
- int distance_from_pharaoh(int i, int p)
198
- {
187
+ int distance_from_pharaoh(int i, int p) {
199
188
  int px = p / 12;
200
189
  int py = p % 12;
201
190
  int ix = i / 12;
@@ -204,9 +193,8 @@ int distance_from_pharaoh(int i, int p)
204
193
  return m_distance;
205
194
  }
206
195
 
207
- void make_move(Move move)
208
- {
209
- uint64_t hash = hashes[move_num++];
196
+ void make_move(Move move) {
197
+ uint64_t hash = hashes[hashes_index++];
210
198
 
211
199
  int start = get_start(move);
212
200
  // remove starting piece
@@ -214,15 +202,12 @@ void make_move(Move move)
214
202
  int end = get_end(move);
215
203
  int rotation = get_rotation(move);
216
204
 
217
- if (rotation != 0)
218
- {
205
+ if (rotation != 0) {
219
206
  board[start] = rotate(board[start], rotation);
220
207
  // add starting piece back with rotation
221
208
  hash ^= keys[board[start]][start];
222
- }
223
- else
224
- {
225
- // remove ending piece if swapping
209
+ } else {
210
+ // remove ending piece
226
211
  if (is_piece(board[end]))
227
212
  hash ^= keys[board[end]][end];
228
213
 
@@ -232,11 +217,18 @@ void make_move(Move move)
232
217
  // add starting piece to end location
233
218
  hash ^= keys[board[end]][end];
234
219
 
220
+ enum Player moving_player = get_owner(moving_piece);
221
+ update_piece_tracker(moving_player, start, end);
222
+
235
223
  // add ending piece to start location if swapping
236
- if (is_piece(board[start]))
224
+ if (is_piece(board[start])) {
237
225
  hash ^= keys[board[start]][start];
238
226
 
239
- if (get_piece(moving_piece) == Pharaoh)
227
+ enum Player other_player = get_owner(board[start]);
228
+ update_piece_tracker(other_player, end, start);
229
+ }
230
+
231
+ if (get_piece(moving_piece) == PHARAOH)
240
232
  pharaoh_loc[get_owner(moving_piece)] = end;
241
233
  }
242
234
 
@@ -248,65 +240,60 @@ void make_move(Move move)
248
240
  // testing that hashing works properly
249
241
  // printf("\nHASH:\t%lu\nBOARD:\t%lu\n", hash, get_board_hash());
250
242
 
251
- hashes[move_num] = hash;
243
+ hashes[hashes_index] = hash;
252
244
  undo_index++;
253
245
  }
254
246
 
255
- void fire_laser(uint64_t *hash)
256
- {
247
+ void fire_laser(uint64_t *hash) {
257
248
  int i = sphinx_loc[whose_turn];
258
249
  int laser_dir = get_orientation(board[i]);
259
250
  bool traversing = true;
260
- while (traversing)
261
- {
251
+ while (traversing) {
262
252
  i = i + directions[laser_dir];
263
- if (i >= 0 && i < 120 && on_board[i] == 1)
264
- {
253
+ if (i >= 0 && i < 120 && on_board[i] == 1) {
265
254
  Square s = board[i];
266
- if (is_piece(s))
267
- {
255
+ if (is_piece(s)) {
268
256
  int piece = get_piece(s) - 1;
269
257
  int orientation = get_orientation(s);
270
258
  int result = reflections[laser_dir][piece][orientation];
271
- if (result == Dead)
272
- {
273
- if (get_piece(s) == Pharaoh)
259
+ if (result == DEAD) {
260
+ if (get_piece(s) == PHARAOH)
274
261
  checkmate = true;
275
262
  // remove piece
276
263
  *hash ^= keys[s][i];
264
+
265
+ enum Player remove_player = get_owner(s);
266
+ remove_from_piece_tracker(remove_player, i);
267
+
277
268
  undo_capture_indices[undo_index] = i;
278
269
  undo_capture_squares[undo_index] = s;
279
270
  board[i] = (Square)0;
280
271
  traversing = false;
281
- }
282
- else if (result == Absorbed)
283
- {
272
+ } else if (result == ABSORBED) {
284
273
  traversing = false;
285
- }
286
- else
287
- {
274
+ } else {
288
275
  laser_dir = result;
289
276
  }
290
277
  }
291
- }
292
- else
293
- {
278
+ } else {
294
279
  traversing = false;
295
280
  }
296
281
  }
297
282
  }
298
283
 
299
- void undo_move()
300
- {
301
- move_num--;
284
+ void undo_move() {
285
+ hashes_index--;
302
286
  undo_index--;
303
287
 
304
288
  Square captured = (Square)undo_capture_squares[undo_index];
305
289
  undo_capture_squares[undo_index] = 0;
306
- if (captured > 0)
307
- {
308
- board[undo_capture_indices[undo_index]] = captured;
290
+ if (captured > 0) {
291
+ uint8_t board_pos = undo_capture_indices[undo_index];
292
+ board[board_pos] = captured;
309
293
  undo_capture_indices[undo_index] = 0;
294
+
295
+ enum Player captured_player = get_owner(captured);
296
+ add_to_piece_tracker(captured_player, board_pos);
310
297
  }
311
298
 
312
299
  Move move = undo_moves[undo_index];
@@ -315,47 +302,47 @@ void undo_move()
315
302
  int end = get_end(move);
316
303
  int rotation = get_rotation(move);
317
304
 
318
- if (rotation != 0)
319
- {
305
+ if (rotation != 0) {
320
306
  board[start] = rotate(board[start], rotation);
321
- }
322
- else
323
- {
307
+ } else {
324
308
  Square moving_piece = board[start];
325
309
  board[start] = board[end];
326
310
  board[end] = moving_piece;
327
311
 
328
- if (get_piece(moving_piece) == Pharaoh)
312
+ enum Player moving_player = get_owner(moving_piece);
313
+ update_piece_tracker(moving_player, start, end);
314
+
315
+ if (board[start] != 0) {
316
+ enum Player other_player = get_owner(board[start]);
317
+ update_piece_tracker(other_player, end, start);
318
+ }
319
+
320
+ if (get_piece(moving_piece) == PHARAOH)
329
321
  pharaoh_loc[get_owner(moving_piece)] = end;
330
322
  }
331
323
  checkmate = false;
332
324
  }
333
325
 
334
- void find_valid_moves(Move *valid_moves, int *vi)
335
- {
336
- for (int i = 0; i < 120; i++)
337
- {
338
- Square s = board[i];
339
- enum Player piece_color = get_owner(s);
340
- if (is_piece(s) && piece_color == whose_turn)
341
- {
342
- enum Piece piece = get_piece(s);
343
- switch (piece)
344
- {
345
- case Anubis:
346
- find_valid_anubis_pyramid_moves(i, valid_moves, vi);
326
+ void find_valid_moves(Move *valid_moves, int *vi) {
327
+ for (int i = 0; i < 13; i++) {
328
+ uint8_t board_pos = piece_trackers[whose_turn].positions[i];
329
+ if (board_pos != EPT) {
330
+ enum Piece piece = get_piece(board[board_pos]);
331
+ switch (piece) {
332
+ case ANUBIS:
333
+ find_valid_anubis_pyramid_moves(board_pos, valid_moves, vi);
347
334
  break;
348
- case Pyramid:
349
- find_valid_anubis_pyramid_moves(i, valid_moves, vi);
335
+ case PYRAMID:
336
+ find_valid_anubis_pyramid_moves(board_pos, valid_moves, vi);
350
337
  break;
351
- case Scarab:
352
- find_valid_scarab_moves(i, valid_moves, vi);
338
+ case SCARAB:
339
+ find_valid_scarab_moves(board_pos, valid_moves, vi);
353
340
  break;
354
- case Pharaoh:
355
- find_valid_pharaoh_moves(i, valid_moves, vi);
341
+ case PHARAOH:
342
+ find_valid_pharaoh_moves(board_pos, valid_moves, vi);
356
343
  break;
357
- case Sphinx:
358
- find_valid_sphinx_moves(i, valid_moves, vi);
344
+ case SPHINX:
345
+ find_valid_sphinx_moves(board_pos, valid_moves, vi);
359
346
  break;
360
347
  default:
361
348
  break;
@@ -364,78 +351,60 @@ void find_valid_moves(Move *valid_moves, int *vi)
364
351
  }
365
352
  }
366
353
 
367
- void find_valid_anubis_pyramid_moves(int i, Move *valid_moves, int *vi)
368
- {
369
- for (int j = 0; j < 8; j++)
370
- {
354
+ void find_valid_anubis_pyramid_moves(int i, Move *valid_moves, int *vi) {
355
+ for (int j = 0; j < 8; j++) {
371
356
  int dest = i + directions[j];
372
- if (!is_piece(board[dest]) && can_move[whose_turn][dest])
373
- {
357
+ if (!is_piece(board[dest]) && can_move[whose_turn][dest]) {
374
358
  valid_moves[(*vi)++] = new_move(i, dest, 0);
375
359
  }
376
360
  }
377
- for (int j = 0; j < 2; j++)
378
- {
361
+ for (int j = 0; j < 2; j++) {
379
362
  valid_moves[(*vi)++] = new_move(i, i, rotations[j]);
380
363
  }
381
364
  }
382
365
 
383
- void find_valid_scarab_moves(int i, Move *valid_moves, int *vi)
384
- {
385
- for (int j = 0; j < 8; j++)
386
- {
366
+ void find_valid_scarab_moves(int i, Move *valid_moves, int *vi) {
367
+ for (int j = 0; j < 8; j++) {
387
368
  int dest = i + directions[j];
388
- if (can_move[whose_turn][dest])
389
- {
390
- if (!is_piece(board[dest]) || get_piece(board[dest]) != Pharaoh)
391
- {
369
+ if (can_move[whose_turn][dest]) {
370
+ if (!is_piece(board[dest]) || (get_owner(board[dest]) != whose_turn && get_piece(board[dest]) != PHARAOH)) {
392
371
  valid_moves[(*vi)++] = new_move(i, dest, 0);
393
372
  }
394
373
  }
395
374
  }
396
- for (int j = 0; j < 2; j++)
397
- {
375
+ for (int j = 0; j < 2; j++) {
398
376
  valid_moves[(*vi)++] = new_move(i, i, rotations[j]);
399
377
  }
400
378
  }
401
379
 
402
- void find_valid_pharaoh_moves(int i, Move *valid_moves, int *vi)
403
- {
404
- for (int j = 0; j < 8; j++)
405
- {
380
+ void find_valid_pharaoh_moves(int i, Move *valid_moves, int *vi) {
381
+ for (int j = 0; j < 8; j++) {
406
382
  int dest = i + directions[j];
407
- if (!is_piece(board[dest]) && can_move[whose_turn][dest])
408
- {
383
+ if (!is_piece(board[dest]) && can_move[whose_turn][dest]) {
409
384
  valid_moves[(*vi)++] = new_move(i, dest, 0);
410
385
  }
411
386
  }
412
387
  }
413
388
 
414
- void find_valid_sphinx_moves(int i, Move *valid_moves, int *vi)
415
- {
389
+ void find_valid_sphinx_moves(int i, Move *valid_moves, int *vi) {
416
390
  enum Player player = get_owner(board[i]);
417
391
  enum Orientation orientation = get_orientation(board[i]);
418
- int rotation = player == Silver ? (orientation == North ? -1 : 1) : (orientation == South ? -1 : 1);
392
+ int rotation = player == SILVER ? (orientation == NORTH ? -1 : 1) : (orientation == SOUTH ? -1 : 1);
419
393
  valid_moves[(*vi)++] = new_move(i, i, rotation);
420
394
  }
421
395
 
422
- void init_zobrist()
423
- {
424
- for (int i = 0; i < 0xFF; i++)
425
- {
426
- for (int j = 0; j < 120; j++)
427
- {
396
+ void init_zobrist() {
397
+ for (int i = 0; i < 0xFF; i++) {
398
+ for (int j = 0; j < 120; j++) {
428
399
  keys[i][j] = random_number();
429
400
  }
430
401
  }
431
402
  turn_key = random_number();
432
403
  }
433
404
 
434
- uint64_t get_board_hash()
435
- {
405
+ uint64_t get_board_hash() {
436
406
  uint64_t hash = 0;
437
- for (int i = 0; i < 120; i++)
438
- {
407
+ for (int i = 0; i < 120; i++) {
439
408
  if (is_piece(board[i]))
440
409
  hash ^= keys[board[i]][i];
441
410
  }
@@ -444,97 +413,116 @@ uint64_t get_board_hash()
444
413
  return hash;
445
414
  }
446
415
 
447
- bool is_move_legal(Move move)
448
- {
416
+ void init_piece_trackers() {
417
+ for (int i = 0; i < 13; i++) {
418
+ piece_trackers[SILVER].positions[i] = EPT;
419
+ piece_trackers[RED].positions[i] = EPT;
420
+ }
421
+
422
+ int si = 0;
423
+ int ri = 0;
424
+
425
+ for (int i = 0; i < 120; i++) {
426
+ Square s = board[i];
427
+ if (is_piece(s)) {
428
+ if (get_owner(s) == SILVER) {
429
+ piece_trackers[SILVER].positions[si] = i;
430
+ piece_trackers[SILVER].board_idx_position[i] = si;
431
+ si++;
432
+ } else if (get_owner(s) == RED) {
433
+ piece_trackers[RED].positions[ri] = i;
434
+ piece_trackers[RED].board_idx_position[i] = ri;
435
+ ri++;
436
+ }
437
+ } else {
438
+ piece_trackers[SILVER].board_idx_position[i] = EPT;
439
+ piece_trackers[RED].board_idx_position[i] = EPT;
440
+ }
441
+ }
442
+ }
443
+
444
+ bool is_move_legal(Move move) {
449
445
  int start = get_start(move);
450
446
  int end = get_end(move);
451
- if (is_piece(board[start]) && get_owner(board[start]) == whose_turn)
452
- {
447
+ if (is_piece(board[start]) && get_owner(board[start]) == whose_turn) {
453
448
  if (!is_piece(board[end]) || get_rotation(move) != 0)
454
449
  return true;
455
- else if (is_piece(board[end]) && get_piece(board[start]) == Scarab && get_piece(board[end]) < 3)
450
+ else if (is_piece(board[end]) && get_piece(board[start]) == SCARAB && get_piece(board[end]) <= 3)
456
451
  return true;
457
452
  }
458
453
  return false;
459
454
  }
460
455
 
461
- void reset_undo()
462
- {
456
+ void reset_undo() {
463
457
  undo_index = 0;
464
- for (int i = 0; i < MAX_DEPTH; i++)
465
- {
458
+ for (int i = 0; i < MAX_DEPTH; i++) {
466
459
  undo_moves[i] = 0;
467
460
  undo_capture_indices[i] = 0;
468
461
  undo_capture_squares[i] = 0;
469
462
  }
470
463
  }
471
464
 
472
- void setup_board(char *init_board[120])
473
- {
474
- move_num = 0;
465
+ void setup_board(char *init_board[120]) {
466
+ hashes_index = 0;
475
467
  uint64_t hash = 0;
476
- for (int i = 0; i < 120; i++)
477
- {
468
+ for (int i = 0; i < 120; i++) {
478
469
  board[i] = str_to_square(init_board[i]);
479
470
  Square s = board[i];
480
- if (is_piece(s))
481
- {
471
+ if (is_piece(s)) {
482
472
  hash ^= keys[s][i];
483
- if (get_piece(s) == Pharaoh)
484
- {
485
- if (get_owner(s) == Silver)
486
- pharaoh_loc[Silver] = i;
487
- else if (get_owner(s) == Red)
488
- pharaoh_loc[Red] = i;
473
+ if (get_piece(s) == PHARAOH) {
474
+ if (get_owner(s) == SILVER)
475
+ pharaoh_loc[SILVER] = i;
476
+ else if (get_owner(s) == RED)
477
+ pharaoh_loc[RED] = i;
489
478
  }
490
479
  }
491
480
  }
492
- hashes[0] = hash;
481
+ hashes[hashes_index] = hash;
493
482
 
494
- for (int i = 0; i < TABLE_SIZE; i++)
495
- {
483
+ for (int i = 0; i < TABLE_SIZE; i++) {
496
484
  table[i].key = 0;
497
485
  table[i].depth = 0;
498
486
  table[i].flag = 0;
499
487
  table[i].score = 0;
500
488
  table[i].move = 0;
501
489
  }
490
+
491
+ init_piece_trackers();
502
492
  }
503
493
 
504
- Square str_to_square(char *str)
505
- {
494
+ Square str_to_square(char *str) {
506
495
  enum Player player;
507
496
  enum Piece piece;
508
497
  enum Orientation orientation;
509
498
 
510
- if (str[0] != '-')
511
- {
499
+ if (str[0] != '-') {
512
500
  if (islower(str[0]))
513
- player = Silver;
501
+ player = SILVER;
514
502
  else
515
- player = Red;
503
+ player = RED;
516
504
 
517
505
  char p = tolower(str[0]);
518
506
  if (p == 'a')
519
- piece = Anubis;
507
+ piece = ANUBIS;
520
508
  else if (p == 'p')
521
- piece = Pyramid;
509
+ piece = PYRAMID;
522
510
  else if (p == 's')
523
- piece = Scarab;
511
+ piece = SCARAB;
524
512
  else if (p == 'x')
525
- piece = Pharaoh;
513
+ piece = PHARAOH;
526
514
  else
527
- piece = Sphinx;
515
+ piece = SPHINX;
528
516
 
529
517
  char o = str[1];
530
518
  if (o == '0')
531
- orientation = North;
519
+ orientation = NORTH;
532
520
  else if (o == '1')
533
- orientation = East;
521
+ orientation = EAST;
534
522
  else if (o == '2')
535
- orientation = South;
523
+ orientation = SOUTH;
536
524
  else
537
- orientation = West;
525
+ orientation = WEST;
538
526
 
539
527
  return (Square)((int)player << 1 | (int)piece << 2 | (int)orientation << 5);
540
528
  }
@@ -542,55 +530,50 @@ Square str_to_square(char *str)
542
530
  return (Square)0;
543
531
  }
544
532
 
545
- void print_board()
546
- {
547
- for (int i = 0; i < 120; i++)
548
- {
533
+ void print_board() {
534
+ for (int i = 0; i < 120; i++) {
549
535
  print_piece(board[i]);
550
536
  if ((i + 1) % 12 == 0)
551
537
  printf("\n");
552
538
  }
553
539
  }
554
540
 
555
- void print_piece(Square s)
556
- {
541
+ void print_piece(Square s) {
557
542
  enum Player player = get_owner(s);
558
- if (is_piece(s))
559
- {
543
+ if (is_piece(s)) {
560
544
  enum Piece piece = get_piece(s);
561
545
  enum Orientation orientation = get_orientation(s);
562
- switch (piece)
563
- {
564
- case Anubis:
565
- if (player == Silver)
546
+ switch (piece) {
547
+ case ANUBIS:
548
+ if (player == SILVER)
566
549
  printf("a");
567
550
  else
568
551
  printf("A");
569
552
  break;
570
553
 
571
- case Pyramid:
572
- if (player == Silver)
554
+ case PYRAMID:
555
+ if (player == SILVER)
573
556
  printf("p");
574
557
  else
575
558
  printf("P");
576
559
  break;
577
560
 
578
- case Scarab:
579
- if (player == Silver)
561
+ case SCARAB:
562
+ if (player == SILVER)
580
563
  printf("s");
581
564
  else
582
565
  printf("S");
583
566
  break;
584
567
 
585
- case Pharaoh:
586
- if (player == Silver)
568
+ case PHARAOH:
569
+ if (player == SILVER)
587
570
  printf("x");
588
571
  else
589
572
  printf("X");
590
573
  break;
591
574
 
592
- case Sphinx:
593
- if (player == Silver)
575
+ case SPHINX:
576
+ if (player == SILVER)
594
577
  printf("l");
595
578
  else
596
579
  printf("L");
@@ -599,26 +582,24 @@ void print_piece(Square s)
599
582
  printf("-");
600
583
  break;
601
584
  }
602
- switch (orientation)
603
- {
604
- case North:
585
+ switch (orientation) {
586
+ case NORTH:
605
587
  printf("0");
606
588
  break;
607
- case East:
589
+ case EAST:
608
590
  printf("1");
609
591
  break;
610
- case South:
592
+ case SOUTH:
611
593
  printf("2");
612
594
  break;
613
- case West:
595
+ case WEST:
614
596
  printf("3");
615
597
  break;
616
598
  default:
617
599
  printf("-");
618
600
  break;
619
601
  }
620
- }
621
- else
602
+ } else
622
603
  printf("--");
623
604
  }
624
605
 
@@ -626,8 +607,7 @@ int get_start_wrapper(Move move) { return get_start(move); }
626
607
  int get_end_wrapper(Move move) { return get_end(move); }
627
608
  int get_rotation_wrapper(Move move) { return get_rotation(move); }
628
609
 
629
- void set_time_parameters(int _max_time, time_t _start_time)
630
- {
610
+ void set_time_parameters(int _max_time, time_t _start_time) {
631
611
  max_time = _max_time;
632
612
  start_time = _start_time;
633
613
  }