mirror of
git://git.savannah.nongnu.org/eliot.git
synced 2025-01-13 20:03:23 +01:00
- Players can now have a name
- Use player names in the ncurses interface - In training mode, create the hidden player in the constructor, not in start() - When the AI has nothing to play, change the letters instead of simply passing - New Makefile to build the win32 dependencies automatically (INSTALL file updated)
This commit is contained in:
parent
8c3708fa99
commit
0a4b342f78
9 changed files with 247 additions and 91 deletions
117
INSTALL
117
INSTALL
|
@ -1,83 +1,86 @@
|
||||||
|
Installation on Linux/Unix
|
||||||
|
==========================
|
||||||
|
|
||||||
Installation sous Linux (Un*x) (bien/facile)
|
In the following, do not forget that the ./configure command can take options.
|
||||||
------------------------------
|
Run ./configure --help to have the list of available options.
|
||||||
* Pour installer à partir de l'archive CVS :
|
|
||||||
|
|
||||||
./bootstrap
|
* If you build from a CVS snapshot, run the following commands:
|
||||||
|
./bootstrap
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
|
||||||
./configure
|
Then, as root:
|
||||||
make
|
make install
|
||||||
make install
|
|
||||||
|
|
||||||
* Pour installer à partir de l'archive tar.gz
|
No graphical interface is built by default, see below for more details.
|
||||||
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
|
|
||||||
Il existe en fait 3 versions d'eliot, une en mode texte, une avec une
|
* If you build from a release tarball, run the following commands:
|
||||||
interface curses et une avec wxwidgets. Les modes peuvent être
|
./configure
|
||||||
sélectionnés à l'aide de la commande configure lors de la compilation
|
make
|
||||||
du programme.
|
|
||||||
|
|
||||||
./configure --enable-text --enable-ncurses --enable-wxwidgets
|
Then, as root:
|
||||||
|
make install
|
||||||
|
|
||||||
|
No graphical interface is built by default, see below for more details.
|
||||||
|
|
||||||
|
|
||||||
|
There are in fact several interfaces to Eliot:
|
||||||
|
- one in text mode: mostly useful to debug Eliot
|
||||||
|
- one using the ncursesw library: nice but not really graphical
|
||||||
|
- a wxWidgets interface: complete, but it does not allow multiplayer
|
||||||
|
modes, only training mode
|
||||||
|
- a Qt interface: currently under construction, it will replace the
|
||||||
|
wxWidgets interface when finished. It will support all Eliot features.
|
||||||
|
|
||||||
|
These interfaces can be enabled or disabled at configuration time. Example:
|
||||||
|
./configure --disable-text --enable-ncurses --disable-wxwidgets --enable-qt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Installation pour Windows (moins bien/facile)
|
Windows build
|
||||||
-------------------------
|
=============
|
||||||
|
|
||||||
Il y a 2 principales façons de procéder :
|
There are 2 ways to proceed:
|
||||||
* directement depuis Windows, en utilisant Cygwin (http://www.cygwin.com/).
|
* cross-compilation from a Linux host, using the mingw32 cross-compiler
|
||||||
* depuis GNU/Linux, en utilisant le cross-compilateur Mingw32.
|
* directly on Windows, using Cygwin (http://www.cygwin.com/)
|
||||||
|
Only the cross-compilation is officially supported (but adapting these
|
||||||
|
instructions for Cygwin shouldn't be too hard; patches welcome!).
|
||||||
|
|
||||||
|
Here are the steps for the cross-compilation:
|
||||||
|
|
||||||
Dans les 2 cas, les étapes sont les mêmes :
|
* install the build environment (this step is not documented here,
|
||||||
* installation de l'environnement de compilation (cette étape n'est pas
|
as it is out of the scope of this document)
|
||||||
décrite ici, car elle ne rentre pas dans le cadre de ce document)
|
|
||||||
|
|
||||||
* compilation et installation des dépendances (même remarque):
|
* build and install dependencies:
|
||||||
|
The Makefile in the 'extras/contrib' directory should be able to do it for you:
|
||||||
|
|
||||||
- wxWidgets (http://www.wxwidgets.org/), version 2.4.2 ou ultérieure, avec
|
cd extras/contrib && make all
|
||||||
support de l'unicode
|
|
||||||
|
|
||||||
- libiconv (http://www.gnu.org/software/libiconv/), de préférence compilée
|
Eliot dependencies (libiconv, boost, wxWidgets and Qt) will be downloaded
|
||||||
en mode statique (--disable-shared --enable-static)
|
and cross-compiled, except Qt, which is only downloaded. Install it with
|
||||||
|
Wine, ignoring the warning that mingw is not found.
|
||||||
|
The dependencies are installed in 'extras/contrib/inst'
|
||||||
|
|
||||||
- boost (http://www.boost.org/). Eliot n'utilise pas de librairie de Boost
|
* build Eliot:
|
||||||
(uniquement des headers), donc il n'y a pas vraiment besoin de compiler
|
|
||||||
|
|
||||||
* compilation d'Eliot :
|
- if you don't have the 'configure' script, generate it:
|
||||||
|
|
||||||
- si vous utilisez l'archive CVS, il faut générer le script 'configure'
|
|
||||||
(aussi bien sous Cygwin que sous GNU/Linux) :
|
|
||||||
./bootstrap
|
./bootstrap
|
||||||
|
|
||||||
- à cause d'un bug de gettext, il faut appliquer un patch aux fichiers installés
|
- because of a bug in gettext, you need to apply a little patch to the files
|
||||||
dans intl/ :
|
installed in the 'intl' directory:
|
||||||
- télécharger le patch ici (lien en haut à gauche) :
|
- download the patch here (link in the top-left-hand corner)
|
||||||
http://www.koders.com/noncode/fid46DF595700FEB564B6EF45BFF55067F95DCF0420.aspx
|
http://www.koders.com/noncode/fid46DF595700FEB564B6EF45BFF55067F95DCF0420.aspx
|
||||||
- exécuter la commande suivante :
|
- apply the patch:
|
||||||
patch -p2 < gettext-win32.patch
|
patch -p2 < gettext-win32.patch
|
||||||
|
|
||||||
- avec Cygwin, configurer avec la ligne de commande suivante :
|
- configure with the following command:
|
||||||
CPPFLAGS=-I/path/to/installs/include LDFLAGS=-L/path/to/installs/lib \
|
export INST=`pwd`/extras/contrib/inst && \
|
||||||
CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin" \
|
CPPFLAGS=-I${INST}/include LDFLAGS=-L${INST}/lib \
|
||||||
./configure --enable-wxwidgets --with-wx-config=/path/to/wx-config \
|
|
||||||
--with-boost=/path/to/boost/installs
|
|
||||||
en prenant soin de remplacer les différents chemins par les bonnes valeurs.
|
|
||||||
Ensuite, un simple 'make' suffit pour terminer la compilation,
|
|
||||||
éventuellement suivi de 'make install'.
|
|
||||||
|
|
||||||
- pour la cross-compilation depuis GNU/Linux, configurer avec la ligne
|
|
||||||
de commande suivante :
|
|
||||||
CPPFLAGS=-I/path/to/installs/include LDFLAGS=-L/path/to/installs/lib \
|
|
||||||
CC=i586-mingw32msvc-gcc CXX=i586-mingw32msvc-g++ \
|
CC=i586-mingw32msvc-gcc CXX=i586-mingw32msvc-g++ \
|
||||||
./configure --host=i586-mingw32msvc --build=i386-linux \
|
./configure --host=i586-mingw32msvc --build=i386-linux \
|
||||||
--enable-wxwidgets --with-wx-config=/path/to/wx-config \
|
--enable-wxwidgets --with-wx-config=${INST}/bin/wx-config \
|
||||||
--with-boost=/path/to/installs
|
--with-boost=${INST}
|
||||||
en prenant soin de remplacer les différents chemins par les bonnes valeurs.
|
|
||||||
Ensuite, un simple 'make' suffit pour terminer la compilation,
|
- to compile, run 'make', possibly followed with 'make install'
|
||||||
éventuellement suivi de 'make install'.
|
|
||||||
|
|
||||||
|
|
85
extras/contrib/Makefile
Normal file
85
extras/contrib/Makefile
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
ICONV_VERSION = 1.12
|
||||||
|
WX_VERSION = 2.6.4
|
||||||
|
BOOST_VERSION = 1_34_1
|
||||||
|
QT_VERSION = 4.3.3
|
||||||
|
|
||||||
|
PREFIX = $(shell pwd)/inst
|
||||||
|
WGET = wget -c
|
||||||
|
|
||||||
|
# XXX: Hardcoded for mingw on linux, at the moment
|
||||||
|
CC = i586-mingw32msvc-gcc
|
||||||
|
CXX = i586-mingw32msvc-g++
|
||||||
|
CPPFLAGS += -I$(PREFIX)/include
|
||||||
|
CONFIGURE = CC=$(CC) CXX=$(CXX) CPPFLAGS=$(CPPFLAGS) ./configure --host=i586-mingw32msvc --build=i386-linux --prefix=$(PREFIX)
|
||||||
|
|
||||||
|
.PHONY: help all
|
||||||
|
|
||||||
|
help:
|
||||||
|
echo "Usage: make all"
|
||||||
|
|
||||||
|
all: .iconv .wxWidgets .boost .qt
|
||||||
|
|
||||||
|
|
||||||
|
### iconv ###
|
||||||
|
|
||||||
|
ICONV_DIR = libiconv-$(ICONV_VERSION)
|
||||||
|
ICONV_ARCHIVE = libiconv-$(ICONV_VERSION).tar.gz
|
||||||
|
|
||||||
|
$(ICONV_DIR):
|
||||||
|
$(WGET) http://ftp.gnu.org/pub/gnu/libiconv/$(ICONV_ARCHIVE)
|
||||||
|
tar xzf $(ICONV_ARCHIVE)
|
||||||
|
|
||||||
|
.iconv: $(ICONV_DIR)
|
||||||
|
(cd $< && $(CONFIGURE) --enable-static --disable-shared && make && make install)
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
|
||||||
|
### wxWidgets ###
|
||||||
|
|
||||||
|
WX_ARCHIVE = wxMSW-$(WX_VERSION).zip
|
||||||
|
WX_DIR = wxWidgets-$(WX_VERSION)
|
||||||
|
WX_DOS_FILES = config* *.sh install-sh mkinstalldirs
|
||||||
|
|
||||||
|
$(WX_DIR):
|
||||||
|
$(WGET) http://heanet.dl.sourceforge.net/sourceforge/wxwindows/$(WX_ARCHIVE)
|
||||||
|
unzip $(WX_ARCHIVE)
|
||||||
|
|
||||||
|
.wxWidgets: $(WX_DIR)
|
||||||
|
(cd $< && dos2unix $(WX_DOS_FILES) && chmod +x $(WX_DOS_FILES))
|
||||||
|
(cd $< && $(CONFIGURE) --disable-shared --enable-optimise --disable-debug --enable-unicode --without-libtiff --without-expat --without-zlib --without-libpng --without-libjpeg --without-regex --disable-mediactrl && make && make install)
|
||||||
|
dos2unix $(PREFIX)/bin/wx-config
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
|
||||||
|
### Boost ###
|
||||||
|
|
||||||
|
BOOST_DIR = boost_$(BOOST_VERSION)
|
||||||
|
BOOST_ARCHIVE = boost_$(BOOST_VERSION).tar.bz2
|
||||||
|
|
||||||
|
$(BOOST_DIR):
|
||||||
|
$(WGET) http://garr.dl.sourceforge.net/sourceforge/boost/$(BOOST_ARCHIVE)
|
||||||
|
tar xjf $(BOOST_ARCHIVE)
|
||||||
|
|
||||||
|
# We don't build any library, because we don't need them (and it is really
|
||||||
|
# hard to cross-compile with their crappy build system)
|
||||||
|
.boost: $(BOOST_DIR)
|
||||||
|
#(cd $< && ./configure --prefix=$(PREFIX) && ./tools/jam/src/bin.linuxx86/bjam --toolset=gcc --prefix=$(PREFIX) --without-date_time --without-filesystem --without-graph --without-iostreams --without-program_options --without-python --without-regex --without-serialization --without-signals --without-test --without-thread --without-wave install)
|
||||||
|
cp -r $</boost $(PREFIX)/include
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Qt ###
|
||||||
|
|
||||||
|
# FIXME: No automated way at the moment :-(
|
||||||
|
QT_ARCHIVE = qt-win-opensource-$(QT_VERSION)-mingw.exe
|
||||||
|
|
||||||
|
$(QT_ARCHIVE):
|
||||||
|
$(WGET) ftp://ftp.trolltech.com/qt/source/qt-win-opensource-4.3.3-mingw.exe
|
||||||
|
|
||||||
|
.qt: $(QT_ARCHIVE)
|
||||||
|
@echo "=============== Important note ==============="
|
||||||
|
@echo "You need to install $(QT_ARCHIVE) yourself using wine!"
|
||||||
|
@echo "=============================================="
|
||||||
|
touch $@
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
noinst_LIBRARIES = libgame.a
|
noinst_LIBRARIES = libgame.a
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/dic
|
AM_CPPFLAGS = -I$(top_srcdir)/dic -I../intl -I$(top_srcdir)/intl
|
||||||
|
|
||||||
libgame_a_SOURCES= \
|
libgame_a_SOURCES= \
|
||||||
ai_percent.cpp ai_percent.h \
|
ai_percent.cpp ai_percent.h \
|
||||||
|
|
|
@ -53,9 +53,12 @@ Move AIPercent::getMove() const
|
||||||
{
|
{
|
||||||
if (m_results.size() == 0)
|
if (m_results.size() == 0)
|
||||||
{
|
{
|
||||||
// If there is no result, simply pass the turn
|
// If there is no result, change all the letters
|
||||||
// XXX: it is forbidden in duplicate mode, but well, what else to do?
|
// XXX: it is forbidden in duplicate mode (even passing is forbidden),
|
||||||
return Move(L"");
|
// but well, what else to do?
|
||||||
|
Rack rack;
|
||||||
|
getCurrentRack().getRack(rack);
|
||||||
|
return Move(rack.toString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,18 +26,27 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
|
#if ENABLE_NLS
|
||||||
|
# include <libintl.h>
|
||||||
|
# define _(String) gettext(String)
|
||||||
|
#else
|
||||||
|
# define _(String) String
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "game_factory.h"
|
#include "game_factory.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "training.h"
|
#include "training.h"
|
||||||
#include "freegame.h"
|
#include "freegame.h"
|
||||||
#include "duplicate.h"
|
#include "duplicate.h"
|
||||||
|
#include "player.h"
|
||||||
#include "dic.h"
|
#include "dic.h"
|
||||||
|
#include "encoding.h"
|
||||||
|
|
||||||
|
|
||||||
GameFactory *GameFactory::m_factory = NULL;
|
GameFactory *GameFactory::m_factory = NULL;
|
||||||
|
|
||||||
|
|
||||||
GameFactory::GameFactory(): m_dic(NULL), m_human(0), m_ai(0), m_joker(false)
|
GameFactory::GameFactory(): m_dic(NULL), m_joker(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,12 +103,12 @@ Game *GameFactory::createFromCmdLine(int argc, char **argv)
|
||||||
{"dictionary", required_argument, NULL, 'd'},
|
{"dictionary", required_argument, NULL, 'd'},
|
||||||
{"dict", required_argument, NULL, 'd'},
|
{"dict", required_argument, NULL, 'd'},
|
||||||
{"mode", required_argument, NULL, 'm'},
|
{"mode", required_argument, NULL, 'm'},
|
||||||
{"human", no_argument, NULL, 300},
|
{"human", required_argument, NULL, 'u'},
|
||||||
{"ai", no_argument, NULL, 400},
|
{"ai", required_argument, NULL, 'a'},
|
||||||
{"joker", no_argument, NULL, 500},
|
{"joker", no_argument, NULL, 500},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
static char short_options[] = "hvd:m:";
|
static char short_options[] = "hvd:m:u:a:";
|
||||||
|
|
||||||
int option_index = 1;
|
int option_index = 1;
|
||||||
int res;
|
int res;
|
||||||
|
@ -126,11 +135,22 @@ Game *GameFactory::createFromCmdLine(int argc, char **argv)
|
||||||
m_modeStr = optarg;
|
m_modeStr = optarg;
|
||||||
found_m = true;
|
found_m = true;
|
||||||
break;
|
break;
|
||||||
case 300:
|
case 'u':
|
||||||
m_human++;
|
case 'a':
|
||||||
break;
|
// Handle both types of players together
|
||||||
case 400:
|
{
|
||||||
m_ai++;
|
wstring name;
|
||||||
|
if (optarg == NULL)
|
||||||
|
{
|
||||||
|
// TODO: use Boost.Format
|
||||||
|
char s[200];
|
||||||
|
snprintf(s, 200, _("Player %u"), m_players.size() + 1);
|
||||||
|
name = convertToWc(s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
name = convertToWc(optarg);
|
||||||
|
m_players.push_back(make_pair<bool, wstring>(res == 'u', name));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 500:
|
case 500:
|
||||||
m_joker = true;
|
m_joker = true;
|
||||||
|
@ -184,10 +204,15 @@ Game *GameFactory::createFromCmdLine(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5) Add the players
|
// 5) Add the players
|
||||||
for (int i = 0; i < m_human; i++)
|
for (unsigned int i = 0; i < m_players.size(); ++i)
|
||||||
game->addHumanPlayer();
|
{
|
||||||
for (int i = 0; i < m_ai; i++)
|
// Human?
|
||||||
game->addAIPlayer();
|
if (m_players[i].first)
|
||||||
|
game->addHumanPlayer();
|
||||||
|
else
|
||||||
|
game->addAIPlayer();
|
||||||
|
const_cast<Player*>(&game->getPlayer(i))->setName(m_players[i].second);
|
||||||
|
}
|
||||||
|
|
||||||
// 6) Set the variant
|
// 6) Set the variant
|
||||||
if (m_joker)
|
if (m_joker)
|
||||||
|
@ -225,9 +250,9 @@ void GameFactory::printUsage(const string &iBinaryName) const
|
||||||
<< " -v, --version Print version information and exit" << endl
|
<< " -v, --version Print version information and exit" << endl
|
||||||
<< " -m, --mode {duplicate,d,freegame,f,training,t}" << endl
|
<< " -m, --mode {duplicate,d,freegame,f,training,t}" << endl
|
||||||
<< " Choose game mode (mandatory)" << endl
|
<< " Choose game mode (mandatory)" << endl
|
||||||
<< " -d, --dict <string> Choose a dictionary (mandatory)" << endl
|
<< " -d, --dict <path> Choose a dictionary (mandatory)" << endl
|
||||||
<< " --human Add a human player" << endl
|
<< " -u --human <name> Add a human player" << endl
|
||||||
<< " --ai Add a AI (Artificial Intelligence) player" << endl
|
<< " -a --ai <name> Add a AI (Artificial Intelligence) player" << endl
|
||||||
<< " --joker Play with the \"Joker game\" variant" << endl;
|
<< " --joker Play with the \"Joker game\" variant" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,12 @@
|
||||||
#define _GAME_FACTORY_H_
|
#define _GAME_FACTORY_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using std::wstring;
|
||||||
|
using std::vector;
|
||||||
|
using std::pair;
|
||||||
|
|
||||||
class Dictionary;
|
class Dictionary;
|
||||||
class Game;
|
class Game;
|
||||||
|
@ -85,15 +89,12 @@ private:
|
||||||
/// Game mode
|
/// Game mode
|
||||||
string m_modeStr;
|
string m_modeStr;
|
||||||
|
|
||||||
/// Number of human players
|
|
||||||
int m_human;
|
|
||||||
|
|
||||||
/// Number of AI players
|
|
||||||
int m_ai;
|
|
||||||
|
|
||||||
/// Variant of the game
|
/// Variant of the game
|
||||||
bool m_joker;
|
bool m_joker;
|
||||||
|
|
||||||
|
typedef pair<bool, wstring> PlayerDesc;
|
||||||
|
vector<PlayerDesc> m_players;
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// Print command-line usage
|
/// Print command-line usage
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "pldrack.h"
|
#include "pldrack.h"
|
||||||
#include "history.h"
|
#include "history.h"
|
||||||
|
|
||||||
|
using std::wstring;
|
||||||
|
|
||||||
class Turn;
|
class Turn;
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,12 +45,17 @@ public:
|
||||||
// Pseudo RTTI
|
// Pseudo RTTI
|
||||||
virtual bool isHuman() const = 0;
|
virtual bool isHuman() const = 0;
|
||||||
|
|
||||||
|
/// Get the name of the player
|
||||||
|
const wstring & getName() const { return m_name; }
|
||||||
|
/// Set the name of the player
|
||||||
|
void setName(const wstring &iName) { m_name = iName; }
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
* General getters
|
* General getters
|
||||||
**************************/
|
**************************/
|
||||||
// Get the (possibly incomplete) rack of the player
|
/// Get the (possibly incomplete) rack of the player
|
||||||
const PlayedRack & getCurrentRack() const;
|
const PlayedRack & getCurrentRack() const;
|
||||||
// Get the previous rack
|
/// Get the previous rack
|
||||||
const PlayedRack & getLastRack() const;
|
const PlayedRack & getLastRack() const;
|
||||||
/// Get the previous move (corresponding to the previous rack...)
|
/// Get the previous move (corresponding to the previous rack...)
|
||||||
const Move & getLastMove() const;
|
const Move & getLastMove() const;
|
||||||
|
@ -56,6 +63,7 @@ public:
|
||||||
void setCurrentRack(const PlayedRack &iPld);
|
void setCurrentRack(const PlayedRack &iPld);
|
||||||
|
|
||||||
const History& getHistory() const { return m_history; }
|
const History& getHistory() const { return m_history; }
|
||||||
|
|
||||||
/// Remove last turn
|
/// Remove last turn
|
||||||
void removeLastTurn();
|
void removeLastTurn();
|
||||||
|
|
||||||
|
@ -84,6 +92,9 @@ private:
|
||||||
/// Score of the player
|
/// Score of the player
|
||||||
int m_score;
|
int m_score;
|
||||||
|
|
||||||
|
/// Name of the player
|
||||||
|
wstring m_name;
|
||||||
|
|
||||||
/// History of the racks and rounds for the player
|
/// History of the racks and rounds for the player
|
||||||
History m_history;
|
History m_history;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,13 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#if ENABLE_NLS
|
||||||
|
# include <libintl.h>
|
||||||
|
# define _(String) gettext(String)
|
||||||
|
#else
|
||||||
|
# define _(String) String
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "dic.h"
|
#include "dic.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "rack.h"
|
#include "rack.h"
|
||||||
|
@ -37,6 +44,9 @@
|
||||||
Training::Training(const Dictionary &iDic)
|
Training::Training(const Dictionary &iDic)
|
||||||
: Game(iDic)
|
: Game(iDic)
|
||||||
{
|
{
|
||||||
|
// Training mode implicitly uses 1 human player
|
||||||
|
Game::addHumanPlayer();
|
||||||
|
m_players[0]->setName(convertToWc(_("Training")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,8 +134,6 @@ int Training::start()
|
||||||
if (getNPlayers() != 0)
|
if (getNPlayers() != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Training mode implicitly uses 1 human player
|
|
||||||
Game::addHumanPlayer();
|
|
||||||
m_currPlayer = 0;
|
m_currPlayer = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "ncurses.h"
|
#include "ncurses.h"
|
||||||
#include "dic.h"
|
#include "dic.h"
|
||||||
|
@ -266,14 +267,27 @@ void CursesIntf::drawBoard(WINDOW *win, int y, int x) const
|
||||||
|
|
||||||
void CursesIntf::drawScoresRacks(WINDOW *win, int y, int x) const
|
void CursesIntf::drawScoresRacks(WINDOW *win, int y, int x) const
|
||||||
{
|
{
|
||||||
|
// Compute the longest player name
|
||||||
|
unsigned int longest = 0;
|
||||||
|
for (unsigned int i = 0; i < m_game->getNPlayers(); i++)
|
||||||
|
{
|
||||||
|
longest = std::max(longest, m_game->getPlayer(i).getName().size());
|
||||||
|
}
|
||||||
|
|
||||||
Box box(win, y, x, m_game->getNPlayers() + 2, 25);
|
Box box(win, y, x, m_game->getNPlayers() + 2, 25);
|
||||||
box.draw(_("Scores"));
|
box.draw(_("Scores"));
|
||||||
|
// Magic formula to truncate too long names
|
||||||
|
unsigned int maxForScores =
|
||||||
|
std::min(longest,
|
||||||
|
box.getWidth() - strlen(_("%s: %d")) - 1);
|
||||||
for (unsigned int i = 0; i < m_game->getNPlayers(); i++)
|
for (unsigned int i = 0; i < m_game->getNPlayers(); i++)
|
||||||
{
|
{
|
||||||
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
||||||
attron(A_BOLD);
|
attron(A_BOLD);
|
||||||
mvwprintw(win, y + i + 1, x + 2,
|
mvwprintw(win, y + i + 1, x + 2, _("%s: %d"),
|
||||||
_("Player %d: %d"), i, m_game->getPlayer(i).getPoints());
|
truncOrPad(convertToMb(m_game->getPlayer(i).getName()),
|
||||||
|
maxForScores).c_str(),
|
||||||
|
m_game->getPlayer(i).getPoints());
|
||||||
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
||||||
attroff(A_BOLD);
|
attroff(A_BOLD);
|
||||||
}
|
}
|
||||||
|
@ -283,13 +297,19 @@ void CursesIntf::drawScoresRacks(WINDOW *win, int y, int x) const
|
||||||
|
|
||||||
Box box2(win, y + yOff, x, m_game->getNPlayers() + 2, 25);
|
Box box2(win, y + yOff, x, m_game->getNPlayers() + 2, 25);
|
||||||
box2.draw(_("Racks"));
|
box2.draw(_("Racks"));
|
||||||
|
// Magic formula to truncate too long names
|
||||||
|
unsigned int maxForRacks =
|
||||||
|
std::min(longest,
|
||||||
|
box.getWidth() - strlen(_("%s: %ls")) - 4);
|
||||||
for (unsigned int i = 0; i < m_game->getNPlayers(); i++)
|
for (unsigned int i = 0; i < m_game->getNPlayers(); i++)
|
||||||
{
|
{
|
||||||
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
||||||
attron(A_BOLD);
|
attron(A_BOLD);
|
||||||
wstring rack = m_game->getPlayer(i).getCurrentRack().toString(PlayedRack::RACK_SIMPLE);
|
wstring rack = m_game->getPlayer(i).getCurrentRack().toString(PlayedRack::RACK_SIMPLE);
|
||||||
mvwprintw(win, y + yOff + i + 1, x + 2,
|
mvwprintw(win, y + yOff + i + 1, x + 2, _("%s: %ls"),
|
||||||
_("Player %d: %ls"), i, rack.c_str());
|
truncOrPad(convertToMb(m_game->getPlayer(i).getName()),
|
||||||
|
maxForRacks).c_str(),
|
||||||
|
rack.c_str());
|
||||||
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
|
||||||
attroff(A_BOLD);
|
attroff(A_BOLD);
|
||||||
// Force to refresh the whole rack
|
// Force to refresh the whole rack
|
||||||
|
|
Loading…
Reference in a new issue