blob: 237b440bdd2b2894b1a99fe4ff69a69cbe325e67 [file] [log] [blame]
#include "globals.h"
//########################################################
// Sanity check functions.
// These functions try to do a quick check of some set of
// information. They crash and burn if the check fails.
//########################################################
static void
check_hashkey_bit_set(Hash_Key key, s32bit index)
{
if(! (key.key[index/32] & NTH_BIT(index%32)) ){
printf("%d", index);
print_bitboard(HORIZONTAL);
print_hashkey(key);
fatal_error(1, "HashKey Incorrect.\n");
}
}
static void
check_hashkey_bit_not_set(Hash_Key key, s32bit index)
{
if( (key.key[index/32] & NTH_BIT(index%32)) ){
printf("%d", index);
print_bitboard(HORIZONTAL);
print_hashkey(key);
fatal_error(1, "HashKey Incorrect.\n");
}
}
static void
check_hashkey_code(Hash_Key key)
{
s32bit i, j, index, n_rows, n_cols, code;
n_rows = g_board_size[HORIZONTAL], n_cols = g_board_size[VERTICAL];
code = key.code;
for(i = 0; i < n_rows; i++)
for(j = 0; j < n_cols; j++){
index = (i*n_cols) + j;
if(key.key[index/32] & NTH_BIT(index%32))
code ^= g_zobrist[i+1][j+1];
}
if(code != 0){
fatal_error(1, "Invalid hash code.\n");
}
}
//========================================================
// This function checks to make sure hash codes
// and keys are correct.
//========================================================
extern void
check_hash_code_sanity()
{
s32bit i, j, index, n_rows, n_cols;
n_rows = g_board_size[HORIZONTAL], n_cols = g_board_size[VERTICAL];
for(i = 0; i < n_rows; i++)
for(j = 0; j < n_cols; j++)
if(g_board[HORIZONTAL][i+1] & NTH_BIT(j+1)) {
index = (i*n_cols)+j;
check_hashkey_bit_set(g_norm_hashkey, index);
index = (i*n_cols) + (n_cols - j - 1);
check_hashkey_bit_set(g_flipV_hashkey, index);
index = ( (n_rows - i - 1) *n_cols) + j;
check_hashkey_bit_set(g_flipH_hashkey, index);
index = ( (n_rows - i - 1) *n_cols) + (n_cols - j - 1);
check_hashkey_bit_set(g_flipVH_hashkey, index);
} else {
index = (i*n_cols)+j;
check_hashkey_bit_not_set(g_norm_hashkey, index);
index = (i*n_cols) + (n_cols - j - 1);
check_hashkey_bit_not_set(g_flipV_hashkey, index);
index = ( (n_rows - i - 1) *n_cols) + j;
check_hashkey_bit_not_set(g_flipH_hashkey, index);
index = ( (n_rows - i - 1) *n_cols) + (n_cols - j - 1);
check_hashkey_bit_not_set(g_flipVH_hashkey, index);
}
check_hashkey_code(g_norm_hashkey);
check_hashkey_code(g_flipV_hashkey);
check_hashkey_code(g_flipH_hashkey);
check_hashkey_code(g_flipVH_hashkey);
}
//========================================================
// This function compares the Horizontal board info to
// the vertical board info.
//========================================================
extern void
check_board_sanity()
{
s32bit i, j;
s32bit count;
for(j = 0; j < g_board_size[HORIZONTAL] + 2; j++)
for(i = 0; i < g_board_size[VERTICAL] + 2; i++){
count = 0;
if(g_board[VERTICAL][i] & NTH_BIT(j)) count++;
if(g_board[HORIZONTAL][j] & NTH_BIT(i)) count++;
if(count == 1){
print_board(VERTICAL);
print_board(HORIZONTAL);
printf("%d %d - %d.\n", j, i, count);
fatal_error(1, "Board is inconsistent.\n");
}
}
}
//========================================================
// Check the board info which we have to make sure that it
// is accurate.
//========================================================
/*
extern void
check_info_sanity()
{
}*/
//########################################################
// Display functions.
// These functions print out some set of information in what
// is hopefully a fairly readable format.
//########################################################
extern void
print_hashentry(s32bit index)
{
Hash_Entry entry = g_trans_table[index];
printf("Hash entry: %d.\n", index);
printf(" Key:%8X:%8X:%8X:%8X, n:%u, d:%d, w:%d"
", v:%d, t:%d, int:%d.\n",
entry.key[0], entry.key[1], entry.key[2], entry.key[3],
entry.nodes, entry.depth, entry.whos_turn,
entry.value, entry.type, entry.best_move);
}
extern void
print_board(s32bit player)
{
s32bit player_index;
s32bit row, col, i, j;
player_index = player&PLAYER_MASK;
row = g_board_size[player_index];
col = g_board_size[player_index^PLAYER_MASK];
for(i = 0; i < row; i++){
for(j = 0; j < col; j++){
if(g_board[player_index][i+1] & NTH_BIT(j+1))
printf(" #");
else
printf(" 0");
}
printf("\n");
}
}
extern void
print_board_info(s32bit player)
{
s32bit num_rows, num_cols, max_dim, i;
char str[32][80], null_str[1] = "";
num_rows = g_board_size[HORIZONTAL];
num_cols = g_board_size[VERTICAL];
max_dim = MAX_TWO(num_rows, num_cols);
sprintf(str[1], "Number of rows = %d", g_board_size[HORIZONTAL]);
sprintf(str[2], "Number of columns = %d", g_board_size[VERTICAL]);
printf("%7s %15s %15s\n",
null_str, "Vertical", "Horizontal");
printf("%7s %7s %7s %7s %7s\n",
null_str, "Real", "Safe", "Real", "Safe");
for(i = 0; i < max_dim; i++){
printf("%6d) %7d %7d %7d %7d %s\n", i + 1,
g_info[VERTICAL][i+1].real, g_info[VERTICAL][i+1].safe,
g_info[HORIZONTAL][i+1].real, g_info[HORIZONTAL][i+1].safe,
(i < 2) ? str[i+1] : null_str);
}
printf("Totals: %7d %7d %7d %7d\n",
g_info_totals[VERTICAL].real, g_info_totals[VERTICAL].safe,
g_info_totals[HORIZONTAL].real, g_info_totals[HORIZONTAL].safe);
}
extern void
print_bitboard(s32bit player)
{
s32bit player_index;
s32bit i;
player_index = player&PLAYER_MASK;
for(i = 0; i < g_board_size[player_index] + 2; i++)
printf("%X\n", g_board[player_index][i]);
}
extern void
print_hashkey(Hash_Key key)
{
printf("Key: %8X:%8X:%8X:%8X, Code: %8X.\n",
key.key[0], key.key[1], key.key[2], key.key[3], key.code);
}
extern void
print_u64bit(u64bit val)
{
s32bit vals[10];
s32bit i = 0;
do {
vals[i] = val % 1000;
val = val / 1000;
i++;
} while(val != 0);
if(i > 10) fatal_error(1, "Too large???\n");
printf("%d", vals[--i]);
while(i != 0)
printf(",%3d", vals[--i]);
}
extern void
print_keyinfo(KeyInfo_s info, s32bit with)
{
if(info.bit1_index == -1) fatal_error(1, "bit1_index equal to -1");
if(with)
printf("%3d:%3d %8X ",
info.bit1_index, info.bit2_index, info.hash_code);
else
printf("%3d:%3d ",
info.bit1_index, info.bit2_index);
}
extern void
print_keyinfo_table(s32bit player, s32bit with_hashcode)
{
s32bit r, c;
for(r = 0; r < 32; r++)
for(c = 0; c < 32; c++){
if(g_keyinfo[player][r][c].norm.bit1_index != -1){
printf("(%2d,%2d)>> ", r, c);
print_keyinfo(g_keyinfo[player][r][c].norm, with_hashcode);
print_keyinfo(g_keyinfo[player][r][c].flipV, with_hashcode);
print_keyinfo(g_keyinfo[player][r][c].flipH, with_hashcode);
print_keyinfo(g_keyinfo[player][r][c].flipVH, with_hashcode);
putchar('\n');
}
}
}
extern void
print_external()
{
// print_keyinfo_table(HORIZONTAL, 1);
print_keyinfo_table(VERTICAL, 1);
}
extern s32bit g_print;
extern void
print_current_state()
{
print_board(HORIZONTAL);
printf("\n");
print_board_info(HORIZONTAL);
g_print = 0;
}
extern const char*
current_search_state()
{
static char* str = NULL;
g_print = 1;
if(str != NULL) free(str);
asprintf(&str, "Nodes: %s.\n%d %d %d %d %d %d %d %d %d.",
u64bit_to_string(g_num_nodes),
g_move_number[1], g_move_number[2], g_move_number[3],
g_move_number[4], g_move_number[5], g_move_number[6],
g_move_number[7], g_move_number[8], g_move_number[9]);
return str;
}