khetai 0.2.3 → 0.3.0

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