Commit 29e98396 authored by Dmitry Suzdalev's avatar Dmitry Suzdalev

And now you can play with computer!

Edited Engine.cpp a bit. I forghot that KReversiMove takes (x,y) swapped
(and calls them row,col) compared to old Move class

svn path=/branches/work/kreversi_rewrite/; revision=572726
parent 9de53c75
......@@ -263,7 +263,11 @@ MoveAndValue::MoveAndValue(int x, int y, int value)
*/
class Score {
public:
Score();
Score()
{
m_score[White] = 0;
m_score[Black] = 0;
}
uint score(ChipColor color) const { return m_score[color]; }
......@@ -300,6 +304,8 @@ Engine::Engine(int st, int sd)/* : SuperEngine(st, sd) */
: m_strength(st)
{
m_random.setSeed(sd);
m_score = new Score;
m_bc_score = new Score;
SetupBcBoard();
SetupBits();
}
......@@ -309,6 +315,8 @@ Engine::Engine(int st) //: SuperEngine(st)
: m_strength(st)
{
m_random.setSeed(0);
m_score = new Score;
m_bc_score = new Score;
SetupBcBoard();
SetupBits();
}
......@@ -318,10 +326,17 @@ Engine::Engine()// : SuperEngine(1)
: m_strength(1)
{
m_random.setSeed(0);
m_score = new Score;
m_bc_score = new Score;
SetupBcBoard();
SetupBits();
}
Engine::~Engine()
{
delete m_score;
delete m_bc_score;
}
// keep GUI alive
/*
......@@ -398,7 +413,7 @@ KReversiMove Engine::computeMove(const KReversiGame& game, bool competitive)
for (uint y = 0; y < 10; y++) {
if (1 <= x && x <= 8
&& 1 <= y && y <= 8)
m_board[x][y] = game.chipColorAt(x-1, y-1);
m_board[x][y] = game.chipColorAt(y-1, x-1);
else
m_board[x][y] = NoColor;
}
......@@ -496,7 +511,7 @@ KReversiMove Engine::computeMove(const KReversiGame& game, bool competitive)
if (interrupted())
return KReversiMove(NoColor, -1, -1);
else if (maxval != -LARGEINT)
return KReversiMove(color, max_x, max_y);
return KReversiMove(color, max_y-1, max_x-1);
else
return KReversiMove(NoColor, -1, -1);
}
......@@ -513,16 +528,16 @@ KReversiMove Engine::ComputeFirstMove(const KReversiGame& game)
r = m_random.getLong(4) + 1;
if (color == White) {
if (r == 1) return KReversiMove(color, 3, 5);
else if (r == 2) return KReversiMove(color, 4, 6);
else if (r == 3) return KReversiMove(color, 5, 3);
else return KReversiMove(color, 6, 4);
if (r == 1) return KReversiMove(color, 4, 2);
else if (r == 2) return KReversiMove(color, 5, 3);
else if (r == 3) return KReversiMove(color, 2, 4);
else return KReversiMove(color, 3, 5);
}
else {
if (r == 1) return KReversiMove(color, 3, 4);
else if (r == 2) return KReversiMove(color, 5, 6);
else if (r == 3) return KReversiMove(color, 4, 3);
else return KReversiMove(color, 6, 5);
if (r == 1) return KReversiMove(color, 3, 2);
else if (r == 2) return KReversiMove(color, 5, 4);
else if (r == 3) return KReversiMove(color, 2, 3);
else return KReversiMove(color, 4, 5);
}
}
......
......@@ -207,6 +207,8 @@ public:
Engine(int st);
Engine();
~Engine();
KReversiMove computeMove(const KReversiGame& game, bool competitive);
void setInterrupt(bool intr) { m_interrupt = intr; }
......
......@@ -2,28 +2,56 @@
#include "kreversiboard.h"
#include "kreversigame.h"
#include "Engine.h"
KReversiGame::KReversiGame()
: m_curPlayer(Black), m_computerColor( White )
{
m_board = new KReversiBoard();
m_engine = new Engine(1);
}
KReversiGame::~KReversiGame()
{
delete m_board;
delete m_engine;
}
void KReversiGame::putChipAt( int row, int col )
void KReversiGame::makePlayerMove( int row, int col )
{
// FIXME dimsuz: debug temporary code
if( m_curPlayer == m_computerColor )
{
kDebug() << "Warning! Player turn called while it's computer turn" << endl;
return;
}
KReversiMove move( m_curPlayer, row, col );
if( !isMovePossible(move) )
{
kDebug() << "No move possible" << endl;
return;
}
m_board->setChipColor( row, col, m_curPlayer );
makeMove( move );
}
void KReversiGame::makeComputerMove()
{
// FIXME dimsuz: debug temporary code
if( m_curPlayer != m_computerColor )
{
kDebug() << "Warning! Computer turn called while it's player turn" << endl;
return;
}
KReversiMove move = m_engine->computeMove( *this, true );
kDebug() << "Computer plays ("<<move.row<<","<<move.col<<")" <<endl;
makeMove(move);
}
void KReversiGame::makeMove( const KReversiMove& move )
{
m_board->setChipColor( move.row, move.col, m_curPlayer );
// now turn color of all chips that were won
if( hasChunk( Up, move ) )
{
......@@ -101,6 +129,7 @@ void KReversiGame::putChipAt( int row, int col )
m_curPlayer = (m_curPlayer == White ? Black : White );
kDebug() << "Now " << (m_curPlayer == White ? "White" : "Black" )<< " play" << endl;
emit boardChanged();
emit currentPlayerChanged();
}
bool KReversiGame::isMovePossible( const KReversiMove& move ) const
......
......@@ -6,6 +6,7 @@
#include "commondefs.h"
class KReversiBoard;
class Engine;
/**
* KReversiGame incapsulates all of the game logic.
......@@ -31,16 +32,30 @@ public:
int playerScore( ChipColor player ) const;
// NOTE: this is just a wrapper around KReversiBoard::playerScore
ChipColor chipColorAt( int row, int col ) const;
void putChipAt(int row, int col);
/**
* This will put the player chip at row, col.
* If that is possible of course
*/
void makePlayerMove(int row, int col);
/**
* This function will make computer decide where he
* wants to put his chip... and he'll put it there!
*/
void makeComputerMove();
/**
* Returns true, if it's computer's turn now
*/
bool computersTurn() const { return m_curPlayer == m_computerColor; }
signals:
void boardChanged();
void currentPlayerChanged();
private:
enum Direction { Up, Down, Right, Left, UpLeft, UpRight, DownLeft, DownRight };
/**
* This function will tell you if the move is possible.
* That's why it was given such a name ;)
*/
bool isMovePossible( const KReversiMove& move ) const;
enum Direction { Up, Down, Right, Left, UpLeft, UpRight, DownLeft, DownRight };
/**
* Searches for "chunk" in direction dir for move.
* As my English-skills are somewhat limited, let me introduce
......@@ -51,6 +66,11 @@ private:
* where [O] is one or more opponent's pieces
*/
bool hasChunk( Direction dir, const KReversiMove& move) const;
/**
* Performs move, i.e. marks all the chips that player wins with
* this move with current player color
*/
void makeMove( const KReversiMove& move );
/**
* Board itself
*/
......@@ -63,5 +83,9 @@ private:
* The color of the computer played chips
*/
ChipColor m_computerColor;
/**
* Our AI
*/
Engine *m_engine;
};
#endif
......@@ -25,6 +25,7 @@ void KReversiScene::setGame( KReversiGame* game )
{
m_game = game;
connect( m_game, SIGNAL(boardChanged()), this, SLOT(updateBoard()) );
connect( m_game, SIGNAL(currentPlayerChanged()), this, SLOT(currentPlayerChanged()) );
// this will remove all items left from previous game
QList<QGraphicsItem*> allChips = items( m_boardRect );
......@@ -66,6 +67,12 @@ void KReversiScene::updateBoard()
}
}
void KReversiScene::currentPlayerChanged()
{
if( m_game->computersTurn() )
m_game->makeComputerMove();
}
QPointF KReversiScene::cellCenter( int row, int col ) const
{
return QPointF( m_boardRect.x() + col*CHIP_SIZE + CHIP_SIZE/2, m_boardRect.y() + row*CHIP_SIZE + CHIP_SIZE/2 );
......@@ -96,6 +103,12 @@ void KReversiScene::drawBackground( QPainter *p, const QRectF& )
void KReversiScene::mousePressEvent( QGraphicsSceneMouseEvent* ev )
{
if( m_game->computersTurn() )
{
kDebug() << "Not your turn, player" << endl;
return;
}
if( !m_boardRect.contains(ev->scenePos()) )
return;
int row = (int)ev->scenePos().y() / CHIP_SIZE;
......@@ -103,7 +116,7 @@ void KReversiScene::mousePressEvent( QGraphicsSceneMouseEvent* ev )
kDebug() << "Cell (" << row << "," << col << ") clicked." << endl;
m_game->putChipAt( row, col );
m_game->makePlayerMove( row, col );
}
#include "kreversiscene.moc"
......@@ -23,6 +23,7 @@ public:
void setGame( KReversiGame* game );
public slots:
void updateBoard();
void currentPlayerChanged();
private:
/**
* Draws a background with 8x8 cell matrix.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment