khetai 0.2.2 → 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,96 +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
- {
448
+ void setup_board(char *init_board[120]) {
449
+ hashes_index = 0;
474
450
  uint64_t hash = 0;
475
- for (int i = 0; i < 120; i++)
476
- {
451
+ for (int i = 0; i < 120; i++) {
477
452
  board[i] = str_to_square(init_board[i]);
478
453
  Square s = board[i];
479
- if (is_piece(s))
480
- {
454
+ if (is_piece(s)) {
481
455
  hash ^= keys[s][i];
482
- if (get_piece(s) == Pharaoh)
483
- {
484
- if (get_owner(s) == Silver)
485
- pharaoh_loc[Silver] = i;
486
- else if (get_owner(s) == Red)
487
- 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;
488
461
  }
489
462
  }
490
463
  }
491
- hashes[0] = hash;
464
+ hashes[hashes_index] = hash;
492
465
 
493
- for (int i = 0; i < TABLE_SIZE; i++)
494
- {
466
+ for (int i = 0; i < TABLE_SIZE; i++) {
495
467
  table[i].key = 0;
496
468
  table[i].depth = 0;
497
469
  table[i].flag = 0;
498
470
  table[i].score = 0;
499
471
  table[i].move = 0;
500
472
  }
473
+
474
+ init_piece_trackers();
501
475
  }
502
476
 
503
- Square str_to_square(char *str)
504
- {
477
+ Square str_to_square(char *str) {
505
478
  enum Player player;
506
479
  enum Piece piece;
507
480
  enum Orientation orientation;
508
481
 
509
- if (str[0] != '-')
510
- {
482
+ if (str[0] != '-') {
511
483
  if (islower(str[0]))
512
- player = Silver;
484
+ player = SILVER;
513
485
  else
514
- player = Red;
486
+ player = RED;
515
487
 
516
488
  char p = tolower(str[0]);
517
489
  if (p == 'a')
518
- piece = Anubis;
490
+ piece = ANUBIS;
519
491
  else if (p == 'p')
520
- piece = Pyramid;
492
+ piece = PYRAMID;
521
493
  else if (p == 's')
522
- piece = Scarab;
494
+ piece = SCARAB;
523
495
  else if (p == 'x')
524
- piece = Pharaoh;
496
+ piece = PHARAOH;
525
497
  else
526
- piece = Sphinx;
498
+ piece = SPHINX;
527
499
 
528
500
  char o = str[1];
529
501
  if (o == '0')
530
- orientation = North;
502
+ orientation = NORTH;
531
503
  else if (o == '1')
532
- orientation = East;
504
+ orientation = EAST;
533
505
  else if (o == '2')
534
- orientation = South;
506
+ orientation = SOUTH;
535
507
  else
536
- orientation = West;
508
+ orientation = WEST;
537
509
 
538
510
  return (Square)((int)player << 1 | (int)piece << 2 | (int)orientation << 5);
539
511
  }
@@ -541,55 +513,50 @@ Square str_to_square(char *str)
541
513
  return (Square)0;
542
514
  }
543
515
 
544
- void print_board()
545
- {
546
- for (int i = 0; i < 120; i++)
547
- {
516
+ void print_board() {
517
+ for (int i = 0; i < 120; i++) {
548
518
  print_piece(board[i]);
549
519
  if ((i + 1) % 12 == 0)
550
520
  printf("\n");
551
521
  }
552
522
  }
553
523
 
554
- void print_piece(Square s)
555
- {
524
+ void print_piece(Square s) {
556
525
  enum Player player = get_owner(s);
557
- if (is_piece(s))
558
- {
526
+ if (is_piece(s)) {
559
527
  enum Piece piece = get_piece(s);
560
528
  enum Orientation orientation = get_orientation(s);
561
- switch (piece)
562
- {
563
- case Anubis:
564
- if (player == Silver)
529
+ switch (piece) {
530
+ case ANUBIS:
531
+ if (player == SILVER)
565
532
  printf("a");
566
533
  else
567
534
  printf("A");
568
535
  break;
569
536
 
570
- case Pyramid:
571
- if (player == Silver)
537
+ case PYRAMID:
538
+ if (player == SILVER)
572
539
  printf("p");
573
540
  else
574
541
  printf("P");
575
542
  break;
576
543
 
577
- case Scarab:
578
- if (player == Silver)
544
+ case SCARAB:
545
+ if (player == SILVER)
579
546
  printf("s");
580
547
  else
581
548
  printf("S");
582
549
  break;
583
550
 
584
- case Pharaoh:
585
- if (player == Silver)
551
+ case PHARAOH:
552
+ if (player == SILVER)
586
553
  printf("x");
587
554
  else
588
555
  printf("X");
589
556
  break;
590
557
 
591
- case Sphinx:
592
- if (player == Silver)
558
+ case SPHINX:
559
+ if (player == SILVER)
593
560
  printf("l");
594
561
  else
595
562
  printf("L");
@@ -598,26 +565,24 @@ void print_piece(Square s)
598
565
  printf("-");
599
566
  break;
600
567
  }
601
- switch (orientation)
602
- {
603
- case North:
568
+ switch (orientation) {
569
+ case NORTH:
604
570
  printf("0");
605
571
  break;
606
- case East:
572
+ case EAST:
607
573
  printf("1");
608
574
  break;
609
- case South:
575
+ case SOUTH:
610
576
  printf("2");
611
577
  break;
612
- case West:
578
+ case WEST:
613
579
  printf("3");
614
580
  break;
615
581
  default:
616
582
  printf("-");
617
583
  break;
618
584
  }
619
- }
620
- else
585
+ } else
621
586
  printf("--");
622
587
  }
623
588
 
@@ -625,8 +590,7 @@ int get_start_wrapper(Move move) { return get_start(move); }
625
590
  int get_end_wrapper(Move move) { return get_end(move); }
626
591
  int get_rotation_wrapper(Move move) { return get_rotation(move); }
627
592
 
628
- void set_time_parameters(int _max_time, time_t _start_time)
629
- {
593
+ void set_time_parameters(int _max_time, time_t _start_time) {
630
594
  max_time = _max_time;
631
595
  start_time = _start_time;
632
596
  }