Source Code (Use browser search to find items of interest.)
Class Index
kreversi'Engine (./kdegames/kreversi/Engine.h:187)
class Engine : public SuperEngine {
public:
Engine(int st, int sd);
Engine(int st);
Engine();
virtual ~Engine() {};
Move ComputeMove(Game g);
Move ComputeFirstMove(Game g);
int ComputeMove2(int xplay, int yplay, int player, int level,
int cutoffval, ULONG64 playerbits, ULONG64 opponentbits);
int TryAllMoves(int opponent, int level, int cutoffval,
ULONG64 opponentbits, ULONG64 playerbits);
int EvaluatePosition(int player);
void SetupBcBoard();
void SetupBits();
int CalcBcScore(int player);
ULONG64 ComputeOccupiedBits(int player);
void yield();
private:
static const int LARGEINT;
static const int ILLEGAL_VALUE;
static const int BC_WEIGHT;
int m_board[10][10];
int m_bc_board[9][9];
Score m_score;
Score m_bc_score;
SquareStack m_squarestack;
int m_depth;
int m_coeff;
int m_nodes_searched;
bool m_exhaustive;
ULONG64 m_coord_bit[9][9];
ULONG64 m_neighbor_bits[9][9];
long lastYield;
};
kreversi'Engine::Engine() (./kdegames/kreversi/Engine.cpp:211)
Engine::Engine(int st, int sd) : SuperEngine(st, sd) {
SetupBcBoard();
SetupBits();
}
kreversi'Engine::Engine() (./kdegames/kreversi/Engine.cpp:217)
Engine::Engine(int st) : SuperEngine(st) {
SetupBcBoard();
SetupBits();
}
kreversi'Engine::Engine() (./kdegames/kreversi/Engine.cpp:223)
Engine::Engine() : SuperEngine(5) {
SetupBcBoard();
SetupBits();
}
// keep GUI alive
kreversi'Engine::yield() (./kdegames/kreversi/Engine.cpp:230)
void Engine::yield() {
qApp->processEvents();
}
kreversi'Engine::ComputeMove() (./kdegames/kreversi/Engine.cpp:235)
Move Engine::ComputeMove(Game g) {
m_exhaustive = false;
int player = g.GetWhoseTurn();
if (player == Score::NOBODY)
return Move(-1,-1,-1);
m_score.InitScore(g.GetScore(Score::WHITE), g.GetScore(Score::BLACK));
if (m_score.GetScore(Score::WHITE) + m_score.GetScore(Score::BLACK) == 4)
return ComputeFirstMove(g);
// JAVA m_board = new int[10][10];
//m_squarestack = new SquareStack(3000); // More than enough...
m_squarestack.init(3000);
m_depth = m_strength;
if (m_score.GetScore(Score::WHITE) + m_score.GetScore(Score::BLACK) +
m_depth + 4 >= 64)
m_depth =
64 - m_score.GetScore(Score::WHITE) - m_score.GetScore(Score::BLACK);
else if (m_score.GetScore(Score::WHITE) + m_score.GetScore(Score::BLACK) +
m_depth + 7 >= 64)
m_depth += 3;
else if (m_score.GetScore(Score::WHITE) + m_score.GetScore(Score::BLACK) +
m_depth + 9 >= 64)
m_depth += 2;
else if (m_score.GetScore(Score::WHITE) + m_score.GetScore(Score::BLACK) +
m_depth + 11 >= 64)
m_depth++;
if (m_score.GetScore(Score::WHITE) + m_score.GetScore(Score::BLACK) +
m_depth >= 64) m_exhaustive = true;
m_coeff =
100 - (100*
(m_score.GetScore(Score::WHITE) + m_score.GetScore(Score::BLACK) +
m_depth - 4))/60;
m_nodes_searched = 0;
for (int x=0; x<10; x++)
for (int y=0; y<10; y++)
m_board[x][y] = Score::NOBODY;
for (int x=1; x<9; x++)
for (int y=1; y<9; y++)
m_board[x][y] = g.GetSquare(x, y);
m_bc_score.InitScore(CalcBcScore(Score::WHITE), CalcBcScore(Score::BLACK));
ULONG64 playerbits = ComputeOccupiedBits(player);
ULONG64 opponentbits = ComputeOccupiedBits(Score::GetOpponent(player));
int maxval = -LARGEINT;
int max_x = 0;
int max_y = 0;
MoveAndValue moves[60];
int number_of_moves = 0;
int number_of_maxval = 0;
SetInterrupt(false);
ULONG64 null_bits;
null_bits = 0;
//struct tms tmsdummy;
//long starttime = times(&tmsdummy);
for (int x=1; x<9; x++)
for (int y=1; y<9; y++)
if (m_board[x][y] == Score::NOBODY &&
(m_neighbor_bits[x][y] & opponentbits) != null_bits)
{
int val = ComputeMove2(x, y, player, 1, maxval,
playerbits, opponentbits);
if (val != ILLEGAL_VALUE)
{
moves[number_of_moves++].setXYV(x, y, val);
if (val > maxval)
{
maxval = val;
max_x = x;
max_y = y;
number_of_maxval = 1;
}
else if (val == maxval) number_of_maxval++;
}
if (GetInterrupt()) break;
}
// long endtime = times(&tmsdummy);
if (number_of_maxval > 1)
{
int r = m_random.getLong(number_of_maxval) + 1;
int i;
for (i=0; i < number_of_moves; i++)
if (moves[i].m_value == maxval && --r <= 0) break;
max_x = moves[i].m_x;
max_y = moves[i].m_y;
}
if (GetInterrupt()) {
return Move(-1, -1, -1);
} else if (maxval != -LARGEINT) {
return Move(max_x, max_y, player);
} else {
return Move(-1, -1, -1);
}
}
kreversi'Engine::ComputeFirstMove() (./kdegames/kreversi/Engine.cpp:356)
Move Engine::ComputeFirstMove(Game g) {
int r;
int player = g.GetWhoseTurn();
r = m_random.getLong(4) + 1;
if (player == Score::WHITE)
{
if (r == 1) return Move(3, 5, player);
else if (r == 2) return Move(4, 6, player);
else if (r == 3) return Move(5, 3, player);
else return Move(6, 4, player);
}
else
{
if (r == 1) return Move(3, 4, player);
else if (r == 2) return Move(5, 6, player);
else if (r == 3) return Move(4, 3, player);
else return Move(6, 5, player);
}
}
kreversi'Engine::ComputeMove2() (./kdegames/kreversi/Engine.cpp:379)
int Engine::ComputeMove2(int xplay, int yplay, int player, int level,
int cutoffval, ULONG64 playerbits,
ULONG64 opponentbits)
{
int number_of_turned = 0;
SquareStackEntry mse;
int opponent = Score::GetOpponent(player);
m_nodes_searched++;
m_board[xplay][yplay] = player;
playerbits |= m_coord_bit[xplay][yplay];
m_score.ScoreAdd(player, 1);
m_bc_score.ScoreAdd(player, m_bc_board[xplay][yplay]);
///////////////////
// Turn all pieces:
///////////////////
for (int xinc=-1; xinc<=1; xinc++)
for (int yinc=-1; yinc<=1; yinc++)
if (xinc != 0 || yinc != 0)
{
int x, y;
for (x = xplay+xinc, y = yplay+yinc; m_board[x][y] == opponent;
x += xinc, y += yinc)
;
if (m_board[x][y] == player)
for (x -= xinc, y -= yinc; x != xplay || y != yplay;
x -= xinc, y -= yinc)
{
m_board[x][y] = player;
playerbits |= m_coord_bit[x][y];
opponentbits &= ~m_coord_bit[x][y];
m_squarestack.Push(x, y);
m_bc_score.ScoreAdd(player, m_bc_board[x][y]);
m_bc_score.ScoreSubtract(opponent, m_bc_board[x][y]);
number_of_turned++;
}
}
int retval = -LARGEINT;
if (number_of_turned > 0)
{
//////////////
// Legal move:
//////////////
m_score.ScoreAdd(player, number_of_turned);
m_score.ScoreSubtract(opponent, number_of_turned);
if (level >= m_depth) retval = EvaluatePosition(player); // Terminal node
else
{
int maxval = TryAllMoves(opponent, level, cutoffval, opponentbits,
playerbits);
if (maxval != -LARGEINT) retval = -maxval;
else
{
///////////////////////////////////////////////////////////////
// No possible move for the opponent, it is players turn again:
///////////////////////////////////////////////////////////////
retval= TryAllMoves(player, level, -LARGEINT, playerbits,
opponentbits);
if (retval == -LARGEINT)
{
///////////////////////////////////////////////
// No possible move for anybody => end of game:
///////////////////////////////////////////////
int finalscore =
m_score.GetScore(player) - m_score.GetScore(opponent);
if (m_exhaustive) retval = finalscore;
else
{
// Take a sure win and avoid a sure loss (may not be optimal):
if (finalscore > 0) retval = LARGEINT - 65 + finalscore;
else if (finalscore < 0) retval = -(LARGEINT - 65 + finalscore);
else retval = 0;
}
}
}
}
m_score.ScoreAdd(opponent, number_of_turned);
m_score.ScoreSubtract(player, number_of_turned);
}
/////////////////
// Restore board:
/////////////////
for (int i = number_of_turned; i > 0; i--)
{
mse = m_squarestack.Pop();
m_bc_score.ScoreAdd(opponent, m_bc_board[mse.m_x][mse.m_y]);
m_bc_score.ScoreSubtract(player, m_bc_board[mse.m_x][mse.m_y]);
m_board[mse.m_x][mse.m_y] = opponent;
}
m_board[xplay][yplay] = Score::NOBODY;
m_score.ScoreSubtract(player, 1);
m_bc_score.ScoreSubtract(player, m_bc_board[xplay][yplay]);
if (number_of_turned < 1 || GetInterrupt()) return ILLEGAL_VALUE;
else return retval;
}
kreversi'Engine::TryAllMoves() (./kdegames/kreversi/Engine.cpp:495)
int Engine::TryAllMoves(int opponent, int level, int cutoffval,
ULONG64 opponentbits, ULONG64 playerbits)
{
int maxval = -LARGEINT;
// keep GUI alive
yield();
ULONG64 null_bits;
null_bits = 0;
for (int x=1; x<9; x++)
{
for (int y=1; y<9; y++)
if (m_board[x][y] == Score::NOBODY &&
(m_neighbor_bits[x][y] & playerbits) != null_bits)
{
int val = ComputeMove2(x, y, opponent, level+1, maxval, opponentbits,
playerbits);
if (val != ILLEGAL_VALUE && val > maxval)
{
maxval = val;
if (maxval > -cutoffval || GetInterrupt()) break;
}
}
if (maxval > -cutoffval || GetInterrupt()) break;
}
if (GetInterrupt()) return -LARGEINT;
return maxval;
}
kreversi'Engine::EvaluatePosition() (./kdegames/kreversi/Engine.cpp:530)
int Engine::EvaluatePosition(int player)
{
int retval;
int opponent = Score::GetOpponent(player);
int score_player = m_score.GetScore(player);
int score_opponent = m_score.GetScore(opponent);
if (m_exhaustive) retval = score_player - score_opponent;
else
{
retval = (100-m_coeff) *
(m_score.GetScore(player) - m_score.GetScore(opponent)) +
m_coeff * BC_WEIGHT *
(m_bc_score.GetScore(player)-m_bc_score.GetScore(opponent));
}
return retval;
}
kreversi'Engine::SetupBits() (./kdegames/kreversi/Engine.cpp:551)
void Engine::SetupBits()
{
//m_coord_bit = new long[9][9];
//m_neighbor_bits = new long[9][9];
ULONG64 bits = 1;
for (int i=1; i < 9; i++)
for (int j=1; j < 9; j++)
{
m_coord_bit[i][j] = bits;
#if !defined(__GNUC__)
bits.shl();
#else
bits *= 2;
#endif
}
for (int i=1; i < 9; i++)
for (int j=1; j < 9; j++)
{
m_neighbor_bits[i][j] = 0;
for (int xinc=-1; xinc<=1; xinc++)
for (int yinc=-1; yinc<=1; yinc++)
if (xinc != 0 || yinc != 0)
if (i + xinc > 0 && i + xinc < 9 && j + yinc > 0 && j + yinc < 9)
m_neighbor_bits[i][j] |= m_coord_bit[i + xinc][j + yinc];
}
}
kreversi'Engine::SetupBcBoard() (./kdegames/kreversi/Engine.cpp:583)
void Engine::SetupBcBoard()
{
// JAVA m_bc_board = new int[9][9];
for (int i=1; i < 9; i++)
for (int j=1; j < 9; j++)
{
if (i == 2 || i == 7) m_bc_board[i][j] = -2; else m_bc_board[i][j] = 0;
if (j == 2 || j == 7) m_bc_board[i][j] -= 2;
}
m_bc_board[1][1] = 20;
m_bc_board[8][1] = 20;
m_bc_board[1][8] = 20;
m_bc_board[8][8] = 20;
m_bc_board[1][2] = -2;
m_bc_board[2][1] = -2;
m_bc_board[1][7] = -2;
m_bc_board[7][1] = -2;
m_bc_board[8][2] = -2;
m_bc_board[2][8] = -2;
m_bc_board[8][7] = -2;
m_bc_board[7][8] = -2;
}
kreversi'Engine::CalcBcScore() (./kdegames/kreversi/Engine.cpp:610)
int Engine::CalcBcScore(int player)
{
int sum = 0;
for (int i=1; i < 9; i++)
for (int j=1; j < 9; j++)
if (m_board[i][j] == player)
sum += m_bc_board[i][j];
return sum;
}
kreversi'Engine::ComputeOccupiedBits() (./kdegames/kreversi/Engine.cpp:623)
ULONG64 Engine::ComputeOccupiedBits(int player)
{
ULONG64 retval = 0;
for (int i=1; i < 9; i++)
for (int j=1; j < 9; j++)
if (m_board[i][j] == player) retval |= m_coord_bit[i][j];
return retval;
}