Initial import/add

This commit is contained in:
Stian Selnes 2007-10-15 19:32:30 +00:00
commit b0afee3d60
25 changed files with 1945 additions and 0 deletions

35
mancatux.pro Normal file
View File

@ -0,0 +1,35 @@
######################################################################
# Automatically generated by qmake (2.01a) . okt. 14 20:36:22 2007
######################################################################
OBJECTS_DIR = obj
UI_DIR = src/gui/uic
MOC_DIR = src/gui/moc
TEMPLATE = app
TARGET = mancatux
DEPENDPATH += . src src/gui src/gui/uic
INCLUDEPATH += . src src/gui src/gui/uic
# Input
HEADERS += src/Board.h \
src/EngineFactory.h \
src/Game.h \
src/IEngine.h \
src/IGame.h \
src/KalahEngine.h \
src/Player.h \
src/Session.h \
src/gui/ClickLabel.h \
src/gui/GuiWrapper.h \
src/gui/Hole.h \
src/gui/MainWindow.h
FORMS += src/gui/MainWindow.ui
SOURCES += src/Board.cpp \
src/Game.cpp \
src/KalahEngine.cpp \
src/Main.cpp \
src/Player.cpp \
src/Session.cpp \
src/gui/ClickLabel.cpp \
src/gui/GuiWrapper.cpp \
src/gui/MainWindow.cpp

16
qmake.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
TARGET=mancatux
OBJECTS_DIR=obj
UI_DIR=src/gui/uic
MOC_DIR=src/gui/moc
qmake -project \
"OBJECTS_DIR = $OBJECTS_DIR" \
"UI_DIR = $UI_DIR" \
"MOC_DIR = $MOC_DIR" \
-o $TARGET.pro
qmake
make

293
src/Board.cpp Normal file
View File

@ -0,0 +1,293 @@
/**
* A class for a Mancala board. The following board layout is assumed
*
* Holes num:
*
* 13 12 11 10 9 8
* 0 7
* 1 2 3 4 5 6
*
*
* Corresponding store num:
*
* 2 1
*
* Corresponding house num:
*
* 12 11 10 9 8 7
*
* 1 2 3 4 5 6
*
*
*
* Any even number of houses is allowed.
*
*/
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <vector>
#include <cassert>
#include "Board.h"
using namespace std;
//const int INITIAL_NUMBER_OF_SEEDS_PER_HOUSE = 3;
/** Constructor.
*
* @param holes is the number of holes, including both house and store, in
* the board. Must be an even number.
* @param seeds is the initial number of seeds per hole.
*
* @exception std::invalid_argument.
*/
Board::Board() {}
Board::Board(int houses, int seeds)
{
int holes = houses + 2;
if (holes % 2 != 0 || holes <= 0)
{
ostringstream msg;
msg << "'holes' = " << holes << ": "
<< "The number of holes in a board must be equal";
throw invalid_argument(msg.str());
}
store2 = 0;
store1 = holes / 2;
board.reserve(holes);
for (int i = 0; i < holes; ++i)
{
if (i == store1 || i == store2)
board.push_back(0);
else
board.push_back(seeds);
}
}
int & Board::operator[] (int hole)
{
if (hole < 0 || hole > static_cast<int>(board.size()-1))
throw invalid_argument("argument out of range");
return board[hole];
}
#if 0
/* house number starts at 1 */
bool Board::sow(int house, Half playersHalf, int * endId, Board::HoleType * endType)
{
int hole;
assert (playersHalf == SOUTH || playersHalf == NORTH);
try
{
hole = house2hole(house);
}
catch (...)
{
return false;
}
if (getHalf(hole) != playersHalf)
return false;
int seeds = getSeedsInHouse(house);
if (seeds == 0)
return false;
board[hole] = 0;
int opponentStore = getStoreHole((playersHalf == SOUTH) ? NORTH : SOUTH);
while (seeds)
{
hole = ( hole == static_cast<int>( board.size())-1 ) ? 0 : hole + 1;
if (hole != opponentStore)
{
++board[hole];
--seeds;
}
}
*endType = (hole == store1 || hole == store2) ? STORE : HOUSE;
*endId = *endType == STORE ? hole2store(hole) : hole2house(hole);
return true;
}
#endif
bool Board::isHalfEmpty(Half half) const
{
int isEmpty = true;
int hole = half == SOUTH ? store2 + 1 : store1 + 1;
int end = half == SOUTH ? store1 : store2;
while (hole != end)
{
if (board[hole] != 0)
{
isEmpty = false;
break;
}
hole = ( hole == static_cast<int>( board.size())-1 ) ? 0 : hole + 1;
}
return isEmpty;
}
int Board::getSeedsInHouse(int house) const
{
return board[house2hole(house)];
}
int Board::getSeedsInStore(int store) const
{
return board[store2hole(store)];
}
Board::Half Board::getHalf (int hole) const
{
if (hole <= store1 && hole != store2)
return SOUTH;
else
return NORTH;
}
int Board::getOppositeHole( int hole ) const
{
int opposite;
checkRange (hole);
if ( hole == 0 )
opposite = board.size() / 2;
else if ( hole == static_cast<int>(board.size()) / 2 )
opposite = 0;
else
opposite = board.size() - hole;
return opposite;
}
int Board::hole2house(int hole) const
{
checkRange (hole);
return hole < store1 ? hole : hole - 1;
}
/**
* Returns the store number which HOLE corresponds to. Returns 0 if hole does
* not correspond to any store.
*/
int Board::hole2store(int hole) const
{
checkRange (hole);
if ( hole == store1 )
return 1;
else if ( hole == store2)
return 2;
else
return 0;
}
int Board::house2hole(int house) const
{
if (house < 1 || house > static_cast<int>(board.size()-2))
throw invalid_argument("Invalid house number");
return house < store1 ? house : house + 1;
}
int Board::store2hole(int store) const
{
if (store < 1 || store > 2)
throw invalid_argument("Invalid store number");
return store == 1 ? store1 : store2;
}
#if 0
// num is number from 1...
int Board::getHole(int num, HoleType type) const
{
int hole;
if (type == HOUSE)
{
if (num < 1 || num > board.size() - 2)
throw invalid_argument("Invalid house number");
hole = (num < store1) ? num : num + 1;
}
else if (type == STORE)
{
}
else
throw invalid_argument("Unknown hole type");
return hole;
}
#endif
int Board::getStoreHole(Half half) const
{
int hole;
if (half == SOUTH)
hole = store1;
else if (half == NORTH)
hole = store2;
else
throw invalid_argument("Only store for half SOUTH and NORTH");
return hole;
}
size_t Board::size () const
{
return board.size();
}
void Board::print(std::ostream & out) const
{
int i;
std::ostringstream s1, s2, s3;
for ( i = 1; i < static_cast<int>(board.size())/2; ++i )
{
s1 << getSeedsInHouse( board.size()-1 - i ) << "\t";
s2 << "\t";
s3 << getSeedsInHouse( i ) << "\t";
}
out << "\t" << s1.str() << "\n";
out << getSeedsInStore( 2 ) << s2.str() << "\t "<< getSeedsInStore( 1 ) << "\n";
out << "\t" << s3.str() << std::endl;
}
bool Board::checkRange( int hole ) const
{
if ( hole < 0 || hole > static_cast<int>(board.size()-1) )
throw invalid_argument("Invalid hole number");
return true;
}
// Board::~Board()
// {
// delete[] board;
// }

48
src/Board.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef _BOARD_H_
#define _BOARD_H_
#include <vector>
#include <iostream>
class Board
{
public:
enum HoleType { HOUSE, STORE };
enum Half {UNSPECIFIED, NORTH, SOUTH};
Board();
Board(int houses, int seeds);
// ~Board();
int & operator[] (int hole);
// bool sow(int house, Half playersHalf, int * endId, HoleType * endType);
int getSeedsInHouse(int house) const;
int getSeedsInStore(int store) const;
int getOppositeHole(int hole) const;
void print ( std::ostream & out) const;
bool isHalfEmpty(Half half) const;
int store2hole(int store) const;
int hole2store(int hole) const;
int hole2house(int hole) const;
int getStoreHole(Half Half) const;
int house2hole(int house) const;
Half getHalf(int hole) const;
size_t size() const;
private:
int store1;
int store2;
std::vector<int> board;
bool checkRange (int hole) const;
};
#endif

