[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdegames/kreversi
From: Dmitry Suzdalev <dimsuz () gmail ! com>
Date: 2007-12-05 9:08:45
Message-ID: 1196845725.171904.20756.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 745061 by dimsuz:
Fix crash caused by the fact that KReversi Engine can't compute to moves at the same time.
Someday it should become multithreaded I guess...
BUG: 153465
M +48 -33 Engine.cpp
M +3 -1 Engine.h
M +2 -0 commondefs.h
M +13 -1 kreversigame.cpp
M +1 -1 kreversiscene.cpp
--- trunk/KDE/kdegames/kreversi/Engine.cpp #745060:745061
@@ -118,6 +118,7 @@
#include "Engine.h"
#include "kreversigame.h"
#include <QApplication>
+#include <KDebug>
// ================================================================
// Class ULONG64
@@ -126,7 +127,7 @@
#if !defined(__GNUC__)
-ULONG64::ULONG64() : QBitArray(64)
+ULONG64::ULONG64() : QBitArray(64)
{
fill(0);
}
@@ -135,7 +136,7 @@
// Initialize an ULONG64 from a 32 bit value.
//
-ULONG64::ULONG64( unsigned int value ) : QBitArray(64)
+ULONG64::ULONG64( unsigned int value ) : QBitArray(64)
{
fill(0);
for(int i = 0; i < 32; i++) {
@@ -148,7 +149,7 @@
// Shift an ULONG64 left one bit.
//
-void ULONG64::shl()
+void ULONG64::shl()
{
for(int i = 63; i > 0; i--)
setBit(i, testBit(i - 1));
@@ -191,7 +192,7 @@
}
-void SquareStack::resize(int size)
+void SquareStack::resize(int size)
{
m_squarestack.resize(size);
}
@@ -201,7 +202,7 @@
// resize it to 'size'.
//
-void SquareStack::init(int size)
+void SquareStack::init(int size)
{
resize(size);
@@ -212,7 +213,7 @@
-inline SquareStackEntry SquareStack::Pop()
+inline SquareStackEntry SquareStack::Pop()
{
return m_squarestack[--m_top];
}
@@ -233,7 +234,7 @@
//
-inline void MoveAndValue::setXYV(int x, int y, int value)
+inline void MoveAndValue::setXYV(int x, int y, int value)
{
m_x = x;
m_y = y;
@@ -241,13 +242,13 @@
}
-MoveAndValue::MoveAndValue()
+MoveAndValue::MoveAndValue()
{
setXYV(0,0,0);
}
-MoveAndValue::MoveAndValue(int x, int y, int value)
+MoveAndValue::MoveAndValue(int x, int y, int value)
{
setXYV(x, y, value);
}
@@ -274,7 +275,7 @@
void dec(ChipColor color) { m_score[color]--; }
void add(ChipColor color, uint s) { m_score[color] += s; }
void sub(ChipColor color, uint s) { m_score[color] -= s; }
-
+
private:
uint m_score[2];
};
@@ -290,7 +291,7 @@
Engine::Engine(int st, int sd)/* : SuperEngine(st, sd) */
- : m_strength(st)
+ : m_strength(st), m_computingMove( false )
{
m_random.setSeed(sd);
m_score = new Score;
@@ -300,8 +301,8 @@
}
-Engine::Engine(int st) //: SuperEngine(st)
- : m_strength(st)
+Engine::Engine(int st) //: SuperEngine(st)
+ : m_strength(st), m_computingMove(false)
{
m_random.setSeed(0);
m_score = new Score;
@@ -311,8 +312,8 @@
}
-Engine::Engine()// : SuperEngine(1)
- : m_strength(1)
+Engine::Engine()// : SuperEngine(1)
+ : m_strength(1), m_computingMove(false)
{
m_random.setSeed(0);
m_score = new Score;
@@ -328,7 +329,7 @@
}
// keep GUI alive
-void Engine::yield()
+void Engine::yield()
{
qApp->processEvents();
}
@@ -336,8 +337,15 @@
// Calculate the best move from the current position, and return it.
-KReversiPos Engine::computeMove(const KReversiGame& game, bool competitive)
+KReversiPos Engine::computeMove(const KReversiGame& game, bool competitive)
{
+ if( m_computingMove )
+ {
+ kDebug() << "I'm already computing move! Yours KReversi Engine.";
+ return KReversiPos();
+ }
+ m_computingMove = true;
+
ChipColor color;
// A competitive game is one where we try our damnedest to make the
@@ -355,7 +363,10 @@
// Get the color to calculate the move for.
color = game.currentPlayer();
if (color == NoColor)
- return KReversiPos(NoColor, -1, -1);
+ {
+ m_computingMove = false;
+ return KReversiPos();
+ }
// Figure out the current score
m_score->set(White, game.playerScore(White));
@@ -364,7 +375,10 @@
// Treat the first move as a special case (we can basically just
// pick a move at random).
if (m_score->score(White) + m_score->score(Black) == 4)
- return ComputeFirstMove(game);
+ {
+ m_computingMove = false;
+ return ComputeFirstMove(game);
+ }
// Let there be room for 3000 changes during the recursive search.
// This is more than will ever be needed.
@@ -372,7 +386,7 @@
// Get the search depth. If we are close to the end of the game,
// the number of possible moves goes down, so we can search deeper
- // without using more time.
+ // without using more time.
m_depth = m_strength;
if (m_score->score(White) + m_score->score(Black) + m_depth + 3 >= 64)
m_depth = 64 - m_score->score(White) - m_score->score(Black);
@@ -392,7 +406,7 @@
// values and the later in the game the more we use the number of
// pieces.
m_coeff = 100 - (100*
- (m_score->score(White) + m_score->score(Black)
+ (m_score->score(White) + m_score->score(Black)
+ m_depth - 4)) / 60;
// Initialize the board that we use for the search.
@@ -430,7 +444,7 @@
null_bits = 0;
// The main search loop. Step through all possible moves and keep
- // track of the most valuable one. This move is stored in
+ // track of the most valuable one. This move is stored in
// (max_x, max_y) and the value is stored in maxval.
m_nodes_searched = 0;
for (int x = 1; x < 9; x++) {
@@ -458,8 +472,8 @@
// user wants a casual game, which is set in the settings
// dialog.
int randi = m_random.getLong(7);
- if (maxval == -LARGEINT
- || m_competitive
+ if (maxval == -LARGEINT
+ || m_competitive
|| randi < (int) m_strength) {
maxval = val;
max_x = x;
@@ -473,7 +487,7 @@
}
// Jump out prematurely if interrupt is set.
- if (interrupted())
+ if (interrupted())
break;
}
}
@@ -486,7 +500,7 @@
int i;
for (i = 0; i < number_of_moves; i++) {
- if (moves[i].m_value == maxval && --r <= 0)
+ if (moves[i].m_value == maxval && --r <= 0)
break;
}
@@ -494,6 +508,7 @@
max_y = moves[i].m_y;
}
+ m_computingMove = false;
// Return a suitable move.
if (interrupted())
return KReversiPos(NoColor, -1, -1);
@@ -507,7 +522,7 @@
// Get the first move. We can pick any move at random.
//
-KReversiPos Engine::ComputeFirstMove(const KReversiGame& game)
+KReversiPos Engine::ComputeFirstMove(const KReversiGame& game)
{
int r;
ChipColor color = game.currentPlayer();
@@ -554,7 +569,7 @@
// Loop through all 8 directions and turn the pieces that can be turned.
for (int xinc = -1; xinc <= 1; xinc++)
for (int yinc = -1; yinc <= 1; yinc++) {
- if (xinc == 0 && yinc == 0)
+ if (xinc == 0 && yinc == 0)
continue;
int x, y;
@@ -616,7 +631,7 @@
else {
// Take a sure win and avoid a sure loss (may not be optimal):
- if (finalscore > 0)
+ if (finalscore > 0)
retval = LARGEINT - 65 + finalscore;
else if (finalscore < 0)
retval = -(LARGEINT - 65 + finalscore);
@@ -670,14 +685,14 @@
for (int x = 1; x < 9; x++) {
for (int y = 1; y < 9; y++) {
- if (m_board[x][y] == NoColor
+ if (m_board[x][y] == NoColor
&& (m_neighbor_bits[x][y] & colorbits) != null_bits) {
int val = ComputeMove2(x, y, opponent, level+1, maxval, opponentbits,
colorbits);
if (val != ILLEGAL_VALUE && val > maxval) {
maxval = val;
- if (maxval > -cutoffval || interrupted())
+ if (maxval > -cutoffval || interrupted())
break;
}
}
@@ -687,7 +702,7 @@
break;
}
- if (interrupted())
+ if (interrupted())
return -LARGEINT;
return maxval;
@@ -713,7 +728,7 @@
retval = score_color - score_opponent;
else {
retval = (100-m_coeff) *
- (m_score->score(color) - m_score->score(opponent))
+ (m_score->score(color) - m_score->score(opponent))
+ m_coeff * BC_WEIGHT * (m_bc_score->score(color)
- m_bc_score->score(opponent));
}
--- trunk/KDE/kdegames/kreversi/Engine.h #745060:745061
@@ -249,7 +249,7 @@
Score* m_score;
Score* m_bc_score;
SquareStack m_squarestack;
-
+
int m_depth;
int m_coeff;
int m_nodes_searched;
@@ -262,6 +262,8 @@
ULONG64 m_coord_bit[9][9];
ULONG64 m_neighbor_bits[9][9];
+
+ bool m_computingMove;
};
#endif
--- trunk/KDE/kdegames/kreversi/commondefs.h #745060:745061
@@ -33,6 +33,8 @@
ChipColor color;
int row;
int col;
+
+ bool isValid() const { return ( color != NoColor || row != -1 || col != -1 ); }
};
typedef QList<KReversiPos> PosList;
--- trunk/KDE/kdegames/kreversi/kreversigame.cpp #745060:745061
@@ -79,7 +79,11 @@
if( !demoMode )
move = KReversiPos( m_playerColor, row, col );
else
+ {
move = m_engine->computeMove( *this, true );
+ if( !move.isValid() )
+ return;
+ }
if( !isMovePossible(move) )
{
@@ -145,7 +149,15 @@
// FIXME dimsuz: m_competitive. Read from config.
// (also there's computeMove in getHint)
KReversiPos move = m_engine->computeMove( *this, true );
- Q_ASSERT(move.color == m_computerColor);
+ if( !move.isValid() )
+ return;
+
+ if( move.color != m_computerColor )
+ {
+ kDebug() << "Strange! makeComputerMove() just got not computer move!";
+ return;
+ }
+
makeMove(move);
m_undoStack.push( m_changedChips );
}
--- trunk/KDE/kdegames/kreversi/kreversiscene.cpp #745060:745061
@@ -392,7 +392,7 @@
return;
}
KReversiPos hint = m_game->getHint();
- if(hint.row == -1 || hint.col == -1)
+ if( !hint.isValid() )
return;
if( m_hintChip == 0 )
m_hintChip = new KReversiChip( hint.color, m_frameSet, this );
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic