blob: 2a5b2f644df84bc32c2d3beb130e1ef711542551 [file] [log] [blame]
#include "globals.h"
#include "macros.h"
//########################################################
// This function counts the number of safe moves in a row.
//
// Never call this function for rows 0 or 31.
//########################################################
static inline s32bit
count_safe(s32bit player, s32bit row)
{
u32bit guard = g_board[player][row-1] & g_board[player][row+1];
// mask contains a bit for each safe move.
u32bit mask= ( (~(g_board[player][row] | (g_board[player][row] << 1)))
& (guard & (guard << 1)) );
return COUNTMOVES(mask);
}
//########################################################
// This function counts the number of real moves in a row.
//
// Never call this function for rows 0 or 31.
//########################################################
static inline s32bit
count_real(s32bit player, s32bit row)
{
// mask contains a bit for each real move.
u32bit mask= ~(g_board[player][row] | (g_board[player][row] << 1));
return COUNTMOVES(mask);
}
static inline void
_update_safe(s32bit player, s32bit row)
{
s32bit count = count_safe(player, row);
g_info_totals[player].safe += count - g_info[player][row].safe;
g_info[player][row].safe = count;
}
static inline void
_update_real(s32bit player, s32bit row)
{
s32bit count = count_real(player, row);
g_info_totals[player].real += count - g_info[player][row].real;
g_info[player][row].real = count;
}
extern void
update_safe(s32bit player, s32bit row)
{ _update_safe(player, row); }
extern void
update_real(s32bit player, s32bit row)
{ _update_real(player, row); }
extern void
toggle_move(Move move, s32bit player)
{
s32bit row, col, horz_play, vert_play;
row = (move).array_index, col = (move).mask_index;
horz_play = player & PLAYER_MASK;
vert_play = player ^ PLAYER_MASK;
g_board[horz_play][row] ^= (3<<col);
g_board[vert_play][col] ^= (1<<row);
g_board[vert_play][col+1] ^= (1<<row);
// update safe moves
if(row - 1 != 0)
_update_safe(horz_play, row - 1);
_update_safe(horz_play, row);
if(row != g_board_size[horz_play])
_update_safe(horz_play, row + 1);
if(col - 1 != 0)
_update_safe(vert_play, col - 1);
if(col + 1 != g_board_size[vert_play])
_update_safe(vert_play, col + 2);
// update real moves
_update_real(horz_play, row);
_update_real(vert_play, col);
_update_real(vert_play, col + 1);
}
//#define DEBUG_SCORE_MOVE
static inline s32bit
score_move(Move move, s32bit player)
{
s32bit row, col, horz_play, vert_play;
s32bit score;
row = move.array_index, col = move.mask_index;
horz_play = player & PLAYER_MASK;
vert_play = player ^ PLAYER_MASK;
g_board[horz_play][row] ^= (3<<col);
g_board[vert_play][col] ^= (1<<row);
g_board[vert_play][col+1] ^= (1<<row);
// update real moves
score = count_real(horz_play, row) - g_info[horz_play][row].real;
score -= count_real(vert_play, col) - g_info[vert_play][col].real;
score -= count_real(vert_play, col + 1) - g_info[vert_play][col+1].real;
// update safe moves
if(row - 1 != 0)
score += count_safe(horz_play, row - 1) - g_info[horz_play][row-1].safe;
score += count_safe(horz_play, row) - g_info[horz_play][row].safe;
if(row != g_board_size[horz_play])
score += count_safe(horz_play, row+1) - g_info[horz_play][row+1].safe;
if(col - 1 != 0)
score -= count_safe(vert_play, col - 1) - g_info[vert_play][col-1].safe;
if(col + 1 != g_board_size[vert_play])
score -= count_safe(vert_play, col + 2) - g_info[vert_play][col+2].safe;
g_board[horz_play][row] ^= (3<<col);
g_board[vert_play][col] ^= (1<<row);
g_board[vert_play][col+1] ^= (1<<row);
score *= 128;
score += g_first_move[player][row][col];
return score;
}
extern void
score_and_get_first(Move movelist[MAXMOVES], s32bit num_moves,
s32bit player, Move first)
{
s32bit i, max = -50000, max_index = -1;
//========================================================
// Give the move from the hashtable a large sorting value.
//========================================================
/*
{
int z = 0;
for (z = 0; z < num_moves; z++)
printf("> %d %d\n", movelist[z].array_index, movelist[z].mask_index);
}
*/
if(first.array_index != -1){
for(i = 0; i < num_moves; i++){
if(first.array_index == movelist[i].array_index
&& first.mask_index == movelist[i].mask_index){
movelist[i].info = 450000;
max_index = i;
} else {
movelist[i].info = score_move(movelist[i], player);
}
}
}
else {
for(i = 0; i < num_moves; i++){
movelist[i].info = score_move(movelist[i], player);
if(movelist[i].info > max){
max = movelist[i].info;
max_index = i;
}
}
}
if(max_index == -1) fatal_error(1, "No maximum\n");
// put biggest at front
if(num_moves > 1) {
Move tmp_move = movelist[max_index];
for(i = max_index; i > 0; i--)
movelist[i] = movelist[i - 1];
movelist[0] = tmp_move;
}
}