14
src/EngineFactory.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ENGINEFACTORY_H_
#define _ENGINEFACTORY_H_
#include "KalahEngine.h"
class IEngine;
class EngineFactory
{
public:
static IEngine * createKalah() { return new KalahEngine(); }
};
#endif

110
src/Game.cpp Normal file
View File

@ -0,0 +1,110 @@
#include <cassert>
#include <string>
#include "Game.h"
#include "Board.h"
#include "Player.h"
#include "IEngine.h"
Game::Game ( IEngine * engine, int houses, int seeds )
: engine_(engine),
board_( houses, seeds ),
finished_(false)
{ }
void Game::player1 ( std::string name, bool user )
{
player1_ = new Player(name, user ? Player::USER : Player::COMPUTER, &board_, Board::SOUTH);
activePlayer_ = player1_;
}
void Game::player2 ( std::string name, bool user )
{
player2_ = new Player(name, user ? Player::USER : Player::COMPUTER, &board_, Board::NORTH);
}
/**
* Makes the active user make a move (seed) on HOUSE and updates game state.
* Returns TRUE if the move is valid.
*/
bool Game::makeMove( int house )
{
assert( player1_ );
assert( player2_ );
if (finished_)
return false;
IEngine::MoveResult res = engine_->makeMove( activePlayer_, &board_, house );
switch (res)
{
case IEngine::INVALID_MOVE:
return false;
case IEngine::VALID_MOVE_EXTRA_TURN:
return true;
case IEngine::VALID_MOVE_CHANGE_TURN:
activePlayer_ = activePlayer_ == player1_ ? player2_ : player1_;
return true;
case IEngine::VALID_MOVE_GAME_FINISHED:
finished_ = true;
return true;
default:
std::cerr << __FUNCTION__ << ": Got invalid move result" << std::endl;
assert(true);
}
return false;
}
/**
* Returns the name of the winner or an empty string if the game ends in a
* draw. If the game is not finished a 0 pointer is returned.
*/
std::string Game::getWinner () const
{
if (finished_)
{
Player * winner = engine_->getWinner (player1_, player2_, &board_);
if ( winner == 0 )
return "";
else
return winner->name();
}
return 0;
}
bool Game::isFinished () const
{
return finished_;
}
int Game::getSeedsInHouse ( int house ) const
{
return board_.getSeedsInHouse( house );
}
int Game::getSeedsInStorage ( int storage ) const
{
return board_.getSeedsInStore ( storage );
}
std::string Game::getActivePlayerName () const
{
return activePlayer_->name();
}
std::string Game::getPlayer1Name () const
{
return player1_->name();
}
std::string Game::getPlayer2Name () const
{
return player2_->name();
}

45
src/Game.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef _GAME_H_
#define _GAME_H_
#include <string>
#include <memory>
#include "IGame.h"
#include "Player.h"
#include "Board.h"
class IEngine;
class Game : public IGame
{
public:
Game(IEngine * engine, int houses = 12, int seeds = 3);
void player1(std::string name, bool user);
void player2(std::string name, bool user);
virtual bool isFinished() const;
virtual std::string getWinner() const;
virtual std::string getActivePlayerName() const;
virtual std::string getPlayer1Name () const;
virtual std::string getPlayer2Name () const;
// Board & getBoard() const;
virtual bool makeMove( int house );
virtual int getSeedsInHouse( int house ) const;
virtual int getSeedsInStorage( int storage ) const;
private:
std::auto_ptr<IEngine> engine_;
Player * player1_;
Player * player2_;
Player * activePlayer_;
Board board_;
bool finished_;
// void updateState (int latestEndHoleId, Board::HoleType latestEndHoleType);
};
#endif

