khetai 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }