The game mode and the players are nod hardcoded anymore in the ncurses

interface: they can be entered with the command-line (parsed using getopt).
The text interface does not benefit from this facility yet.
This commit is contained in:
Olivier Teulière 2005-03-03 22:14:41 +00:00
parent 8b54450438
commit f45fd22c16
8 changed files with 238 additions and 82 deletions

View file

@ -3,8 +3,8 @@ dnl Process this file with autoconf to produce a configure script.
dnl --------------------------------------------------------------
dnl configure.in for Eliot
dnl --------------------------------------------------------------
dnl AC_REVISION($Id: configure.in,v 1.8 2005/02/18 18:16:23 ipkiss Exp $)
AC_INIT(eliot, 1.4)
dnl AC_REVISION($Id: configure.in,v 1.9 2005/03/03 22:14:41 ipkiss Exp $)
AC_INIT(eliot, 1.5-cvs)
AC_CONFIG_SRCDIR(wxwin/main.cc)
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)

View file

@ -2,7 +2,7 @@
* Copyright (C) 1999-2005 Eliot
* Authors: Antoine Fraboulet <antoine.fraboulet@free.fr>
*
* $Id: debug.h,v 1.2 2005/02/05 11:14:56 ipkiss Exp $
* $Id: debug.h,v 1.3 2005/03/03 22:14:41 ipkiss Exp $
*
* 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
@ -26,11 +26,19 @@
* General
**********/
#ifdef DEBUG
// XXX: Temporary
#define _DEBUG_
#ifdef _DEBUG_
# include <stdio.h>
# define PDEBUG(cond,msg) { if (cond) fprintf(stderr,"GAME DEBUG: %s\n",msg);}
# define PDEBUG(cond, msg) \
{ \
if (cond) \
fprintf(stderr, "GAME DEBUG: %s (at %s#%i)\n", \
msg, __FILE__, __LINE__); \
}
#else
# define PDEBUG(cond,msg)
# define PDEBUG(cond, msg)
#endif
#endif

View file

@ -3,7 +3,7 @@
* Authors: Antoine Fraboulet <antoine.fraboulet@free.fr>
* Olivier Teuliere <ipkiss@via.ecp.fr>
*
* $Id: game.h,v 1.8 2005/02/26 22:57:34 ipkiss Exp $
* $Id: game.h,v 1.9 2005/03/03 22:14:41 ipkiss Exp $
*
* 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
@ -179,8 +179,8 @@ public:
*************************/
int getNPlayers() const { return m_players.size(); }
int getNHumanPlayers() const;
void addHumanPlayer();
void addAIPlayer();
virtual void addHumanPlayer();
virtual void addAIPlayer();
int getPlayerPoints(int) const;
string getPlayerRack(int) const;

View file

@ -2,7 +2,7 @@
* Copyright (C) 2005 Eliot
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* $Id: game_factory.cpp,v 1.1 2005/02/24 08:06:25 ipkiss Exp $
* $Id: game_factory.cpp,v 1.2 2005/03/03 22:14:41 ipkiss Exp $
*
* 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
@ -19,12 +19,28 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
#include <getopt.h>
#include "config.h"
#include "dic.h"
#include "game_factory.h"
GameFactory *GameFactory::m_factory = NULL;
GameFactory::GameFactory(): m_dic(NULL), m_human(0), m_ai(0)
{
}
GameFactory::~GameFactory()
{
if (m_dic)
Dic_destroy(m_dic);
}
GameFactory *GameFactory::Instance()
{
if (m_factory == NULL)
@ -62,8 +78,107 @@ Duplicate *GameFactory::createDuplicate(const Dictionary &iDic)
}
Game *GameFactory::createFromCmdLine(int argc, char **argv)
{
// 1) Parse command-line and store everything in member variables
static struct option long_options[] =
{
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{"dictionary", required_argument, NULL, 'd'},
{"dict", required_argument, NULL, 'd'},
{"mode", required_argument, NULL, 'm'},
{"human", no_argument, NULL, 300},
{"ai", no_argument, NULL, 400},
{0, 0, 0, 0}
};
static char short_options[] = "hvd:m:";
int option_index = 1;
int res;
while ((res = getopt_long(argc, argv, short_options,
long_options, &option_index)) != -1)
{
switch (res)
{
case 'h':
// Help requested, display it and exit
printUsage(argv[0]);
return NULL;
case 'v':
// Version requested, display it and exit
printVersion();
return NULL;
case 'd':
m_dicStr = optarg;
break;
case 'm':
m_modeStr = optarg;
break;
case 300:
m_human++;
break;
case 400:
m_ai++;
}
}
// 2) Try to load the dictionary
if (Dic_load(&m_dic, m_dicStr.c_str()))
return NULL;
// 3) Try to create a game object
Game *game = NULL;
if (m_modeStr == "training" || m_modeStr == "t")
{
game = createTraining(m_dic);
}
else if (m_modeStr == "freegame" || m_modeStr == "f")
{
game = createFreeGame(m_dic);
}
else if (m_modeStr == "duplicate" || m_modeStr == "d")
{
game = createDuplicate(m_dic);
}
else
return NULL;
// 4) Add the players
for (int i = 0; i < m_human; i++)
game->addHumanPlayer();
for (int i = 0; i < m_ai; i++)
game->addAIPlayer();
return game;
}
void GameFactory::releaseGame(Game &iGame)
{
delete &iGame;
}
void GameFactory::printUsage(const string &iBinaryName) const
{
cout << "Usage: " << iBinaryName << " [options]\n"
<< "\n"
<< " -h, --help Print this help and exit\n"
<< " -v, --version Print version information and exit\n"
<< " -m, --mode {duplicate,d,freegame,f,training,t}\n"
<< " Choose game mode\n"
<< " -d, --dict <string> Choose a dictionary\n"
<< " --human Add a human player\n"
<< " --ai Add a AI (Artificial Intelligence) player\n";
}
void GameFactory::printVersion() const
{
cout << PACKAGE_STRING << "\n"
<< "This program comes with NO WARRANTY, to the extent permitted by "
<< "law.\nYou may redistribute it under the terms of the GNU General "
<< "Public License;\nsee the file named COPYING for details.\n";
}

View file

@ -2,7 +2,7 @@
* Copyright (C) 2005 Eliot
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* $Id: game_factory.h,v 1.1 2005/02/24 08:06:25 ipkiss Exp $
* $Id: game_factory.h,v 1.2 2005/03/03 22:14:41 ipkiss Exp $
*
* 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
@ -31,30 +31,57 @@
class GameFactory
{
public:
static GameFactory *Instance();
static void Destroy();
/*************************
* Functions to create and destroy a game
* The dictionary does not belong to the
* game (ie: it won't be destroyed by ~Game)
*
* The dictionary can be changed afterwards by setDic
*************************/
static GameFactory *Instance();
static void Destroy();
Training *createTraining(const Dictionary &iDic);
FreeGame *createFreeGame(const Dictionary &iDic);
Duplicate *createDuplicate(const Dictionary &iDic);
//Game *loadGame(FILE *fin, const Dictionary &iDic);
Game *createFromCmdLine(int argc, char **argv);
void releaseGame(Game &iGame);
private:
GameFactory() {}
virtual ~GameFactory() {}
GameFactory();
virtual ~GameFactory();
// The unique instance of the class
/// The unique instance of the class
static GameFactory *m_factory;
/// Initial dictionary (it could be changed later)
Dictionary m_dic;
/** Parameters specified on the command-line */
//@{
/// Dictionary
string m_dicStr;
/// Game mode
string m_modeStr;
/// Number of human players
int m_human;
/// Number of AI players
int m_ai;
//@}
/// Print command-line usage
void printUsage(const string &iBinaryName) const;
/// Print version
void printVersion() const;
};
#endif // _GAME_FACTORY_H_

View file