23
src/IEngine.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _IENGINE_H_
#define _IENGINE_H_
class Player;
class Board;
class IEngine
{
public:
enum MoveResult {
INVALID_MOVE,
VALID_MOVE_CHANGE_TURN,
VALID_MOVE_EXTRA_TURN,
VALID_MOVE_GAME_FINISHED
};
virtual ~IEngine() { }
virtual MoveResult makeMove (const Player * player, Board * board, int house) = 0;
virtual Player * getWinner (Player * p1, Player * p2, const Board * board) const = 0;
};
#endif

28
src/IGame.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef _IGAME_H_
#define _IGAME_H_
#include <string>
class Player;
class IGame
{
public:
virtual ~IGame() {};
virtual bool makeMove ( int house ) = 0;
virtual int getSeedsInHouse ( int house ) const = 0;
virtual int getSeedsInStorage ( int storage ) const = 0;
virtual bool isFinished () const = 0;
virtual std::string getWinner () const = 0;
virtual std::string getActivePlayerName () const = 0;
virtual std::string getPlayer1Name () const = 0;
virtual std::string getPlayer2Name () const = 0;
};
#endif

102
src/KalahEngine.cpp Normal file
View File

@ -0,0 +1,102 @@
#include <cassert>
#include <stdexcept>
#include "KalahEngine.h"
#include "Player.h"
#include "Board.h"
IEngine::MoveResult KalahEngine::makeMove (const Player * player, Board * board, int house)
{
// TODO: Use an board iterator instead.
// We should not have to guess the relation between holes in this class
Board::Half playersHalf = player->half();
assert (playersHalf == Board::SOUTH || playersHalf == Board::NORTH);
// Check validity of move
int hole;
try
{
hole = board->house2hole(house);
}
catch (...) // insert correct exception: invalid_argument
{
return INVALID_MOVE;
}
if (board->getHalf(hole) != playersHalf)
return INVALID_MOVE;
int seeds = (*board)[hole];
if (seeds == 0)
return INVALID_MOVE;
// Move seeds
(*board)[hole] = 0;
int opponentStoreHole = board->getStoreHole((playersHalf == Board::SOUTH) ? Board::NORTH : Board::SOUTH);
while (seeds)
{
hole = ( hole == static_cast<int>( board->size())-1 ) ? 0 : hole + 1;
if (hole != opponentStoreHole)
{
++(*board)[hole];
--seeds;
}
}
// If the last sown seed lands in an empty house owned by the player, and
// the opposite house contains seeds, both the last seed and the opposite
// seeds are captured and placed into the player's store.
int storeHole = board->getStoreHole(playersHalf);
int oppositeHole = board->getOppositeHole(hole);
if ( (*board)[hole] == 1 &&
board->getHalf(hole) == playersHalf &&
hole != storeHole &&
(*board)[oppositeHole] > 0 )
{
int oppositeHole = board->getOppositeHole(hole);
(*board)[storeHole] += (*board)[hole] + (*board)[oppositeHole];
(*board)[hole] = 0;
(*board)[oppositeHole] = 0;
}
// Check if game is finished
if ( board->isHalfEmpty( playersHalf ) )
{
// Move remaining seeds on opponents half into his/her store
int i = storeHole + 1;
while ( i != opponentStoreHole )
{
(*board)[opponentStoreHole] += (*board)[i];
(*board)[i] = 0;
i = ( i == static_cast<int>( board->size())-1 ) ? 0 : i + 1;
}
return VALID_MOVE_GAME_FINISHED;
}
// If last seed is sown in own store the player gets an extra turn
return hole == storeHole ? VALID_MOVE_EXTRA_TURN : VALID_MOVE_CHANGE_TURN;
}
/**
* Must only be called when a game is finished. If not, the return value is undefined.
*
* Returns the winning player, or 0 if the game ends in a draw.
*/
Player * KalahEngine::getWinner (Player * p1, Player * p2, const Board * b) const
{
int point1 = b->getSeedsInStore( 1 );
int point2 = b->getSeedsInStore( 2 );
Player * winner = 0;
if (point1 > point2)
winner = p1;
else if (point2 > point1)
winner = p2;
return winner;
}

16
src/KalahEngine.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _KALAHENGINE_H_
#define _KALAHENGINE_H_
#include "IEngine.h"
class Player;
class Board;
class KalahEngine : public IEngine
{
public:
virtual KalahEngine::MoveResult makeMove (const Player * player, Board * board, int house);
virtual Player * getWinner (Player * p1, Player * p2, const Board * board) const;
};
#endif

12
src/Main.cpp Normal file
View File

@ -0,0 +1,12 @@
#include <QApplication>
#include "GuiWrapper.h"
#include "Session.h"
int main ( int argc, char * argv[] )
{
QApplication app ( argc, argv );
GuiWrapper guiwrapper;
Session session( &guiwrapper );
return app.exec();
}

28
src/Player.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "Player.h"
#include "Board.h"
Player::Player(std::string name, Player::type type, Board * board, Board::Half half ) :
name_(name), type_(type), board_(board), half_(half)
{}
Board::Half Player::half() const
{
return half_;
}
std::string Player::name() const
{
return name_;
}
// bool Player::sow(int house, int * endId, Board::HoleType * endType )
// {
// if (!board_ || half_ == Board::UNSPECIFIED)
// return false;
// return board_->sow( house, half_, endId, endType );
// }

28
src/Player.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef _PLAYER_H_
#define _PLAYER_H_
#include <string>
#include "Board.h"
class Player
{
public:
enum type {USER, COMPUTER};
Player( std::string name, type type, Board * board, Board::Half half );
Board::Half half() const;
std::string name() const;
// bool sow(int house, int * endId, Board::HoleType * endType);
private:
std::string name_;
type type_;
Board * board_;
Board::Half half_;
};
#endif

28
src/Session.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "Session.h"
#include "EngineFactory.h"
#include "IGame.h"
#include "Game.h"
#include "GuiWrapper.h"
Session::Session ( GuiWrapper * g)
: gui_(g)
{
newGame();
gui_->init(this);
gui_->start();
}
void Session::newGame ()
{
// todo: do this completely different
// delete game_;
Game * g = new Game( factory.createKalah(), 12);
g->player1("P1", true);
g->player2("P2", true);
game_ = g;
}
IGame * Session::game () const
{
return game_;
}

22
src/Session.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef _SESSION_H_
#define _SESSION_H_
#include "IGame.h"
#include "EngineFactory.h"
class GuiWrapper;
class Session
{
public:
Session ( GuiWrapper * g ); // todo: change to GuiInterface
void newGame();
IGame * game() const;
private:
IGame * game_;
GuiWrapper * gui_;
EngineFactory factory;
};
#endif

42
src/gui/ClickLabel.cpp Normal file
View File

@ -0,0 +1,42 @@
#include <QMouseEvent>
#include <QLabel>
#include "ClickLabel.h"
ClickLabel::ClickLabel ( QWidget * parent, Qt::WindowFlags f )
: QLabel( parent, f )
{}
ClickLabel::ClickLabel ( const QString & text, QWidget * parent , Qt::WindowFlags f )
: QLabel( text, parent, f )
{}
void ClickLabel::mousePressEvent ( QMouseEvent * event)
{
if ( event->button() == Qt::LeftButton )
{
emit clicked();
}
}
#if 0
#include <QApplication>
#include <QMainWindow>
#include "ui_mainWindow.h"
int main ( int argc, char * argv[] )
{
QApplication app ( argc, argv );
QMainWindow qmw;
Ui::MainWindow mainwin;
mainwin.setupUi(&qmw);
QObject::connect( mainwin.label, SIGNAL(clicked()), &app, SLOT(quit()) );
qmw.show();
return app.exec();
}
#endif

24
src/gui/ClickLabel.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef _CLICKLABEL_H_
#define _CLICKLABEL_H_
#include <QWidget>
#include <QLabel>
class ClickLabel : public QLabel
{
Q_OBJECT
public:
ClickLabel( QWidget * parent = 0, Qt::WindowFlags f = 0 );
ClickLabel ( const QString & text, QWidget * parent = 0, Qt::WindowFlags f = 0 );
signals:
void clicked();
protected:
virtual void mousePressEvent (QMouseEvent * event);
};
#endif

26
src/gui/GuiWrapper.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "GuiWrapper.h"
#include "MainWindow.h"
GuiWrapper::GuiWrapper ( )
{ }
GuiWrapper::~GuiWrapper ()
{
delete mainWin_;
}
void GuiWrapper::init (Session * session)
{
session_ = session;
mainWin_ = new MainWindow(session_);
}
void GuiWrapper::start ()
{
mainWin_->init();
mainWin_->show();
}

25
src/gui/GuiWrapper.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef _GUIWRAPPER_H_
#define _GUIWRAPPER_H_
class MainWindow;
class Session;
class GuiWrapper
{
public:
GuiWrapper();
~GuiWrapper();
void init( Session * session);
void start();
private:
MainWindow * mainWin_;
Session * session_;
// Disable copy construction and assignment
GuiWrapper ( const GuiWrapper & );
GuiWrapper & operator= ( const GuiWrapper & );
};
#endif

33
src/gui/Hole.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef _HOLE_H_
#define _HOLE_H_
#include <QMouseEvent>
#include "ClickLabel.h"
class Hole : public ClickLabel
{
Q_OBJECT
public:
Hole ( QWidget * parent = 0, Qt::WindowFlags f = 0 )
: ClickLabel ( parent, f ), id_( 0 ) { }
void setId ( int id ) { id_ = id; }
signals:
void clicked ( int id );
private:
int id_;
void mousePressEvent ( QMouseEvent * event )
{
if ( event->button() == Qt::LeftButton )
emit clicked( id_ );
}
};
#endif

99
src/gui/MainWindow.cpp Normal file
View File

@ -0,0 +1,99 @@
#include "MainWindow.h"
#include "Session.h"
#include <QString>
#include <string>
MainWindow::MainWindow ( Session * session, QMainWindow * parent )
: QMainWindow( parent ), session_(session)
{
setupUi( this );
houses_.push_back( house1 );
houses_.push_back( house2 );
houses_.push_back( house3 );
houses_.push_back( house4 );
houses_.push_back( house5 );
houses_.push_back( house6 );
houses_.push_back( house7 );
houses_.push_back( house8 );
houses_.push_back( house9 );
houses_.push_back( house10 );
houses_.push_back( house11 );
houses_.push_back( house12 );
for (size_t i = 0 ; i < houses_.size(); ++i )
{
houses_[i]->setId( i + 1);
QObject::connect( houses_[i], SIGNAL( clicked(int) ),
this, SLOT( houseClicked(int) ) );
}
storages_.push_back( storage1 );
storages_.push_back( storage2 );
}
void MainWindow::init()
{
if (session_->game())
{
player1->setText( session_->game()->getPlayer1Name().c_str() );
player2->setText( session_->game()->getPlayer2Name().c_str() );
update();
}
}
void MainWindow::update()
{
for (size_t i = 0 ; i < houses_.size(); ++i )
houses_[i]->setNum( session_->game()->getSeedsInHouse(i+1) );
for (size_t i = 0 ; i < storages_.size(); ++i )
storages_[i]->setNum( session_->game()->getSeedsInStorage(i+1) );
if (session_->game()->isFinished())
{
QString winner = session_->game()->getWinner().c_str();
if (winner != "")
status->setText(winner + " wins!");
else
status->setText("It's a draw!");
}
else
{
// Change font on players name to show current player
QFont font1(player1->font());
QFont font2(player2->font());
QString activePlayer = session_->game()->getActivePlayerName().c_str();
// todo: this approach does not work when players have same name.
if (player1->text() == activePlayer)
{
font1.setUnderline(true);
font1.setBold(true);
font2.setUnderline(false);
font2.setBold(false);
}
else
{
font1.setUnderline(false);
font1.setBold(false);
font2.setUnderline(true);
font2.setBold(true);
}
player1->setFont(font1);
player2->setFont(font2);
status->setText("Waiting for " + activePlayer + " To make a move...");
}
QMainWindow::update();
}
void MainWindow::houseClicked (int id)
{
if ( session_->game()->makeMove(id) )
update();
}

32
src/gui/MainWindow.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef _MAINWINDOW_H_
#define _MAINWINOW_H_
#include <QMainWindow>
#include <vector>
#include "ui_MainWindow.h"
class Session;
class Hole;
class MainWindow : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
public:
MainWindow (Session * session, QMainWindow * parent = 0 );
void init();
void update();
private slots:
void houseClicked ( int id );
private:
Session * session_;
std::vector<Hole *> houses_;
std::vector<Hole *> storages_;
};
#endif

408
src/gui/MainWindow.ui Normal file
View File

@ -0,0 +1,408 @@
<ui version="4.0" >
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>197</height>
</rect>
</property>
<property name="windowTitle" >
<string>Mancala</string>
</property>
<widget class="QWidget" name="centralwidget" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<layout class="QVBoxLayout" >
<item>
<layout class="QGridLayout" >
<item row="0" column="0" >
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>61</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="player2" >
<property name="text" >
<string>Player 2</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1" >
<layout class="QHBoxLayout" >
<item>
<widget class="Hole" name="house12" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house11" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house10" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house9" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house8" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house7" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" >
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Hole" name="storage2" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2" >
<layout class="QHBoxLayout" >
<item>
<widget class="Hole" name="storage1" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1" >
<layout class="QHBoxLayout" >
<item>
<widget class="Hole" name="house1" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house2" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house3" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house4" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house5" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house6" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="2" >
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="player1" >
<property name="text" >
<string>Player 1</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>61</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="status" >
<property name="text" >
<string>status</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>29</height>
</rect>
</property>
<widget class="QMenu" name="menuFile" >
<property name="title" >
<string>File</string>
</property>
<addaction name="actionNew_game" />
</widget>
<addaction name="menuFile" />
</widget>
<widget class="QStatusBar" name="statusbar" />
<action name="actionNew_game" >
<property name="text" >
<string>New game</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>Hole</class>
<extends>QLabel</extends>
<header>Hole.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

408
src/gui/MainWindow.ui.bak Normal file
View File

@ -0,0 +1,408 @@
<ui version="4.0" >
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>197</height>
</rect>
</property>
<property name="windowTitle" >
<string>Mancala</string>
</property>
<widget class="QWidget" name="centralwidget" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<layout class="QVBoxLayout" >
<item>
<layout class="QGridLayout" >
<item row="0" column="0" >
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>61</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="player2" >
<property name="text" >
<string>Player 2</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1" >
<layout class="QHBoxLayout" >
<item>
<widget class="Hole" name="house12" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house11" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house10" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house9" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house8" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house7" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" >
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Hole" name="storage2" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2" >
<layout class="QHBoxLayout" >
<item>
<widget class="Hole" name="storage1" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1" >
<layout class="QHBoxLayout" >
<item>
<widget class="Hole" name="house1" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house2" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house3" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house4" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house5" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Hole" name="house6" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text" >
<string>0</string>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="2" >
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="player1" >
<property name="text" >
<string>Player 1</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>61</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="status" >
<property name="text" >
<string>status</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>29</height>
</rect>
</property>
<widget class="QMenu" name="menuFile" >
<property name="title" >
<string>File</string>
</property>
<addaction name="actionNew_game" />
</widget>
<addaction name="menuFile" />
</widget>
<widget class="QStatusBar" name="statusbar" />
<action name="actionNew_game" >
<property name="text" >
<string>New game</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>Hole</class>
<extends>QLabel</extends>
<header>hole.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>