8 static void tt_copy(state
*s
, state_t
*t
, short alpha
, short beta
);
12 int black_misc
= 0, white_misc
= 0; //miscellaneous heuristic values
15 /* Heuristic Weights */
16 #define QUEEN_LOSS 15 //point deduction when losing a queen
17 #define QUEEN_DANGER 10 //point deduction when queen in danger
18 #define QUEEN_CLUSTER 5 //point deduction when a queen isn't in
20 #define OWN_VALUE 1.5 //Value of owning a square
24 /*==============================================================================
27 * This gets a stream of bits from the given bit board in a "forwards" diagonal
28 * starting at the position diag, and returns the stream.
30 int get_forward_diag(ull board_l
, ull board_u
, int diag
)
32 int len
= GET_FDIAG_LEN(diag
);
46 res
|= (*board
>> (pos
% 50)) & mask
;
55 /*==============================================================================
58 * This gets a stream of bits from the given bit board in a "backwards" diagonal
59 * starting at the position diag, and returns the stream.
61 int get_back_diag(ull board_l
, ull board_u
, int diag
)
63 int len
= GET_BDIAG_LEN(diag
);
69 for (i
=0; i
<=len
; i
++)
71 //This needs some funky footwork to get bits in the early 50's
76 res
|= (board_u
>> (pos
% 50)) & mask
;
80 res
|= (board_u
<< (50 - pos
)) & mask
;
84 res
|= (board_l
>> pos
) & mask
;
93 /*==============================================================================
96 * This takes a stream of bits and stores them on the given bit board in a
97 * "forward" diagonal starting at the position diag.
99 void put_forward_diag(ull
*board_l
, ull
*board_u
, ushort stream
, int diag
)
101 int len
= GET_FDIAG_LEN(diag
);
107 for (i
=0; i
<len
; i
++)
114 *board
|= ((ull
) (stream
& mask
) << (pos
% 50));
121 /*==============================================================================
124 * This takes a stream of bits and stores them on the given bit board in a
125 * "backwards" diagonal starting at the position diag.
127 void put_back_diag(ull
*board_l
, ull
*board_u
, ushort stream
, int diag
)
129 int len
= GET_BDIAG_LEN(diag
);
134 for (i
=0; i
<len
; i
++)
136 //This needs some funky footwork to get bits in the early 50's
140 *board_u
|= ((ull
) (stream
& mask
) << (pos
% 50));
142 *board_u
|= ((ull
) (stream
& mask
) >> (50 - pos
));
145 *board_l
|= ((ull
) (stream
& mask
) << pos
);
153 /*==============================================================================
156 * This calculates the heuristic evaluation for a given state. It currently
157 * bases it's evaluation on the number of squares the queens can move to and the
158 * number of squares each side "owns".
163 float own1L0
= 0, own2L0
= 0;
164 float own1L1
= 0, own2L1
= 0;
165 ull board_u
, board_l
;
166 ull web_board_u
=0, web_board_l
=0;
167 ull white_web1_u
=0, white_web1_l
=0, black_web1_u
=0, black_web1_l
=0;
168 ull res1_l
=0, res1_u
=0, res2_l
=0, res2_u
=0;
169 ull dirs_l
=0, dirs_u
=0;
171 //Generates quads that look like:
172 // 1 1 1 1 1 0 0 0 0 0
173 // 1 1 1 1 1 0 0 0 0 0
174 // 1 1 1 1 1 0 0 0 0 0
175 // 1 1 1 1 1 0 0 0 0 0
176 // 1 1 1 1 1 0 0 0 0 0
177 ull low_quad
= 0x07c1f07c1f, high_quad
= 0xf83e0f83e0;
184 white_misc
= black_misc
= 0;
186 //establish queen positions
189 black_q_pos
[i
] = XY_TO_POS(s
->black_q_x
[i
], s
->black_q_y
[i
]);
190 white_q_pos
[i
] = XY_TO_POS(s
->white_q_x
[i
], s
->white_q_y
[i
]);
192 //printf("heval:\n");
195 board_u
= s
->white_bd
[1] | s
->black_bd
[1] | s
->blocks_bd
[1];
196 board_l
= s
->white_bd
[0] | s
->black_bd
[0] | s
->blocks_bd
[0];
200 //pbvec(board_l, board_u);
206 p1 += calc_moves(board_l, board_u, white_q_pos[i]);
207 p2 += calc_moves(board_l, board_u, black_q_pos[i]);
211 //make webs for queens & count # of moves
214 if (!(p1
+= gen_web_board_count(&white_web1_l
, &white_web1_u
, board_l
, board_u
, white_q_pos
[i
])))
215 white_misc
-= QUEEN_LOSS
; //white queen is trapped.
217 if (!(p2
+= gen_web_board_count(&black_web1_l
, &black_web1_u
, board_l
, board_u
, black_q_pos
[i
])))
218 black_misc
-= QUEEN_LOSS
; //black queen is trapped.
221 /* look for queens in trouble */
225 gen_dirs_board(&dirs_l
, &dirs_u
, white_q_pos
[i
]);
226 res1_l
= white_web1_l
& dirs_l
;
227 res1_u
= white_web1_u
& dirs_u
;
229 if (count_bits(res1_l
, res1_u
) < 3)
231 res2_l
= res1_l
& black_web1_l
;
232 res2_u
= res1_u
& black_web1_u
;
233 if (!((res1_l
^ res2_l
) || (res1_u
^ res2_u
)))
234 white_misc
-= QUEEN_DANGER
;
238 gen_dirs_board(&dirs_l
, &dirs_u
, black_q_pos
[i
]);
239 res1_l
= black_web1_l
& dirs_l
;
240 res1_u
= black_web1_u
& dirs_u
;
241 if (count_bits(res1_l
, res1_u
) < 3)
243 res2_l
= res1_l
& white_web1_l
;
244 res2_u
= res1_u
& white_web1_u
;
245 if (!((res1_l
^ res2_l
) || (res1_u
^ res2_u
)))
246 black_misc
-= QUEEN_DANGER
;
250 /* Encourage queens to spread out a bit */
253 if (!(s
->white_bd
[i
] & low_quad
))
254 white_misc
-= QUEEN_CLUSTER
;
255 else if (!(s
->black_bd
[i
] & low_quad
))
256 white_misc
+= QUEEN_CLUSTER
; //give bonus points for owning a quadrant
257 if (!(s
->white_bd
[i
] & high_quad
))
258 white_misc
-= QUEEN_CLUSTER
;
259 else if (!(s
->black_bd
[i
] & high_quad
))
260 white_misc
+= QUEEN_CLUSTER
; //give bonus points for owning a quadrant
261 if (!(s
->black_bd
[i
] & low_quad
))
262 black_misc
-= QUEEN_CLUSTER
;
263 else if (!(s
->white_bd
[i
] & low_quad
))
264 black_misc
+= QUEEN_CLUSTER
;
265 if (!(s
->black_bd
[i
] & high_quad
))
266 black_misc
-= QUEEN_CLUSTER
;
267 else if (!(s
->white_bd
[i
] & high_quad
))
268 black_misc
+= QUEEN_CLUSTER
;
272 *calculate square ownership
276 printf("white moves = %d, black moves = %d\n", p1
, p2
);
280 printf("White's web board:\n");
281 pbvec(white_web1_l
, white_web1_u
);
283 printf("Blacks's web board:\n");
284 pbvec(black_web1_l
, black_web1_u
);
286 //make webs for each empty square
287 for (i
=0; i
<100; i
++)
291 if (board_u
& ((ull
)0x1 << (i
% 50)))
296 if (board_l
& ((ull
)0x1 << (i
% 50)))
300 web_board_l
= web_board_u
= 0;
301 gen_web_board(&web_board_l
, &web_board_u
, board_l
, board_u
, i
);
304 printf("web board for square %d:\n", i
);
305 pbvec(web_board_l
, web_board_u
);
308 if (s
->turn
== WHITE_PLAYER
) //player 1 moves next
310 if ((web_board_l
& s
->white_bd
[0]) || (web_board_u
& s
->white_bd
[1]))
312 //printf("Square %d is owned by white - level 0\n", i);
314 if ((web_board_l
& s
->black_bd
[0]) || (web_board_u
& s
->black_bd
[1]))
317 else if ((web_board_l
& s
->black_bd
[0]) || (web_board_u
& s
->black_bd
[1]))
319 //printf("Square %d is owned by black - level 0\n", i);
322 else if ((web_board_l
& white_web1_l
) || (web_board_u
& white_web1_u
))
324 //printf("Square %d is owned by white - level 1\n", i);
326 if ((web_board_l
& black_web1_l
) || (web_board_u
& black_web1_u
))
329 else if ((web_board_l
& black_web1_l
) || (web_board_u
& black_web1_u
))
331 //printf("Square %d is owned by black - level 1\n", i);
336 //printf("Square %d is not owned by anyone\n", i);
341 if ((web_board_l
& s
->black_bd
[0]) || (web_board_u
& s
->black_bd
[1]))
343 //printf("Square %d is owned by black - level 0\n", i);
345 if ((web_board_l
& s
->white_bd
[0]) || (web_board_u
& s
->white_bd
[1]))
348 else if ((web_board_l
& s
->white_bd
[0]) || (web_board_u
& s
->white_bd
[1]))
351 //printf("Square %d is owned by white - level 0\n", i);
353 else if ((web_board_l
& black_web1_l
) || (web_board_u
& black_web1_u
))
355 //printf("Square %d is owned by black - level 1\n", i);
357 if ((web_board_l
& white_web1_l
) || (web_board_u
& white_web1_u
))
360 else if ((web_board_l
& white_web1_l
) || (web_board_u
& white_web1_u
))
362 //printf("Square %d is owned by white - level 1\n", i);
367 //printf("Square %d is not owned by anyone\n", i);
374 printf("Direct white squares = %d, direct black squares = %d\n", own1L0
, own2L0
);
375 printf("Indirect white squares = %d, indirect black squares = %d\n", own1L1
, own2L1
);
376 printf("white squares = %d, black squares = %d\n", own1
, own2
);
378 // printf("own1 = %d p1 = %d own2 = %d p2 = %d\n", own1,p1,own2,p2);
379 return (((own1L0
+ own1L1
) * OWN_VALUE
+ p1
+ white_misc
) - (p2
+ (own2L0
+ own2L1
) * OWN_VALUE
+ black_misc
));
383 /*==============================================================================
386 * This receives a complete bit board with all occupied square bits set. From
387 * the given position, it calculates all possible moves in every direction.
389 * Returns the number of moves possible.
391 int calc_moves(ull board_l
, ull board_u
, int pos
)
394 int row
, col
, fdiag
, bdiag
;
400 stream
= GET_ROW(board_l
, GET_COL_POS(pos
));
402 stream
= GET_ROW(board_u
, GET_COL_POS(pos
));
403 row
= calc_stream_moves(stream
, GET_ROW_POS(pos
), 10);
404 //printf("%d row moves\n", row);
408 stream
= GET_COL(board_l
, board_u
, GET_ROW_POS(pos
));
409 col
= calc_stream_moves(stream
, GET_COL_POS(pos
), 10);
410 //printf("%d col moves\n", col);
412 //count forw diag moves
413 diag
= GET_FDIAG(pos
);
414 stream
= get_forward_diag(board_l
, board_u
, diag
);
415 fdiag
= calc_stream_moves(stream
, GET_FDIAG_POS(pos
), GET_FDIAG_LEN(diag
));
416 //printf("%d fdiag moves\n", fdiag);
418 //count back diag moves
419 diag
= GET_BDIAG(pos
);
420 stream
= get_back_diag(board_l
, board_u
, diag
);
421 bdiag
= calc_stream_moves(stream
, GET_BDIAG_POS(pos
), GET_BDIAG_LEN(diag
));
422 //printf("%d bdiag moves\n", bdiag);
424 //printf("%d total moves\n", row+col+fdiag+bdiag);
425 return (row
+col
+fdiag
+bdiag
);
430 /*==============================================================================
433 * Calculates the number of empty bits in either direction from the given position
434 * in the given stream.
436 * Returns the number of moves in that stream.
438 int calc_stream_moves(ushort stream
, ushort pos
, ushort len
)
442 int before
=0, after
=0;
444 //psvec(stream, len);
448 printf("duh, the position %d can't be greater than the length %d\n", pos
, len
);
452 // printf("stream len = %d\n", len);
453 for (i
=0; i
<pos
; i
++)
456 before
= 0;// (pos - (i+1));
473 moves
= before
+ after
;
474 //printf("Pos = %d, before = %d, after = %d\n", pos, before, after);
480 /*==============================================================================
483 * This generates a stream of 1 bits (the 'web') in both directions, starting
484 * from the given position pos, and stops when it hits a set bit in the given
485 * stream or comes to the end of the stream.
487 * Returns the generated web.
489 ushort
gen_web_stream(ushort stream
, int pos
, int len
)
496 for (i
=pos
-1; i
>=0; i
--)
498 if (stream
& (0x1 << i
))
504 for (i
=pos
+1; i
<len
; i
++)
506 if (stream
& (0x1 << i
))
515 /*==============================================================================
516 * gen_web_stream_plus
518 * This generates a stream of 1 bits (the 'web') in both directions, starting
519 * from the given position pos, and stops when it hits a set bit in the given
520 * stream or comes to the end of the stream. This differs from gen_web_stream
521 * in that it includes a set bit on the square that it ran into. This enables
522 * me to & the generated web stream with a queen board and see if they coincide.
524 * Returns the generated web.
526 ushort
gen_web_stream_plus(ushort stream
, int pos
, int len
)
533 for (i
=pos
-1; i
>=0; i
--)
535 if (stream
& (0x1 << i
))
544 for (i
=pos
+1; i
<len
; i
++)
546 if (stream
& (0x1 << i
))
558 /*==============================================================================
561 * This takes the bit boards, board_l & board_u that represent all the occupied
562 * squares. Then, from the given position pos, generates a stream of 1's in
563 * every direction until they hit an occupied square. The result is stored
564 * in the given web_u & web_l
566 void gen_web_board(ull
*web_l
, ull
*web_u
, ull board_l
, ull board_u
, int pos
)
568 ushort row
, col
, fdiag
, bdiag
;
569 ushort web_row
, web_col
, web_fdiag
, web_bdiag
;
574 row
= GET_ROW(board_u
, GET_COL_POS(pos
));
576 row
= GET_ROW(board_l
, GET_COL_POS(pos
));
578 web_row
= gen_web_stream_plus(row
, GET_ROW_POS(pos
), 10);
579 //printf("Row for pos %d:", pos);
582 printf("Generating web for row "); psvec(row
, 10);
583 printf("Web generated for row at pos %d:", pos
);
588 PUT_ROW(*web_u
, pos
/10, web_row
);
590 PUT_ROW(*web_l
, pos
/10, web_row
);
592 printf("web board after row inserted:\n");
593 pbvec(*web_l
, *web_u
);
597 col
= GET_COL(board_l
, board_u
, pos
%10);
598 web_col
= gen_web_stream_plus(col
, GET_COL_POS(pos
), 10);
601 printf("Generating web for col "); psvec(col
, 10);
602 printf("Web generated for col at pos %d:", pos
);
606 PUT_COL(*web_l
, *web_u
, pos
%10, web_col
);
608 printf("web board after col inserted:\n");
609 pbvec(*web_l
, *web_u
);
613 diag
= GET_FDIAG(pos
);
614 fdiag
= get_forward_diag(board_l
, board_u
, diag
);
615 web_fdiag
= gen_web_stream_plus(fdiag
, GET_FDIAG_POS(pos
), GET_FDIAG_LEN(diag
));
618 printf("Generating web for fdiag "); psvec(fdiag
, GET_FDIAG_LEN(diag
));
619 printf("Web generated for fdiag at pos %d:", pos
);
620 psvec(web_fdiag
, 10);
623 put_forward_diag(web_l
, web_u
, web_fdiag
, diag
);
625 printf("web board after fdiag inserted:\n");
626 pbvec(*web_l
, *web_u
);
630 diag
= GET_BDIAG(pos
);
631 bdiag
= get_back_diag(board_l
, board_u
, diag
);
632 web_bdiag
= gen_web_stream_plus(bdiag
, GET_BDIAG_POS(pos
), GET_BDIAG_LEN(diag
));
635 printf("Generating web for bdiag "); psvec(bdiag
, GET_BDIAG_LEN(diag
));
636 printf("Web generated for bdiag at pos %d:", pos
);
637 psvec(web_bdiag
, 10);
640 put_back_diag(web_l
, web_u
, web_bdiag
, diag
);
642 printf("web board after bdiag inserted:\n");
643 pbvec(*web_l
, *web_u
);
648 /*==============================================================================
649 * gen_web_board_count
651 * This takes the bit boards, board_l & board_u that represent all the occupied
652 * squares. Then, from the given position pos, generates a stream of 1's in
653 * every direction until they hit an occupied square. The result is stored
654 * in the given web_u & web_l
656 int gen_web_board_count(ull
*web_l
, ull
*web_u
, ull board_l
, ull board_u
, int pos
)
658 ushort row
, col
, fdiag
, bdiag
;
659 ushort web_row
, web_col
, web_fdiag
, web_bdiag
;
661 int row_count
, col_count
, fdiag_count
, bdiag_count
;
664 printf("Counting moves for queen on position %d\n", pos
);
668 row
= GET_ROW(board_u
, GET_COL_POS(pos
));
670 row
= GET_ROW(board_l
, GET_COL_POS(pos
));
672 web_row
= gen_web_stream(row
, GET_ROW_POS(pos
), 10);
673 row_count
= count_contig_bits(web_row
, 10);
674 //printf("Row for pos %d:", pos);
677 printf("Counting moves for queen on position %d\n", pos
);
678 printf(" Row moves: %d\n", row_count
);
682 printf("Generating web for row "); psvec(row
, 10);
683 printf("Web generated for row at pos %d:", pos
);
688 PUT_ROW(*web_u
, pos
/10, web_row
);
690 PUT_ROW(*web_l
, pos
/10, web_row
);
692 printf("web board after row inserted:\n");
693 pbvec(*web_l
, *web_u
);
697 col
= GET_COL(board_l
, board_u
, pos
%10);
698 web_col
= gen_web_stream(col
, GET_COL_POS(pos
), 10);
699 col_count
= count_contig_bits(web_col
, 10);
702 printf(" Col moves: %d\n", col_count
);
706 printf("Generating web for col "); psvec(col
, 10);
707 printf("Web generated for col at pos %d:", pos
);
711 PUT_COL(*web_l
, *web_u
, pos
%10, web_col
);
713 printf("web board after col inserted:\n");
714 pbvec(*web_l
, *web_u
);
718 diag
= GET_FDIAG(pos
);
719 fdiag
= get_forward_diag(board_l
, board_u
, diag
);
720 web_fdiag
= gen_web_stream(fdiag
, GET_FDIAG_POS(pos
), GET_FDIAG_LEN(diag
));
721 fdiag_count
= count_contig_bits(web_fdiag
, GET_FDIAG_LEN(diag
));
724 printf(" Fdiag moves: %d\n", fdiag_count
);
728 printf("Generating web for fdiag "); psvec(fdiag
, GET_FDIAG_LEN(diag
));
729 printf("Web generated for fdiag at pos %d:", pos
);
730 psvec(web_fdiag
, 10);
733 put_forward_diag(web_l
, web_u
, web_fdiag
, diag
);
735 printf("web board after fdiag inserted:\n");
736 pbvec(*web_l
, *web_u
);
740 diag
= GET_BDIAG(pos
);
741 bdiag
= get_back_diag(board_l
, board_u
, diag
);
742 web_bdiag
= gen_web_stream(bdiag
, GET_BDIAG_POS(pos
), GET_BDIAG_LEN(diag
));
743 bdiag_count
= count_contig_bits(web_bdiag
, GET_BDIAG_LEN(diag
));
746 printf(" Bdiag moves: %d\n", bdiag_count
);
749 printf("Generating web for bdiag "); psvec(bdiag
, GET_BDIAG_LEN(diag
));
750 printf("Web generated for bdiag at pos %d:", pos
);
751 psvec(web_bdiag
, 10);
754 put_back_diag(web_l
, web_u
, web_bdiag
, diag
);
756 printf("web board after bdiag inserted:\n");
757 pbvec(*web_l
, *web_u
);
760 return (row_count
+ col_count
+ fdiag_count
+ bdiag_count
- 4);
763 /*==============================================================================
766 * This counts the number of contiguous bits in a stream. It starts looking at
767 * the 0th bit, and starts counting when it finds the first set bit, and stops
768 * counting on the next unset bit.
770 * Returns the number of contiguous set bits.
772 int count_contig_bits(ushort stream
, int len
)
777 for (i
=0; i
<len
; i
++)
779 if (stream
& (0x1 << i
))
790 /*==============================================================================
793 * This prints out a bit board with the same ordering as pboard.
796 int pbvec(ull l
, ull u
)
805 printf("%d ", (int)((u
>> (i
*10 + j
)) &0x1));
816 printf("%d ", (int)((l
>> (i
*10 + j
)) &0x1));
824 /*==============================================================================
827 * This looks a given state up in the transposition table (TT). If it's found, it
828 * returns a pointer to the tt entry and lets the caller decide if it's usable.
830 * Otherwise, it returns NULL.
832 * Note: this also allocates the initial TT. On first run, if the TT hasn't been
833 * created yet, this will create it. This means that it MUST be called before
834 * tt_store, otherwise very bad things will happen.
837 state_t
* tt_lookup(state
*s
)
839 ull board_u
, board_l
;
845 tt
= (state_t
**) calloc(TT
, sizeof(state_t
*));
848 board_u
= s
->white_bd
[1] | s
->black_bd
[1] | s
->blocks_bd
[1];
849 board_l
= s
->white_bd
[0] | s
->black_bd
[0] | s
->blocks_bd
[0];
851 hash_index
= (board_u
^ board_l
) % TT
;
853 while(tt
[hash_index
] && !found
&& (max
< MAX_TT_SEARCH
) && (hash_index
< TT
))
855 found
= tt_compare(s
,tt
[hash_index
]);
864 return (tt
[--hash_index
]);
866 s->value = tt[--hash_index]->value;
867 s->depth = tt[hash_index]->depth;
876 /*==============================================================================
879 * This compares a state to a state_t. Returns TRUE if they're equivalent, FALSE
882 int tt_compare(state
*s
, state_t
*t
)
884 if ((s
->white_bd
[0] == t
->white_bd
[0]) && (s
->white_bd
[1] == t
->white_bd
[1]) &&
885 (s
->black_bd
[0] == t
->black_bd
[0]) && (s
->black_bd
[1] == t
->black_bd
[1]) &&
886 (s
->blocks_bd
[0] == t
->blocks_bd
[0]) && (s
->blocks_bd
[1] == t
->blocks_bd
[1]) &&
887 (s
->turn
== t
->turn
))
893 /*==============================================================================
896 * tt_store takes a state and stores the necessary components into the TT. If
897 * the calculated hash index is already occupied (collision), it will proceed on
898 * to the next one, etc etc... If it doesn't find an empty spot withint
899 * MAX_TT_SEARCH, it will go back to the initial hash index it calculated, free
900 * whatever was there, and replace it with the new one.
903 void tt_store(state
*s
, short alpha
, short beta
)
905 ull board_u
, board_l
;
909 board_u
= s
->white_bd
[1] | s
->black_bd
[1] | s
->blocks_bd
[1];
910 board_l
= s
->white_bd
[0] | s
->black_bd
[0] | s
->blocks_bd
[0];
912 hash_index
= (board_u
^ board_l
) % TT
;
916 //looks at a max of MAX_TT_SEARCH items before freeing the first one and storing there
917 while(tt
[hash_index
] && (max
< MAX_TT_SEARCH
) && (hash_index
< TT
))
923 if (max
== MAX_TT_SEARCH
)
930 free(tt
[hash_index
]);
932 tt
[hash_index
] = (state_t
*) malloc(sizeof(state_t
));
933 tt_copy(s
, tt
[hash_index
], alpha
, beta
);
937 /*==============================================================================
940 * Copies a state struct into a state_t struct.
942 static void tt_copy(state
*s
, state_t
*t
, short alpha
, short beta
)
945 t
->white_bd
[0] = s
->white_bd
[0];
946 t
->white_bd
[1] = s
->white_bd
[1];
948 t
->black_bd
[0] = s
->black_bd
[0];
949 t
->black_bd
[1] = s
->black_bd
[1];
951 t
->blocks_bd
[0] = s
->blocks_bd
[0];
952 t
->blocks_bd
[1] = s
->blocks_bd
[1];
962 /*==============================================================================
965 * This is used to update the value and depth members of a TT entry that already
966 * exists. Sometimes, if the value stored in the TT isn't accurate to a very deep
967 * level, it's desireable to go ahead and search deeper and update the entry with
968 * a more accurate reading.
970 * Of course, it's possible in the meantime for the original entry to have been
971 * overwritten, so if it isn't found, it recreates the entire entry.
973 void tt_update(state
*s
, short alpha
, short beta
)
975 ull board_u
, board_l
;
981 tt
= (state_t
**) calloc(TT
, sizeof(state_t
*));
983 board_u
= s
->white_bd
[1] | s
->black_bd
[1] | s
->blocks_bd
[1];
984 board_l
= s
->white_bd
[0] | s
->black_bd
[0] | s
->blocks_bd
[0];
986 hash_index
= (board_u
^ board_l
) % TT
;
988 while(tt
[hash_index
] && !found
&& (max
< MAX_TT_SEARCH
) && (hash_index
< TT
))
990 found
= tt_compare(s
,tt
[hash_index
]);
997 tt
[--hash_index
]->value
= s
->value
;
998 tt
[hash_index
]->depth
= s
->depth
;
1001 else //create a new one
1003 hash_index
-= MAX_TT_SEARCH
;
1005 free(tt
[hash_index
]);
1007 tt
[hash_index
] = (state_t
*) malloc(sizeof(state_t
));
1008 tt_copy(s
, tt
[hash_index
], alpha
, beta
);
1015 /*==============================================================================
1018 * This function generates a bitmask board that completely surrounds a single
1021 * The generated mask will look something like:
1027 * Where the 0 bit is the position passed in. This gets tricky when the position
1028 * is right next to a border and part of the mask will need to be amputated
1031 void gen_dirs_board(ull
*board_l
, ull
*board_u
, int pos
)
1033 int row
= GET_COL_POS(pos
);
1034 int row_adj
= row
% 5;
1035 int pos_adj
= pos
% 50;
1036 ull
*board_ptr
= NULL
;
1038 /* Generate top row */
1039 if (row
< 9) //position is not against top border, generate this row
1041 if (pos
> 39) //use upper board
1042 board_ptr
= board_u
;
1044 board_ptr
= board_l
;
1045 //The 2nd half of this expressions is a row bitmask that takes care of
1046 //positions next to the left or right borders, ensuring that the bits
1047 //placed on the board stay in the row
1051 *board_ptr
|= (((ull
)0x7 << ((pos_adj
+ 9) % 50)) & ((ull
)0x3ff << (((row_adj
+ 1)%5) * 10)));
1054 /* Generate middle row */
1056 board_ptr
= board_l
; //otherwise board_ptr is still pointing to board_u
1058 board_ptr
= board_u
; //otherwise board_ptr is still pointing to board_u
1061 *board_ptr
|= (ull
) (0x2); //in bottom left corner of board half, can't shift neg
1063 *board_ptr
|= (((ull
) 0x5 << (pos_adj
- 1)) & ((ull
) 0x3ff << (row_adj
* 10)));
1065 /* Generate bottom row */
1066 if (row
> 0) //position is not against bottom border, generate this row
1069 board_ptr
= board_l
; //otherwise board_ptr is still pointing to board_u
1071 board_ptr
= board_u
; //otherwise board_ptr is still pointing to board_u
1073 *board_ptr
|= (ull
) 0x3; //in bottom left corner of board half, can't shift neg
1075 *board_ptr
|= (((ull
) 0x7 << ((pos
- 11)%50)) & ((ull
) 0x3ff << (((row
- 1)%5) * 10)));
1081 int count_bits(ull board_l
, ull board_u
)
1086 for (i
=0; i
< 64; i
++)