Commit c26a2eea authored by Inge Wallin's avatar Inge Wallin

Revert "Extract all Reversi logic into it's own file."

This reverts commit d1ec9049.
parent eb93090b
......@@ -23,7 +23,6 @@ include_directories( ${CMAKE_SOURCE_DIR}/libkdegames/highscore )
########### next target ###############
set(kreversi_SRCS
reversi.cpp
colorscheme.cpp
kreversigame.cpp
kreversiview.cpp
......
......@@ -241,13 +241,13 @@ public:
m_score[Black] = 0;
}
uint score(Color color) const { return m_score[color]; }
uint score(ChipColor color) const { return m_score[color]; }
void set(Color color, uint score) { m_score[color] = score; }
void inc(Color color) { m_score[color]++; }
void dec(Color color) { m_score[color]--; }
void add(Color color, uint s) { m_score[color] += s; }
void sub(Color color, uint s) { m_score[color] -= s; }
void set(ChipColor color, uint score) { m_score[color] = score; }
void inc(ChipColor color) { m_score[color]++; }
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];
......@@ -314,7 +314,7 @@ void Engine::yield()
// Calculate the best move from the current position, and return it.
KReversiPos Engine::computeMove(const KReversiGame& game, Color color, bool competitive)
KReversiPos Engine::computeMove(const KReversiGame& game, bool competitive)
{
if (m_computingMove) {
//kDebug() << "I'm already computing move! Yours KReversi Engine.";
......@@ -322,6 +322,8 @@ KReversiPos Engine::computeMove(const KReversiGame& game, Color color, bool comp
}
m_computingMove = true;
ChipColor color;
// A competitive game is one where we try our damnedest to make the
// best move. The opposite is a casual game where the engine might
// make "a mistake". The idea behind this is not to scare away
......@@ -334,7 +336,8 @@ KReversiPos Engine::computeMove(const KReversiGame& game, Color color, bool comp
// but that case is determined further down.
m_exhaustive = false;
// Check the color to get the move for.
// Get the color to calculate the move for.
color = game.currentPlayer();
if (color == NoColor) {
m_computingMove = false;
return KReversiPos();
......@@ -494,7 +497,7 @@ KReversiPos Engine::computeMove(const KReversiGame& game, Color color, bool comp
KReversiPos Engine::ComputeFirstMove(const KReversiGame& game)
{
int r;
Color color = game.currentPlayer();
ChipColor color = game.currentPlayer();
r = m_random.getLong(4) + 1;
......@@ -519,13 +522,13 @@ KReversiPos Engine::ComputeFirstMove(const KReversiGame& game)
// search.
//
int Engine::ComputeMove2(int xplay, int yplay, Color color, int level,
int Engine::ComputeMove2(int xplay, int yplay, ChipColor color, int level,
int cutoffval, quint64 colorbits,
quint64 opponentbits)
{
int number_of_turned = 0;
SquareStackEntry mse;
Color opponent = opponentColorFor(color);
ChipColor opponent = opponentColorFor(color);
m_nodesSearched++;
......@@ -643,7 +646,7 @@ int Engine::ComputeMove2(int xplay, int yplay, Color color, int level,
// most valuable move, but not the move itself.
//
int Engine::TryAllMoves(Color opponent, int level, int cutoffval,
int Engine::TryAllMoves(ChipColor opponent, int level, int cutoffval,
quint64 opponentbits, quint64 colorbits)
{
int maxval = -LARGEINT;
......@@ -685,11 +688,11 @@ int Engine::TryAllMoves(Color opponent, int level, int cutoffval,
// using the board control values.
//
int Engine::EvaluatePosition(Color color)
int Engine::EvaluatePosition(ChipColor color)
{
int retval;
Color opponent = opponentColorFor(color);
ChipColor opponent = opponentColorFor(color);
int score_color = m_score->score(color);
int score_opponent = m_score->score(opponent);
......@@ -779,7 +782,7 @@ void Engine::SetupBcBoard()
// Calculate the board control score.
//
int Engine::CalcBcScore(Color color)
int Engine::CalcBcScore(ChipColor color)
{
int sum = 0;
......@@ -795,7 +798,7 @@ int Engine::CalcBcScore(Color color)
// Calculate a bitmap of the occupied squares for a certain color.
//
quint64 Engine::ComputeOccupiedBits(Color color)
quint64 Engine::ComputeOccupiedBits(ChipColor color)
{
quint64 retval = 0;
......
......@@ -128,10 +128,18 @@
// KReversi
#include "commondefs.h"
class KReversiGame;
static ChipColor opponentColorFor(ChipColor color)
{
if (color == NoColor)
return color;
else
return (color == White ? Black : White);
}
// SquareStackEntry and SquareStack are used during search to keep
// track of turned pieces.
......@@ -195,7 +203,7 @@ class Engine
~Engine();
KReversiPos computeMove(const KReversiGame& game, Color color, bool competitive);
KReversiPos computeMove(const KReversiGame& game, bool competitive);
bool isThinking() const { return m_computingMove; }
void setInterrupt(bool intr) { m_interrupt = intr; }
......@@ -205,24 +213,24 @@ class Engine
uint strength() const { return m_strength; }
private:
KReversiPos ComputeFirstMove(const KReversiGame& game);
int ComputeMove2(int xplay, int yplay, Color color, int level,
int ComputeMove2(int xplay, int yplay, ChipColor color, int level,
int utoffval,
quint64 colorbits, quint64 opponentbits);
int TryAllMoves(Color opponent, int level, int cutoffval,
int TryAllMoves(ChipColor opponent, int level, int cutoffval,
quint64 opponentbits, quint64 colorbits);
int EvaluatePosition(Color color);
int EvaluatePosition(ChipColor color);
void SetupBcBoard();
void SetupBits();
int CalcBcScore(Color color);
quint64 ComputeOccupiedBits(Color color);
int CalcBcScore(ChipColor color);
quint64 ComputeOccupiedBits(ChipColor color);
void yield();
private:
Color m_board[10][10];
ChipColor m_board[10][10];
int m_bc_board[9][9];
Score* m_score;
Score* m_bc_score;
......
......@@ -24,17 +24,21 @@
#ifndef COMMONDEFS_H
#define COMMONDEFS_H
#include "reversi.h"
// noColor = empty
enum ChipColor {
White = 0,
Black = 1,
NoColor = 2
};
using namespace Reversi;
struct KReversiPos
{
KReversiPos(Color col = NoColor, int r = -1, int c = -1 )
KReversiPos( ChipColor col = NoColor, int r = -1, int c = -1 )
: color(col), row(r), col(c) { }
Color color;
ChipColor color;
int row;
int col;
......
......@@ -65,7 +65,7 @@ void KReversiGame::makePlayerMove(int row, int col, bool demoMode)
if (!demoMode)
move = KReversiPos(m_playerColor, row, col);
else {
move = m_engine->computeMove(*this, m_playerColor, true);
move = m_engine->computeMove(*this, true);
if (!move.isValid())
return;
}
......@@ -93,7 +93,6 @@ void KReversiGame::startNextTurn(bool demoMode)
// No Computer move possible and not in demo mode
//kDebug() << "Computer can't move!";
m_curPlayer = m_playerColor;
m_position.setToMove(m_playerColor);
emit computerCantMove();
}
}
......@@ -121,7 +120,7 @@ void KReversiGame::makeComputerMove()
m_curPlayer = m_computerColor;
// FIXME dimsuz: m_competitive. Read from config.
// (also there's computeMove in getHint)
KReversiPos move = m_engine->computeMove(*this, m_computerColor, true);
KReversiPos move = m_engine->computeMove(*this, true);
if (!move.isValid())
return;
......@@ -158,37 +157,19 @@ int KReversiGame::undo()
// Yes, I like long descriptions in comments ;).
KReversiPos move = lastUndo.takeFirst();
setColor(NoColor, move.row, move.col);
setChipColor(NoColor, move.row, move.col);
// and change back the color of the rest chips
foreach (const KReversiPos &pos, lastUndo) {
Color opponentColor = opponentColorFor(m_cells[pos.row][pos.col]);
setColor(opponentColor, pos.row, pos.col);
ChipColor opponentColor = opponentColorFor(m_cells[pos.row][pos.col]);
setChipColor(opponentColor, pos.row, pos.col);
}
lastUndo.clear();
// ----------------------------------------------------------------
// new code. The old code will be disabled when we trust the new code enough
Move move2 = m_newUndoStack.pop();
if (move2.color != move.color
|| move2.row != move.row
|| move2.col != move.col) {
kDebug() << "Moves not the same in undo: "
<< move.color << move.row << move.col << " "
<< move2.color << move2.row << move2.col;
}
if (!m_position.undoMove(move2, true)) {
kDebug() << "UNDO FAILED!";
}
checkBoard();
// ----------------------------------------------------------------
movesUndone++;
if (move.color == m_playerColor)
break; //we've undone all computer + one player moves
}
m_curPlayer = m_playerColor;
......@@ -205,7 +186,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
{
changedChips.clear();
setColor(move.color, move.row, move.col);
setChipColor(move.color, move.row, move.col);
// the first one is the move itself
changedChips.append(move);
......@@ -215,7 +196,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int r=move.row-1; r >= 0; --r) {
if (m_cells[r][move.col] == move.color)
break;
setColor(move.color, r, move.col);
setChipColor(move.color, r, move.col);
changedChips.append(KReversiPos(move.color, r, move.col));
}
}
......@@ -223,7 +204,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int r=move.row+1; r < 8; ++r) {
if (m_cells[r][move.col] == move.color)
break;
setColor(move.color, r, move.col);
setChipColor(move.color, r, move.col);
changedChips.append(KReversiPos(move.color, r, move.col));
}
}
......@@ -231,7 +212,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int c=move.col-1; c >= 0; --c) {
if (m_cells[move.row][c] == move.color)
break;
setColor(move.color, move.row, c);
setChipColor(move.color, move.row, c);
changedChips.append(KReversiPos(move.color, move.row, c));
}
}
......@@ -239,7 +220,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int c=move.col+1; c < 8; ++c) {
if (m_cells[move.row][c] == move.color)
break;
setColor(move.color, move.row, c);
setChipColor(move.color, move.row, c);
changedChips.append(KReversiPos(move.color, move.row, c));
}
}
......@@ -247,7 +228,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int r=move.row-1, c=move.col-1; r>=0 && c >= 0; --r, --c) {
if (m_cells[r][c] == move.color)
break;
setColor(move.color, r, c);
setChipColor(move.color, r, c);
changedChips.append(KReversiPos(move.color, r, c));
}
}
......@@ -255,7 +236,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int r=move.row-1, c=move.col+1; r>=0 && c < 8; --r, ++c) {
if (m_cells[r][c] == move.color)
break;
setColor(move.color, r, c);
setChipColor(move.color, r, c);
changedChips.append(KReversiPos(move.color, r, c));
}
}
......@@ -263,7 +244,7 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int r=move.row+1, c=move.col-1; r < 8 && c >= 0; ++r, --c) {
if (m_cells[r][c] == move.color)
break;
setColor(move.color, r, c);
setChipColor(move.color, r, c);
changedChips.append(KReversiPos(move.color, r, c));
}
}
......@@ -271,21 +252,13 @@ void KReversiGame::makeMove(const KReversiPos& move, PosList &changedChips)
for (int r=move.row+1, c=move.col+1; r < 8 && c < 8; ++r, ++c) {
if (m_cells[r][c] == move.color)
break;
setColor(move.color, r, c);
setChipColor(move.color, r, c);
changedChips.append(KReversiPos(move.color, r, c));
}
}
m_curPlayer = (m_curPlayer == White ? Black : White);
//kDebug() << "Current player changed to" << (m_curPlayer == White ? "White" : "Black");
// ----------------------------------------------------------------
// new code
Move move2(move.color, move.row, move.col);
m_position.makeMove(move2);
m_newUndoStack.push(move2);
checkBoard();
}
PosList KReversiGame::changedChips() const
......@@ -324,12 +297,12 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
//
// Well, I wrote this description from my head, now lets produce some code for that ;)
Color opColor = opponentColorFor(move.color);
ChipColor opColor = opponentColorFor(move.color);
int opponentChipsNum = 0;
bool foundPlayerColor = false;
if (dir == Up) {
for (int row=move.row-1; row >= 0; --row) {
Color color = m_cells[row][move.col];
ChipColor color = m_cells[row][move.col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -346,7 +319,7 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
}
else if (dir == Down) {
for (int row=move.row+1; row < 8; ++row) {
Color color = m_cells[row][move.col];
ChipColor color = m_cells[row][move.col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -363,7 +336,7 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
}
else if (dir == Left) {
for (int col=move.col-1; col >= 0; --col) {
Color color = m_cells[move.row][col];
ChipColor color = m_cells[move.row][col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -380,7 +353,7 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
}
else if (dir == Right) {
for (int col=move.col+1; col < 8; ++col) {
Color color = m_cells[move.row][col];
ChipColor color = m_cells[move.row][col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -397,7 +370,7 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
}
else if (dir == UpLeft) {
for (int row=move.row-1, col=move.col-1; row >= 0 && col >= 0; --row, --col) {
Color color = m_cells[row][col];
ChipColor color = m_cells[row][col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -414,7 +387,7 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
}
else if (dir == UpRight) {
for (int row=move.row-1, col=move.col+1; row >= 0 && col < 8; --row, ++col) {
Color color = m_cells[row][col];
ChipColor color = m_cells[row][col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -431,7 +404,7 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
}
else if (dir == DownLeft) {
for (int row=move.row+1, col=move.col-1; row < 8 && col >= 0; ++row, --col) {
Color color = m_cells[row][col];
ChipColor color = m_cells[row][col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -448,7 +421,7 @@ bool KReversiGame::hasChunk(Direction dir, const KReversiPos& move) const
}
else if (dir == DownRight) {
for (int row=move.row+1, col=move.col+1; row < 8 && col < 8; ++row, ++col) {
Color color = m_cells[row][col];
ChipColor color = m_cells[row][col];
if (color == opColor) {
opponentChipsNum++;
}
......@@ -522,7 +495,7 @@ void KReversiGame::setComputerSkill(int skill)
KReversiPos KReversiGame::getHint() const
{
// FIXME dimsuz: don't use true, use m_competitive
return m_engine->computeMove(*this, m_playerColor, true);
return m_engine->computeMove(*this, true);
}
KReversiPos KReversiGame::getLastMove() const
......@@ -547,13 +520,12 @@ PosList KReversiGame::possibleMoves() const
return l;
}
int KReversiGame::playerScore(Color player) const
int KReversiGame::playerScore(ChipColor player) const
{
//return m_score[player];
return m_position.playerScore(player);
return m_score[player];
}
void KReversiGame::setColor(Color color, int row, int col)
void KReversiGame::setChipColor(ChipColor color, int row, int col)
{
Q_ASSERT(row < 8 && col < 8);
// first: if the current cell already contains a chip of the opponent,
......@@ -577,47 +549,10 @@ void KReversiGame::setColor(Color color, int row, int col)
//kDebug() << "Score of Black player:" << m_score[Black];
}
Color KReversiGame::chipColorAt(int row, int col) const
ChipColor KReversiGame::chipColorAt(int row, int col) const
{
Q_ASSERT(row < 8 && col < 8);
return m_cells[row][col];
}
void KReversiGame::checkBoard()
{
bool equal = true;
for (int r = 0; r < 8; ++r) {
for (int c = 0; c < 8; ++c) {
if (m_cells[r][c] != m_position.colorAt(r, c)) {
equal = false;
}
}
}
if (m_score[Black] != m_position.playerScore(Black)
|| m_score[White] != m_position.playerScore(White))
equal = false;
if (!equal) {
kDebug() << "BOARDS NOT EQUAL:";
kDebug() << " OLD " << " " << " NEW ";
for (int r = 0; r < 8; ++r) {
QString oldBoard;
QString newBoard;
for (int c = 0; c < 8; ++c) {
oldBoard.append("*o_"[m_cells[r][c]]);
}
for (int c = 0; c < 8; ++c) {
newBoard.append("*o_"[m_position.colorAt(r, c)]);
}
kDebug() << oldBoard << " " << newBoard;
}
kDebug() << m_score[Black] << m_score[White] << " "
<< m_position.playerScore(Black) << m_position.playerScore(White);
}
}
#include "kreversigame.moc"
......@@ -30,12 +30,9 @@
// KReversi
#include "commondefs.h"
#include "reversi.h"
class Engine;
using namespace Reversi;
/**
* KReversiGame incapsulates all of the game logic.
* Whenever the board state changes it emits corresponding signals.
......@@ -117,17 +114,16 @@ public:
/**
* @return a color of the current player
*/
//Color currentPlayer() const { return m_curPlayer; }
Color currentPlayer() const { return m_position.toMove(); }
ChipColor currentPlayer() const { return m_curPlayer; }
/**
* @return score (number of chips) of the player
*/
int playerScore(Color player) const;
int playerScore(ChipColor player) const;
/**
* @return color of the chip at position [row, col]
*/
Color chipColorAt(int row, int col) const;
ChipColor chipColorAt(int row, int col) const;
/**
* @return if undo is possible
*/
......@@ -143,8 +139,7 @@ public:
/**
* @return true, if it's computer's turn now
*/
//bool isComputersTurn() const { return m_curPlayer == m_computerColor; }
bool isComputersTurn() const { return m_position.toMove() == m_computerColor; }
bool isComputersTurn() const { return m_curPlayer == m_computerColor; }
/**
* @return a list of chips which were changed during last move.
* First of them will be the move itself, and the rest - chips which
......@@ -188,11 +183,11 @@ private:
/**
* Sets the type of chip at (row,col)
*/
void setColor(Color type, int row, int col);
void setChipColor(ChipColor type, int row, int col);
/**
* The board itself
*/
Color m_cells[8][8];
ChipColor m_cells[8][8];
/**
* Score of each player
*/
......@@ -200,15 +195,15 @@ private:
/**
* Color of the current player
*/
Color m_curPlayer;
ChipColor m_curPlayer;
/**
* The color of the human played chips
*/
Color m_playerColor;
ChipColor m_playerColor;
/**
* The color of the computer played chips
*/
Color m_computerColor;
ChipColor m_computerColor;
/**
* Our AI
......@@ -221,19 +216,6 @@ private:
* @see m_changedChips
*/
QStack<PosList> m_undoStack;
// ----------------------------------------------------------------
// New code
/**
* The current position.
*/
Position m_position;
QStack<Move> m_newUndoStack;
// Checks if the board in m_cells is equal to the board in m_position
void checkBoard();
};
#endif
/*******************************************************************
*
* Copyright 2013 Inge Wallin <inge@lysator.liu.se>
* Copyright 2006 Dmitry Suzdalev <dimsuz@gmail.com>
*
* This file is part of the KDE project "KReversi"
*
* KReversi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* KReversi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KReversi; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
********************************************************************/