2008-11-30 21:53:44 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* Eliot
|
2012-10-07 16:25:41 +02:00
|
|
|
* Copyright (C) 2008-2012 Olivier Teulière
|
2009-01-24 18:44:56 +01:00
|
|
|
* Authors: Olivier Teulière <ipkiss @@ gmail.com>
|
2008-11-30 21:53:44 +01:00
|
|
|
*
|
|
|
|
* This program 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 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2009-11-29 17:01:31 +01:00
|
|
|
#ifndef PUBLIC_GAME_H_
|
|
|
|
#define PUBLIC_GAME_H_
|
2008-11-30 21:53:44 +01:00
|
|
|
|
2012-12-29 18:49:52 +01:00
|
|
|
#include <vector>
|
2008-11-30 21:53:44 +01:00
|
|
|
#include <string>
|
|
|
|
|
2011-08-27 19:21:26 +02:00
|
|
|
class GameParams;
|
2008-11-30 21:53:44 +01:00
|
|
|
class Game;
|
|
|
|
class Dictionary;
|
|
|
|
class Bag;
|
|
|
|
class Board;
|
|
|
|
class History;
|
|
|
|
class Player;
|
|
|
|
class Navigation;
|
2012-01-12 17:43:57 +01:00
|
|
|
class Round;
|
2008-11-30 21:53:44 +01:00
|
|
|
class Results;
|
2012-03-17 23:45:47 +01:00
|
|
|
class LimitResults;
|
2012-03-05 01:27:56 +01:00
|
|
|
class Move;
|
2012-03-26 07:48:33 +02:00
|
|
|
class PlayedRack;
|
2008-11-30 21:53:44 +01:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This class is a wrapper around a Game object (Façade design pattern).
|
|
|
|
*
|
|
|
|
* Game objects are not meant for direct use outside of the game library,
|
|
|
|
* because they expose too many internal members.
|
|
|
|
* A PublicGame provides a cleaner interface to implement a UI, avoiding
|
|
|
|
* the need to know too much about the Game internals.
|
|
|
|
*/
|
|
|
|
class PublicGame
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Build a PublicGame from a Game object
|
|
|
|
* The PublicGame takes the ownership of the Game object.
|
|
|
|
*/
|
|
|
|
// XXX: should be private?
|
|
|
|
PublicGame(Game &iGame);
|
|
|
|
~PublicGame();
|
|
|
|
|
|
|
|
/***************
|
|
|
|
* Game type
|
|
|
|
***************/
|
|
|
|
|
|
|
|
// XXX: should not be in Game?
|
|
|
|
/// Game mode: each one of these modes is implemented in an inherited class
|
|
|
|
enum GameMode
|
|
|
|
{
|
|
|
|
kTRAINING,
|
|
|
|
kFREEGAME,
|
2012-03-05 01:27:56 +01:00
|
|
|
kDUPLICATE,
|
|
|
|
kARBITRATION,
|
2012-12-25 17:30:03 +01:00
|
|
|
kTOPPING,
|
2008-11-30 21:53:44 +01:00
|
|
|
};
|
|
|
|
GameMode getMode() const;
|
|
|
|
|
|
|
|
/***************
|
|
|
|
* Various getters
|
|
|
|
***************/
|
|
|
|
|
2011-08-27 19:21:26 +02:00
|
|
|
/// Get the game characteristics
|
|
|
|
const GameParams & getParams() const;
|
|
|
|
|
2012-12-30 16:14:13 +01:00
|
|
|
bool hasMasterGame() const;
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/**
|
|
|
|
* Get the dictionary associated with the game.
|
|
|
|
* You should never create a new dictionary object while a Game
|
|
|
|
* object still exists
|
|
|
|
*/
|
|
|
|
const Dictionary & getDic() const;
|
|
|
|
|
|
|
|
/// Get the board
|
|
|
|
const Board& getBoard() const;
|
|
|
|
/// Get the bag
|
|
|
|
const Bag& getBag() const;
|
2012-03-26 07:48:33 +02:00
|
|
|
/// Get the rack
|
|
|
|
const PlayedRack & getCurrentRack() const;
|
2008-11-30 21:53:44 +01:00
|
|
|
|
|
|
|
/// Get the history of the game */
|
|
|
|
const History& getHistory() const;
|
|
|
|
|
|
|
|
/***************
|
|
|
|
* Methods to access players.
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a player to the game.
|
|
|
|
* The Game object takes ownership of the given player
|
|
|
|
*/
|
|
|
|
void addPlayer(Player *iPlayer);
|
|
|
|
|
|
|
|
const Player& getPlayer(unsigned int iNum) const;
|
|
|
|
const Player& getCurrentPlayer() const;
|
|
|
|
unsigned int getNbPlayers() const;
|
|
|
|
unsigned int getNbHumanPlayers() const;
|
|
|
|
|
2012-03-19 12:39:13 +01:00
|
|
|
void setPlayerName(unsigned iPlayerId, const wstring &iName);
|
|
|
|
void setPlayerTableNb(unsigned iPlayerId, unsigned iTableNb);
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/// Return true if the player has played for the current turn
|
|
|
|
// XXX: not very nice API, should be a player property...
|
|
|
|
bool hasPlayed(unsigned int player) const;
|
|
|
|
|
|
|
|
/***************
|
|
|
|
* Game handling
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start the game.
|
|
|
|
* AI players are handled automatically, so if the game only has AI
|
|
|
|
* players, it will play until the end.
|
|
|
|
*/
|
|
|
|
void start();
|
|
|
|
|
2011-01-30 01:23:45 +01:00
|
|
|
/**
|
|
|
|
* Indicate whether we reached the end of the game.
|
|
|
|
* This should be checked regularly.
|
|
|
|
* XXX: using a signal would be nice here...
|
|
|
|
*/
|
|
|
|
bool isFinished() const;
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/**
|
|
|
|
* Method used by human players to play the word iWord at coordinates
|
|
|
|
* iCoord, and end the turn (if possible)
|
|
|
|
* Possible return values:
|
|
|
|
* 0: correct word, the Round can be used by the caller
|
|
|
|
* 1: one letter of the word is invalid in the current dictionary
|
|
|
|
* 2: invalid coordinates (unreadable or out of the board)
|
|
|
|
* 3: word not present in the dictionary
|
|
|
|
* 4: not enough letters in the rack to play the word
|
|
|
|
* 5: word is part of a longer one
|
|
|
|
* 6: word overwriting an existing letter
|
|
|
|
* 7: invalid crosscheck
|
|
|
|
* 8: word already present on the board (no new letter from the rack)
|
|
|
|
* 9: isolated word (not connected to the rest)
|
|
|
|
* 10: first word not horizontal
|
|
|
|
* 11: first word not covering the H8 square
|
|
|
|
* 12: word going out of the board
|
|
|
|
*/
|
|
|
|
int play(const wstring &iWord, const wstring &iCoord);
|
|
|
|
|
2012-12-24 16:21:50 +01:00
|
|
|
// TODO: doc
|
2012-12-24 20:32:47 +01:00
|
|
|
// Ignores the word validity and connexion with the rest
|
2012-12-24 16:21:50 +01:00
|
|
|
int checkPlayedWord(const wstring &iWord, const wstring &iCoord,
|
|
|
|
Move &oMove) const;
|
|
|
|
|
2011-07-17 01:31:17 +02:00
|
|
|
/**
|
|
|
|
* Compute the points for playing the word iWord at coordinates iCoord.
|
|
|
|
* A negative return value indicates an error (same codes as for the
|
|
|
|
* play() method, but negative instead of positive).
|
|
|
|
*/
|
|
|
|
int computePoints(const wstring &iWord, const wstring &iCoord) const;
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/// Shuffle the rack of the current player
|
|
|
|
void shuffleRack();
|
|
|
|
|
2013-01-09 18:42:49 +01:00
|
|
|
/**
|
|
|
|
* Reorder the rack of the given player.
|
|
|
|
* An assertion is there to check that the letters are the same.
|
|
|
|
*/
|
|
|
|
void reorderRack(const PlayedRack &iRack);
|
|
|
|
|
2012-02-18 20:22:10 +01:00
|
|
|
/**
|
|
|
|
* Place a temporary word on the board for preview purposes.
|
|
|
|
* It is up to the caller to provide a Round
|
|
|
|
* which makes sense for the current game.
|
|
|
|
*/
|
2012-01-12 17:43:57 +01:00
|
|
|
void setTestRound(const Round &iRound);
|
2012-02-18 20:22:10 +01:00
|
|
|
/** Remove the round set with setTestRound */
|
2012-01-12 17:43:57 +01:00
|
|
|
void removeTestRound();
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/***************
|
|
|
|
* Training games
|
|
|
|
* These methods throw an exception if the current game is not in
|
|
|
|
* the Training mode.
|
|
|
|
***************/
|
|
|
|
|
|
|
|
void trainingSearch();
|
|
|
|
const Results& trainingGetResults() const;
|
|
|
|
int trainingPlayResult(unsigned int iResultIndex);
|
|
|
|
|
|
|
|
enum RackMode
|
|
|
|
{
|
|
|
|
kRACK_NEW, // Only new tiles
|
|
|
|
kRACK_ALL // All tiles
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Complete (or reset) the rack randomly.
|
|
|
|
* @exception EndGameException if it is impossible to complete the rack
|
|
|
|
* for some reason...
|
|
|
|
*/
|
|
|
|
void trainingSetRackRandom(bool iCheck, RackMode iRackMode);
|
|
|
|
|
2009-01-24 11:28:20 +01:00
|
|
|
void trainingSetRackManual(bool iCheck, const wstring &iLetters);
|
2008-11-30 21:53:44 +01:00
|
|
|
|
2012-12-29 18:49:52 +01:00
|
|
|
|
|
|
|
/***************
|
|
|
|
* Topping games
|
|
|
|
* These methods throw an exception if the current game is not in
|
|
|
|
* the Topping mode.
|
|
|
|
***************/
|
|
|
|
|
2013-01-06 19:05:30 +01:00
|
|
|
void toppingPlay(const wstring &iWord, const wstring &iCoord, int iElapsed);
|
|
|
|
|
2012-12-29 18:49:52 +01:00
|
|
|
vector<Move> toppingGetTriedMoves() const;
|
|
|
|
|
2013-01-08 15:54:11 +01:00
|
|
|
Move toppingGetTopMove() const;
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/***************
|
|
|
|
* Duplicate games
|
|
|
|
* These methods throw an exception if the current game is not in
|
|
|
|
* the Duplicate mode.
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the current player, given its ID.
|
2009-01-24 18:11:07 +01:00
|
|
|
* The given player ID must correspond to a human player, who did not
|
2008-11-30 21:53:44 +01:00
|
|
|
* play yet for this turn.
|
2009-01-24 18:11:07 +01:00
|
|
|
* @param p: ID of the player
|
|
|
|
* @exception GameException: Thrown if the player is not human or if
|
|
|
|
* he has already played
|
2008-11-30 21:53:44 +01:00
|
|
|
*/
|
2009-01-24 18:11:07 +01:00
|
|
|
void duplicateSetPlayer(unsigned int p);
|
2008-11-30 21:53:44 +01:00
|
|
|
|
2012-03-05 01:27:56 +01:00
|
|
|
void duplicateSetMasterMove(const Move &iMove);
|
|
|
|
const Move & duplicateGetMasterMove() const;
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/***************
|
|
|
|
* FreeGame games
|
|
|
|
* These methods throw an exception if the current game is not in
|
|
|
|
* the FreeGame mode.
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pass the turn, changing the letters listed in iToChange.
|
|
|
|
* If you simply want to pass the turn without changing any letter,
|
|
|
|
* provide an empty string.
|
|
|
|
*
|
|
|
|
* Possible return values:
|
|
|
|
* 0: everything went fine
|
|
|
|
* 1: changing letters is not allowed if there are less than 7 tiles
|
|
|
|
* left in the bag
|
|
|
|
* 2: the rack of the current player does not contain all the
|
|
|
|
* listed letters
|
|
|
|
* 3: the game is already finished
|
|
|
|
* 4: some letters are invalid for the current dictionary
|
|
|
|
*/
|
|
|
|
int freeGamePass(const wstring &iToChange);
|
|
|
|
|
2012-03-05 01:27:56 +01:00
|
|
|
/***************
|
|
|
|
* Arbitration games
|
|
|
|
* These methods throw an exception if the current game is not in
|
|
|
|
* the Arbitration mode
|
|
|
|
***************/
|
|
|
|
|
2012-03-11 00:24:21 +01:00
|
|
|
/**
|
|
|
|
* Complete the rack randomly.
|
|
|
|
* @exception EndGameException if it is impossible to complete the rack
|
|
|
|
* for some reason...
|
|
|
|
*/
|
|
|
|
void arbitrationSetRackRandom();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the rack manually
|
|
|
|
* @exception EndGameException if the game is over
|
|
|
|
* @exception GameException if any other error occurs
|
|
|
|
*/
|
|
|
|
void arbitrationSetRackManual(const wstring &iLetters);
|
|
|
|
|
2012-03-17 23:45:47 +01:00
|
|
|
void arbitrationSearch(LimitResults &oResults);
|
2012-03-05 01:27:56 +01:00
|
|
|
|
|
|
|
Move arbitrationCheckWord(const wstring &iWord,
|
|
|
|
const wstring &iCoords) const;
|
|
|
|
|
2012-10-05 12:52:42 +02:00
|
|
|
void arbitrationToggleSolo(unsigned iPlayerId);
|
|
|
|
int arbitrationGetSolo(unsigned iPlayerId) const;
|
|
|
|
|
2012-03-23 07:41:16 +01:00
|
|
|
void arbitrationToggleWarning(unsigned iPlayerId);
|
2012-03-23 08:12:03 +01:00
|
|
|
bool arbitrationHasWarning(unsigned iPlayerId) const;
|
|
|
|
|
2012-05-20 22:12:42 +02:00
|
|
|
void arbitrationTogglePenalty(unsigned iPlayerId);
|
2012-03-23 08:12:03 +01:00
|
|
|
int arbitrationGetPenalty(unsigned iPlayer) const;
|
2012-03-23 07:41:16 +01:00
|
|
|
|
|
|
|
void arbitrationAssign(unsigned playerId, const Move &iMove);
|
2012-03-05 01:27:56 +01:00
|
|
|
void arbitrationFinalizeTurn();
|
|
|
|
|
2008-11-30 21:53:44 +01:00
|
|
|
/***************
|
|
|
|
* Saved games handling
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/**
|
2009-11-29 17:01:31 +01:00
|
|
|
* Return the loaded game, from an XML file.
|
|
|
|
* An exception is thrown in case of problem.
|
2008-11-30 21:53:44 +01:00
|
|
|
*/
|
2009-11-29 17:01:31 +01:00
|
|
|
static PublicGame * load(const string &iFileName, const Dictionary &iDic);
|
2008-11-30 21:53:44 +01:00
|
|
|
|
|
|
|
/**
|
2009-11-29 17:01:31 +01:00
|
|
|
* Save a game to a XML file
|
2008-11-30 21:53:44 +01:00
|
|
|
*/
|
2009-11-29 17:01:31 +01:00
|
|
|
void save(const string &iFileName) const;
|
2008-11-30 21:53:44 +01:00
|
|
|
|
|
|
|
/***************
|
|
|
|
* Navigation in the game history
|
|
|
|
***************/
|
|
|
|
|
|
|
|
unsigned int getCurrTurn() const;
|
|
|
|
unsigned int getNbTurns() const;
|
|
|
|
bool isFirstTurn() const;
|
|
|
|
bool isLastTurn() const;
|
|
|
|
|
|
|
|
void firstTurn();
|
|
|
|
void prevTurn();
|
|
|
|
void nextTurn();
|
|
|
|
void lastTurn();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get rid of the future turns of the game, the current turn
|
|
|
|
* becoming the last one.
|
|
|
|
*/
|
|
|
|
void clearFuture();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Print the contents of the commands history, to ease debugging
|
|
|
|
*/
|
|
|
|
void printTurns() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// Wrapped game
|
|
|
|
Game &m_game;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|