@ -3,7 +3,7 @@
* Authors: Antoine Fraboulet <antoine.fraboulet@free.fr>
* Olivier Teuliere <ipkiss@via.ecp.fr>
*
* $Id: training.cpp,v 1.2 2005/02/17 20:01:59 ipkiss Exp $
* $Id: training.cpp,v 1.3 2005/03/03 22:14:41 ipkiss Exp $
*
* 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
@ -44,15 +44,6 @@ Training::~Training()
}
void Training::search()
{
// Search for the current player
Rack r;
m_players[m_currPlayer]->getCurrentRack().getRack(r);
m_results.search(*m_dic, m_board, r, getNRounds());
}
int Training::play(const string &iCoord, const string &iWord)
{
/* Perform all the validity checks, and fill a round */
@ -78,30 +69,6 @@ int Training::play(const string &iCoord, const string &iWord)
}
int Training::playResult(int n)
{
Player *player = m_players[m_currPlayer];
if (n >= m_results.size())
return 2;
const Round &round = m_results.get(n);
/* Update the rack and the score of the current player */
player->addPoints(round.getPoints());
player->endTurn(round, getNRounds());
int res = helperPlayRound(round);
if (res == 0)
m_results.clear();
/* Next turn */
// XXX: Should it be done by the interface instead?
endTurn();
return res;
}
int Training::setRackRandom(int p, bool iCheck, set_rack_mode mode)
{
int res;
@ -134,8 +101,8 @@ int Training::start()
if (getNPlayers() != 0)
return 1;
/* Training mode implicitly uses 1 human player */
addHumanPlayer();
// Training mode implicitly uses 1 human player
Game::addHumanPlayer();
m_currPlayer = 0;
return 0;
}
@ -148,6 +115,53 @@ int Training::endTurn()
}
void Training::search()
{
// Search for the current player
Rack r;
m_players[m_currPlayer]->getCurrentRack().getRack(r);
m_results.search(*m_dic, m_board, r, getNRounds());
}
int Training::playResult(int n)
{
Player *player = m_players[m_currPlayer];
if (n >= m_results.size())
return 2;
const Round &round = m_results.get(n);
/* Update the rack and the score of the current player */
player->addPoints(round.getPoints());
player->endTurn(round, getNRounds());
int res = helperPlayRound(round);
if (res == 0)
m_results.clear();
/* Next turn */
// XXX: Should it be done by the interface instead?
endTurn();
return res;
}
void Training::addHumanPlayer()
{
// We are not supposed to be here...
PDEBUG(true, "Trying to add a human player in Training mode!");
}
void Training::addAIPlayer()
{
// We are not supposed to be here...
PDEBUG(true, "Trying to add a AI player in Training mode!");
}
int Training::getNResults() const
{
return m_results.size();

View file

@ -3,7 +3,7 @@
* Authors: Antoine Fraboulet <antoine.fraboulet@free.fr>
* Olivier Teuliere <ipkiss@via.ecp.fr>
*
* $Id: training.h,v 1.4 2005/02/24 08:06:25 ipkiss Exp $
* $Id: training.h,v 1.5 2005/03/03 22:14:41 ipkiss Exp $
*
* 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
@ -47,6 +47,13 @@ public:
int playResult(int);
int setRackManual(bool iCheck, const string &iLetters);
/*************************
* Override the default behaviour of these methods, because in training
* we only want a human player
*************************/
virtual void addHumanPlayer();
virtual void addAIPlayer();
/*************************
* Functions to access the current search results
* The int parameter should be 0 <= int < getNResults

View file

@ -2,7 +2,7 @@
* Copyright (C) 2005 Eliot
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* $Id: ncurses.cpp,v 1.7 2005/02/24 08:06:25 ipkiss Exp $
* $Id: ncurses.cpp,v 1.8 2005/03/03 22:14:41 ipkiss Exp $
*
* 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
@ -819,9 +819,15 @@ int main(int argc, char ** argv)
textdomain(PACKAGE);
#endif
Game *game = GameFactory::Instance()->createFromCmdLine(argc, argv);
if (game == NULL)
return 1;
game->start();
// Initialize the ncurses library
WINDOW *wBoard = initscr();
keypad( wBoard, true );
keypad(wBoard, true);
// Take input chars one at a time
cbreak();
// Do not do NL -> NL/CR
@ -845,28 +851,8 @@ int main(int argc, char ** argv)
init_pair(COLOR_RED, COLOR_BLACK, COLOR_RED);
}
char dic_path[100];
Dictionary dic = NULL;
srand(time(NULL));
if (argc != 2)
{
endwin();
fprintf(stdout, _("Usage: eliotcurses /path/to/ods4.dawg\n"));
exit(1);
}
else
strcpy(dic_path, argv[1]);
if (Dic_load(&dic, dic_path))
return -1;
Game *game = GameFactory::Instance()->createFreeGame(dic);
game->addHumanPlayer();
game->addAIPlayer();
// game->addAIPlayer();
// game->addAIPlayer();
game->start();
// Do not echo
noecho();
@ -874,7 +860,7 @@ int main(int argc, char ** argv)
CursesIntf mainIntf(wBoard, *game);
mainIntf.redraw(wBoard);
while (! mainIntf.isDying())
while (!mainIntf.isDying())
{
int c = getch();
if (mainIntf.handleKey(c) == 1)
@ -883,13 +869,12 @@ int main(int argc, char ** argv)
}
}
GameFactory::Destroy();
Dic_destroy(dic);
delwin(wBoard);
// Exit the ncurses library
endwin();
GameFactory::Destroy();
return 0;
}