[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Eliot-dev] eliot INSTALL TODO configure.in dic/.cvsignore ...
From: |
eliot-dev |
Subject: |
[Eliot-dev] eliot INSTALL TODO configure.in dic/.cvsignore ... |
Date: |
Tue, 08 Jan 2008 13:52:45 +0000 |
CVSROOT: /cvsroot/eliot
Module name: eliot
Changes by: Olivier Teulière <ipkiss> 08/01/08 13:52:43
Modified files:
. : INSTALL TODO configure.in
dic : .cvsignore Makefile.am automaton.h dic.h
dic_internals.h hashtable.h regexp.h
doc : dic.txt
game : Makefile.am ai_percent.cpp ai_percent.h
ai_player.h bag.cpp bag.h board.cpp board.h
board_cross.cpp board_search.cpp coord.cpp
coord.h cross.cpp cross.h debug.h duplicate.cpp
duplicate.h freegame.cpp freegame.h game.cpp
game.h game_factory.cpp game_factory.h
game_io.cpp history.cpp history.h player.cpp
player.h pldrack.cpp pldrack.h rack.cpp rack.h
results.cpp results.h round.cpp round.h
training.cpp training.h turn.cpp turn.h
m4 : .cvsignore
po : .cvsignore LINGUAS POTFILES.in eliot.pot fr.po
test : .cvsignore driver duplicate_2_ai.input
duplicate_2_ai.ref freegame_3_ai.input
freegame_3_ai.ref freegame_change.input
freegame_change.ref freegame_passing.input
freegame_passing.ref load_saved_game.ref
regexp.ref regression.pl training_back.input
training_back.ref training_cross.ref
training_cross2.ref training_cross3.ref
training_joker2.ref training_rosace.ref
training_search.ref
utils : Makefile.am eliottxt.cpp game_io.cpp
ncurses.cpp ncurses.h
wxwin : Makefile.am auxframes.cc auxframes.h
confdimdlg.cc configdb.cc confsearch.cc
gfxresult.cc main.cc mainframe.cc mainframe.h
printout.cc searchpanel.cc searchpanel.h
Added files:
dic : automaton.cpp compdic.cpp dic.cpp
dic_exception.cpp dic_exception.h
dic_search.cpp encoding.cpp encoding.h erl.lpp
ery.ypp hashtable.cpp hashtable.i header.cpp
header.h listdic.cpp regexp.cpp regexpmain.cpp
tile.cpp tile.h
game : move.cpp move.h settings.cpp settings.h
m4 : ax_boost_base.m4
test : duplicate_humans_ai.input
duplicate_humans_ai.ref training_7pl1.input
training_7pl1.ref training_benj.input
training_benj.ref training_racc.input
training_racc.ref
Removed files:
dic : alist.c alist.h automaton.c compdic.c dic.c
dic_search.c dic_search.h erl.l ery.y
hashtable.c listdic.c regexp.c regexpmain.c
game : encoding.cpp encoding.h tile.cpp tile.h
Log message:
Merged the "cppdic" branch back into HEAD.
There are too many change to list properly, here is an overview of the
main changes:
- the dictionary is now in C++
- the dictionary has a new format, where it is possible to specify the
letters,
their points, their frequency, ... It is backwards compatible.
- Eliot now supports non-ASCII characters everywhere
- i18n of the compdic, listdic, regexpmain binaries
- i18n of the wxWidgets interface (now in english by default)
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/INSTALL?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/TODO?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/configure.in?cvsroot=eliot&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/.cvsignore?cvsroot=eliot&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/Makefile.am?cvsroot=eliot&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/automaton.h?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic.h?cvsroot=eliot&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_internals.h?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/hashtable.h?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/regexp.h?cvsroot=eliot&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/automaton.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/compdic.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_exception.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_exception.h?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_search.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/encoding.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/encoding.h?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/erl.lpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/ery.ypp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/hashtable.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/hashtable.i?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/header.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/header.h?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/listdic.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/regexp.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/regexpmain.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/tile.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/tile.h?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/alist.c?cvsroot=eliot&r1=1.5&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/alist.h?cvsroot=eliot&r1=1.4&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/automaton.c?cvsroot=eliot&r1=1.13&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/compdic.c?cvsroot=eliot&r1=1.10&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic.c?cvsroot=eliot&r1=1.12&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_search.c?cvsroot=eliot&r1=1.21&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_search.h?cvsroot=eliot&r1=1.12&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/erl.l?cvsroot=eliot&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/ery.y?cvsroot=eliot&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/hashtable.c?cvsroot=eliot&r1=1.5&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/listdic.c?cvsroot=eliot&r1=1.10&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/regexp.c?cvsroot=eliot&r1=1.12&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/regexpmain.c?cvsroot=eliot&r1=1.13&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/doc/dic.txt?cvsroot=eliot&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/eliot/game/Makefile.am?cvsroot=eliot&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/eliot/game/ai_percent.cpp?cvsroot=eliot&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/eliot/game/ai_percent.h?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/game/ai_player.h?cvsroot=eliot&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/eliot/game/bag.cpp?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/bag.h?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board.cpp?cvsroot=eliot&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board.h?cvsroot=eliot&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board_cross.cpp?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board_search.cpp?cvsroot=eliot&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/eliot/game/coord.cpp?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/coord.h?cvsroot=eliot&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/eliot/game/cross.cpp?cvsroot=eliot&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/eliot/game/cross.h?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/debug.h?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/game/duplicate.cpp?cvsroot=eliot&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/eliot/game/duplicate.h?cvsroot=eliot&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/eliot/game/freegame.cpp?cvsroot=eliot&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/eliot/game/freegame.h?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.cpp?cvsroot=eliot&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.h?cvsroot=eliot&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game_factory.cpp?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game_factory.h?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game_io.cpp?cvsroot=eliot&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/eliot/game/history.cpp?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/game/history.h?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/game/player.cpp?cvsroot=eliot&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/eliot/game/player.h?cvsroot=eliot&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/eliot/game/pldrack.cpp?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/pldrack.h?cvsroot=eliot&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/eliot/game/rack.cpp?cvsroot=eliot&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/eliot/game/rack.h?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/results.cpp?cvsroot=eliot&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/eliot/game/results.h?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/round.cpp?cvsroot=eliot&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/eliot/game/round.h?cvsroot=eliot&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/eliot/game/training.cpp?cvsroot=eliot&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/eliot/game/training.h?cvsroot=eliot&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/eliot/game/turn.cpp?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/game/turn.h?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/move.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/move.h?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/settings.cpp?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/settings.h?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/game/encoding.cpp?cvsroot=eliot&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/game/encoding.h?cvsroot=eliot&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/game/tile.cpp?cvsroot=eliot&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/game/tile.h?cvsroot=eliot&r1=1.8&r2=0
http://cvs.savannah.gnu.org/viewcvs/eliot/m4/.cvsignore?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/m4/ax_boost_base.m4?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/po/.cvsignore?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/po/LINGUAS?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/po/POTFILES.in?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/po/eliot.pot?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/po/fr.po?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/test/.cvsignore?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/driver?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_2_ai.input?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_2_ai.ref?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_3_ai.input?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_3_ai.ref?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_change.input?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_change.ref?cvsroot=eliot&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_passing.input?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_passing.ref?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/test/load_saved_game.ref?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/regexp.ref?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/regression.pl?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_back.input?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_back.ref?cvsroot=eliot&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_cross.ref?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_cross2.ref?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_cross3.ref?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_joker2.ref?cvsroot=eliot&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_rosace.ref?cvsroot=eliot&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_search.ref?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_humans_ai.input?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_humans_ai.ref?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_7pl1.input?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_7pl1.ref?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_benj.input?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_benj.ref?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_racc.input?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_racc.ref?cvsroot=eliot&rev=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/Makefile.am?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/eliottxt.cpp?cvsroot=eliot&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/game_io.cpp?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/ncurses.cpp?cvsroot=eliot&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/ncurses.h?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/Makefile.am?cvsroot=eliot&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/auxframes.cc?cvsroot=eliot&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/auxframes.h?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/confdimdlg.cc?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/configdb.cc?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/confsearch.cc?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/gfxresult.cc?cvsroot=eliot&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/main.cc?cvsroot=eliot&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/mainframe.cc?cvsroot=eliot&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/mainframe.h?cvsroot=eliot&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/printout.cc?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/searchpanel.cc?cvsroot=eliot&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/eliot/wxwin/searchpanel.h?cvsroot=eliot&r1=1.4&r2=1.5
Patches:
Index: INSTALL
===================================================================
RCS file: /cvsroot/eliot/eliot/INSTALL,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- INSTALL 4 Aug 2007 20:01:28 -0000 1.9
+++ INSTALL 8 Jan 2008 13:52:32 -0000 1.10
@@ -1,6 +1,7 @@
+
Installation sous Linux (Un*x) (bien/facile)
------------------------------
-* Pour installer à partir de l'archive CVS :
+* Pour installer à partir de l'archive CVS :
./bootstrap
@@ -8,16 +9,16 @@
make
make install
-* Pour installer à partir de l'archive tar.gz
+* Pour installer à partir de l'archive tar.gz
./configure
make
make install
-il existe en fait 3 versions d'eliot, une en mode texte, une avec une
-interface curses et une avec wxwidgets. Les modes peuvent être
-sélectionnés à l'aide de la commande configure lors de la compilation
+Il existe en fait 3 versions d'eliot, une en mode texte, une avec une
+interface curses et une avec wxwidgets. Les modes peuvent être
+sélectionnés à l'aide de la commande configure lors de la compilation
du programme.
./configure --enable-text --enable-ncurses --enable-wxwidgets
@@ -27,39 +28,56 @@
Installation pour Windows (moins bien/facile)
-------------------------
-Il y a 2 principales façons de procéder :
+Il y a 2 principales façons de procéder :
* directement depuis Windows, en utilisant Cygwin (http://www.cygwin.com/).
* depuis GNU/Linux, en utilisant le cross-compilateur Mingw32.
-Dans les 2 cas, les étapes sont les mêmes :
-* installation de l'environnement de compilation (cette étape n'est pas
- décrite ici, car elle ne rentre pas dans le cadre de ce document)
+Dans les 2 cas, les étapes sont les mêmes :
+* installation de l'environnement de compilation (cette étape n'est pas
+ décrite ici, car elle ne rentre pas dans le cadre de ce document)
+
+* compilation et installation des dépendances (même remarque):
+
+ - wxWidgets (http://www.wxwidgets.org/), version 2.4.2 ou ultérieure, avec
+ support de l'unicode
-* compilation et installation de wxWindows (http://www.wxwidgets.org/),
- version 2.4.2 ou ultérieure (même remarque)
+ - libiconv (http://www.gnu.org/software/libiconv/), de préférence
compilée
+ en mode statique (--disable-shared --enable-static)
+
+ - boost (http://www.boost.org/). Eliot n'utilise pas de librairie de Boost
+ (uniquement des headers), donc il n'y a pas vraiment besoin de compiler
* compilation d'Eliot :
- - si vous utilisez l'archive CVS, il faut générer le script 'configure'
+ - si vous utilisez l'archive CVS, il faut générer le script 'configure'
(aussi bien sous Cygwin que sous GNU/Linux) :
./bootstrap
+ - Ã cause d'un bug de gettext, il faut appliquer un patch aux fichiers
installés
+ dans intl/ :
+ - télécharger le patch ici (lien en haut à gauche) :
+
http://www.koders.com/noncode/fid46DF595700FEB564B6EF45BFF55067F95DCF0420.aspx
+ - exécuter la commande suivante :
+ patch -p2 < gettext-win32.patch
+
- avec Cygwin, configurer avec la ligne de commande suivante :
+ CPPFLAGS=-I/path/to/installs/include
LDFLAGS=-L/path/to/installs/lib \
CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin" \
- ./configure --with-wx-config=/path/to/wx-config
- en prenant soin d'indiquer le chemin correct vers le fichier
- 'wx-config' de l'installation de wxWindows.
+ ./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'.
+ é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++ \
./configure --host=i586-mingw32msvc --build=i386-linux \
- --with-wx-config=/path/to/wx-config
- en prenant soin d'indiquer le chemin correct vers le fichier
- 'wx-config' de l'installation de wxWindows.
+ --enable-wxwidgets --with-wx-config=/path/to/wx-config \
+ --with-boost=/path/to/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'.
+ éventuellement suivi de 'make install'.
Index: TODO
===================================================================
RCS file: /cvsroot/eliot/eliot/TODO,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- TODO 22 Jan 2006 12:23:52 -0000 1.6
+++ TODO 8 Jan 2008 13:52:32 -0000 1.7
@@ -1,33 +1,19 @@
-* ====================
-* TODO Current version
-* ====================
-
- - Correct game save/load functions : Advanced format
- file saving for freegames and duplicate need a serious
- rewrite. We need to specifie a file format that can handle
- all the information contained in a multiplayer game.
-
- - Add "joker" type games in wxwin version of Eliot, Freegame
- and Duplicate will follow
-
- - full French i18n interface and error messages for wxwin.
-
-
* ==================
* Next Eliot version
* ==================
- - new dictionnary format that includes tiles
- - number
- - points
- - printable equivalent
- - other languages support using the new dictionary
- - new wxWidgets interface
+ - Improve error handling (use exceptions more)
+ - Correct game save/load functions: Advanced format
+ file saving for freegames and duplicate need a serious
+ rewrite. We need to specify a file format that can handle
+ all the information contained in a multiplayer game.
+ - rack shuffling
+ - new wxWidgets or QT interface
- support of the different modes
- ability to choose the number and type of the players
- ability to display the history and score of all the players
- -- partly done : history is now a separate class
+ -- partly done: history is now a separate class
- detection of blocked positions?
- getopt support for all the interfaces (only ncurses is done)
Index: configure.in
===================================================================
RCS file: /cvsroot/eliot/eliot/configure.in,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- configure.in 4 Aug 2007 20:01:28 -0000 1.20
+++ configure.in 8 Jan 2008 13:52:33 -0000 1.21
@@ -7,6 +7,8 @@
AC_CONFIG_SRCDIR(wxwin/main.cc)
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
+AC_CANONICAL_HOST
+AC_CANONICAL_BUILD
AM_OPTIONS_WXCONFIG
dnl --------------------------------------------------------------
@@ -14,6 +16,8 @@
dnl --------------------------------------------------------------
AC_PROG_INSTALL
AC_PROG_CC
+dnl Needed for gettext
+AC_GNU_SOURCE
AC_PROG_CXX
AC_PROG_MAKE_SET
AC_PROG_RANLIB
@@ -23,6 +27,7 @@
AC_MSG_ERROR([Could not find the 'bison' program on your system])
fi
+dnl Better than AC_PROG_LEX
AM_PROG_LEX
if test "$LEX" != "flex" ; then
AC_MSG_ERROR([Could not find the 'flex' program on your system])
@@ -56,15 +61,17 @@
dnl Debug mode
AC_ARG_ENABLE([debug],AC_HELP_STRING([--enable-debug],[debug mode (default
disabled)]))
if test "${enable_debug}" = "yes"; then
- CFLAGS+=" -g -DDEBUG"
- CXXFLAGS+=" -g -DDEBUG"
+ CPPFLAGS+=" -DDEBUG"
+ CFLAGS+=" -g"
+ CXXFLAGS+=" -g"
fi
dnl Profile mode
AC_ARG_ENABLE([profile],AC_HELP_STRING([--enable-profile],[profile mode
(default disabled)]))
if test "${enable_profile}" = "yes"; then
- CFLAGS+=" -pg -DPROFILE"
- CXXFLAGS+=" -pg -DPROFILE"
+ CPPFLAGS+=" -DPROFILE"
+ CFLAGS+=" -pg"
+ CXXFLAGS+=" -pg"
LDFLAGS+=" -pg"
fi
@@ -77,6 +84,9 @@
dnl --------------------------------------------------------------
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h unistd.h sys/wait.h)
+AC_CHECK_HEADERS(arpa/inet.h netinet/in.h)
+AC_CHECK_HEADERS([readline/readline.h], [has_readline=1], [has_readline=0])
+AM_CONDITIONAL(HAS_READLINE, test "$has_readline" = "1")
dnl --------------------------------------------------------------
dnl Checks for typedefs, structures, and compiler characteristics.
@@ -85,22 +95,26 @@
AC_TYPE_SIZE_T
AC_C_BIGENDIAN
AC_C_INLINE
-AC_CHECK_SIZEOF(char, 1)
-AC_CHECK_SIZEOF(short, 2)
-AC_CHECK_SIZEOF(int *, 4)
-AC_CHECK_SIZEOF(int, 4)
-AC_CHECK_SIZEOF(long, 4)
-AC_CHECK_SIZEOF(long long, 0)
+dnl AC_CHECK_SIZEOF(char, 1)
+dnl AC_CHECK_SIZEOF(short, 2)
+dnl AC_CHECK_SIZEOF(int *, 4)
+dnl AC_CHECK_SIZEOF(int, 4)
+dnl AC_CHECK_SIZEOF(long, 4)
+dnl AC_CHECK_SIZEOF(long long, 0)
dnl --------------------------------------------------------------
dnl Checks for library functions.
dnl --------------------------------------------------------------
AC_FUNC_MEMCMP
+AC_CHECK_FUNCS([wcwidth])
dnl --------------------------------------------------------------
dnl Checks for libraries.
dnl --------------------------------------------------------------
+dnl Check for the Boost libraries (in fact we only need the headers)
+AX_BOOST_BASE([1.33.1])
+
dnl Check for wxWidgets
AC_ARG_ENABLE([wxwidgets],AC_HELP_STRING([--enable-wxwidgets],[wxWidgets
interface support (default disabled)]))
if test "${enable_wxwidgets}" = "yes"
@@ -125,27 +139,53 @@
AM_CONDITIONAL([BUILD_WXWIDGETS], [test "${wxWin}" = "1"])
dnl Check for ncurses
-AC_ARG_ENABLE([ncurses],AC_HELP_STRING([--enable-ncurses],[ncurses interface
support (default disabled)]))
-if test "${enable_ncurses}" = "yes"
-then
- AC_CHECK_HEADERS(ncurses.h, want_ncurses=1,
- [AC_MSG_ERROR([Could not find the ncurses library on your system])])
+dnl We enable it if asked by the user, or if ncursesw is found
+AC_ARG_ENABLE([ncurses],AC_HELP_STRING([--enable-ncurses],
+ [ncurses interface support (default enabled if ncursesw found on
your system)]))
+AC_CHECK_HEADERS(ncursesw/curses.h, [has_ncursesw=1], [has_ncursesw=0])
+if test "${enable_ncurses}" != "no" -a "${has_ncursesw}" = "1"; then
+ want_ncurses=1
+else
+ want_ncurses=0
+ if test "${enable_ncurses}" = "yes"; then
+ AC_MSG_ERROR([Could not find the ncursesw library on your system])
+ fi
fi
AM_CONDITIONAL([BUILD_NCURSES], [test "${want_ncurses}" = "1"])
dnl Enable/disable text version
AC_ARG_ENABLE([text],AC_HELP_STRING([--enable-text],[text interface support
(default enabled)]))
-if test "${enable_text}" != "no"
-then
- AC_CHECK_HEADERS(readline/readline.h, want_text=1,
- [AC_MSG_ERROR([Could not find the readline library on your system])])
-fi
AM_CONDITIONAL([BUILD_TEXT], [test "${enable_text}" != "no"])
dnl Internationalization macros
-AM_GNU_GETTEXT_VERSION(0.11.5)
+AM_GNU_GETTEXT_VERSION(0.16.1)
AM_GNU_GETTEXT
+dnl Iconv
+dnl This test depends on AM_GNU_GETTEXT executed before
+AS_IF([test "$am_cv_func_iconv" != "yes"],
+ [AC_MSG_ERROR([libiconv is needed for Eliot to work properly])])
+
+
+dnl Information about who built eliot (useful for the dictionary)
+AC_DEFINE_UNQUOTED(ELIOT_COMPILE_BY, "`whoami`", [user who ran configure])
+AC_DEFINE_UNQUOTED(ELIOT_COMPILE_HOST, "`hostname`", [host which ran
configure])
+
+dnl Check the operating system
+case "${host_os}" in
+ *mingw32* |Â *cygwin*)
+ SYS=mingw32
+ ;;
+ *)
+ dnl nothing to do
+ ;;
+esac
+
+if test "$SYS" = "mingw32"; then
+ # For ntohl, in particular
+ LIBS="${LIBS} -lws2_32"
+fi
+
dnl --------------------------------------------------------------
dnl Output
dnl --------------------------------------------------------------
Index: dic/.cvsignore
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/.cvsignore,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- dic/.cvsignore 22 Jan 2006 12:23:53 -0000 1.2
+++ dic/.cvsignore 8 Jan 2008 13:52:33 -0000 1.3
@@ -1,10 +1,10 @@
.deps
Makefile
Makefile.in
-scanner.h
-er.c
-libdic_a-er.c
-libdic_a-er.h
+libdic_a-erl.cpp
+libdic_a-erl.h
+libdic_a-ery.cpp
+libdic_a-ery.h
compdic
listdic
regexp
Index: dic/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Makefile.am,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- dic/Makefile.am 4 Aug 2007 19:57:46 -0000 1.15
+++ dic/Makefile.am 8 Jan 2008 13:52:33 -0000 1.16
@@ -1,6 +1,7 @@
# Eliot
-# Copyright (C) 1999 Antoine Fraboulet
-# address@hidden
+# Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+# Authors: Antoine Fraboulet <address@hidden>
+# Olivier Teulière <ipkiss @@ gmail.com>
#
# 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
@@ -18,47 +19,52 @@
noinst_LIBRARIES = libdic.a
-INCLUDES = -I$(top_srcdir)
+localedir = $(datadir)/locale
+AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"
-libdic_a_CFLAGS=$(DEBUGFLAGS)
-libdic_a_YFLAGS=
+INCLUDES = -I$(top_srcdir) -I../intl -I$(top_srcdir)/intl $(INCICONV)
+
+libdic_a_CFLAGS=
+libdic_a_YFLAGS=-d
libdic_a_LFLAGS=
-libdic_a_SOURCES= \
- ery.y \
- erl.l \
+libdic_a_SOURCES = \
+ erl.lpp \
+ ery.ypp \
+ dic_exception.cpp dic_exception.h \
+ header.cpp header.h \
dic_internals.h \
- dic_search.c dic_search.h \
- dic.c dic.h \
- automaton.c automaton.h \
- hashtable.h hashtable.c \
- regexp.c regexp.h \
- alist.h alist.c
+ tile.cpp tile.h \
+ dic.cpp dic.h \
+ dic_search.cpp \
+ encoding.cpp encoding.h \
+ automaton.cpp automaton.h \
+ regexp.cpp regexp.h
BUILT_SOURCES= \
- libdic_a-erl.c \
+ libdic_a-erl.cpp \
libdic_a-erl.h \
- libdic_a-ery.c \
+ libdic_a-ery.cpp \
libdic_a-ery.h
-nodist_libdic_a_SOURCES= \
- libdic_a-erl.c \
- libdic_a-erl.h \
- libdic_a-ery.c \
- libdic_a-ery.h
+# This hook triggers on 'make dist' (and 'make distcheck')
+# XXX: In fact, the recommended behaviour is:
+# - list only libdic_a-ery.h in BUILT_SOURCES,
+# - do not die with an error in configure.in if flex or bison is not found
+# - do not have any dist-hook trigger
+# The result is that the generated files are kept in the tarball generated
with make dist,
+# with still an error message for developers when the ypp or lpp file has been
modified
+# and bison or flex is not found.
+# The problem is that, even though Automake is aware of the header generated
by bison,
+# it seems to have problems with the one generated by flex...
+dist-hook:
+ -for file in $(BUILT_SOURCES) ; do rm -f $(distdir)/$$file ; done
CLEANFILES= \
- libdic_a-erl.c \
+ libdic_a-erl.cpp \
libdic_a-erl.h \
- libdic_a-ery.c \
+ libdic_a-ery.cpp \
libdic_a-ery.h
-
-## automake workaround to generate .h file
-libdic_a-erl.h: erl.l
- ${LEX} ${srcdir}/erl.l
-
-#####################################
-
#####################################
if BUILD_DICTOOLS
@@ -67,18 +73,17 @@
listdic \
regexp
-compdic_SOURCES= \
- dic_internals.h \
- hashtable.c hashtble.h \
- compdic.c
+compdic_SOURCES=compdic.cpp \
+ hashtable.h hashtable.cpp hashtable.i
+compdic_CPPFLAGS=$(AM_CPPFLAGS) @BOOST_CPPFLAGS@
+compdic_LDADD=libdic.a @LIBINTL@
-listdic_SOURCES= \
- dic_internals.h \
- dic.c dic.h \
- listdic.c
+listdic_SOURCES=listdic.cpp
+listdic_LDADD=libdic.a @LIBINTL@
#regexp_CFLAGS=-DDEBUG_RE
-regexp_SOURCES=regexpmain.c
-regexp_LDADD=libdic.a
+regexp_SOURCES=regexpmain.cpp
+regexp_LDADD=libdic.a @LIBINTL@
endif
+
Index: dic/automaton.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/automaton.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- dic/automaton.h 1 Jan 2006 19:51:00 -0000 1.11
+++ dic/automaton.h 8 Jan 2008 13:52:33 -0000 1.12
@@ -1,21 +1,22 @@
-/* Eliot */
-/* Copyright (C) 2005 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file automaton.h
@@ -26,51 +27,68 @@
#ifndef _DIC_AUTOMATON_H_
#define _DIC_AUTOMATON_H_
-#if defined(__cplusplus)
-extern "C"
- {
-#endif
-typedef struct automaton_t *automaton;
+class AutomatonHelper;
+class Automaton
+{
+public:
+ /// Constructor
/**
- * build a static deterministic finite automaton from
+ * Build a static deterministic finite automaton from
* "init_state", "ptl" and "PS" given by the parser
*/
-automaton automaton_build(int init_state, int *ptl, int *PS, struct
search_RegE_list_t *list);
+ Automaton(int init_state, int *ptl, int *PS, struct search_RegE_list_t
*iList);
- /**
- * automaton delete function
- */
-void automaton_delete (automaton a);
+ /// Destructor
+ ~Automaton();
/**
- * get the number of states in the automaton
+ * Get the number of states in the automaton.
* @returns number of states
*/
-int automaton_get_nstate (automaton a);
+ int getNbStates() const { return m_nbStates; }
/**
- * query the id of the init state
+ * Query the id of the init state.
* @returns init state id
*/
-int automaton_get_init (automaton a);
+ int getInitId() const { return m_init; }
/**
- * ask for the acceptor flag for the state
- * @returns boolean flag 0 or 1
+ * Query the acceptor flag for the given state
+ * @return true/false
*/
-int automaton_get_accept (automaton a, int state);
+ bool accept(int state) const { return m_acceptors[state]; }
/**
- * returns the next state when the transition is taken
+ * Return the next state when the transition is taken
* @returns next state id (1 <= id <= nstate, 0 = invalid id)
*/
-int automaton_get_next_state (automaton a, int start, char l);
+ int getNextState(int start, char l) const
+ {
+ return m_transitions[start][(int)l];
+ }
-void automaton_dump (automaton a, char* filename);
+ /**
+ * Dump the automaton into a file (for debugging purposes)
+ */
+ void dump(const string &iFileName) const;
+
+private:
+ /// Number of states
+ int m_nbStates;
+
+ /// ID of the init state
+ int m_init;
+
+ /// Array of booleans, one for each state
+ bool *m_acceptors;
+
+ /// Matrix of transitions
+ int **m_transitions;
+
+ void finalize(const AutomatonHelper &a);
+};
-#if defined(__cplusplus)
- }
-#endif
#endif /* _DIC_AUTOMATON_H_ */
Index: dic/dic.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/dic.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- dic/dic.h 16 Apr 2006 11:27:19 -0000 1.13
+++ dic/dic.h 8 Jan 2008 13:52:34 -0000 1.14
@@ -1,119 +1,153 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file dic.h
* \brief Dawg dictionary
- * \author Antoine Fraboulet
+ * \author Antoine Fraboulet & Olivier Teuliere
* \date 2002
*/
#ifndef _DIC_H_
#define _DIC_H_
-#if defined(__cplusplus)
-extern "C"
- {
-#endif
-/**
- * different letters in the dictionary
- */
-#define DIC_LETTERS 27
+#include <string>
+#include <vector>
+#include <map>
+
+#include "tile.h"
+
+using namespace std;
+
/**
* max length of words (including last \0)
*/
#define DIC_WORD_MAX 16
-typedef struct _Dict_header Dict_header;
-typedef struct _Dictionary *Dictionary;
+class Header;
typedef unsigned int dic_elt_t;
typedef unsigned char dic_code_t;
-
-
+struct params_cross_t;
+struct params_7plus1_t;
+struct params_regexp_t;
+struct search_RegE_list_t;
+
+class Dictionary
+{
+public:
/**
- * Dictionary header loading from a file
- * @param dic : pointer to a header
- * @param path : compressed dictionary path
- * @return 0 ok, otherwise error
+ * Dictionary creation and loading from a file
+ * @param path: compressed dictionary path
*/
-int Dic_check_header(Dict_header *header, const char* path);
+ Dictionary(const string &path);
+
+ /// Destructor
+ ~Dictionary();
/**
- * Dictionary creation and loading from a file
- * @param dic : pointer to a dictionary
- * @param path : compressed dictionary path
- * @return 0 ok, 1 error
+ * Return the current instance of the dictionary object
+ * XXX: This is ugly, but I don't see any clean way apart from carrying
+ * a reference to a Dictionary object in many places...
+ * Other more or less ugly options:
+ * - Make the dictionary a singleton (2 dictionaries cannot coexist...)
+ * - Make many classes inherit from a common base class with a dictionary
+ * member (possibly bad for performances)
+ * A new created dictionary replaces the previous instance, even if the
+ * previous instance is not destroyed yet
+ * If no dictionary object is instanciated when this method is called,
+ * it will probably crash...
*/
-int Dic_load (Dictionary* dic,const char* path);
+ static const Dictionary& GetDic() { return *m_dic; }
+
+ /** Give access to the dictionary header */
+ const Header& getHeader() const { return *m_header; }
/**
- * Destroy a dictionary
+ * Check whether all the given letters are present in the dictionary,
+ * or are one of the other accepted letters.
+ * Return true if this is the case, false otherwise
*/
-int Dic_destroy(Dictionary dic);
+ bool validateLetters(const wstring &iLetters,
+ const wstring &iAccepted = L"") const;
+
+ /** Return a vector containing one of each possible tile */
+ const vector<Tile>& getAllTiles() const { return m_tilesVect; }
+
+ /** Return the number of different tiles (including the joker) */
+ unsigned int getTileNumber() const { return m_tilesVect.size(); }
+
+ /** Return a tile from its code */
+ const Tile &getTileFromCode(unsigned int iCode) const { return
m_tilesVect[iCode - 1]; }
/**
- * Dic_chr returns the character code associated with an element,
+ * Returns the character code associated with an element,
* codes may range from 0 to 31. 0 is the null character.
* @returns code for the encoded character
*/
-dic_code_t Dic_chr (Dictionary dic, dic_elt_t elt);
+ const dic_code_t getCode(const dic_elt_t &elt) const;
+
+ /**
+ * Returns the wide character associated with an element.
+ * @returns wide character for the element
+ */
+ wchar_t getChar(const dic_elt_t &elt) const;
/**
* Returns a boolean to show if there is another available
* character in the current depth (a neighbor in the tree)
* @returns 0 or 1 (true)
*/
-int Dic_last(Dictionary dic, dic_elt_t elt);
+ bool isLast(const dic_elt_t &elt) const;
/**
* Returns a boolean to show if we are at the end of a word
- * (see Dic_next)
+ * (see getNext)
* @returns 0 or 1 (true)
*/
-int Dic_word(Dictionary dic, dic_elt_t elt);
+ bool isEndOfWord(const dic_elt_t &elt) const;
/**
* Returns the root of the dictionary
* @returns root element
*/
-dic_elt_t Dic_root(Dictionary dic);
+ const dic_elt_t getRoot() const;
/**
- * Returns the next available neighbor (see Dic_last)
+ * Returns the next available neighbor (see getLast)
* @returns next dictionary element at the same depth
*/
-dic_elt_t Dic_next(Dictionary dic, dic_elt_t elt);
+ const dic_elt_t getNext(const dic_elt_t &elt) const;
/**
* Returns the first element available at the next depth
* in the dictionary
- * @params dic : dictionary
* @params elt : current dictionary element
* @returns next element (successor)
*/
-dic_elt_t Dic_succ(Dictionary dic, dic_elt_t elt);
+ const dic_elt_t getSucc(const dic_elt_t &elt) const;
/**
* Find the dictionary element matching the pattern starting
* from the given root node by walking the dictionary tree
- * @params dic : valid dictionary
* @params root : starting dictionary node for the search
* @params pattern : string encoded according to the dictionary codes,
* the pattern must be null ('\0') terminated
@@ -121,19 +155,11 @@
* element that results from walking the dictionary according to the
* pattern
*/
-unsigned int Dic_lookup(Dictionary dic, dic_elt_t root, dic_code_t* pattern);
-
- /**
- * Dic_char returns the character associated with an element
- * (in the range ['A'-'Z']), or the null character ('\0').
- * @returns ASCII code for the character
- */
-char Dic_char (Dictionary dic, dic_elt_t elt);
+ unsigned int lookup(const dic_elt_t &root, const dic_code_t *pattern)
const;
/**
* Find the dictionary element matching the pattern starting
* from the given root node by walking the dictionary tree
- * @params dic : valid dictionary
* @params root : starting dictionary node for the search
* @params pattern : string made of uppercase characters in the range
* ['A'-'Z']. The pattern must be null ('\0') terminated
@@ -141,11 +167,136 @@
* element that results from walking the dictionary according to the
* pattern
*/
-unsigned int Dic_char_lookup(Dictionary dic, dic_elt_t root, char* pattern);
+ unsigned int charLookup(const dic_elt_t &iRoot, const wchar_t *iPattern)
const;
+
+ /// Getter for the edge at the given position
+ const uint32_t *getEdgeAt(const dic_elt_t &iElt) const { return m_dawg +
iElt; }
+
+ /**
+ * Search for a word in the dictionary
+ * @param iWord: lookup word
+ * @return true if the word is valid, false otherwise
+ */
+ bool searchWord(const wstring &iWord) const;
+
+ /**
+ * Search for benjamins
+ * @param iWord: letters
+ * @param oWordList: results
+ */
+ void searchBenj(const wstring &iWord, list<wstring> &oWordList) const;
+
+ /**
+ * Search for all words feasible by adding a letter in front or at the end
+ * @param iWord: word
+ * @param oWordList: results
+ */
+ void searchRacc(const wstring &iWord, list<wstring> &oWordList) const;
+
+ /**
+ * Search for crosswords
+ * @param iMask: letters
+ * @param oWordList: results
+ */
+ void searchCross(const wstring &iMask, list<wstring> &oWordList) const;
+
+ /**
+ * Search for all feasible word with "rack" plus one letter
+ * @param iRack: letters
+ * @param oWordlist: results
+ * @param joker: true if the search must be performed when a joker is in
the rack
+ */
+ void search7pl1(const wstring &iRack,
+ map<wchar_t, list<wstring> > &oWordList,
+ bool joker) const;
+
+ /**
+ * Search for words matching a regular expression
+ * @param iRegexp: regular expression
+ * @param oWordList: results
+ * @param iList: parameters for the search (?)
+ */
+ void searchRegExp(const wstring &iRegexp,
+ list<wstring> &oWordList,
+ struct search_RegE_list_t *iList) const;
+
+
+
+private:
+ // Prevent from copying the dictionary!
+ Dictionary &operator=(const Dictionary&);
+ Dictionary(const Dictionary&);
+
+ Header *m_header;
+ uint32_t *m_dawg;
+
+ /** Letters of the dictionary, both in uppercase and lowercase */
+ wstring m_allLetters;
+
+ /// Vector of available tiles
+ vector<Tile> m_tilesVect;
-#if defined(__cplusplus)
+ static const Dictionary *m_dic;
+
+ void convertDataToArch();
+ void initializeTiles();
+
+ /// Template getter for the edge at the given position
+ template <typename DAWG_EDGE>
+ const DAWG_EDGE * getEdgeAt(const dic_elt_t &iElt) const
+ {
+ return reinterpret_cast<const DAWG_EDGE*>(m_dawg + iElt);
}
-#endif
+
+ /**
+ * Walk the dictionary until the end of the word
+ * @param s: current pointer to letters
+ * @param eptr: current edge in the dawg
+ */
+ template <typename DAWG_EDGE>
+ const DAWG_EDGE * seekEdgePtr(const wchar_t *s, const DAWG_EDGE *eptr)
const;
+
+ /// Helper for searchBenj()
+ template <typename DAWG_EDGE>
+ void searchBenjTempl(const wstring &iWord, list<wstring> &oWordList) const;
+
+ /// Helper for searchRacc()
+ template <typename DAWG_EDGE>
+ void searchRaccTempl(const wstring &iWord, list<wstring> &oWordList) const;
+
+ /// Helper for searchCross()
+ template <typename DAWG_EDGE>
+ void searchCrossRecTempl(struct params_cross_t *params,
+ list<wstring> &oWordList,
+ const DAWG_EDGE *edgeptr) const;
+
+ /// Helper for search7pl1()
+ template <typename DAWG_EDGE>
+ void search7pl1Templ(const wstring &iRack,
+ map<wchar_t, list<wstring> > &oWordList,
+ bool joker) const;
+
+ /// Second helper for search7pl1()
+ template <typename DAWG_EDGE>
+ void searchWordByLen(struct params_7plus1_t *params,
+ int i, const DAWG_EDGE *edgeptr) const;
+
+ /**
+ * Internal version of searchRegExp, needed until
+ * wide chars are supported by our regexp engine.
+ */
+ void searchRegExpInner(const string &iRegexp,
+ list<string> &oWordList,
+ struct search_RegE_list_t *iList) const;
+
+ /// Helper for searchRegExp()
+ template <typename DAWG_EDGE>
+ void searchRegexpRecTempl(struct params_regexp_t *params,
+ int state,
+ const DAWG_EDGE *edgeptr,
+ list<string> &oWordList) const;
+};
+
#endif /* _DIC_H_ */
/// Local Variables:
Index: dic/dic_internals.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/dic_internals.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- dic/dic_internals.h 4 Aug 2007 20:01:28 -0000 1.8
+++ dic/dic_internals.h 8 Jan 2008 13:52:34 -0000 1.9
@@ -1,21 +1,22 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file dic_internals.h
@@ -26,27 +27,11 @@
#ifndef _DIC_INTERNALS_H_
#define _DIC_INTERNALS_H_
-#if defined(__cplusplus)
-extern "C"
- {
-#endif
#include <stdint.h>
#include "config.h"
/**
- * bit masking for ascii characters \n
- * ('a' & CHAR) == ('A' & CHAR) == 1
- */
-#define DIC_CHAR_MASK 0x1F
-
-/**
- * keyword included in dictionary headers
- * implies little endian storage on words
- */
-#define _COMPIL_KEYWORD_ "_COMPILED_DICTIONARY_"
-
-/**
* structure of a compressed dictionary \n
* \n
* ---------------- \n
@@ -60,53 +45,36 @@
* ----------------
*/
-#if defined(WORDS_BIGENDIAN)
-struct __attribute__ ((packed)) _Dawg_edge {
- uint32_t
- chr : 5,
- fill : 1,
- last : 1,
- term : 1,
- ptr : 24;
-};
-#else
-struct __attribute__ ((packed)) _Dawg_edge {
+struct __attribute__ ((packed)) DicEdgeOld
+{
+ public:
uint32_t
ptr : 24,
- term : 1,
- last : 1,
- fill : 1,
+ term: 1,
+ last: 1,
+ fill: 1,
chr : 5;
-};
-#endif
-
-typedef struct _Dawg_edge Dawg_edge;
-
-
-struct _Dict_header {
- char ident[sizeof(_COMPIL_KEYWORD_)];
- char unused_1;
- char unused_2;
- int32_t root;
- int32_t nwords;
- uint32_t edgesused;
- uint32_t nodesused;
- uint32_t nodessaved;
- uint32_t edgessaved;
+ bool operator==(const DicEdgeOld &iOther) const
+ {
+ return memcmp(this, &iOther, sizeof(*this)) == 0;
+ }
};
-struct _Dictionary
+struct __attribute__ ((packed)) DicEdge
{
- Dawg_edge *dawg;
- unsigned int root;
- int nwords;
- int nnodes;
- int nedges;
+ public:
+ uint32_t
+ ptr : 24,
+ term: 1,
+ last: 1,
+ chr : 6;
+ bool operator==(const DicEdge &iOther) const
+ {
+ return memcmp(this, &iOther, sizeof(*this)) == 0;
+ }
};
-#if defined(__cplusplus)
- }
-#endif
+
#endif /* _DIC_INTERNALS_H */
Index: dic/hashtable.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/hashtable.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- dic/hashtable.h 1 Jan 2006 19:51:00 -0000 1.6
+++ dic/hashtable.h 8 Jan 2008 13:52:35 -0000 1.7
@@ -1,21 +1,23 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file hashtable.h
@@ -26,21 +28,55 @@
#ifndef _HASHTABLE_H
#define _HASHTABLE_H
-#if defined(__cplusplus)
-extern "C"
+
+
+/// Compute a hash for the data pointed to by iPtr
+/**
+ * This function is useful to define the HASH_FCN template parameter
+ * of HashTable.
+ */
+unsigned int HashPtr(const void *iPtr, unsigned int iSize);
+
+
+template<typename KEY, typename VALUE, typename HASH_FCN>
+class HashTable
+{
+ public:
+ /// Constructor taking the number of records in the table
+ HashTable(unsigned int iSize);
+
+ /// Destructor
+ ~HashTable();
+
+ /// Return the number of records in the table
+ unsigned int size() const { return m_size; }
+
+ /// Return the value corresponding to the given key, or NULL if not
found
+ const VALUE *find(const KEY &iKey) const;
+
+ /// Add a new key/value pair (both the key and the value are copied)
+ void add(const KEY& iKey, const VALUE &iValue);
+
+ private:
+ /// Maximum number of records
+ unsigned int m_size;
+
+ /// Definition of a record
+ class Node
{
-#endif
+ public:
+ Node(const KEY &iKey, const VALUE &iValue, const Node *iNext);
+ ~Node();
+ KEY m_key;
+ VALUE m_value;
+ const Node *m_next;
+ };
+
+ /// All the nodes
+ const Node **m_nodes;
+};
-typedef struct _Hash_table* Hash_table;
+// Include the implementation of the template
+#include "hashtable.i"
-Hash_table hash_init(unsigned int);
-int hash_destroy(Hash_table);
-int hash_size(Hash_table);
-void* hash_find(Hash_table,void* key,unsigned keysize);
-int hash_add (Hash_table,void* key,unsigned keysize,
- void* value,unsigned valuesize);
-
-#if defined(__cplusplus)
- }
-#endif
#endif /* _HASHTABLE_H_ */
Index: dic/regexp.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/regexp.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- dic/regexp.h 1 Jan 2006 19:51:00 -0000 1.12
+++ dic/regexp.h 8 Jan 2008 13:52:36 -0000 1.13
@@ -1,21 +1,22 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 1999-2006 Antoine Fraboulet
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file regexp.h
@@ -24,12 +25,8 @@
* \date 2005
*/
-#ifndef _TREE_H_
-#define _TREE_H_
-#if defined(__cplusplus)
-extern "C"
- {
-#endif
+#ifndef _REGEXP_H_
+#define _REGEXP_H_
#define NODE_TOP 0
#define NODE_VAR 1
@@ -38,12 +35,14 @@
#define NODE_STAR 4
#define NODE_PLUS 5
-typedef struct node {
+
+typedef struct node
+{
int type;
char var;
struct node *fg;
struct node *fd;
- int numero;
+ int number;
int position;
int annulable;
int PP;
@@ -51,6 +50,11 @@
} NODE;
/**
+ * different letters in the dictionary
+ */
+#define DIC_LETTERS 27
+
+ /**
* maximum number of accepted terminals in regular expressions
*/
#define REGEXP_MAX 32
@@ -139,7 +143,7 @@
char msg[MAX_REGEXP_ERROR_LENGTH];
};
-#include <stdio.h>
+#include <cstdio>
void regexp_print_letter(FILE* f, char l);
void regexp_print_letter2(FILE* f, char l);
@@ -147,10 +151,7 @@
void regexp_print_ptl(int ptl[]);
void regexp_print_tree(NODE* n, char* name, int detail);
-#if defined(__cplusplus)
- }
-#endif
-#endif /* _TREE_H_ */
+#endif /* _REGEXP_H_ */
/// Local Variables:
/// mode: c++
Index: doc/dic.txt
===================================================================
RCS file: /cvsroot/eliot/eliot/doc/dic.txt,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- doc/dic.txt 19 Apr 2005 16:25:06 -0000 1.2
+++ doc/dic.txt 8 Jan 2008 13:52:36 -0000 1.3
@@ -29,36 +29,51 @@
ptr : index in the array of the first child
term : is it the last letter of a word (*)
last : is it the last child of its local root (!)
- fill : currently unused.
chr : guess what !
There is no pointer from a cell to its brother, it is simply the
next cell in the array (you know you are on the last brother when
the flag "last" is set).
- The way it is stored in a file is different thing! The tree is
+ The way it is stored in a file is a different thing! The tree is
stored bottom-up. The sink (offset 0) is the first cell of
the array.
- Using compdict (which you can found in the eliot/dic directory),
+ Using compdic (which you can find in the eliot/dic directory),
the compiled dictionary will look like this:
-compdict's console output:
-============================
-keyword length 21 bytes
-keyword size 22 bytes
-header size 48 bytes
-
-3 words
-
-root : 9 (edge)
-root : 36 (byte)
-
-nodes : 7+1
-edges : 9+1
-============================
+compdic console output (cut in the middle):
+===================================================================
+dictionary name: ODS 4.0
+compressed on: mer 12 déc 2007 07:29:50 GMT
+compressed using a binary compiled by: address@hidden
+dictionary type: DAWG
+letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ?
+number of letters: 27
+number of words: 369085
+header size: 360 bytes
+root: 100950 (edge)
+nodes: 40377 used + 418387 saved
+edges: 100950 used + 601922 saved
+===============================================
+letter | points | frequency | vowel | consonant
+-------+--------+-----------+-------+----------
+ A | 1 | 9 | 1 | 0
+ B | 3 | 2 | 0 | 1
+ C | 3 | 2 | 0 | 1
+ D | 2 | 3 | 0 | 1
+[... output cut here ...]
+ X | 10 | 1 | 0 | 1
+ Y | 10 | 1 | 1 | 1
+ Z | 10 | 1 | 0 | 1
+ ? | 0 | 2 | 1 | 1
+===============================================
+ Load time: 0,060 s
+ Compression time: 0,170 s
+ Maximum recursion level reached: 16
+===================================================================
-binary view of the dictionary:
+binary view of the dictionary (FIXME: not up to date):
===================================================================
0001 0203 0405 0607 0809 0a0b 0c0d 0e0f
00000000: 5f43 4f4d 5049 4c45 445f 4449 4354 494f _COMPILED_DICTIO
@@ -69,27 +84,85 @@
00000050: 0600 002a 0700 0000 ...*....
===================================================================
-The header structure is the following:
-
+The header is made of 2 structures (for backwards compatibility
+with older headers) like this:
+===================================================================
#define _COMPIL_KEYWORD_ "_COMPILED_DICTIONARY_"
-typedef struct _Dict_header { // offset
+struct Dict_header_old // offset
+{
char ident[sizeof(_COMPIL_KEYWORD_)]; // 0x00
- char unused_1; // 0x16
- char unused_2; // 0x17
- int root; // 0x18
- int nwords; // 0x1c
- unsigned int edgesused; // 0x20
- unsigned int nodesused; // 0x24
- unsigned int nodessaved; // 0x2c
- unsigned int edgessaved; // 0x30
-} Dict_header;
+ uint8_t version; // 0x16
+ char unused; // 0x17
+ uint32_t root; // 0x18
+ uint32_t nwords; // 0x1c
+ uint32_t edgesused; // 0x20
+ uint32_t nodesused; // 0x24
+ uint32_t nodessaved; // 0x28
+ uint32_t edgessaved; // 0x2c
+};
+
+#define _MAX_USER_HOST_ 32
+#define _MAX_DIC_NAME_SIZE_ 30
+#define _MAX_LETTERS_NB_ 63
+#define _MAX_LETTERS_SIZE_ 80
+
+struct Dict_header
+{
+ uint64_t compressDate;
+ // Build information
+ char userHost[_MAX_USER_HOST_];
+ // Size taken by the build information
+ uint32_t userHostSize;
+
+ // Compression algorithm (1 = DAWG, 2 = GADDAG)
+ uint8_t algorithm;
+ // Variant used in the rules (XXX: currently unused)
+ uint8_t variant;
+
+ // Dictionary official name and version (e.g.: ODS 5.0)
+ char dicName[_MAX_DIC_NAME_SIZE_];
+ // Size taken by the dictionary name
+ uint32_t dicNameSize;
+
+ // Letters used in the dictionary
+ // We should have: nbLetters <= lettersSize <= _MAX_LETTERS_SIZE_
+ // and: nbLetters <= _MAX_LETTERS_NB_
+ // The letters themselves, in UTF-8
+ char letters[_MAX_LETTERS_SIZE_];
+ // Size taken by the letters
+ uint32_t lettersSize;
+ // Number of letters (XXX: in theory useless, but allows a sanity check)
+ uint32_t nbLetters;
+
+ // Points of the letters (indexed by their code)
+ // The "+ 1" is there for struct alignment
+ uint8_t points[_MAX_LETTERS_NB_ + 1];
+ // Frequency of the letters (indexedy their code)
+ // The "+ 1" is there for struct alignment
+ uint8_t frequency[_MAX_LETTERS_NB_ + 1];
+ // Bitfield indicating whether letters are vowels
+ uint64_t vowels;
+ // Bitfield indicating whether letters are consonants
+ uint64_t consonants;
+}
+===================================================================
-binary output of the header:
+In the old version of the dictionary, only the first structure was used
+(with version = 0). The current format (version = 1) has the 2 structs
+next to each other.
+The dictionary name, the letters, and the user/host information are
+stored in UTF-8. All the numbers are big endian (i.e. the output of
+the htonl() function).
+To avoid alignment issues, the extended header has been designed to
+have multiples of 64 bits regularly.
+
+
+binary output of the header (FIXME: not up to date):
===================================================================
0x00 ident : _COMPILED_DICTIONARY_
-0x16 unused 1 : 0 00000000
-0x17 unused 2 : 0 00000000
+0x16 version : 0 00000001
+0x17 unused : 0 00000000
0x18 root : 9 00000009
0x1c words : 3 00000003
0x20 edges used : 9 00000009
@@ -98,40 +171,37 @@
0x2c edges saved : 1 00000001
===================================================================
-The real array of data begins at offset 0x34. Integer are stored in a
-machine dependent way. This dictionary was compiled on a i386 and is
-not readable on a machine with a different endianess (unless swapping
-all necessary information). The array is stored 'as is' right after
-the header. Each array cell is a bit-structure on 4 bytes :
+The real array of data begins at offset 0x168. The array is stored
+'as is' right after the header. Each array cell is a bit-structure
+on 4 bytes:
-typedef struct _Dawg_edge {
+struct DicEdge
+{
unsigned int ptr : 24;
unsigned int term : 1;
unsigned int last : 1;
- unsigned int fill : 1; // reserved (currently unused)
- unsigned int chr : 5;
-} Dawg_edge;
-
-Characters are not stored in ASCII. The order is preserved but
-we changed the values: A=1, B=2, ... This is very easy to do
-with the ASCII table as ('A' & 0x1f) == ('a' & 0x1f) == 1.
-This may not work on machines that are not using ASCII. The dictionary
-can thus handle up to 32 different letters but not more.
+ unsigned int chr : 6;
+};
+
+Characters are not stored in ASCII. The order of the letters given
+to the compdic binary is preserved, but we changed the values: the
+first letter is 1, the second one is 2, etc...
+The dictionary can thus handle up to 64 different letters but not more.
+The letter 0 is special (used for the sink node in particular), so
+in practice there are only 63 distinct letters.
offs binary structure
---- -------- | ------------------
-0x00 02000000 | 0 ptr= 0 t=0 l=1 f=0 chr=0 (`)
-0x04 1b000000 | 1 ptr= 0 t=1 l=1 f=0 chr=3 (c)
-0x08 0b000000 | 2 ptr= 0 t=1 l=1 f=0 chr=1 (a)
-0x0c 10000001 | 3 ptr= 1 t=0 l=0 f=0 chr=2 (b)
-0x10 22000002 | 4 ptr= 2 t=0 l=1 f=0 chr=4 (d)
-0x14 0a000002 | 5 ptr= 2 t=0 l=1 f=0 chr=1 (a)
-0x18 22000005 | 6 ptr= 5 t=0 l=1 f=0 chr=4 (d)
-0x1c 08000003 | 7 ptr= 3 t=0 l=0 f=0 chr=1 (a)
-0x20 2a000006 | 8 ptr= 6 t=0 l=1 f=0 chr=5 (e)
-0x24 00000007 | 9 ptr= 7 t=0 l=0 f=0 chr=0 (`)
+0x00 02000000 | 0 ptr= 0 t=0 l=1 chr=0 (`)
+0x04 1b000000 | 1 ptr= 0 t=1 l=1 chr=3 (c)
+0x08 0b000000 | 2 ptr= 0 t=1 l=1 chr=1 (a)
+0x0c 10000001 | 3 ptr= 1 t=0 l=0 chr=2 (b)
+0x10 22000002 | 4 ptr= 2 t=0 l=1 chr=4 (d)
+0x14 0a000002 | 5 ptr= 2 t=0 l=1 chr=1 (a)
+0x18 22000005 | 6 ptr= 5 t=0 l=1 chr=4 (d)
+0x1c 08000003 | 7 ptr= 3 t=0 l=0 chr=1 (a)
+0x20 2a000006 | 8 ptr= 6 t=0 l=1 chr=5 (e)
+0x24 00000007 | 9 ptr= 7 t=0 l=0 chr=0 (`)
Strictly speaking, there is no node in the graph, only labelled edges.
-
-
Index: game/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/game/Makefile.am,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- game/Makefile.am 22 Jan 2006 12:23:53 -0000 1.13
+++ game/Makefile.am 8 Jan 2008 13:52:36 -0000 1.14
@@ -1,6 +1,7 @@
# Eliot
-# Copyright (C) 1999 Antoine Fraboulet
-# address@hidden
+# Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+# Authors: Antoine Fraboulet <address@hidden>
+# Olivier Teulière <ipkiss @@ gmail.com>
#
# 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
@@ -23,7 +24,6 @@
libgame_a_SOURCES= \
ai_percent.cpp ai_percent.h \
ai_player.h \
- tile.cpp tile.h \
bag.cpp bag.h \
coord.cpp coord.h \
cross.cpp cross.h \
@@ -31,17 +31,19 @@
board_cross.cpp \
board_search.cpp \
duplicate.cpp duplicate.h \
- encoding.cpp encoding.h \
freegame.cpp freegame.h \
game.cpp game.h \
game_factory.cpp game_factory.h \
game_io.cpp \
+ move.cpp move.h \
player.cpp player.h \
pldrack.cpp pldrack.h \
rack.cpp rack.h \
results.cpp results.h \
round.cpp round.h \
+ settings.cpp settings.h \
training.cpp training.h \
turn.cpp turn.h \
- history.cpp history.h
+ history.cpp history.h \
+ debug.h
Index: game/ai_percent.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/ai_percent.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- game/ai_percent.cpp 1 Jan 2006 19:49:35 -0000 1.5
+++ game/ai_percent.cpp 8 Jan 2008 13:52:37 -0000 1.6
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -21,6 +22,7 @@
#include "rack.h"
#include "pldrack.h"
#include "round.h"
+#include "move.h"
#include "results.h"
#include "board.h"
#include "ai_percent.h"
@@ -37,32 +39,46 @@
}
-void AIPercent::compute(const Dictionary &iDic, Board &iBoard, int turn)
+void AIPercent::compute(const Dictionary &iDic, Board &iBoard, bool iFirstWord)
{
m_results.clear();
Rack rack;
getCurrentRack().getRack(rack);
- m_results.search(iDic, iBoard, rack, turn);
+ m_results.search(iDic, iBoard, rack, iFirstWord);
}
-bool AIPercent::changesLetters() const
+Move AIPercent::getMove() const
{
- return (m_results.size() == 0);
-}
-
-
-const Round & AIPercent::getChosenRound() const
-{
- int index = (int)(m_percent * (m_results.size() - 1));
- return m_results.get(index);
-}
-
-
-vector<Tile> AIPercent::getChangedLetters() const
-{
- return vector<Tile>();
+ if (m_results.size() == 0)
+ {
+ // If there is no result, simply pass the turn
+ // XXX: it is forbidden in duplicate mode, but well, what else to do?
+ return Move(L"");
+ }
+ else
+ {
+ // If there are results, apply the algorithm
+ double wantedScore = m_percent * m_results.get(0).getPoints();
+ // Look for the first round giving at least 'wantedScore' points
+ // Browse the results 10 by 10 (a dichotomy would be better, but this
+ // is not performance critical)
+ unsigned int index = 0;
+ while (index < m_results.size() &&
+ m_results.get(index).getPoints() > wantedScore)
+ {
+ index += 10;
+ }
+ // Now the wanted round is in the last 10 indices
+ if (index >= m_results.size())
+ index = m_results.size() - 1;
+ while (m_results.get(index).getPoints() < wantedScore)
+ {
+ --index;
+ }
+ return Move(m_results.get(index));
+ }
}
/// Local Variables:
Index: game/ai_percent.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/ai_percent.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- game/ai_percent.h 1 Jan 2006 19:49:35 -0000 1.6
+++ game/ai_percent.h 8 Jan 2008 13:52:37 -0000 1.7
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -27,10 +28,10 @@
* This kind of AI is parameterized by a percentage p.
* The computation consists in finding all the N possible rounds for the
* current rack/board, and sorting the list.
- * The chosen round is the n'th element of the sorted list, such that n/N
- * is closest to the percentage p.
- * A percentage of 0 should always return the best round (i.e. the one with
- * the highest score), while a percentage of 1 should return the worst one.
+ * The chosen round is the one with the smallest score at least equal to
+ * p * best_score.
+ * A percentage of 1 should always return the best round (i.e. the one with
+ * the highest score), while a percentage of 0 should return the worst one.
* This kind of AI will never change letters (unless it cannot play anything,
* in which case it just passes without changing letters).
*/
@@ -45,17 +46,15 @@
* This method does the actual computation. It will be called before any
* of the following methods, so it must prepare everything for them.
*/
- virtual void compute(const Dictionary &iDic, Board &iBoard, int turn);
- /// Return true when the AI wants to change letters instead of playing a
word
- virtual bool changesLetters() const;
- /// Return the round played by the AI (if changesLetters() returns false)
- virtual const Round & getChosenRound() const;
- /// Get the letters to change (if changesLetters() returns true)
- virtual vector<Tile> getChangedLetters() const;
+ virtual void compute(const Dictionary &iDic, Board &iBoard, bool
iFirstWord);
+
+ /// Return the move played by the AI
+ virtual Move getMove() const;
private:
/// Percentage used for this player
float m_percent;
+
/// Container for all the found solutions
Results m_results;
};
Index: game/ai_player.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/ai_player.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- game/ai_player.h 1 Jan 2006 19:49:35 -0000 1.7
+++ game/ai_player.h 8 Jan 2008 13:52:37 -0000 1.8
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -22,10 +23,10 @@
#include "player.h"
+class Dictionary;
class Round;
class Board;
class Tile;
-typedef struct _Dictionary * Dictionary;
/**
* This class is a pure interface, that must be implemented by all the AI
@@ -69,22 +70,14 @@
* This method does the actual computation. It will be called before any
* of the following methods, so it must prepare everything for them.
*/
- virtual void compute(const Dictionary &iDic, Board &iBoard, int turn) = 0;
- /**
- * Return true when the AI wants to change letters instead of playing a
- * word.
- * Should return false in duplicate mode, as it is not allowed to change
- * letters.
- */
- virtual bool changesLetters() const = 0;
- /// Return the round played by the AI (if changesLetters() returns false)
- virtual const Round & getChosenRound() const = 0;
- /// Get the letters to change (if changesLetters() returns true)
- virtual vector<Tile> getChangedLetters() const = 0;
+ virtual void compute(const Dictionary &iDic, Board &iBoard, bool
iFirstWord) = 0;
+
+ /// Return the move played by the AI
+ virtual Move getMove() const = 0;
protected:
/// This class is a pure interface, forbid any direct instanciation
- AIPlayer(int iId): Player(iId) {}
+ AIPlayer(unsigned int iId): Player(iId) {}
};
#endif
Index: game/bag.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/bag.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- game/bag.cpp 23 Dec 2006 13:50:43 -0000 1.8
+++ game/bag.cpp 8 Jan 2008 13:52:37 -0000 1.9
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -20,22 +21,18 @@
#include <string>
-#include "tile.h"
+#include <dic.h>
#include "bag.h"
#include "debug.h"
+#include "encoding.h"
-Bag::Bag()
-{
- init();
-}
-
-
-void Bag::init()
+Bag::Bag(const Dictionary &iDic)
+ : m_dic(iDic)
{
m_ntiles = 0;
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = m_dic.getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
m_tilesMap[*it] = it->maxNumber();
@@ -53,7 +50,7 @@
}
-unsigned int Bag::nVowels() const
+unsigned int Bag::getNbVowels() const
{
map<Tile, int>::const_iterator it;
int v = 0;
@@ -67,7 +64,7 @@
}
-unsigned int Bag::nConsonants() const
+unsigned int Bag::getNbConsonants() const
{
map<Tile, int>::const_iterator it;
int c = 0;
@@ -84,7 +81,7 @@
void Bag::takeTile(const Tile &iTile)
{
ASSERT(in(iTile),
- (wstring(L"The bag does not contain the letter ") +
iTile.toChar()).c_str());
+ "The bag does not contain the letter " +
convertToMb(iTile.toChar()));
m_tilesMap[iTile]--;
m_ntiles--;
@@ -94,28 +91,71 @@
void Bag::replaceTile(const Tile &iTile)
{
ASSERT(in(iTile) < iTile.maxNumber(),
- (wstring(L"Cannot replace tile: ") + iTile.toChar()).c_str());
+ "Cannot replace tile: " + convertToMb(iTile.toChar()));
m_tilesMap[iTile]++;
m_ntiles++;
}
-Tile Bag::selectRandom()
+Tile Bag::selectRandom() const
{
- map<Tile, int>::const_iterator it;
- int n;
double max = m_ntiles;
+ ASSERT(max > 0, "The bag is empty");
+
+ int n = (int)(max * rand() / (RAND_MAX + 1.0));
+
+ map<Tile, int>::const_iterator it;
+ for (it = m_tilesMap.begin(); it != m_tilesMap.end(); it++)
+ {
+ if (n < it->second)
+ return it->first;
+ n -= it->second;
+ }
+ ASSERT(false, "We should not come here");
+ return Tile();
+}
- n = (int)(max * rand() / (RAND_MAX + 1.0));
+
+Tile Bag::selectRandomVowel() const
+{
+ double max = getNbVowels();
+ ASSERT(max > 0, "Not enough vowels in the bag");
+
+ int n = (int)(max * rand() / (RAND_MAX + 1.0));
+
+ map<Tile, int>::const_iterator it;
+ for (it = m_tilesMap.begin(); it != m_tilesMap.end(); it++)
+ {
+ if (!it->first.isVowel())
+ continue;
+ if (n < it->second)
+ return it->first;
+ n -= it->second;
+ }
+ ASSERT(false, "We should not come here");
+ return Tile();
+}
+
+
+Tile Bag::selectRandomConsonant() const
+{
+ double max = getNbConsonants();
+ ASSERT(max > 0, "Not enough consonants in the bag");
+
+ int n = (int)(max * rand() / (RAND_MAX + 1.0));
+
+ map<Tile, int>::const_iterator it;
for (it = m_tilesMap.begin(); it != m_tilesMap.end(); it++)
{
+ if (!it->first.isConsonant())
+ continue;
if (n < it->second)
return it->first;
n -= it->second;
}
ASSERT(false, "We should not come here");
- return Tile::dummy();
+ return Tile();
}
Index: game/bag.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/bag.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- game/bag.h 23 Dec 2006 16:48:15 -0000 1.9
+++ game/bag.h 8 Jan 2008 13:52:37 -0000 1.10
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -21,11 +22,13 @@
#ifndef _BAG_H_
#define _BAG_H_
-#include "tile.h"
#include <map>
+#include "tile.h"
using std::map;
+class Dictionary;
+
/**
* A bag stores the set of free tiles for the game.
@@ -33,9 +36,7 @@
class Bag
{
public:
- Bag();
- virtual ~Bag() {}
- void init();
+ explicit Bag(const Dictionary &iDic);
/// Take a tile in the bag
void takeTile(const Tile &iTile);
@@ -47,18 +48,30 @@
/**
* Return how many tiles/vowels/consonants are available
- * Warning: b.nVowels() + b.nConsonants() != b.nTiles(),
+ * Warning: b.getNbVowels() + b.getNbConsonants() != b.getNbTiles(),
* because of the jokers and the 'Y'.
*/
- unsigned int nTiles() const { return m_ntiles; }
- unsigned int nVowels() const;
- unsigned int nConsonants() const;
+ unsigned int getNbTiles() const { return m_ntiles; }
+ unsigned int getNbVowels() const;
+ unsigned int getNbConsonants() const;
/**
* Return a random available tile
* The tile is not taken out of the bag.
*/
- Tile selectRandom();
+ Tile selectRandom() const;
+
+ /**
+ * Return a random available vowel.
+ * The tile is not taken out of the bag.
+ */
+ Tile selectRandomVowel() const;
+
+ /**
+ * Return a random available consonant.
+ * The tile is not taken out of the bag.
+ */
+ Tile selectRandomConsonant() const;
void operator=(const Bag &iOther);
@@ -66,8 +79,12 @@
void dumpAll() const;
private:
+ /// Dictionary
+ const Dictionary &m_dic;
+
/// Associate to each tile its number of occurrences in the bag
map<Tile, int> m_tilesMap;
+
/// Total number of tiles in the bag
int m_ntiles;
};
Index: game/board.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- game/board.cpp 4 Aug 2007 20:01:28 -0000 1.17
+++ game/board.cpp 8 Jan 2008 13:52:37 -0000 1.18
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -82,8 +83,8 @@
Board::Board():
- m_tilesRow(BOARD_REALDIM, Tile::dummy()),
- m_tilesCol(BOARD_REALDIM, Tile::dummy()),
+ m_tilesRow(BOARD_REALDIM, Tile()),
+ m_tilesCol(BOARD_REALDIM, Tile()),
m_jokerRow(BOARD_REALDIM, false),
m_jokerCol(BOARD_REALDIM, false),
m_crossRow(BOARD_REALDIM, Cross()),
@@ -154,13 +155,12 @@
void Board::addRound(const Dictionary &iDic, const Round &iRound)
{
Tile t;
- int row, col;
- row = iRound.getCoord().getRow();
- col = iRound.getCoord().getCol();
+ int row = iRound.getCoord().getRow();
+ int col = iRound.getCoord().getCol();
if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
{
- for (int i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (m_tilesRow[row][col + i].isEmpty())
{
@@ -174,7 +174,7 @@
}
else
{
- for (int i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (m_tilesRow[row + i][col].isEmpty())
{
@@ -195,20 +195,18 @@
void Board::removeRound(const Dictionary &iDic, const Round &iRound)
{
- int row, col;
-
- row = iRound.getCoord().getRow();
- col = iRound.getCoord().getCol();
+ int row = iRound.getCoord().getRow();
+ int col = iRound.getCoord().getCol();
if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
{
- for (int i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (iRound.isPlayedFromRack(i))
{
- m_tilesRow[row][col + i] = Tile::dummy();
+ m_tilesRow[row][col + i] = Tile();
m_jokerRow[row][col + i] = false;
m_crossRow[row][col + i].setAny();
- m_tilesCol[col + i][row] = Tile::dummy();
+ m_tilesCol[col + i][row] = Tile();
m_jokerCol[col + i][row] = false;
m_crossCol[col + i][row].setAny();
}
@@ -216,14 +214,14 @@
}
else
{
- for (int i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (iRound.isPlayedFromRack(i))
{
- m_tilesRow[row + i][col] = Tile::dummy();
+ m_tilesRow[row + i][col] = Tile();
m_jokerRow[row + i][col] = false;
m_crossRow[row + i][col].setAny();
- m_tilesCol[col][row + i] = Tile::dummy();
+ m_tilesCol[col][row + i] = Tile();
m_jokerCol[col][row + i] = false;
m_crossCol[col][row + i].setAny();
}
@@ -246,17 +244,15 @@
bool firstturn)
{
Tile t;
- int row, col, i;
- int l, p, fromrack;
- int pts, ptscross, wordmul;
+ int l, p;
bool isolated = true;
- fromrack = 0;
- pts = 0;
- ptscross = 0;
- wordmul = 1;
- row = iRound.getCoord().getRow();
- col = iRound.getCoord().getCol();
+ unsigned int fromrack = 0;
+ int pts = 0;
+ int ptscross = 0;
+ int wordmul = 1;
+ int row = iRound.getCoord().getRow();
+ int col = iRound.getCoord().getCol();
/* Is the word an extension of another word? */
if (!iTilesMx[row][col - 1].isEmpty() ||
@@ -265,7 +261,7 @@
return 1;
}
- for (i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
t = iRound.getTile(i);
if (!iTilesMx[row][col + i].isEmpty())
@@ -383,13 +379,12 @@
void Board::testRound(const Round &iRound)
{
Tile t;
- int row, col;
- row = iRound.getCoord().getRow();
- col = iRound.getCoord().getCol();
+ int row = iRound.getCoord().getRow();
+ int col = iRound.getCoord().getCol();
if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
{
- for (int i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (m_tilesRow[row][col + i].isEmpty())
{
@@ -405,7 +400,7 @@
}
else
{
- for (int i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (m_tilesRow[row + i][col].isEmpty())
{
@@ -430,11 +425,11 @@
{
if (m_testsRow[row][col])
{
- m_tilesRow[row][col] = Tile::dummy();
+ m_tilesRow[row][col] = Tile();
m_testsRow[row][col] = 0;
m_jokerRow[row][col] = false;
- m_tilesCol[col][row] = Tile::dummy();
+ m_tilesCol[col][row] = Tile();
m_jokerCol[col][row] = false;
}
}
Index: game/board.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- game/board.h 5 Nov 2006 13:30:06 -0000 1.13
+++ game/board.h 8 Jan 2008 13:52:37 -0000 1.14
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -21,12 +22,13 @@
#ifndef _BOARD_H_
#define _BOARD_H_
-#include "tile.h"
-#include "cross.h"
#include <string>
#include <vector>
-typedef struct _Dictionary*Dictionary;
+#include "tile.h"
+#include "cross.h"
+
+class Dictionary;
class Rack;
class Round;
class Results;
@@ -61,7 +63,6 @@
{
public:
Board();
- virtual ~Board() {}
/*************************
* Coordinates have to be BOARD_MIN <= int <= BOARD_MAX
Index: game/board_cross.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board_cross.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- game/board_cross.cpp 23 Dec 2006 13:50:43 -0000 1.8
+++ game/board_cross.cpp 8 Jan 2008 13:52:37 -0000 1.9
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -25,11 +26,14 @@
* \date 2005
*/
+#include <wctype.h>
+
#include <dic.h>
#include "tile.h"
#include "board.h"
#include "debug.h"
+
static void Board_checkout_tile(const Dictionary &iDic,
vector<Tile>& iTiles,
vector<bool> & iJoker,
@@ -37,7 +41,7 @@
int& oPoints,
int index)
{
- int i,left;
+ int i, left;
unsigned int node, succ;
oPoints = 0;
@@ -52,36 +56,36 @@
}
// FIXME: create temporary strings until the dictionary uses Tile objects
- char leftTiles [BOARD_DIM + 1];
- char rightTiles[BOARD_DIM + 1];
+ wchar_t leftTiles [BOARD_DIM + 1];
+ wchar_t rightTiles[BOARD_DIM + 1];
for (i = left; i < index; i++)
- leftTiles[i - left] = toupper(iTiles[i].toChar());
+ leftTiles[i - left] = towupper(iTiles[i].toChar());
leftTiles[index - left] = 0;
for (i = index + 1; !iTiles[i].isEmpty(); i++)
- rightTiles[i - index - 1] = toupper(iTiles[i].toChar());
+ rightTiles[i - index - 1] = towupper(iTiles[i].toChar());
rightTiles[i - index - 1] = 0;
/* Tiles that can be played */
- node = Dic_char_lookup(iDic, Dic_root(iDic), leftTiles);
+ node = iDic.charLookup(iDic.getRoot(), leftTiles);
if (node == 0)
{
oCross.setNone();
return;
}
- for (succ = Dic_succ(iDic, node); succ; succ = Dic_next(iDic, succ))
+ for (succ = iDic.getSucc(node); succ; succ = iDic.getNext(succ))
{
- if (Dic_word(iDic, Dic_char_lookup(iDic, succ, rightTiles)))
- oCross.insert(Tile(Dic_char(iDic, succ)));
- if (Dic_last(iDic, succ))
+ if (iDic.isEndOfWord(iDic.charLookup(succ, rightTiles)))
+ oCross.insert(Tile(iDic.getChar(succ)));
+ if (iDic.isLast(succ))
break;
}
/* Points on the right part */
- /* yes, it is REALLY [index+1] */
- while (!iTiles[index+1].isEmpty())
+ /* yes, it is REALLY [index + 1] */
+ while (!iTiles[index + 1].isEmpty())
{
index++;
if (!iJoker[index])
Index: game/board_search.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board_search.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- game/board_search.cpp 4 Aug 2007 20:01:28 -0000 1.14
+++ game/board_search.cpp 8 Jan 2008 13:52:37 -0000 1.15
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -38,21 +39,17 @@
Matrix<bool> &iJokerMx,
Results &iResults, Round &iWord)
{
- int i, pts, ptscross;
- int l, t, fromrack;
- int len, row, col, wordmul;
+ unsigned int fromrack = 0;
+ int pts = 0;
+ int ptscross = 0;
+ int wordmul = 1;
- fromrack = 0;
- pts = 0;
- ptscross = 0;
- wordmul = 1;
+ unsigned int len = iWord.getWordLen();
- len = iWord.getWordLen();
+ int row = iWord.getCoord().getRow();
+ int col = iWord.getCoord().getCol();
- row = iWord.getCoord().getRow();
- col = iWord.getCoord().getCol();
-
- for (i = 0; i < len; i++)
+ for (unsigned int i = 0; i < len; i++)
{
if (!iTilesMx[row][col+i].isEmpty())
{
@@ -61,6 +58,7 @@
}
else
{
+ int l;
if (!iWord.isJoker(i))
l = iWord.getTile(i).getPoints() *
iBoard.getLetterMultiplier(row, col + i);
@@ -69,7 +67,7 @@
pts += l;
wordmul *= iBoard.getWordMultiplier(row, col + i);
- t = iPointsMx[row][col+i];
+ int t = iPointsMx[row][col+i];
if (t >= 0)
ptscross += (t + l) * iBoard.getWordMultiplier(row, col + i);
fromrack++;
@@ -109,33 +107,40 @@
if (iTilesMx[iRow][iCol].isEmpty())
{
- if (Dic_word(iDic, iNode) && iCol > iAnchor)
+ if (iDic.isEndOfWord(iNode) && iCol > iAnchor)
+ {
BoardSearchEvalMove(iBoard, iTilesMx, iPointsMx, iJokerMx,
iResults, ioPartialWord);
+ }
- for (succ = Dic_succ(iDic, iNode); succ; succ = Dic_next(iDic, succ))
+ // Optimization: avoid entering the for loop if no tile can match
+ if (iCrossMx[iRow][iCol].isNone())
+ return;
+
+ bool hasJokerInRack = iRack.in(Tile::Joker());
+ for (succ = iDic.getSucc(iNode); succ; succ = iDic.getNext(succ))
{
- l = Tile(Dic_char(iDic, succ));
+ l = Tile(iDic.getChar(succ));
if (iCrossMx[iRow][iCol].check(l))
{
if (iRack.in(l))
{
iRack.remove(l);
- ioPartialWord.addRightFromRack(l, 0);
+ ioPartialWord.addRightFromRack(l, false);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iCol + 1, iAnchor);
- ioPartialWord.removeRightToRack(l, 0);
+ ioPartialWord.removeRightToRack(l, false);
iRack.add(l);
}
- if (iRack.in(Tile::Joker()))
+ if (hasJokerInRack)
{
iRack.remove(Tile::Joker());
- ioPartialWord.addRightFromRack(l, 1);
+ ioPartialWord.addRightFromRack(l, true);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iCol + 1, iAnchor);
- ioPartialWord.removeRightToRack(l, 1);
+ ioPartialWord.removeRightToRack(l, true);
iRack.add(Tile::Joker());
}
}
@@ -144,15 +149,19 @@
else
{
l = iTilesMx[iRow][iCol];
- for (succ = Dic_succ(iDic, iNode); succ ; succ = Dic_next(iDic, succ))
+ wint_t upperChar = towupper(l.toChar());
+ for (succ = iDic.getSucc(iNode); succ ; succ = iDic.getNext(succ))
{
- if (Dic_char(iDic, succ) == toupper(l.toChar()))
+ if ((wint_t)iDic.getChar(succ) == upperChar)
{
ioPartialWord.addRightFromBoard(l);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, ioPartialWord,
iResults, succ, iRow, iCol + 1, iAnchor);
ioPartialWord.removeRightToBoard(l);
+ // The letter will be present only once in the dictionary,
+ // so we can stop looping
+ break;
}
}
}
@@ -177,31 +186,32 @@
if (iLimit > 0)
{
- for (succ = Dic_succ(iDic, n); succ; succ = Dic_next(iDic, succ))
+ bool hasJokerInRack = iRack.in(Tile::Joker());
+ for (succ = iDic.getSucc(n); succ; succ = iDic.getNext(succ))
{
- l = Tile(Dic_char(iDic, succ));
+ l = Tile(iDic.getChar(succ));
if (iRack.in(l))
{
iRack.remove(l);
- ioPartialWord.addRightFromRack(l, 0);
+ ioPartialWord.addRightFromRack(l, false);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() - 1);
LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iAnchor, iLimit - 1);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() + 1);
- ioPartialWord.removeRightToRack(l, 0);
+ ioPartialWord.removeRightToRack(l, false);
iRack.add(l);
}
- if (iRack.in(Tile::Joker()))
+ if (hasJokerInRack)
{
iRack.remove(Tile::Joker());
- ioPartialWord.addRightFromRack(l, 1);
+ ioPartialWord.addRightFromRack(l, true);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() - 1);
LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, ioPartialWord, iResults,
succ, iRow, iAnchor, iLimit - 1);
ioPartialWord.accessCoord().setCol(ioPartialWord.getCoord().getCol() + 1);
- ioPartialWord.removeRightToRack(l, 1);
+ ioPartialWord.removeRightToRack(l, true);
iRack.add(Tile::Joker());
}
}
@@ -221,10 +231,10 @@
int row, col, lastanchor;
Round partialword;
- list<Tile> rackTiles;
+ vector<Tile> rackTiles;
iRack.getTiles(rackTiles);
- list<Tile>::const_iterator it;
- bool match;
+ vector<Tile>::const_iterator it;
+ vector<Tile>::const_iterator itEnd;
for (row = 1; row <= BOARD_DIM; row++)
{
@@ -261,13 +271,13 @@
// Optimization compared to the original Appel & Jacobson
// algorithm: skip Leftpart if none of the tiles of the rack
// matches the cross mask for the current anchor
- match = false;
- for (it = rackTiles.begin();
- !match && it != rackTiles.end(); it++)
+ bool match = false;
+ for (it = rackTiles.begin(); it != rackTiles.end(); it++)
{
if (iCrossMx[row][col].check(*it))
{
match = true;
+ break;
}
}
if (match)
@@ -277,14 +287,14 @@
partialword.accessCoord().setCol(lastanchor + 1);
ExtendRight(iBoard, iDic, iTilesMx, iCrossMx,
iPointsMx,
iJokerMx, iRack, partialword, iResults,
- Dic_root(iDic), row, lastanchor + 1, col);
+ iDic.getRoot(), row, lastanchor + 1, col);
}
else
{
partialword.accessCoord().setCol(col);
LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
iJokerMx, iRack, partialword, iResults,
- Dic_root(iDic), row, col, col -
+ iDic.getRoot(), row, col, col -
lastanchor - 1);
}
}
@@ -328,8 +338,8 @@
partialword.accessCoord().setDir(Coord::HORIZONTAL);
LeftPart(*this, iDic, m_tilesRow, m_crossRow,
m_pointRow, m_jokerRow,
- copyRack, partialword, oResults, Dic_root(iDic), row, col,
- copyRack.nTiles() - 1);
+ copyRack, partialword, oResults, iDic.getRoot(), row, col,
+ copyRack.getNbTiles() - 1);
}
/// Local Variables:
Index: game/coord.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/coord.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- game/coord.cpp 22 Jan 2006 12:23:53 -0000 1.9
+++ game/coord.cpp 8 Jan 2008 13:52:37 -0000 1.10
@@ -1,21 +1,23 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file coord.cpp
Index: game/coord.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/coord.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- game/coord.h 22 Jan 2006 12:23:53 -0000 1.7
+++ game/coord.h 8 Jan 2008 13:52:37 -0000 1.8
@@ -1,21 +1,23 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file coord.h
@@ -27,19 +29,24 @@
#ifndef _COORD_H
#define _COORD_H
-using std::string;
+#include <string>
+
using std::wstring;
+
+/**
+ * This class handles coordinates of a square on the board.
+ * The row and column start at 1.
+ */
class Coord
{
public:
enum Direction {VERTICAL, HORIZONTAL};
- // Construction, destruction
+ // Construction
Coord(int iRow = -1, int iCol = -1, Direction iDir = HORIZONTAL);
Coord(const wstring &iStr);
- virtual ~Coord() {}
// Accessors
void setRow(int iRow) { m_row = iRow; }
Index: game/cross.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/cross.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- game/cross.cpp 5 Nov 2006 13:30:06 -0000 1.7
+++ game/cross.cpp 8 Jan 2008 13:52:37 -0000 1.8
@@ -1,6 +1,8 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière & Antoine Fraboulet
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ * Antoine Fraboulet <antoine.fraboulet @@ free.fr>
*
* 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
@@ -22,26 +24,25 @@
#define CROSS_MASK 0xFFFFFFFF
+
Cross::Cross()
{
// The default behaviour is to match everything
setAny();
}
+
void Cross::setAny()
{
m_mask = CROSS_MASK;
}
+
bool Cross::isAny() const
{
return m_mask == CROSS_MASK;
}
-void Cross::setNone()
-{
- m_mask = 0;
-}
string Cross::getHexContent() const
{
@@ -51,22 +52,21 @@
return s;
}
+
bool Cross::check(const Tile& iTile) const
{
return (iTile.isJoker() && m_mask != 0) || (m_mask & (1 <<
iTile.toCode()));
}
+
void Cross::insert(const Tile& iTile)
{
m_mask |= (1 << iTile.toCode());
}
+
bool Cross::operator==(const Cross &iOther) const
{
- /*
- * if (isAny() || iOther.isAny())
- * return isAny() && iOther.isAny();
- */
return m_mask == iOther.m_mask;
}
Index: game/cross.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/cross.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- game/cross.h 5 Nov 2006 13:30:06 -0000 1.8
+++ game/cross.h 8 Jan 2008 13:52:37 -0000 1.9
@@ -1,6 +1,8 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière & Antoine Fraboulet
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ * Antoine Fraboulet <antoine.fraboulet @@ free.fr>
*
* 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
@@ -34,13 +36,12 @@
{
public:
Cross();
- virtual ~Cross() {}
void setAny();
- void setNone();
+ void setNone() { m_mask = 0; }
bool isAny() const;
- bool isNone() const;
+ bool isNone() const { return m_mask == 0; }
bool check(const Tile& iTile) const;
Index: game/debug.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/debug.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- game/debug.h 1 Jan 2006 19:49:35 -0000 1.11
+++ game/debug.h 8 Jan 2008 13:52:37 -0000 1.12
@@ -1,6 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
+ * Eliot
+ * Copyright (C) 2004-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -17,8 +19,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
-#ifndef _CONST_H_
-#define _CONST_H_
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
/**********
* General
Index: game/duplicate.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/duplicate.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- game/duplicate.cpp 22 Jan 2006 12:23:53 -0000 1.16
+++ game/duplicate.cpp 8 Jan 2008 13:52:37 -0000 1.17
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -17,78 +18,74 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
+#include "duplicate.h"
#include "dic.h"
#include "tile.h"
#include "rack.h"
#include "round.h"
+#include "move.h"
#include "pldrack.h"
#include "results.h"
#include "player.h"
#include "ai_player.h"
-#include "duplicate.h"
+#include "settings.h"
#include "debug.h"
-Duplicate::Duplicate(const Dictionary &iDic): Game(iDic)
-{
-}
-
-
-Duplicate::~Duplicate()
+Duplicate::Duplicate(const Dictionary &iDic)
+ : Game(iDic)
{
}
-int Duplicate::setRackRandom(int p, bool iCheck, set_rack_mode mode)
-{
- int res;
- do
- {
- res = helperSetRackRandom(p, iCheck, mode);
- } while (res == 2);
- return res;
-}
-
-
int Duplicate::play(const wstring &iCoord, const wstring &iWord)
{
- /* Perform all the validity checks, and fill a round */
+ // Perform all the validity checks, and try to fill a round
Round round;
int res = checkPlayedWord(iCoord, iWord, round);
- if (res != 0)
+ if (res != 0 && Settings::Instance().getBool("duplicate-reject-invalid"))
{
return res;
}
- /* Everything is OK, we can play the word */
- playRound(round, m_currPlayer);
+ // If we reach this point, either the move is valid and we can use the
+ // "round" variable, or it is invalid but played nevertheless
+ if (res == 0)
+ {
+ // Everything is OK, we can play the word
+ playMove(Move(round), m_currPlayer);
+ }
+ else
+ {
+ // Record the invalid move of the player
+ playMove(Move(iWord, iCoord), m_currPlayer);
+ }
- /* Next turn */
- // XXX: Should it be done by the interface instead?
- endTurn();
+ // Little hack to handle duplicate games with only AI players.
+ // This will have no effect when there is at least one human player
+ tryEndTurn();
return 0;
}
-void Duplicate::duplicateAI(int n)
+void Duplicate::playAI(unsigned int p)
{
- ASSERT(0 <= n && n < getNPlayers(), "Wrong player number");
- ASSERT(!m_players[n]->isHuman(), "AI requested for a human player");
+ ASSERT(p < getNPlayers(), "Wrong player number");
- AIPlayer *player = static_cast<AIPlayer*>(m_players[n]);
- player->compute(*m_dic, m_board, m_history.getSize());
+ AIPlayer *player = dynamic_cast<AIPlayer*>(m_players[p]);
+ ASSERT(player != NULL, "AI requested for a human player");
- if (player->changesLetters())
- {
- // The AI player has nothing to play. This should not happen in
- // duplicate mode, otherwise the implementation of the AI is buggy...
- ASSERT(false, "AI player has nothing to play!");
- }
- else
+ player->compute(m_dic, m_board, m_history.beforeFirstRound());
+ const Move move = player->getMove();
+ if (move.getType() == Move::CHANGE_LETTERS ||
+ move.getType() == Move::PASS)
{
- playRound(player->getChosenRound(), n);
+ // The AI player must be buggy...
+ ASSERT(false, "AI tried to cheat!");
}
+
+ playMove(move, p);
}
@@ -96,165 +93,155 @@
{
ASSERT(getNPlayers(), "Cannot start a game without any player");
+ // Arbitrary player, since they should all have the same rack
m_currPlayer = 0;
- /* XXX: code similar with endTurnForReal() */
- /* Complete the rack for the player that just played */
- int res = setRackRandom(m_currPlayer, true, RACK_NEW);
- /* End of the game? */
+ // Complete the rack for the player that just played
+ int res = helperSetRackRandom(m_currPlayer, true, RACK_NEW);
+ // End of the game?
if (res == 1)
{
- end();
+ endGame();
return 1;
}
const PlayedRack& pld = m_players[m_currPlayer]->getCurrentRack();
- /* All the players have the same rack */
- for (int i = 0; i < getNPlayers(); i++)
+ // All the players have the same rack
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
if (i != m_currPlayer)
{
m_players[i]->setCurrentRack(pld);
}
- /* Nobody has played yet in this round */
+ // Nobody has played yet in this round
m_hasPlayed[i] = false;
}
- /* Next turn */
- // XXX: Should it be done by the interface instead?
- endTurn();
+ // Little hack to handle duplicate games with only AI players.
+ // This will have no effect when there is at least one human player
+ tryEndTurn();
return 0;
}
-/*
- * This function does not terminate the turn itself, but performs some
- * checks to know whether or not it should be terminated (with a call to
- * endTurnForReal()).
- *
- * For the turn to be terminated, all the players must have played.
- * Since the AI players play after the human players, we check whether
- * one of the human players has not played yet:
- * - if so, we have nothing to do (we are waiting for him)
- * - if not (all human players have played), the AI players can play,
- * and we finish the turn.
- */
-int Duplicate::endTurn()
+void Duplicate::tryEndTurn()
{
- int i;
- for (i = 0; i < getNPlayers(); i++)
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
if (m_players[i]->isHuman() && !m_hasPlayed[i])
{
- /* A human player has not played... */
+ // A human player has not played...
m_currPlayer = i;
- // XXX: check return code meaning
- return 1;
+ // So we don't finish the turn
+ return;
}
}
- /* If all the human players have played */
- if (i == getNPlayers())
- {
- /* Make AI players play their turn */
- for (i = 0; i < getNPlayers(); i++)
+ // Now that all the human players have played,
+ // make AI players play their turn
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
if (!m_players[i]->isHuman())
{
- duplicateAI(i);
- }
+ playAI(i);
}
-
- /* Next turn */
- endTurnForReal();
}
- // XXX: check return code meaning
- return 0;
+ // Next turn
+ endTurn();
}
-void Duplicate::playRound(const Round &iRound, int n)
+void Duplicate::playMove(const Move &iMove, unsigned int p)
{
- ASSERT(0 <= n && n < getNPlayers(), "Wrong player number");
- Player *player = m_players[n];
+ ASSERT(p < getNPlayers(), "Wrong player number");
- /* Update the rack and the score of the current player */
- player->addPoints(iRound.getPoints());
- player->endTurn(iRound, m_history.getSize());
+ // Update the rack and the score of the playing player
+ m_players[p]->endTurn(iMove, m_history.getSize());
- m_hasPlayed[n] = true;
+ m_hasPlayed[p] = true;
}
-/*
- * This function really changes the turn, i.e. the best word is played and
- * a new rack is given to the players.
- * We suppose that all the players have finished to play for this turn (this
- * should have been checked by endturn())
- */
-int Duplicate::endTurnForReal()
+void Duplicate::endTurn()
{
- int res, i, imax;
-
- /* Play the best word on the board */
- imax = 0;
- for (i = 1; i < getNPlayers(); i++)
+ // Find the player with the best score
+ unsigned int imax = 0;
+ for (unsigned int i = 1; i < getNPlayers(); i++)
{
- if (m_players[i]->getLastRound().getPoints() >
- m_players[imax]->getLastRound().getPoints())
+ if (m_players[i]->getLastMove().getScore() >
+ m_players[imax]->getLastMove().getScore())
{
imax = i;
}
}
- m_currPlayer = imax;
- helperPlayRound(m_players[imax]->getLastRound());
- /* Complete the rack for the player that just played */
- res = setRackRandom(imax, true, RACK_NEW);
- /* End of the game? */
- if (res == 1)
+ // TODO: do something if nobody played a valid round!
+
+ // Handle solo bonus
+ // First check whether there are enough players in the game for the
+ // bonus to apply
+ int minNbPlayers = Settings::Instance().getInt("duplicate-solo-players");
+ if (getNPlayers() >= (unsigned int)minNbPlayers &&
+ m_players[imax]->getLastMove().getType() == Move::VALID_ROUND)
{
- end();
- return 1;
+ int maxScore = m_players[imax]->getLastMove().getScore();
+ // Find whether other players than imax have the same score
+ bool otherWithSameScore = false;
+ for (unsigned int i = imax + 1; i < getNPlayers(); i++)
+ {
+ if (m_players[i]->getLastMove().getScore() >= maxScore)
+ {
+ otherWithSameScore = true;
+ break;
+ }
+ }
+ if (!otherWithSameScore)
+ {
+ // Give the bonus to player imax
+ int bonus = Settings::Instance().getInt("duplicate-solo-value");
+ m_players[imax]->addPoints(bonus);
+ // TODO: keep a trace of the solo, so the interface
+ // can be aware of it...
+ }
}
+ // Play the best word on the board
+ helperPlayMove(imax, m_players[imax]->getLastMove());
+
+ // Leave the same reliquate to all players
+ // This is required by the start() method which will be called to
+ // start the next turn
const PlayedRack& pld = m_players[imax]->getCurrentRack();
- /* All the players have the same rack */
- for (i = 0; i < getNPlayers(); i++)
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
if (i != imax)
{
m_players[i]->setCurrentRack(pld);
}
- /* Nobody has played yet in this round */
- m_hasPlayed[i] = false;
}
- /* XXX: Little hack to handle the games with only AI players.
- * This will have no effect when there is at least one human player */
- endTurn();
-
- return 0;
+ // Start next turn...
+ start();
}
-void Duplicate::end()
+void Duplicate::endGame()
{
m_finished = true;
}
-int Duplicate::setPlayer(int n)
+int Duplicate::setPlayer(unsigned int p)
{
- ASSERT(0 <= n && n < getNPlayers(), "Wrong player number");
+ ASSERT(p < getNPlayers(), "Wrong player number");
- /* Forbid switching to an AI player */
- if (!m_players[n]->isHuman())
+ // Forbid switching to an AI player
+ if (!m_players[p]->isHuman())
return 1;
- m_currPlayer = n;
+ m_currPlayer = p;
return 0;
}
Index: game/duplicate.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/duplicate.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- game/duplicate.h 22 Jan 2006 12:23:53 -0000 1.12
+++ game/duplicate.h 8 Jan 2008 13:52:37 -0000 1.13
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -34,7 +35,7 @@
* and rack are updated. He cannot change his word afterwards.
* - if there is still a human player who has not played for the current
* turn, we wait for him
- * - if all the human players have played, it's the turn to the AI players
+ * - if all the human players have played, it's the turn of the AI players
* (currently handled in a loop, but we could imagine that they are running
* in their own thread).
* - once all the players have played, we can really end the turn:
@@ -57,26 +58,73 @@
/*************************
* Game handling
*************************/
+ /**
+ * In Duplicate mode, the start() method starts a new turn, and is
+ * automatically called when the previous turn is finished.
+ *
+ * Pre-requisite: all the players must have the same rack when this
+ * method is called
+ */
virtual int start();
- virtual int setRackRandom(int, bool, set_rack_mode);
+
+ /**
+ * See description of Game::play() for the possible return values.
+ * Note that if the "duplicate-reject-invalid" setting is set to false
+ * the method always returns 0 (the player will have 0 for this turn)
+ */
virtual int play(const wstring &iCoord, const wstring &iWord);
- virtual int endTurn();
- int setPlayer(int);
- // Switch to the previous human player who has not played yet
+ /**
+ * Set the current player, given its ID.
+ * The given player ID must correspond to a human player, which did not
+ * play yet for this turn.
+ * Possible return values:
+ * 0: everything went fine
+ * 1: the player is not human
+ */
+ int setPlayer(unsigned int p);
+
+ /// Switch to the previous human player who has not played yet
void prevHumanPlayer();
- // Switch to the next human player who has not played yet
+
+ /// Switch to the next human player who has not played yet
void nextHumanPlayer();
private:
- // Private constructor and destructor to force using the GameFactory class
+ // Private constructor to force using the GameFactory class
Duplicate(const Dictionary &iDic);
- virtual ~Duplicate();
- void playRound(const Round &iRound, int n);
- int endTurnForReal();
- void end();
- void duplicateAI(int n);
+ void playMove(const Move &iMove, unsigned int p);
+
+ /// Make the AI player whose ID is p play its turn
+ void playAI(unsigned int p);
+
+ /**
+ * This function does not terminate the turn itself, but performs some
+ * checks to know whether or not it should be terminated (with a call to
+ * endTurn()).
+ *
+ * For the turn to be terminated, all the players must have played.
+ * Since the AI players play after the human players, we check whether
+ * one of the human players has not played yet:
+ * - if so, we have nothing to do (we are waiting for him/her)
+ * - if not (all human players have played), the AI players can play,
+ * and we finish the turn.
+ */
+ void tryEndTurn();
+
+ /**
+ * This function really changes the turn, i.e. the best word is played,
+ * the game history is updated, a "solo" bonus is given if needed, and
+ * all racks are made equal to the one of the player who played the
+ * best move.
+ * We suppose here that all the players have finished to play for this
+ * turn (this should have been checked by tryEndturn())
+ */
+ void endTurn();
+
+ /// Finish the game
+ void endGame();
// m_hasPlayed[p] is true iff player p has played for this turn
map<int, bool> m_hasPlayed;
Index: game/freegame.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/freegame.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- game/freegame.cpp 22 Jan 2006 12:23:53 -0000 1.18
+++ game/freegame.cpp 8 Jan 2008 13:52:38 -0000 1.19
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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,89 +20,88 @@
#include <iomanip>
#include <wctype.h>
+
+#include "freegame.h"
#include "dic.h"
#include "tile.h"
#include "rack.h"
#include "round.h"
+#include "move.h"
#include "pldrack.h"
#include "results.h"
#include "player.h"
#include "ai_player.h"
-#include "freegame.h"
+#include "settings.h"
#include "debug.h"
-FreeGame::FreeGame(const Dictionary &iDic): Game(iDic)
-{
-}
-
-
-FreeGame::~FreeGame()
-{
-}
-
-
-int FreeGame::setRackRandom(int p, bool iCheck, set_rack_mode mode)
+FreeGame::FreeGame(const Dictionary &iDic)
+ : Game(iDic)
{
- int res;
- do
- {
- res = helperSetRackRandom(p, iCheck, mode);
- } while (res == 2);
- return res;
}
int FreeGame::play(const wstring &iCoord, const wstring &iWord)
{
- /* Perform all the validity checks, and fill a round */
+ // Perform all the validity checks, and try to fill a round
Round round;
-
int res = checkPlayedWord(iCoord, iWord, round);
- if (res != 0)
+ if (res != 0 && Settings::Instance().getBool("freegame-reject-invalid"))
{
return res;
}
- /* Update the rack and the score of the current player */
- m_players[m_currPlayer]->addPoints(round.getPoints());
- m_players[m_currPlayer]->endTurn(round, m_history.getSize());
+ // If we reach this point, either the move is valid and we can use the
+ // "round" variable, or it is invalid but played nevertheless
+ if (res == 0)
+ {
+ Move move(round);
+
+ // Update the rack and the score of the current player
+ m_players[m_currPlayer]->endTurn(move, m_history.getSize());
+
+ // Everything is OK, we can play the word
+ helperPlayMove(m_currPlayer, move);
+ }
+ else
+ {
+ Move move(iWord, iCoord);
+
+ // Record the invalid move of the player
+ m_players[m_currPlayer]->endTurn(move, m_history.getSize());
- /* Everything is OK, we can play the word */
- helperPlayRound(round);
+ // Update the game
+ helperPlayMove(m_currPlayer, move);
+ }
- /* Next turn */
- // XXX: Should it be done by the interface instead?
+ // Next turn
endTurn();
return 0;
}
-void FreeGame::freegameAI(int n)
+void FreeGame::playAI(unsigned int p)
{
- ASSERT(0 <= n && n < getNPlayers(), "Wrong player number");
- ASSERT(!m_players[n]->isHuman(), "AI requested for a human player");
+ ASSERT(p < getNPlayers(), "Wrong player number");
+ ASSERT(!m_players[p]->isHuman(), "AI requested for a human player");
- AIPlayer *player = static_cast<AIPlayer*>(m_players[n]);
+ AIPlayer *player = static_cast<AIPlayer*>(m_players[p]);
- player->compute(*m_dic, m_board, m_history.getSize());
- if (player->changesLetters())
+ player->compute(m_dic, m_board, m_history.beforeFirstRound());
+ const Move move = player->getMove();
+ if (move.getType() == Move::CHANGE_LETTERS ||
+ move.getType() == Move::PASS)
{
- helperPass(player->getChangedLetters(), n);
- endTurn();
+ ASSERT(checkPass(move.getChangedLetters(), p) == 0, "AI tried to
cheat!");
}
- else
- {
- const Round &round = player->getChosenRound();
- /* Update the rack and the score of the current player */
- player->addPoints(round.getPoints());
- player->endTurn(round, m_history.getSize());
- helperPlayRound(round);
+ // Update the rack and the score of the current player
+ player->endTurn(move, m_history.getSize());
+
+ helperPlayMove(p, move);
endTurn();
- }
}
@@ -109,19 +109,18 @@
{
ASSERT(getNPlayers(), "Cannot start a game without any player");
- /* Set the initial racks of the players */
- for (int i = 0; i < getNPlayers(); i++)
+ // Set the initial racks of the players
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
- setRackRandom(i, false, RACK_NEW);
+ helperSetRackRandom(i, false, RACK_NEW);
}
- // XXX
m_currPlayer = 0;
- /* If the first player is an AI, make it play now */
- if (!m_players[0]->isHuman())
+ // If the first player is an AI, make it play now
+ if (!m_players[m_currPlayer]->isHuman())
{
- freegameAI(0);
+ playAI(m_currPlayer);
}
return 0;
@@ -130,21 +129,21 @@
int FreeGame::endTurn()
{
- /* Complete the rack for the player that just played */
- if (setRackRandom(m_currPlayer, false, RACK_NEW) == 1)
+ // Complete the rack for the player that just played
+ if (helperSetRackRandom(m_currPlayer, false, RACK_NEW) == 1)
{
- /* End of the game */
- end();
+ // End of the game
+ endGame();
return 1;
}
- /* Next player */
+ // Next player
nextPlayer();
- /* If this player is an AI, make it play now */
+ // If this player is an AI, make it play now
if (!m_players[m_currPlayer]->isHuman())
{
- freegameAI(m_currPlayer);
+ playAI(m_currPlayer);
}
return 0;
@@ -152,7 +151,7 @@
// Adjust the scores of the players with the points of the remaining tiles
-void FreeGame::end()
+void FreeGame::endGame()
{
vector<Tile> tiles;
@@ -165,12 +164,12 @@
// We currently handle case 1, and cannot handle case 3 until timers are
// implemented.
// For case 2, we need both to detect a blocked situation (not easy...) and
- // to handle it in the end() method (very easy).
+ // to handle it in the endGame() method (very easy).
/* Add the points of the remaining tiles to the score of the current
* player (i.e. the first player with an empty rack), and remove them
* from the score of the players who still have tiles */
- for (int i = 0; i < getNPlayers(); i++)
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
if (i != m_currPlayer)
{
@@ -184,73 +183,73 @@
}
}
- /* Lock game */
+ // Lock game
m_finished = true;
}
-int FreeGame::pass(const wstring &iToChange, int n)
+int FreeGame::checkPass(const wstring &iToChange, unsigned int p) const
{
+ ASSERT(p < getNPlayers(), "Wrong player number");
+
+ // Check that the game is not finished
if (m_finished)
return 3;
- // According to the rules in the ODS, it is allowed to pass its turn (no
- // need to change letters for that).
- // TODO: However, if all the players pass their turn, the first one has to
- // play, or change at least one letter. To implement this behaviour, we
- // must also take care of blocked positions, where no one _can_ play (see
- // also comment in the end() method).
-
- // Convert the string into tiles
- vector<Tile> tilesVect;
- for (unsigned int i = 0; i < iToChange.size(); i++)
- {
- Tile tile(towupper(iToChange[i]));
- tilesVect.push_back(tile);
- }
-
- int res = helperPass(tilesVect, n);
- if (res == 0)
- endTurn();
- return res;
-}
-
-
-int FreeGame::helperPass(const vector<Tile> &iToChange, int n)
-{
- ASSERT(0 <= n && n < getNPlayers(), "Wrong player number");
+ // Check that the letters are valid for the current dictionary
+ if (!m_dic.validateLetters(iToChange))
+ return 4;
// It is forbidden to change letters when the bag does not contain at
- // least 7 letters (this is explicitely stated in the ODS).
- Bag bag;
+ // least 7 letters (this is explicitly stated in the ODS). But it is
+ // still allowed to pass
+ Bag bag(m_dic);
realBag(bag);
- if (bag.nTiles() < 7)
+ if (bag.getNbTiles() < 7 && !iToChange.empty())
{
return 1;
}
- Player *player = m_players[n];
+ // Check that the letters are all present in the player's rack
+ Player *player = m_players[p];
PlayedRack pld = player->getCurrentRack();
Rack rack;
pld.getRack(rack);
-
for (unsigned int i = 0; i < iToChange.size(); i++)
{
- /* Remove the letter from the rack */
- if (!rack.in(iToChange[i]))
+ // Remove the letter from the rack
+ if (!rack.in(Tile(iToChange[i])))
{
return 2;
}
- rack.remove(iToChange[i]);
+ rack.remove(Tile(iToChange[i]));
}
- pld.reset();
- pld.setOld(rack);
+ // According to the rules in the ODS, it is allowed to pass its turn (no
+ // need to change letters for that).
+ // TODO: However, if all the players pass their turn, the first one has to
+ // play, or change at least one letter. To implement this behaviour, we
+ // must also take care of blocked positions, where no one _can_ play (see
+ // also comment in the endGame() method).
- player->setCurrentRack(pld);
+ return 0;
+}
- // FIXME: the letters to change should not be in the bag while generating
- // the new rack!
+
+int FreeGame::pass(const wstring &iToChange)
+{
+ int res = checkPass(iToChange, m_currPlayer);
+ if (res != 0)
+ return res;
+
+ Move move(iToChange);
+ // End the player's turn
+ m_players[m_currPlayer]->endTurn(move, m_history.getSize());
+ // Update the game
+ helperPlayMove(m_currPlayer, move);
+
+ // Next game turn
+ endTurn();
return 0;
}
Index: game/freegame.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/freegame.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- game/freegame.h 22 Jan 2006 12:23:53 -0000 1.11
+++ game/freegame.h 8 Jan 2008 13:52:38 -0000 1.12
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -48,20 +49,54 @@
/*************************
* Game handling
*************************/
+ /**
+ * Start the game.
+ * Possible return values:
+ * 0: everything went fine
+ */
virtual int start();
- virtual int setRackRandom(int, bool, set_rack_mode);
+
+ /**
+ * See description of Game::play() for the possible return values.
+ * Note that if the "freegame-reject-invalid" setting is set to false
+ * the method always returns 0 (the player will have 0 for this turn)
+ */
virtual int play(const wstring &iCoord, const wstring &iWord);
- virtual int endTurn();
- int pass(const wstring &iToChange, int n);
+
+ /**
+ * 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 pass(const wstring &iToChange);
private:
- // Private constructor and destructor to force using the GameFactory class
+ // Private constructor to force using the GameFactory class
FreeGame(const Dictionary &iDic);
- virtual ~FreeGame();
- void freegameAI(int n);
- void end();
- int helperPass(const vector<Tile> &iToChange, int n);
+ /// Make the AI player whose ID is p play its turn
+ void playAI(unsigned int p);
+
+ /// Finish the current turn
+ int endTurn();
+
+ /// Finish the game
+ void endGame();
+
+ /**
+ * Check whether it is legal to change the letters of iToChange.
+ * The return codes are the same as the ones on the pass() method
+ */
+ int checkPass(const wstring &iToChange, unsigned int p) const;
};
#endif /* _FREEGAME_H_ */
Index: game/game.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- game/game.cpp 4 Aug 2007 20:01:28 -0000 1.33
+++ game/game.cpp 8 Jan 2008 13:52:38 -0000 1.34
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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,7 +20,6 @@
*****************************************************************************/
#include "dic.h"
-#include "dic_search.h"
#include "tile.h"
#include "rack.h"
#include "round.h"
@@ -35,65 +35,70 @@
#include "debug.h"
-const int Game::RACK_SIZE = 7;
+const unsigned int Game::RACK_SIZE = 7;
const int Game::BONUS_POINTS = 50;
Game::Game(const Dictionary &iDic):
- m_dic(&iDic)
+ m_dic(iDic), m_bag(iDic)
{
m_variant = kNONE;
m_points = 0;
- m_currPlayer = -1;
+ m_currPlayer = 0;
m_finished = false;
}
Game::~Game()
{
- for (int i = 0; i < getNPlayers(); i++)
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
delete m_players[i];
}
}
-const Player& Game::getPlayer(int iNum) const
+const Player& Game::getPlayer(unsigned int iNum) const
{
- ASSERT(0 <= iNum && iNum < (int)m_players.size(), "Wrong player number");
+ ASSERT(iNum < m_players.size(), "Wrong player number");
return *(m_players[iNum]);
}
-/* This function plays a round on the board */
-int Game::helperPlayRound(const Round &iRound)
+void Game::helperPlayMove(unsigned int iPlayerId, const Move &iMove)
{
- /*
- * We remove tiles from the bag only when they are played
- * on the board. When going back in the game, we must only
- * replace played tiles.
- * We test a rack when it is set but tiles are left in the bag.
- */
-
// History of the game
- m_history.setCurrentRack(getCurrentPlayer().getLastRack());
- m_history.playRound(m_currPlayer, m_history.getSize(), iRound);
+ m_history.setCurrentRack(getPlayer(iPlayerId).getLastRack());
+ m_history.playMove(iPlayerId, m_history.getSize(), iMove);
+
+ // Points
+ debug(" helper: %d points\n", iMove.getScore());
+ m_points += iMove.getScore();
- debug(" helper: %d points\n",iRound.getPoints());
- m_points += iRound.getPoints();
+ // For moves corresponding to a valid round, we have much more
+ // work to do...
+ if (iMove.getType() == Move::VALID_ROUND)
+ {
+ helperPlayRound(iPlayerId, iMove.getRound());
+ }
+}
+
+
+void Game::helperPlayRound(unsigned int iPlayerId, const Round &iRound)
+{
// Before updating the bag and the board, if we are playing a "joker game",
// we replace in the round the joker by the letter it represents
// This is currently done by a succession of ugly hacks :-/
if (m_variant == kJOKER)
{
- for (int i = 0; i < iRound.getWordLen(); i++)
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (iRound.isPlayedFromRack(i) && iRound.isJoker(i))
{
// Is the represented letter still available in the bag?
- // FIXME: this way to get the represented letter sucks...
+ // XXX: this way to get the represented letter sucks...
Tile t(towupper(iRound.getTile(i).toChar()));
- Bag bag;
+ Bag bag(m_dic);
realBag(bag);
// FIXME: realBag() does not give us a real bag in this
// particular case! This is because Player::endTurn() is called
@@ -108,12 +113,12 @@
// There is a big design problem here, but i am unsure what is
// the best way to fix it.
vector<Tile> tiles;
- getPlayer(m_currPlayer).getCurrentRack().getAllTiles(tiles);
+ getPlayer(iPlayerId).getCurrentRack().getAllTiles(tiles);
for (unsigned int j = 0; j < tiles.size(); j++)
{
bag.replaceTile(tiles[j]);
}
- getPlayer(m_currPlayer).getLastRack().getAllTiles(tiles);
+ getPlayer(iPlayerId).getLastRack().getAllTiles(tiles);
for (unsigned int j = 0; j < tiles.size(); j++)
{
bag.takeTile(tiles[j]);
@@ -128,12 +133,19 @@
// rounds
const_cast<Round&>(iRound).setJoker(i, false);
}
+
+ // In a joker game we should have only 1 joker in the rack
+ break;
}
}
}
- // Update the bag and the board
- for (int i = 0; i < iRound.getWordLen(); i++)
+ // Update the bag
+ // We remove tiles from the bag only when they are played
+ // on the board. When going back in the game, we must only
+ // replace played tiles.
+ // We test a rack when it is set but tiles are left in the bag.
+ for (unsigned int i = 0; i < iRound.getWordLen(); i++)
{
if (iRound.isPlayedFromRack(i))
{
@@ -147,36 +159,34 @@
}
}
}
- m_board.addRound(*m_dic, iRound);
- return 0;
+ // Update the board
+ m_board.addRound(m_dic, iRound);
}
-int Game::back(int n)
+int Game::back(unsigned int n)
{
- int i, j;
- Player *player;
-
- if (n < 0)
- {
- debug("Game::back negative argument\n");
- n = -n;
- }
debug("Game::back %d\n",n);
- for (i = 0; i < n; i++)
- {
- if (m_history.getSize() > 0)
+ // TODO: throw an exception
+ if (m_history.getSize() < n)
+ return 1;
+
+ for (unsigned int i = 0; i < n; i++)
{
prevPlayer();
- player = m_players[m_currPlayer];
- const Round &lastround = m_history.getPreviousTurn().getRound();
+ const Move &lastMove = m_history.getPreviousTurn().getMove();
+ // Nothing to cancel if the move was not a valid round
+ if (lastMove.getType() != Move::VALID_ROUND)
+ continue;
+
+ const Round &lastround = lastMove.getRound();
debug("Game::back last round %s\n",
convertToMb(lastround.toString()).c_str());
/* Remove the word from the board, and put its letters back
* into the bag */
- m_board.removeRound(*m_dic, lastround);
- for (j = 0; j < lastround.getWordLen(); j++)
+ m_board.removeRound(m_dic, lastround);
+ for (unsigned int j = 0; j < lastround.getWordLen(); j++)
{
if (lastround.isPlayedFromRack(j))
{
@@ -187,25 +197,15 @@
}
}
/* Remove the points of this round */
- player->addPoints(- lastround.getPoints());
m_points -= lastround.getPoints();
/* Remove the turns */
- player->removeLastTurn();
+ m_players[m_currPlayer]->removeLastTurn();
m_history.removeLastTurn();
}
- else
- {
- return 1;
- }
- }
return 0;
}
-/**
- * The realBag is the current bag minus all the racks
- * present in the game. It represents the actual
- * letters that are left in the bag.
- */
+
void Game::realBag(Bag &ioBag) const
{
vector<Tile> tiles;
@@ -217,7 +217,7 @@
if (getMode() == kFREEGAME)
{
/* In freegame mode, take the letters from all the racks */
- for (int i = 0; i < getNPlayers(); i++)
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
getPlayer(i).getCurrentRack().getAllTiles(tiles);
for (unsigned int j = 0; j < tiles.size(); j++)
@@ -239,22 +239,36 @@
}
-int Game::helperSetRackRandom(int p, bool iCheck, set_rack_mode mode)
+int Game::helperSetRackRandom(unsigned int p, bool iCheck, set_rack_mode mode)
{
- ASSERT(0 <= p && p < getNPlayers(), "Wrong player number");
+ ASSERT(p < getNPlayers(), "Wrong player number");
+ // FIXME: RACK_MANUAL shouldn't be in the enum
+ ASSERT(mode != RACK_MANUAL, "Invalid rack mode");
- int nold, min;
+ // When iCheck is true, we must make sure that there are at least 2 vowels
+ // and 2 consonants in the rack up to the 15th turn, and at least one of
+ // each starting from the 16th turn.
+ // So before trying to fill the rack, we'd better make sure there is a way
+ // to complete the rack with these constraints...
+ unsigned int min = 0;
+ if (iCheck)
+ {
+ // 2 vowels and 2 consonants are needed up to the 15th turn
+ if (m_history.getSize() < 15)
+ min = 2;
+ else
+ min = 1;
+ }
// Make a copy of the current player's rack
PlayedRack pld = getPlayer(p).getCurrentRack();
- nold = pld.nOld();
+ int nold = pld.getNbOld();
// Create a copy of the bag in which we can do everything we want,
// and take from it the tiles of the players rack so that "bag"
// contains the right number of tiles.
- Bag bag;
+ Bag bag(m_dic);
realBag(bag);
-
if (mode == RACK_NEW && nold != 0)
{
// We may have removed too many letters from the bag (i.e. the 'new'
@@ -286,8 +300,212 @@
debug("Game::helperSetRackRandom not a random mode\n");
}
+ // Get the tiles remaining on the rack
+ vector<Tile> tiles;
+ pld.getOldTiles(tiles);
+ ASSERT(tiles.size() < RACK_SIZE,
+ "Cannot complete the rack, it is already complete");
+
+ bool jokerAdded = false;
+ // Are we dealing with a normal game or a joker game?
+ if (m_variant == kJOKER)
+ {
+ // 1) Is there already a joker in the remaining letters of the rack?
+ bool jokerFound = false;
+ for (unsigned int i = 0; i < tiles.size(); i++)
+ {
+ if (tiles[i].isJoker())
+ {
+ jokerFound = true;
+ break;
+ }
+ }
+
+ // 2) If there was no joker, we add one if possible
+ if (!jokerFound && bag.in(Tile::Joker()))
+ {
+ jokerAdded = true;
+ pld.addNew(Tile::Joker());
+ tiles.push_back(Tile::Joker());
+ }
+
+ // 3) Remove all the jokers from the bag, to avoid taking another one
+ for (unsigned int i = 0; i < bag.in(Tile::Joker()); ++i)
+ {
+ bag.takeTile(Tile::Joker());
+ }
+ }
+
+ // Nothing in the rack, nothing in the bag --> end of the (free)game
+ if (bag.getNbTiles() == 0 && pld.getNbTiles() == 0)
+ {
+ return 1;
+ }
+ // End of game condition
+ if (iCheck)
+ {
+ if (bag.getNbVowels() == 0 || bag.getNbConsonants() == 0 ||
+ bag.getNbTiles() == 1)
+ {
+ return 1;
+ }
+ }
+
+ // Handle reject:
+ // Now that the joker has been dealt with, we try to complete the rack
+ // with truly random tiles. If it meets the requirements (i.e. if there
+ // are at least "min" vowels and "min" consonants in the rack), fine.
+ // Otherwise, we reject the rack completely, and we try again
+ // to complete it, but this time we ensure by construction that the
+ // requirements will be met.
+ while (bag.getNbTiles() != 0 && pld.getNbTiles() < RACK_SIZE)
+ {
+ Tile l = bag.selectRandom();
+ bag.takeTile(l);
+ pld.addNew(l);
+ }
+
+ if (!pld.checkRack(min, min))
+ {
+ // Bad luck... we have to reject the rack
+ vector<Tile> rejectedTiles;
+ pld.getAllTiles(rejectedTiles);
+ for (unsigned int i = 0; i < rejectedTiles.size(); i++)
+ {
+ bag.replaceTile(rejectedTiles[i]);
+ }
+ pld.reset();
+ // Do not mark the rack as rejected if it was empty
+ if (nold > 0)
+ pld.setReject();
+
+ // Restore the joker if we are in a joker game
+ if (jokerAdded)
+ pld.addNew(Tile::Joker());
+
+ // Count the needed consonants and vowels in the rack
+ // (i.e. minimum required, minus what we already have in the rack)
+ unsigned int neededVowels = min;
+ unsigned int neededConsonants = min;
+ for (unsigned int i = 0; i < tiles.size(); ++i)
+ {
+ if (neededVowels > 0 && tiles[i].isVowel())
+ neededVowels--;
+ if (neededConsonants > 0 && tiles[i].isConsonant())
+ neededConsonants--;
+ }
+
+ // Check whether it is possible to complete the rack properly
+ if (bag.getNbVowels() < neededVowels ||
+ bag.getNbConsonants() < neededConsonants)
+ {
+ return 1;
+ }
+
+ // RACK_SIZE - tiles.size() is the number of letters to add to the rack
+ if (neededVowels > RACK_SIZE - tiles.size() ||
+ neededConsonants > RACK_SIZE - tiles.size())
+ {
+ // We cannot fill the rack with enough vowels or consonants!
+ // Actually this should never happen, but it doesn't hurt to
check...
+ // FIXME: this test is not completely right, because it supposes no
+ // letter can be at the same time a vowel and a consonant
+ return 3;
+ }
+
+ // Get the required vowels and consonants first
+ for (unsigned int i = 0; i < neededVowels; ++i)
+ {
+ Tile l = bag.selectRandomVowel();
+ bag.takeTile(l);
+ pld.addNew(l);
+ // Handle the case where the vowel can also be considered
+ // as a consonant
+ if (l.isConsonant() && neededConsonants > 0)
+ neededConsonants--;
+ }
+ for (unsigned int i = 0; i < neededConsonants; ++i)
+ {
+ Tile l = bag.selectRandomConsonant();
+ bag.takeTile(l);
+ pld.addNew(l);
+ }
+
+ // The difficult part is done:
+ // - we have handled joker games
+ // - we have handled the checks
+ // Now complete the rack with truly random letters
+ while (bag.getNbTiles() != 0 && pld.getNbTiles() < RACK_SIZE)
+ {
+ Tile l = bag.selectRandom();
+ bag.takeTile(l);
+ pld.addNew(l);
+ }
+ }
+
+ // Shuffle the new tiles, to hide the order we imposed (joker first in a
+ // joker game, then needed vowels, then needed consonants, and rest of the
+ // rack)
+ pld.shuffleNew();
+
+ // Post-condition check. This should never fail, of course :)
+ ASSERT(pld.checkRack(min, min), "helperSetRackRandom() is buggy!")
+
+ // Until now we didn't modify anything except local variables.
+ // Let's "commit" the changes
+ m_players[p]->setCurrentRack(pld);
+
+ return 0;
+}
+
+
+int Game::helperSetRackRandomOld(unsigned int p, bool iCheck, set_rack_mode
mode)
+{
+ ASSERT(p < getNPlayers(), "Wrong player number");
+
+ // Make a copy of the current player's rack
+ PlayedRack pld = getPlayer(p).getCurrentRack();
+ int nold = pld.getNbOld();
+
+ // Create a copy of the bag in which we can do everything we want,
+ // and take from it the tiles of the players rack so that "bag"
+ // contains the right number of tiles.
+ Bag bag(m_dic);
+ realBag(bag);
+
+ if (mode == RACK_NEW && nold != 0)
+ {
+ // We may have removed too many letters from the bag (i.e. the 'new'
+ // letters of the player)
+ vector<Tile> tiles;
+ pld.getNewTiles(tiles);
+ for (unsigned int i = 0; i < tiles.size(); i++)
+ {
+ bag.replaceTile(tiles[i]);
+ }
+ pld.resetNew();
+ }
+ else if (mode == RACK_NEW && nold == 0 || mode == RACK_ALL)
+ {
+ // Replace all the tiles in the bag before choosing random ones
+ vector<Tile> tiles;
+ pld.getAllTiles(tiles);
+ for (unsigned int i = 0; i < tiles.size(); i++)
+ {
+ bag.replaceTile(tiles[i]);
+ }
+ // RACK_NEW with an empty rack is equivalent to RACK_ALL
+ pld.reset();
+ // Do not forget to update nold, for the RACK_ALL case
+ nold = 0;
+ }
+ else
+ {
+ debug("Game::helperSetRackRandomOld not a random mode\n");
+ }
+
// Nothing in the rack, nothing in the bag --> end of the game
- if (bag.nTiles() == 0 && pld.nTiles() == 0)
+ if (bag.getNbTiles() == 0 && pld.getNbTiles() == 0)
{
return 1;
}
@@ -297,17 +515,17 @@
// them from the 16th turn.
// So before trying to fill the rack, we'd better make sure there is a way
// to complete the rack with these constraints...
- min = 0;
+ unsigned int min = 0;
if (iCheck)
{
- int oldc, oldv;
+ unsigned int oldc, oldv;
- if (bag.nVowels() == 0 || bag.nConsonants() == 0)
+ if (bag.getNbVowels() == 0 || bag.getNbConsonants() == 0)
{
return 1;
}
// 2 vowels and 2 consonants are needed up to the 15th turn
- if (bag.nVowels() > 1 && bag.nConsonants() > 1
+ if (bag.getNbVowels() > 1 && bag.getNbConsonants() > 1
&& m_history.getSize() < 15)
min = 2;
else
@@ -360,7 +578,9 @@
// 3) Complete the rack normally... but without any joker!
Tile l;
- while (bag.nTiles() != 0 && pld.nTiles() != RACK_SIZE)
+ // FIXME: this can be an infinite loop if the only tile left in the
+ // bag is a joker!
+ while (bag.getNbTiles() != 0 && pld.getNbTiles() != RACK_SIZE)
{
l = bag.selectRandom();
if (!l.isJoker())
@@ -374,7 +594,7 @@
{
// Get new tiles from the bag
Tile l;
- while (bag.nTiles() != 0 && pld.nTiles() != RACK_SIZE)
+ while (bag.getNbTiles() != 0 && pld.getNbTiles() != RACK_SIZE)
{
l = bag.selectRandom();
bag.takeTile(l);
@@ -382,7 +602,7 @@
}
}
- if (iCheck && !pld.checkRack(min,min))
+ if (iCheck && !pld.checkRack(min, min))
return 2;
m_players[p]->setCurrentRack(pld);
@@ -391,20 +611,10 @@
}
-/**
- * Check if the players rack can be obtained from the bag.
- * Since letters are removed from the bag only when the
- * round is played we need to check that ALL the racks
- * are in the bag simultaneously.
- *
- * FIXME: since we do not check for all racks it works
- * for training and duplicate but it won't work for
- * freegames.
- */
bool Game::rackInBag(const Rack &iRack, const Bag &iBag) const
{
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = m_dic.getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
if (iRack.in(*it) > iBag.in(*it))
@@ -413,20 +623,16 @@
return true;
}
-/**
- * Set the rack of the player p manually.
- */
-int Game::helperSetRackManual(int p, bool iCheck, const wstring &iLetters)
+
+int Game::helperSetRackManual(unsigned int p, bool iCheck, const wstring
&iLetters)
{
- int min, ret;
+ ASSERT(p < getNPlayers(), "Wrong player number");
- PlayedRack pld = getPlayer(p).getCurrentRack();
- pld.reset();
+ if (!m_dic.validateLetters(iLetters, L"+"))
+ return 3;
- if ((ret = pld.setManual(iLetters)) > 0)
- {
- return 1; /* add new tests */
- }
+ PlayedRack pld;
+ pld.setManual(iLetters);
Rack rack;
pld.getRack(rack);
@@ -438,12 +644,13 @@
if (iCheck)
{
- if (m_bag.nVowels() > 1 && m_bag.nConsonants() > 1
+ int min;
+ if (m_bag.getNbVowels() > 1 && m_bag.getNbConsonants() > 1
&& m_history.getSize() < 15)
min = 2;
else
min = 1;
- if (!pld.checkRack(min,min))
+ if (!pld.checkRack(min, min))
return 2;
}
@@ -456,10 +663,10 @@
*********************************************************/
-int Game::getNHumanPlayers() const
+unsigned int Game::getNHumanPlayers() const
{
- int count = 0;
- for (int i = 0; i < getNPlayers(); i++)
+ unsigned int count = 0;
+ for (unsigned int i = 0; i < getNPlayers(); i++)
count += (getPlayer(i).isHuman() ? 1 : 0);
return count;
}
@@ -474,7 +681,8 @@
void Game::addAIPlayer()
{
- m_players.push_back(new AIPercent(getNPlayers(), 0));
+ // TODO: allow other percentages, and even other types of AI
+ m_players.push_back(new AIPercent(getNPlayers(), 1));
}
@@ -500,34 +708,15 @@
}
-/*
- * This function checks whether it is legal to play the given word at the
- * given coordinates. If so, the function fills a Round object, also given as
- * a parameter.
- * Possible return values:
- * 0: correct word, the Round can be used by the caller
- * 1: no dictionary set
- * 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, or word going out of the board
- * 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
- */
int Game::checkPlayedWord(const wstring &iCoord,
const wstring &iWord, Round &oRound)
{
ASSERT(getNPlayers() != 0, "Expected at least one player");
- int res;
- vector<Tile> tiles;
- Tile t;
+ if (!m_dic.validateLetters(iWord))
+ return 1;
- /* Init the round with the given coordinates */
+ // Init the round with the given coordinates
oRound.init();
oRound.accessCoord().setFromString(iCoord);
if (!oRound.getCoord().isValid())
@@ -536,16 +725,17 @@
return 2;
}
- /* Check the existence of the word */
- if (Dic_search_word(*m_dic, iWord.c_str()) == 0)
+ // Check the existence of the word
+ if (!m_dic.searchWord(iWord))
{
return 3;
}
- /* Set the word */
+ // Set the word
// TODO: make this a Round_ function (Round_setwordfromchar for example)
// or a Tiles_ function (to transform a char* into a vector<Tile>)
// Adding a getter on the word could help too...
+ vector<Tile> tiles;
for (unsigned int i = 0; i < iWord.size(); i++)
{
tiles.push_back(Tile(iWord[i]));
@@ -557,20 +747,21 @@
oRound.setJoker(i);
}
- /* Check the word position, compute its points,
- * and specify the origin of each letter (board or rack) */
- res = m_board.checkRound(oRound, m_history.getSize() == 0);
+ // Check the word position, compute its points,
+ // and specify the origin of each letter (board or rack)
+ int res = m_board.checkRound(oRound, m_history.getSize() == 0);
if (res != 0)
return res + 4;
- /* Check that the word can be formed with the tiles in the rack:
- * we first create a copy of the rack, then we remove the tiles
- * one by one */
+ // Check that the word can be formed with the tiles in the rack:
+ // we first create a copy of the rack, then we remove the tiles
+ // one by one
Rack rack;
Player *player = m_players[m_currPlayer];
player->getCurrentRack().getRack(rack);
- for (int i = 0; i < oRound.getWordLen(); i++)
+ Tile t;
+ for (unsigned int i = 0; i < oRound.getWordLen(); i++)
{
if (oRound.isPlayedFromRack(i))
{
Index: game/game.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- game/game.h 4 Aug 2007 20:01:28 -0000 1.31
+++ game/game.h 8 Jan 2008 13:52:38 -0000 1.32
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -28,12 +29,12 @@
#include "board.h"
#include "history.h"
+class Dictionary;
class Player;
class PlayedRack;
class Round;
class Rack;
class Turn;
-typedef struct _Dictionary * Dictionary;
using namespace std;
@@ -47,13 +48,17 @@
{
public:
/// Game specs.
- static const int RACK_SIZE;
+ static const unsigned int RACK_SIZE;
static const int BONUS_POINTS;
Game(const Dictionary &iDic);
virtual ~Game();
+ /***************
+ * Game type
+ ***************/
+
/// Game mode: each one of these modes is implemented in an inherited class
enum GameMode
{
@@ -79,100 +84,118 @@
void setVariant(GameVariant iVariant) { m_variant = iVariant; }
GameVariant getVariant() const { return m_variant; }
+ /***************
+ * Various getters
+ ***************/
+
/**
- * Dictionary associated with the game.
- * The dictionary can be changed during a game without problem
+ * 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 { return *m_dic; }
- void setDic(const Dictionary &iDic) { m_dic = &iDic; }
+ const Dictionary & getDic() const { return m_dic; }
+ /// Get the board
const Board& getBoard() const { return m_board; }
+ /// Get the bag
const Bag& getBag() const { return m_bag; }
- const Player& getPlayer(int iNum) const;
- const Turn& getTurn(int iNum) const;
+ /// Get the history of the game */
+ const History& getHistory() const { return m_history; }
+
+ /***************
+ * Methods to access players.
+ ***************/
+
+ const Player& getPlayer(unsigned int iNum) const;
const Player& getCurrentPlayer() const { return getPlayer(currPlayer()); };
+ unsigned int getNPlayers() const { return m_players.size(); }
+ unsigned int getNHumanPlayers() const;
+ virtual void addHumanPlayer();
+ // TODO: Ability to specify which kind of AI player is wanted
+ virtual void addAIPlayer();
+ unsigned int currPlayer() const { return m_currPlayer; }
+
+ /***************
+ * Game handling
+ ***************/
+
+ /**
+ * Start the game.
+ * AI players are handled automatically, so if the game only has AI
+ * players, it will play until the end.
+ */
+ virtual int start() = 0;
/**
- * Eliot file formats
+ * 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, or word going out of the board
+ * 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
*/
- typedef enum {
+ virtual int play(const wstring &iCoord, const wstring &iWord) = 0;
+
+ /**
+ * Go back to turn iTurn.
+ * We must have: iTurn < getHistory().getSize()
+ * Possible return values:
+ * 0: everything went fine
+ * 1: iTurn is invalid
+ */
+ int back(unsigned int iTurn);
+
+ /***************
+ * Saved games handling
+ ***************/
+
+ /**
+ * Possible formats for the saved games
+ */
+ enum game_file_format
+ {
FILE_FORMAT_STANDARD,
FILE_FORMAT_ADVANCED
- } game_file_format;
+ };
/**
- * Saved games handling.
- *
* load() returns the loaded game, or NULL if there was a problem
- * load() might need some more work to be robust enough to
+ * load() does need some more work to be robust enough to
* handle "hand written" files
*/
static Game * load(FILE *fin, const Dictionary &iDic);
/**
- * Save a game to a File
+ * Save a game to a file
* Standard format is used for training games so that it is compatible
* with previous versions of Eliot.
*
* Saving can be forced to advanced format for training games by
* setting the last parameter to FILE_FORMAT_ADVANCED
*/
- void save(ostream &out, game_file_format format=FILE_FORMAT_STANDARD)
const;
-
- /*************************
- * Playing the game
- * the int parameter should be 0 <= int < getNTurns
- *************************/
- int back(int);
-
- /*************************
- * Set the rack for searching
- *
- * The int parameter is a boolean, if this parameter
- * set the rack will check that there are at least
- * 2 vowels and 2 consonants before the round 15.
- *
- * The setrackmanual parameter string has to contain
- * 'a' <= char <= 'z' or 'A' <= char <= 'Z' or '?'
- *
- * return value
- * 0 : the rack has been set
- * 1 : the bag does not contain enough tiles
- * 2 : the rack check was set on and failed
- * 3 : the rack cannot be completed (Game_*_setrackrandom only)
- *************************/
- enum set_rack_mode {RACK_ALL, RACK_NEW, RACK_MANUAL};
- int setRack(int player, set_rack_mode mode, bool check, const wstring&
str);
+ void save(ostream &out, game_file_format format = FILE_FORMAT_STANDARD)
const;
- /**
- * Methods to access already played words.
- * The int parameter should be 0 <= int < getNTurns()
- */
- const History& getHistory() const { return m_history; }
+ /***************
+ * Setting the rack
+ ***************/
- /**
- * Methods to access players.
- * The int parameter should be 0 <= int < getNPlayers()
- */
- int getNPlayers() const { return m_players.size(); }
- int getNHumanPlayers() const;
- virtual void addHumanPlayer();
- // TODO: Ability to specify which kind of AI player is wanted
- virtual void addAIPlayer();
- int currPlayer() const { return m_currPlayer; }
+ enum set_rack_mode {RACK_ALL, RACK_NEW, RACK_MANUAL};
- /**
- * Game handling
- */
- virtual int start() = 0;
- virtual int play(const wstring &iCoord, const wstring &iWord) = 0;
- virtual int endTurn() = 0;
protected:
/// All the players, indexed by their ID
vector<Player*> m_players;
/// ID of the "current" player
- int m_currPlayer;
+ unsigned int m_currPlayer;
// TODO: check what should be private and what should be protected
// private:
@@ -181,7 +204,7 @@
GameVariant m_variant;
/// Dictionary currently associated to the game
- const Dictionary * m_dic;
+ const Dictionary & m_dic;
/// Bag
Bag m_bag;
@@ -203,14 +226,91 @@
* Helper functions
*********************************************************/
- int helperPlayRound(const Round &iRound);
- int helperSetRackRandom(int p, bool iCheck, set_rack_mode mode);
- int helperSetRackManual(int p, bool iCheck, const wstring &iLetters);
+ /** Play a Move for the given player, updating game history */
+ void helperPlayMove(unsigned int iPlayerId, const Move &iMove);
+
+ /**
+ * Set the rack randomly for the player p
+ * Possible return values:
+ * 0: everything went fine
+ * 1: the game is over
+ * 3: there is no chance to set the rack with the vowels/consonants
+ * constraints
+ *
+ * Completing a rack randomly is more complex than it seems, because we
+ * must take into account several constraints:
+ * - if iCheck is true, we must ensure that the rack contains a minimum
+ * number of vowels and consonants (2 of each in the 15 first moves of
+ * the game, 1 of each after)
+ * - the game is over if the (real) bag contains only vowels or only
+ * consonants, and in particular if it contains only one letter
+ * - some letters (in particular the joker) can count both as a vowel and
+ * as a consonant (but not at the same time)
+ * - in a joker game, the joker must be present in the rack unless there
+ * is no joker left in the bag. In addition, we must prevent that both
+ * jokers are present in the rack at the same time
+ * - if completing a rack doesn't meet the requirements on the vowels and
+ * consonants, we must reject the rack completely (but only once,
+ * otherwise we have no guarantee that the rejects will stop
eventually).
+ * This also means we have to check whether completing the rack with the
+ * requirements is possible...
+ */
+ int helperSetRackRandom(unsigned int p, bool iCheck, set_rack_mode mode);
+
+ /**
+ * Set the rack randomly for the player p
+ * Possible return values:
+ * 0: everything went fine
+ * 1: the game is over
+ * 2: the rack was checked and was not correct (try calling the
+ * function again)
+ * 3: there is no chance to set the rack with the vowels/consonants
+ * constraints
+ *
+ * @deprecated: use helperSetRackRandom instead
+ */
+ int helperSetRackRandomOld(unsigned int p, bool iCheck, set_rack_mode
mode);
+
+ /**
+ * Set the rack for the player p with the given letters
+ * Possible return values:
+ * 0: everything went fine
+ * 1: the bag doesn't have the wanted letters
+ * 2: the rack was checked for vowels/consonants and was not correct
+ */
+ int helperSetRackManual(unsigned int p, bool iCheck, const wstring
&iLetters);
void prevPlayer();
void nextPlayer();
+
+ /**
+ * Check if the players rack can be obtained from the bag.
+ * Since letters are removed from the bag only when the
+ * round is played we need to check that ALL the racks
+ * are in the bag simultaneously.
+ *
+ * FIXME: since we do not check for all racks it works
+ * for training and duplicate but it won't work for
+ * freegames.
+ */
bool rackInBag(const Rack &iRack, const Bag &iBag) const;
+
+ /**
+ * The realBag is the current bag minus all the racks
+ * present in the game. It represents the actual
+ * letters that are left in the bag.
+ * FIXME: in Duplicate mode, this method uses m_currPlayer to find the
+ * rack of the player. Since not all the players played the same word,
+ * it is important to set m_currPlayer accurately before!
+ */
void realBag(Bag &iBag) const;
+
+ /**
+ * This function checks whether it is legal to play the given word at the
+ * given coordinates. If so, the function fills a Round object, also given
+ * as a parameter.
+ * Possible return values: same as the play() method
+ */
int checkPlayedWord(const wstring &iCoord,
const wstring &iWord, Round &oRound);
@@ -236,6 +336,14 @@
*/
void gameSaveFormat_15(ostream &out) const;
+private:
+
+ /**
+ * Play a round on the board.
+ * This should only be called by helperPlayMove().
+ */
+ void helperPlayRound(unsigned int iPlayerId, const Round &iRound);
+
};
#endif /* _GAME_H_ */
Index: game/game_factory.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game_factory.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- game/game_factory.cpp 11 Aug 2006 22:14:21 -0000 1.8
+++ game/game_factory.cpp 8 Jan 2008 13:52:38 -0000 1.9
@@ -1,6 +1,8 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière & Antoine Fraboulet
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ * Antoine Fraboulet <antoine.fraboulet @@ free.fr>
*
* 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
@@ -17,12 +19,19 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
+#include "config.h"
+
#include <getopt.h>
#include <string>
+#include <fstream>
+#include <exception>
-#include "config.h"
-#include "dic.h"
#include "game_factory.h"
+#include "game.h"
+#include "training.h"
+#include "freegame.h"
+#include "duplicate.h"
+#include "dic.h"
GameFactory *GameFactory::m_factory = NULL;
@@ -35,8 +44,7 @@
GameFactory::~GameFactory()
{
- if (m_dic)
- Dic_destroy(m_dic);
+ delete m_dic;
}
@@ -50,7 +58,6 @@
void GameFactory::Destroy()
{
- if (m_factory)
delete m_factory;
m_factory = NULL;
}
@@ -139,16 +146,20 @@
cerr << "dict";
else if (!found_m)
cerr << "mode";
- cerr << "\n";
+ cerr << endl;
printUsage(argv[0]);
return NULL;
}
// 3) Try to load the dictionary
- if (Dic_load(&m_dic, m_dicStr.c_str()))
+ try
{
- cerr << "Could not load dictionary '" << m_dicStr << "'\n";
+ m_dic = new Dictionary(m_dicStr);
+ }
+ catch (std::exception &e)
+ {
+ cerr << e.what() << endl;
return NULL;
}
@@ -156,19 +167,19 @@
Game *game = NULL;
if (m_modeStr == "training" || m_modeStr == "t")
{
- game = createTraining(m_dic);
+ game = createTraining(*m_dic);
}
else if (m_modeStr == "freegame" || m_modeStr == "f")
{
- game = createFreeGame(m_dic);
+ game = createFreeGame(*m_dic);
}
else if (m_modeStr == "duplicate" || m_modeStr == "d")
{
- game = createDuplicate(m_dic);
+ game = createDuplicate(*m_dic);
}
else
{
- cerr << "Invalid game mode '" << m_modeStr << "'\n";
+ cerr << "Invalid game mode '" << m_modeStr << "'" << endl;
return NULL;
}
@@ -185,21 +196,21 @@
return game;
}
-Game* GameFactory::load(string filename, const Dictionary &iDic)
+
+Game* GameFactory::load(const string &iFileName, const Dictionary &iDic)
{
- Game* game;
- FILE* fin;
- if ((fin = fopen(filename.c_str(), "r")) == NULL)
+ FILE* fin = fopen(iFileName.c_str(), "r");
+ if (fin == NULL)
{
- printf("impossible d'ouvrir %s\n",
- filename.c_str());
+ printf("Cannot open %s\n", iFileName.c_str());
return NULL;
}
- game = Game::load(fin,iDic);
+ Game *game = Game::load(fin, iDic);
fclose(fin);
return game;
}
+
void GameFactory::releaseGame(Game &iGame)
{
delete &iGame;
@@ -208,25 +219,26 @@
void GameFactory::printUsage(const string &iBinaryName) const
{
- cout << "Usage: " << iBinaryName << " [options]\n"
- << "Options:\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 (mandatory)\n"
- << " -d, --dict <string> Choose a dictionary (mandatory)\n"
- << " --human Add a human player\n"
- << " --ai Add a AI (Artificial Intelligence)
player\n"
- << " --joker Play with the \"Joker game\"
variant\n";
+ cout << "Usage: " << iBinaryName << " [options]" << endl
+ << "Options:" << endl
+ << " -h, --help Print this help and exit" << endl
+ << " -v, --version Print version information and exit" <<
endl
+ << " -m, --mode {duplicate,d,freegame,f,training,t}" << endl
+ << " Choose game mode (mandatory)" << endl
+ << " -d, --dict <string> Choose a dictionary (mandatory)" <<
endl
+ << " --human Add a human player" << endl
+ << " --ai Add a AI (Artificial Intelligence)
player" << endl
+ << " --joker Play with the \"Joker game\" variant"
<< endl;
}
void GameFactory::printVersion() const
{
- cout << PACKAGE_STRING << "\n"
+ cout << PACKAGE_STRING << endl
<< "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";
+ << "law." << endl << "You may redistribute it under the terms of the "
+ << "GNU General Public License;" << endl
+ << "see the file named COPYING for details." << endl;
}
Index: game/game_factory.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game_factory.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- game/game_factory.h 11 Aug 2006 22:14:21 -0000 1.8
+++ game/game_factory.h 8 Jan 2008 13:52:38 -0000 1.9
@@ -1,6 +1,7 @@
/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -20,10 +21,15 @@
#ifndef _GAME_FACTORY_H_
#define _GAME_FACTORY_H_
-#include "game.h"
-#include "training.h"
-#include "freegame.h"
-#include "duplicate.h"
+#include <string>
+
+using std::string;
+
+class Dictionary;
+class Game;
+class Training;
+class FreeGame;
+class Duplicate;
/**
@@ -52,7 +58,7 @@
* load() might need some more work to be robust enough to
* handle "hand written" files
*/
- Game *load(string filename, const Dictionary &iDic);
+ Game *load(const string &iFileName, const Dictionary &iDic);
Game *createFromCmdLine(int argc, char **argv);
@@ -62,13 +68,13 @@
private:
GameFactory();
- virtual ~GameFactory();
+ ~GameFactory();
/// The unique instance of the class
static GameFactory *m_factory;
/// Initial dictionary (it could be changed later)
- Dictionary m_dic;
+ Dictionary *m_dic;
/** Parameters specified on the command-line */
//@{
Index: game/game_io.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game_io.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- game/game_io.cpp 23 Dec 2006 16:48:15 -0000 1.5
+++ game/game_io.cpp 8 Jan 2008 13:52:38 -0000 1.6
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -25,12 +26,16 @@
* \date 2002 - 2005
*/
+#include "dic.h"
#include "pldrack.h"
#include "round.h"
#include "turn.h"
#include "player.h"
#include "game.h"
#include "game_factory.h"
+#include "training.h"
+#include "freegame.h"
+#include "duplicate.h"
#include "encoding.h"
#include "debug.h"
@@ -192,14 +197,7 @@
Game *pGame = NULL;
char buff[4096];
- int num;
- char rack[20];
- char word[20];
- char ref[4];
- int pts;
- int player;
char *pos;
- Tile tile;
/*************/
/* Game type */
@@ -322,9 +320,15 @@
}
+ int num;
+ char rack[20];
+ char tmpWord[20];
+ char ref[4];
+ int pts;
+ unsigned int player;
char bonus = 0;
int res = sscanf(buff, " %2d | %8s | %s | %3s | %3d | %1d | %c",
- &num, rack, word, ref, &pts, &player, &bonus);
+ &num, rack, tmpWord, ref, &pts, &player, &bonus);
debug(" -- line %s",buff);
@@ -335,7 +339,7 @@
}
debug(" %2d | %8s | %s | %3s | %3d | %1d | %c \n",
- num, rack, word, ref, pts, player, bonus);
+ num, rack, tmpWord, ref, pts, player, bonus);
// Integrity checks
// TODO: add more checks
@@ -344,7 +348,7 @@
debug(" Game::load15 line -%s- points < 0 ?\n",buff);
continue;
}
- if (player < 0 || player > pGame->getNPlayers())
+ if (player > pGame->getNPlayers())
{
debug(" Game::load15 line -%s- too much player
(%d>%d)",buff,player,pGame->getNPlayers());
continue;
@@ -357,10 +361,11 @@
// Build a rack for the correct player
PlayedRack pldrack;
- if ((res = pldrack.setManual(convertToWc(rack))) > 0)
+ if (!iDic.validateLetters(convertToWc(rack)))
{
- debug(" Game::load15 set rack manual returned with error
%d\n",res);
+ debug(" Game::load15 rack invalid for the current dictionary\n");
}
+ pldrack.setManual(convertToWc(rack));
debug(" history rack %s\n",
convertToMb(pldrack.toString()).c_str());
// Build a round
@@ -369,6 +374,8 @@
if (bonus == '*')
round.setBonus(1);
+ wstring word = convertToWc(tmpWord);
+ Tile tile;
if (isalpha(ref[0]))
{
// Horizontal word
@@ -376,7 +383,7 @@
round.accessCoord().setRow(ref[0] - 'A' + 1);
round.accessCoord().setCol(atoi(ref + 1));
- for (unsigned int i = 0; i < strlen(word); i++)
+ for (unsigned int i = 0; i < word.size(); i++)
{
tile = Tile(word[i]);
@@ -386,8 +393,8 @@
}
else
{
- round.addRightFromRack(tile, islower(word[i]));
- pGame->m_bag.takeTile((islower(word[i])) ? Tile::Joker() :
tile);
+ round.addRightFromRack(tile, iswlower(word[i]));
+ pGame->m_bag.takeTile((iswlower(word[i])) ? Tile::Joker()
: tile);
}
}
}
@@ -398,7 +405,7 @@
round.accessCoord().setRow(ref[strlen(ref) - 1] - 'A' + 1);
round.accessCoord().setCol(atoi(ref));
- for (unsigned int i = 0; i < strlen(word); i++)
+ for (unsigned int i = 0; i < word.size(); i++)
{
tile = Tile(word[i]);
@@ -408,20 +415,20 @@
}
else
{
- round.addRightFromRack(tile, islower(word[i]));
- pGame->m_bag.takeTile((islower(word[i])) ? Tile::Joker() :
tile);
+ round.addRightFromRack(tile, iswlower(word[i]));
+ pGame->m_bag.takeTile((iswlower(word[i])) ? Tile::Joker()
: tile);
}
}
}
- // pGame->m_currPlayer = player;
- // // Update the rack for the player
- // pGame->m_players[player]->setCurrentRack(pldrack);
- // // End the turn for the current player (this creates a
new rack)
- // pGame->m_players[player]->endTurn(round,num - 1);
+// pGame->m_currPlayer = player;
+// // Update the rack for the player
+// pGame->m_players[player]->setCurrentRack(pldrack);
+// // End the turn for the current player (this creates a
new rack)
+// pGame->m_players[player]->endTurn(round,num - 1);
// Play the round
- pGame->helperPlayRound(round);
+ pGame->helperPlayRound(pGame->m_currPlayer, round);
}
/**************************************/
@@ -452,7 +459,7 @@
{
// We don't really know whose turn it is, but at least we know that
// the game was saved while a human was to play.
- for (int i = 0; i < pGame->getNPlayers(); i++)
+ for (unsigned int i = 0; i < pGame->getNPlayers(); i++)
{
if (pGame->m_players[i]->isHuman())
{
@@ -490,21 +497,21 @@
const string decal = " ";
out << IDENT_STRING << endl << endl;
- for (int i = 0; i < m_history.getSize(); i++)
+ for (unsigned int i = 0; i < m_history.getSize(); i++)
{
const Turn& turn = m_history.getTurn(i);
- string rack =
convertToMb(turn.getPlayedRack().toString(PlayedRack::RACK_EXTRA));
- string word = convertToMb(turn.getRound().getWord());
- string coord =
convertToMb(turn.getRound().getCoord().toString(Coord::COORD_MODE_LONG));
+ wstring rack = turn.getPlayedRack().toString(PlayedRack::RACK_EXTRA);
+ // FIXME: this will not work if the move does not correspond to a
played round!
+ const Round &round = turn.getMove().getRound();
+ wstring word = round.getWord();
+ string coord =
convertToMb(round.getCoord().toString(Coord::COORD_MODE_LONG));
// rack [space] word [space] bonus points coord
- sprintf(line,"%s%s%s%s%c%4d %s",
- rack.c_str(),
- string(12 - rack.size(), ' ').c_str(),
- word.c_str(),
- string(16 - word.size(), ' ').c_str(),
- turn.getRound().getBonus() ? '*' : ' ',
- turn.getRound().getPoints(),
+ sprintf(line,"%s%s%c%4d %s",
+ padAndConvert(rack, 12, false).c_str(),
+ padAndConvert(word, 16, false).c_str(),
+ round.getBonus() ? '*' : ' ',
+ round.getPoints(),
coord.c_str()
);
@@ -513,7 +520,7 @@
out << endl;
out << decal << "total" << string(24,' ');
- sprintf(line,"%4d", getCurrentPlayer().getPoints());
+ sprintf(line, "%4d", getCurrentPlayer().getPoints());
out << line << endl;
}
@@ -526,7 +533,7 @@
// Game type
out << "Game type: " << getModeAsString() << endl;
// Player list
- for (int i = 0; i < getNPlayers(); i++)
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
out << "Player " << i << ": ";
if (m_players[i]->isHuman())
@@ -542,21 +549,69 @@
out << decal << "===|==========|=================|=====|=====|===|======"
<< endl;
// Print the game itself
- for (int i = 0; i < m_history.getSize(); i++)
+ for (unsigned int i = 0; i < m_history.getSize(); i++)
{
const Turn& turn = m_history.getTurn(i);
- string rack =
convertToMb(turn.getPlayedRack().toString(PlayedRack::RACK_EXTRA));
- string word = convertToMb(turn.getRound().getWord());
- string coord = convertToMb(turn.getRound().getCoord().toString());
- sprintf(line, "%2d | %8s | %s%s | %3s | %3d | %1d | %c",
+ wstring rack = turn.getPlayedRack().toString(PlayedRack::RACK_EXTRA);
+ const Move &move = turn.getMove();
+ switch (move.getType())
+ {
+ case Move::VALID_ROUND:
+ {
+ const Round &round = move.getRound();
+ wstring word = round.getWord();
+ string coord = convertToMb(round.getCoord().toString());
+ sprintf(line, "%2d | %s | %s | %3s | %3d | %1d | %c",
i + 1,
- rack.c_str(), /* pldrack */
- word.c_str(), /* word */
- string(15 - word.size(), ' ').c_str(), /* fill spaces */
+ padAndConvert(rack, 8).c_str(), /* pldrack
*/
+ padAndConvert(word, 15, false).c_str(), /* word
*/
coord.c_str(), /* coord */
- turn.getRound().getPoints(),
+ move.getScore(),
turn.getPlayer(),
- turn.getRound().getBonus() ? '*' : ' ');
+ round.getBonus() ? '*' : ' ');
+ break;
+ }
+ case Move::INVALID_WORD:
+ {
+ wstring word = move.getBadWord();
+ string coord = convertToMb(move.getBadCoord());
+ sprintf(line, "%2d | %s | %s | %3s | %3d | %1d |",
+ i + 1,
+ padAndConvert(rack, 8).c_str(), /* pldrack
*/
+ padAndConvert(word, 15, false).c_str(), /* word
*/
+ coord.c_str(), /* coord
*/
+ move.getScore(),
+ turn.getPlayer());
+ break;
+ }
+ case Move::PASS:
+ {
+ string action = "(PASS)";
+ string coord = " - ";
+ sprintf(line, "%2d | %s | %s | %3s | %3d | %1d |",
+ i + 1,
+ padAndConvert(rack, 8).c_str(), /* pldrack
*/
+ truncOrPad(action, 15, ' ').c_str(), /* word
*/
+ coord.c_str(), /* coord
*/
+ move.getScore(),
+ turn.getPlayer());
+ break;
+ }
+ case Move::CHANGE_LETTERS:
+ {
+ wstring action = L"(-" + move.getChangedLetters() + L")";
+ string coord = " - ";
+ sprintf(line, "%2d | %s | %s | %3s | %3d | %1d |",
+ i + 1,
+ padAndConvert(rack, 8).c_str(), /* pldrack
*/
+ padAndConvert(action, 15, false).c_str(), /* word
*/
+ coord.c_str(), /* coord
*/
+ move.getScore(),
+ turn.getPlayer());
+ break;
+ }
+
+ }
out << decal << line << endl;
}
@@ -577,7 +632,7 @@
// Print current rack for all the players
out << endl;
- for (int i = 0; i < getNPlayers(); i++)
+ for (unsigned int i = 0; i < getNPlayers(); i++)
{
wstring rack = m_players[i]->getCurrentRack().toString();
out << "Rack " << i << ": " << convertToMb(rack) << endl;
Index: game/history.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/history.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- game/history.cpp 4 Aug 2007 20:01:28 -0000 1.11
+++ game/history.cpp 8 Jan 2008 13:52:38 -0000 1.12
@@ -1,21 +1,23 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file history.cpp
@@ -27,7 +29,7 @@
#include <string>
#include "rack.h"
#include "pldrack.h"
-#include "round.h"
+#include "move.h"
#include "turn.h"
#include "history.h"
#include "encoding.h"
@@ -41,7 +43,7 @@
History::History()
{
- Turn* t = new Turn ();
+ Turn* t = new Turn();
m_history.clear();
m_history.push_back(t);
}
@@ -51,17 +53,14 @@
{
for (unsigned int i = 0; i < m_history.size(); i++)
{
- if (m_history[i] != NULL)
- {
delete m_history[i];
- m_history[i] = NULL;
- }
}
}
-int History::getSize() const
+unsigned int History::getSize() const
{
+ ASSERT(!m_history.empty(), "Invalid history size");
return m_history.size() - 1;
}
@@ -88,33 +87,40 @@
const Turn& History::getTurn(unsigned int n) const
{
- // ASSERT(0 <= n && n < m_history.size(), "Wrong turn number");
ASSERT(n < m_history.size(), "Wrong turn number");
return *(m_history[n]);
}
-/*
- * This function increments the number of racks, and fills the new rack
- * with the unplayed tiles from the previous one.
- * 03 sept 2000 : We have to sort the tiles according to the new rules
- */
-void History::playRound(int player, int turn, const Round& round)
+
+bool History::beforeFirstRound() const
{
- Rack rack;
- Turn * current_turn;
+ for (unsigned int i = 0; i < m_history.size() - 1; i++)
+ {
+ if (m_history[i]->getMove().getType() == Move::VALID_ROUND)
+ return false;
+ }
+ return true;
+}
+
- current_turn = m_history.back();
+void History::playMove(unsigned int iPlayer, unsigned int iTurn, const Move
&iMove)
+{
+ Turn * current_turn = m_history.back();
- /* set the number and the round */
- current_turn->setNum(turn);
- current_turn->setPlayer(player);
- current_turn->setRound(round);
+ // Set the number and the round
+ current_turn->setNum(iTurn);
+ current_turn->setPlayer(iPlayer);
+ current_turn->setMove(iMove);
- /* get what was the rack for the current turn */
+ // Get what was the rack for the current turn
+ Rack rack;
current_turn->getPlayedRack().getRack(rack);
- /* remove the played tiles from the rack */
- for (int i = 0; i < round.getWordLen(); i++)
+ if (iMove.getType() == Move::VALID_ROUND)
+ {
+ // Remove the played tiles from the rack
+ const Round &round = iMove.getRound();
+ for (unsigned int i = 0; i < round.getWordLen(); i++)
{
if (round.isPlayedFromRack(i))
{
@@ -124,8 +130,18 @@
rack.remove(round.getTile(i));
}
}
+ }
+ else if (iMove.getType() == Move::CHANGE_LETTERS)
+ {
+ // Remove the changed tiles from the rack
+ const wstring & changed = iMove.getChangedLetters();
+ for (unsigned int i = 0; i < changed.size(); ++i)
+ {
+ rack.remove(Tile(changed[i]));
+ }
+ }
- /* create a new turn */
+ // Create a new turn
Turn * next_turn = new Turn();
PlayedRack pldrack;
pldrack.setOld(rack);
@@ -146,11 +162,11 @@
delete t;
}
- // now we have the previous played round in back()
- Turn* t = m_history.back();
+ // Now we have the previous played round in back()
+ Turn *t = m_history.back();
t->setNum(0);
t->setPlayer(0);
- t->setRound(Round());
+ //t->setRound(Round());
#ifdef BACK_REMOVE_RACK_NEW_PART
t->getPlayedRound().setNew(Rack());
#endif
Index: game/history.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/history.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- game/history.h 22 Jan 2006 12:23:53 -0000 1.11
+++ game/history.h 8 Jan 2008 13:52:38 -0000 1.12
@@ -1,21 +1,23 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file history.h
@@ -33,7 +35,7 @@
using std::wstring;
using std::vector;
-class Round;
+class Move;
class Turn;
class PlayedRack;
@@ -41,15 +43,12 @@
* History stores all the turns that have been played
* This class is used many times in the game
* - one for the complete game
- * - one for each of the players
- *
- * A History is never void (getSize() can be used as the is the current turn
- * number for the complete game history).
- *
- * History starts at zero.
+ * - one for each player
*
- * The top of the history is an empty
- * Turn until it has been filled and game is up to a new round.
+ * The top of the history is an empty Turn until it has been filled
+ * and the game is up to a new turn. So a History object is never empty.
+ * However, the getSize() method only returns the number of complete
+ * turns, and can therefore return 0.
*
* getCurrentRack() can/should be used to store the current played rack.
* setCurrentRack must be called whenever the current played rack is
@@ -58,15 +57,14 @@
* History owns the turns that it stores. Do not delete a turn referenced
* by History
*/
-
class History
{
public:
History();
- virtual ~History();
+ ~History();
- /// get the size of the history
- int getSize() const;
+ /// Get the size of the history (without the current incomplete turn)
+ unsigned int getSize() const;
/// Get the (possibly incomplete) rack
const PlayedRack& getCurrentRack() const;
@@ -74,15 +72,26 @@
/// Set the current rack
void setCurrentRack(const PlayedRack &iPld);
- /// Get the previous turn
+ /// Get the previous (complete) turn
const Turn& getPreviousTurn() const;
- /// Get turn 'n'
+ /// Get turn 'n' (starting at 0)
const Turn& getTurn(unsigned int) const;
- /// Update the "history" with the given round and complete the turn.
- /// A new turn is created with the remaining letters in the rack
- void playRound(int player, int turn, const Round& round);
+ /**
+ * Return true if the history doesn't contain at least one move
+ * corresponding to a valid round, false otherwise.
+ * Said differently, this method checks whether a word was already played
+ * on the board.
+ */
+ bool beforeFirstRound() const;
+
+ /**
+ * Update the history with the given move and complete the turn.
+ * A new turn is created with the unplayed letters in the rack
+ * 03 sept 2000: We have to sort the tiles according to the new rules
+ */
+ void playMove(unsigned int player, unsigned int turn, const Move &iMove);
/// Remove last turn
void removeLastTurn();
Index: game/player.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/player.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- game/player.cpp 22 Jan 2006 12:23:53 -0000 1.14
+++ game/player.cpp 8 Jan 2008 13:52:39 -0000 1.15
@@ -1,6 +1,8 @@
/*****************************************************************************
- * Copyright (C) 2004-2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2004-2007 Olivier Teulière & Antoine Fraboulet
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ * Antoine Fraboulet <antoine.fraboulet @@ free.fr>
*
* 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,14 +33,8 @@
#include "debug.h"
-Player::Player(int iId)
-{
- m_id = iId;
- m_score = 0;
-}
-
-
-Player::~Player()
+Player::Player(unsigned int iId)
+ : m_id(iId), m_score(0)
{
}
@@ -61,19 +57,22 @@
}
-const Round & Player::getLastRound() const
+const Move & Player::getLastMove() const
{
- return m_history.getPreviousTurn().getRound();
+ return m_history.getPreviousTurn().getMove();
}
-void Player::endTurn(const Round &iRound, int iTurn)
+void Player::endTurn(const Move &iMove, unsigned int iTurn)
{
- m_history.playRound(m_id,iTurn,iRound);
+ addPoints(iMove.getScore());
+ m_history.playMove(m_id, iTurn, iMove);
}
void Player::removeLastTurn()
{
+ // Remove points of the last turn
+ addPoints(- m_history.getPreviousTurn().getMove().getScore());
m_history.removeLastTurn();
}
Index: game/player.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/player.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- game/player.h 22 Jan 2006 12:23:53 -0000 1.18
+++ game/player.h 8 Jan 2008 13:52:39 -0000 1.19
@@ -1,6 +1,8 @@
/*****************************************************************************
- * Copyright (C) 2004-2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2004-2007 Olivier Teulière & Antoine Fraboulet
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ * Antoine Fraboulet <antoine.fraboulet @@ free.fr>
*
* 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
@@ -35,8 +37,8 @@
class Player
{
public:
- Player(int iId);
- virtual ~Player();
+ explicit Player(unsigned int iId);
+ virtual ~Player() {}
// Pseudo RTTI
virtual bool isHuman() const = 0;
@@ -48,8 +50,8 @@
const PlayedRack & getCurrentRack() const;
// Get the previous rack
const PlayedRack & getLastRack() const;
- // Get the previous round (corresponding to the previous rack...)
- const Round & getLastRound() const;
+ /// Get the previous move (corresponding to the previous rack...)
+ const Move & getLastMove() const;
void setCurrentRack(const PlayedRack &iPld);
@@ -65,15 +67,19 @@
void addPoints(int iPoints) { m_score += iPoints; }
int getPoints() const { return m_score; }
- // Update the player "history", with the given round.
- // A new rack is created with the remaining letters
- void endTurn(const Round &iRound, int iTurn);
+ /**
+ * Update the player "history", with the given move.
+ * A new rack is created with the remaining letters.
+ * The score of the player is updated with the one of the move, if it is
+ * meaningful.
+ */
+ void endTurn(const Move &iMove, unsigned int iTurn);
wstring toString() const;
private:
/// ID of the player
- int m_id;
+ unsigned int m_id;
/// Score of the player
int m_score;
@@ -89,8 +95,6 @@
class HumanPlayer: public Player
{
public:
- string name;
-
HumanPlayer(int iId): Player(iId) {}
virtual ~HumanPlayer() {}
Index: game/pldrack.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/pldrack.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- game/pldrack.cpp 22 Jan 2006 12:23:53 -0000 1.9
+++ game/pldrack.cpp 8 Jan 2008 13:52:39 -0000 1.10
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -25,17 +26,17 @@
* \date 2002 - 2005
*/
-#include "rack.h"
+#include <algorithm>
#include "pldrack.h"
-
-#include "debug.h"
+#include "rack.h"
PlayedRack::PlayedRack()
+ : m_reject(false)
{
- reject = false;
}
+
void PlayedRack::addOld(const Tile &t)
{
m_oldTiles.push_back(t);
@@ -51,26 +52,22 @@
void PlayedRack::getOldTiles(vector<Tile> &oTiles) const
{
oTiles.clear();
- for (int i = 0; i < nOld(); i++)
- oTiles.push_back(m_oldTiles[i]);
+ oTiles = m_oldTiles;
}
void PlayedRack::getNewTiles(vector<Tile> &oTiles) const
{
oTiles.clear();
- for (int i = 0; i < nNew(); i++)
- oTiles.push_back(m_newTiles[i]);
+ oTiles = m_newTiles;
}
void PlayedRack::getAllTiles(vector<Tile> &oTiles) const
{
oTiles.clear();
- for (int i = 0; i < nOld(); i++)
- oTiles.push_back(m_oldTiles[i]);
- for (int j = 0; j < nNew(); j++)
- oTiles.push_back(m_newTiles[j]);
+ oTiles = m_oldTiles;
+ oTiles.insert(oTiles.end(), m_newTiles.begin(), m_newTiles.end());
}
@@ -78,6 +75,7 @@
{
m_oldTiles.clear();
m_newTiles.clear();
+ m_reject = false;
}
@@ -122,72 +120,47 @@
void PlayedRack::setOld(const Rack &iRack)
{
- list<Tile> l;
- iRack.getTiles(l);
-
m_oldTiles.clear();
- list<Tile>::const_iterator it;
- for (it = l.begin(); it != l.end(); it++)
- {
- addOld(*it);
- }
+ iRack.getTiles(m_oldTiles);
}
void PlayedRack::setNew(const Rack &iRack)
{
- list<Tile> l;
- iRack.getTiles(l);
-
m_newTiles.clear();
- list<Tile>::const_iterator it;
- for (it = l.begin(); it != l.end(); it++)
- {
- addNew(*it);
- }
+ iRack.getTiles(m_newTiles);
}
-int PlayedRack::setManual(const wstring& iLetters)
+
+void PlayedRack::setManual(const wstring& iLetters)
{
- unsigned int i;
reset();
- if (iLetters.size() == 0)
- {
- return 0; /* empty is ok */
- }
+ // An empty rack is OK
+ if (iLetters.empty())
+ return;
+ unsigned int i;
for (i = 0; i < iLetters.size() && iLetters[i] != L'+'; i++)
{
- Tile tile(iLetters[i]);
- if (tile.isEmpty())
- {
- return 1; /* */
- }
- addOld(tile);
+ addOld(Tile(iLetters[i]));
}
if (i < iLetters.size() && iLetters[i] == L'+')
{
for (i++; i < iLetters.size(); i++)
{
- Tile tile(iLetters[i]);
- if (tile.isEmpty())
- {
- return 1; /* */
- }
- addNew(tile);
+ addNew(Tile(iLetters[i]));
}
}
-
- return 0;
}
-bool PlayedRack::checkRack(int cMin, int vMin) const
+
+bool PlayedRack::checkRack(unsigned int cMin, unsigned int vMin) const
{
vector<Tile>::const_iterator it;
- int v = 0;
- int c = 0;
+ unsigned int v = 0;
+ unsigned int c = 0;
for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
{
@@ -203,10 +176,9 @@
}
-void PlayedRack::operator=(const PlayedRack &iOther)
+void PlayedRack::shuffleNew()
{
- m_oldTiles = iOther.m_oldTiles;
- m_newTiles = iOther.m_newTiles;
+ std::random_shuffle(m_newTiles.begin(), m_newTiles.end());
}
@@ -215,25 +187,23 @@
wstring s;
vector<Tile>::const_iterator it;
- if (nOld() > 0)
+ if (mode >= RACK_EXTRA && m_reject)
{
- for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
- s += it->toChar();
+ s += L"-";
}
- if (mode > RACK_SIMPLE && nOld() > 0 && nNew() > 0)
+ if (getNbOld() > 0)
{
- s += L"+";
+ for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
+ s += it->toChar();
}
- if (mode > RACK_EXTRA && reject)
+ if (mode > RACK_SIMPLE && getNbOld() > 0 && getNbNew() > 0)
{
- s += L"-";
- // new rack: reject
- // not after a scrabble
+ s += L"+";
}
- if (nNew() > 0)
+ if (getNbNew() > 0)
{
for (it = m_newTiles.begin(); it != m_newTiles.end(); it++)
s += it->toChar();
Index: game/pldrack.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/pldrack.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- game/pldrack.h 22 Jan 2006 12:23:53 -0000 1.12
+++ game/pldrack.h 8 Jan 2008 13:52:39 -0000 1.13
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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,7 +48,6 @@
{
public:
PlayedRack();
- virtual ~PlayedRack() {}
void reset();
void resetNew();
@@ -58,11 +58,12 @@
void setOld(const Rack &iRack);
void setNew(const Rack &iRack);
- int setManual(const wstring& iLetters);
+ void setManual(const wstring& iLetters);
+ void setReject(bool iReject = true) { m_reject = iReject; }
- int nTiles() const { return nNew() + nOld(); }
- int nNew() const { return m_newTiles.size(); }
- int nOld() const { return m_oldTiles.size(); }
+ unsigned int getNbTiles() const { return getNbNew() + getNbOld(); }
+ unsigned int getNbNew() const { return m_newTiles.size(); }
+ unsigned int getNbOld() const { return m_oldTiles.size(); }
void addNew(const Tile &t);
void addOld(const Tile &t);
@@ -70,9 +71,10 @@
void getOldTiles(vector<Tile> &oTiles) const;
void getAllTiles(vector<Tile> &oTiles) const;
- bool checkRack(int cMin, int vMin) const;
+ bool checkRack(unsigned int cMin, unsigned int vMin) const;
- void operator=(const PlayedRack &iOther);
+ /// Randomly change the order of the "new" tiles
+ void shuffleNew();
enum display_mode
{
@@ -83,7 +85,7 @@
wstring toString(display_mode iShowExtraSigns = RACK_EXTRA) const;
private:
- bool reject;
+ bool m_reject;
vector<Tile> m_oldTiles;
vector<Tile> m_newTiles;
};
Index: game/rack.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/rack.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- game/rack.cpp 22 Jan 2006 12:23:53 -0000 1.7
+++ game/rack.cpp 8 Jan 2008 13:52:39 -0000 1.8
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -22,23 +23,21 @@
* \file rack.cpp
* \brief Rack class : multiset of tiles
* \author Antoine Fraboulet & Olivier Teuliere
- * \date 2002 - 2005
+ * \date 2002 - 2007
*/
#include "rack.h"
+#include "dic.h"
#include "encoding.h"
#include "debug.h"
-// FIXME: should not be here (duplicated from tile.cpp)
-#define TILES_NUMBER 28
-#define MIN_CODE 1
-
Rack::Rack()
- : m_tiles(TILES_NUMBER, 0), m_ntiles(0)
+ : m_tiles(Dictionary::GetDic().getTileNumber() + 1, 0), m_ntiles(0)
{
}
+
void Rack::remove(const Tile &t)
{
ASSERT(in(t),
@@ -58,14 +57,13 @@
}
-void Rack::getTiles(list<Tile> &oTiles) const
+void Rack::getTiles(vector<Tile> &oTiles) const
{
- for (unsigned int i = MIN_CODE; i < m_tiles.size(); i++)
- {
- for (unsigned int j = 0; j < m_tiles[i]; j++)
+ oTiles.reserve(m_ntiles);
+ for (unsigned int i = 1; i < m_tiles.size(); i++)
{
- oTiles.push_back(Tile::GetTileFromCode(i));
- }
+ // Add m_tiles[i] copies of the tile at the end of the vector
+ oTiles.insert(oTiles.end(), m_tiles[i],
Dictionary::GetDic().getTileFromCode(i));
}
}
@@ -73,12 +71,10 @@
wstring Rack::toString()
{
wstring rs;
- for (unsigned int i = MIN_CODE; i < m_tiles.size(); i++)
- {
- for (unsigned int j = 0; j < m_tiles[i]; j++)
+ for (unsigned int i = 1; i < m_tiles.size(); i++)
{
- rs += Tile::GetTileFromCode(i).toChar();
- }
+ // Append m_tiles[i] copies of the char
+ rs.append(m_tiles[i],
Dictionary::GetDic().getTileFromCode(i).toChar());
}
return rs;
}
Index: game/rack.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/rack.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- game/rack.h 22 Jan 2006 12:23:53 -0000 1.9
+++ game/rack.h 8 Jan 2008 13:52:39 -0000 1.10
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -22,17 +23,17 @@
* \file rack.h
* \brief Rack class : multiset of tiles
* \author Antoine Fraboulet & Olivier Teuliere
- * \date 2002 - 2005
+ * \date 2002 - 2007
*/
#ifndef _RACK_H_
#define _RACK_H_
-#include "tile.h"
-#include <set>
-#include <list>
+#include <vector>
#include <string>
+#include "tile.h"
+
using namespace std;
@@ -44,23 +45,22 @@
{
public:
Rack();
- virtual ~Rack() {}
- int nTiles() const { return m_ntiles; }
- bool isEmpty() const { return nTiles() == 0; }
+ unsigned int getNbTiles() const { return m_ntiles; }
+ bool isEmpty() const { return getNbTiles() == 0; }
unsigned int in(const Tile &t) const { return m_tiles[t.toCode()]; }
void add(const Tile &t) { m_tiles[t.toCode()]++; m_ntiles++; }
void remove(const Tile &t);
void clear();
- void getTiles(list<Tile> &oTiles) const;
+ void getTiles(vector<Tile> &oTiles) const;
wstring toString();
private:
/// Vector indexed by tile codes, containing the number of tiles
vector<unsigned int> m_tiles;
- int m_ntiles;
+ unsigned int m_ntiles;
};
#endif
Index: game/results.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/results.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- game/results.cpp 1 Jan 2006 19:49:35 -0000 1.10
+++ game/results.cpp 8 Jan 2008 13:52:39 -0000 1.11
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -46,19 +47,19 @@
};
-const Round & Results::get(int i) const
+const Round & Results::get(unsigned int i) const
{
- ASSERT(0 <= i && i < size(), "Results index out of bounds");
+ ASSERT(i < size(), "Results index out of bounds");
return m_rounds[i];
}
void Results::search(const Dictionary &iDic, Board &iBoard,
- const Rack &iRack, int iTurn)
+ const Rack &iRack, bool iFirstWord)
{
clear();
- if (iTurn == 0)
+ if (iFirstWord)
{
iBoard.searchFirst(iDic, iRack, *this);
}
@@ -67,11 +68,11 @@
iBoard.search(iDic, iRack, *this);
}
- sort_by_points();
+ sortByPoints();
}
-void Results::sort_by_points()
+void Results::sortByPoints()
{
less_points lp;
std::sort(m_rounds.begin(), m_rounds.end(), lp);
Index: game/results.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/results.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- game/results.h 1 Jan 2006 19:49:35 -0000 1.8
+++ game/results.h 8 Jan 2008 13:52:39 -0000 1.9
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -33,9 +34,9 @@
using namespace std;
+class Dictionary;
class Board;
class Rack;
-typedef struct _Dictionary * Dictionary;
/**
@@ -47,24 +48,22 @@
class Results
{
public:
- Results() {}
- virtual ~Results() {}
-
- int size() const { return m_rounds.size(); }
+ unsigned int size() const { return m_rounds.size(); }
void clear() { m_rounds.clear(); }
- const Round & get(int) const;
+ const Round & get(unsigned int) const;
- // Perform a search on the board
+ /// Perform a search on the board
void search(const Dictionary &iDic, Board &iBoard,
- const Rack &iRack, int iTurn);
+ const Rack &iRack, bool iFirstWord);
- // FIXME: These methods are used to fill the container with the rounds,
- // but they should not be part of the public interface
+ // FIXME: This method is used to fill the container with the rounds,
+ // but it should not be part of the public interface
void add(const Round &iRound) { m_rounds.push_back(iRound); }
- void sort_by_points();
private:
vector<Round> m_rounds;
+
+ void sortByPoints();
};
#endif
Index: game/round.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/round.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- game/round.cpp 4 Aug 2007 20:01:28 -0000 1.12
+++ game/round.cpp 8 Jan 2008 13:52:39 -0000 1.13
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -52,33 +53,27 @@
void Round::setWord(const vector<Tile> &iTiles)
{
- m_word.clear();
-
- vector<Tile>::const_iterator it;
- for (it = iTiles.begin(); it != iTiles.end(); it++)
- {
- m_word.push_back(*it);
+ m_word = iTiles;
// XXX: always from rack?
- m_tileOrigin.push_back(FROMRACK);
- }
+ m_tileOrigin = vector<char>(iTiles.size(), FROMRACK);
}
-void Round::setFromRack(int iIndex)
+void Round::setFromRack(unsigned int iIndex)
{
m_tileOrigin[iIndex] &= ~FROMBOARD;
m_tileOrigin[iIndex] |= FROMRACK;
}
-void Round::setFromBoard(int iIndex)
+void Round::setFromBoard(unsigned int iIndex)
{
m_tileOrigin[iIndex] &= ~FROMRACK;
m_tileOrigin[iIndex] |= FROMBOARD;
}
-void Round::setJoker(int iIndex, bool value)
+void Round::setJoker(unsigned int iIndex, bool value)
{
if (value)
m_tileOrigin[iIndex] |= JOKER;
@@ -87,25 +82,19 @@
}
-bool Round::isJoker(int iIndex) const
+bool Round::isJoker(unsigned int iIndex) const
{
return m_tileOrigin[iIndex] & JOKER;
}
-const Tile& Round::getTile(int iIndex) const
+const Tile& Round::getTile(unsigned int iIndex) const
{
return m_word[iIndex];
}
-int Round::getWordLen() const
-{
- return m_word.size();
-}
-
-
-bool Round::isPlayedFromRack(int iIndex) const
+bool Round::isPlayedFromRack(unsigned int iIndex) const
{
return m_tileOrigin[iIndex] & FROMRACK;
}
@@ -150,7 +139,7 @@
wchar_t c;
wstring s;
- for (int i = 0; i < getWordLen(); i++)
+ for (unsigned int i = 0; i < getWordLen(); i++)
{
c = getTile(i).toChar();
if (isJoker(i))
Index: game/round.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/round.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- game/round.h 22 Jan 2006 12:23:53 -0000 1.12
+++ game/round.h 8 Jan 2008 13:52:39 -0000 1.13
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -42,7 +43,6 @@
*
*************************/
Round();
- virtual ~Round() {}
void init();
/*************************
@@ -58,21 +58,21 @@
*************************/
void setPoints(int iPoints) { m_points = iPoints; }
void setBonus(bool iBonus) { m_bonus = iBonus; }
- void setTile(int iIndex, const Tile &iTile) { m_word[iIndex] = iTile; }
+ void setTile(unsigned int iIndex, const Tile &iTile) { m_word[iIndex] =
iTile; }
void setWord(const vector<Tile> &iTiles);
- void setFromRack(int iIndex);
- void setFromBoard(int iIndex);
- void setJoker(int iIndex, bool value = true);
+ void setFromRack(unsigned int iIndex);
+ void setFromBoard(unsigned int iIndex);
+ void setJoker(unsigned int iIndex, bool value = true);
/*************************
* General getters
*************************/
- bool isJoker (int iIndex) const;
- bool isPlayedFromRack(int iIndex) const;
- const Tile& getTile (int iIndex) const;
+ bool isJoker (unsigned int iIndex) const;
+ bool isPlayedFromRack(unsigned int iIndex) const;
+ const Tile& getTile (unsigned int iIndex) const;
wstring getWord() const;
- int getWordLen() const;
+ unsigned int getWordLen() const { return m_word.size(); }
int getPoints() const { return m_points; }
int getBonus() const { return m_bonus; }
Index: game/training.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/training.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- game/training.cpp 11 Aug 2006 22:15:13 -0000 1.17
+++ game/training.cpp 8 Jan 2008 13:52:40 -0000 1.18
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -18,10 +19,13 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
+#include <algorithm>
+
#include "dic.h"
#include "tile.h"
#include "rack.h"
#include "round.h"
+#include "move.h"
#include "pldrack.h"
#include "player.h"
#include "training.h"
@@ -30,12 +34,8 @@
#include "debug.h"
-Training::Training(const Dictionary &iDic): Game(iDic)
-{
-}
-
-
-Training::~Training()
+Training::Training(const Dictionary &iDic)
+ : Game(iDic)
{
}
@@ -46,11 +46,10 @@
int res;
int try_number = 0;
- int p = m_currPlayer;
m_results.clear();
do
{
- res = helperSetRackRandom(p, iCheck, mode);
+ res = helperSetRackRandomOld(m_currPlayer, iCheck, mode);
try_number ++;
} while (res == 2 && try_number < MAX_RANDOM_TRY);
// 0 : ok
@@ -59,28 +58,27 @@
return res;
}
+
int Training::setRackManual(bool iCheck, const wstring &iLetters)
{
- int res;
- int p = m_currPlayer;
- wstring::iterator it;
- wstring uLetters; // uppercase letters
- // letters can be lowercase or uppercase as they are
+ // Letters can be lowercase or uppercase as they are
// coming from user input. We do not consider a lowercase
// letter to be a joker which has been assigned to a letter.
+ // As a result, we simply make all the letters uppercase
+ wstring upperLetters = iLetters;
+ std::transform(upperLetters.begin(), upperLetters.end(),
+ upperLetters.begin(), towupper);
+ int res = helperSetRackManual(m_currPlayer, iCheck, upperLetters);
+ // 0: ok
+ // 1: not enough tiles
+ // 2: check failed (number of vowels before round 15)
+ // 3: letters not in the dictionary
+ if (res == 0)
m_results.clear();
- uLetters = iLetters;
- for (it = uLetters.begin(); it != uLetters.end(); it ++)
- {
- *it = towupper(*it);
- }
- res = helperSetRackManual(p, iCheck, uLetters);
- // 0 : ok
- // 1 : not enough tiles
- // 2 : check failed (number of voyels before round 15)
return res;
}
+
int Training::setRack(set_rack_mode iMode, bool iCheck, const wstring
&iLetters)
{
int res = 0;
@@ -99,9 +97,10 @@
return res;
}
+
int Training::play(const wstring &iCoord, const wstring &iWord)
{
- /* Perform all the validity checks, and fill a round */
+ // Perform all the validity checks, and fill a round
Round round;
int res = checkPlayedWord(iCoord, iWord, round);
@@ -111,23 +110,21 @@
return res;
}
- /* Update the rack and the score of the current player */
debug("play: %s %s %d\n",
convertToMb(round.getWord()).c_str(),
convertToMb(round.getCoord().toString()).c_str(),
round.getPoints());
- m_players[m_currPlayer]->addPoints(round.getPoints());
- // see game.cpp::helperPlayRound():99 comment
- m_players[m_currPlayer]->endTurn(round, m_history.getSize());
+ Move move(round);
+ // Update the rack and the score of the current player
+ // Player::endTurn() must be called before Game::helperPlayMove().
+ // See the big comment in game.cpp, line 96
+ m_players[m_currPlayer]->endTurn(move, m_history.getSize());
- /* Everything is OK, we can play the word */
- if (helperPlayRound(round))
- {
- debug("play: error during play\n");
- }
+ // Everything is OK, we can play the word
+ helperPlayMove(m_currPlayer, move);
- /* Next turn */
+ // Next turn
endTurn();
return 0;
@@ -146,10 +143,9 @@
}
-int Training::endTurn()
+void Training::endTurn()
{
- // Nothing to do?
- return 0;
+ // Nothing to do, but this method is kept for consistency with other modes
}
@@ -159,31 +155,27 @@
Rack r;
m_players[m_currPlayer]->getCurrentRack().getRack(r);
debug("Training::search for %s\n", convertToMb(r.toString()).c_str());
- m_results.search(*m_dic, m_board, r, m_history.getSize());
+ m_results.search(m_dic, m_board, r, m_history.beforeFirstRound());
}
-int Training::playResult(int n)
+int Training::playResult(unsigned 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, m_history.getSize());
+ Move move(m_results.get(n));
+ // Update the rack and the score of the current player
+ m_players[m_currPlayer]->endTurn(move, m_history.getSize());
- int res = helperPlayRound(round);
-
- if (res == 0)
+ // Update the game
+ helperPlayMove(m_currPlayer, move);
m_results.clear();
- /* Next turn */
- // XXX: Should it be done by the interface instead?
+ // Next turn
endTurn();
- return res;
+ return 0;
}
@@ -201,9 +193,9 @@
}
-void Training::testPlay(int num)
+void Training::testPlay(unsigned int num)
{
- ASSERT(0 <= num && num < m_results.size(), "Wrong result number");
+ ASSERT(num < m_results.size(), "Wrong result number");
m_testRound = m_results.get(num);
m_board.testRound(m_results.get(num));
}
@@ -215,6 +207,7 @@
m_testRound = Round();
}
+
wstring Training::getTestPlayWord() const
{
return m_testRound.getWord();
Index: game/training.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/training.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- game/training.h 22 Jan 2006 12:23:53 -0000 1.15
+++ game/training.h 8 Jan 2008 13:52:40 -0000 1.16
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Antoine Fraboulet <address@hidden>
- * Olivier Teuliere <address@hidden>
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
*
* 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
@@ -24,6 +25,7 @@
#include <string>
#include "game.h"
+#include "round.h"
#include "results.h"
using std::string;
@@ -34,6 +36,7 @@
* This class handles the logic specific to a training game.
* As its name indicates, it is not a game in the literal meaning of the word,
* in particular because the rack can be set at will.
+ *
* Note: No player should be added to this game, a human player is added
* automatically (in the start() method)
*/
@@ -48,10 +51,13 @@
* Game handling
*************************/
virtual int start();
+
+ /// See description of Game::play()
virtual int play(const wstring &iCoord, const wstring &iWord);
- virtual int endTurn();
+
void search();
- int playResult(int);
+ const Results& getResults() const { return m_results; };
+ int playResult(unsigned int);
int setRackRandom(bool, set_rack_mode);
int setRackManual(bool iCheck, const wstring &iLetters);
@@ -59,7 +65,7 @@
/*************************
* Override the default behaviour of these methods, because in training
- * we only want a human player
+ * mode we only want a human player
*************************/
virtual void addHumanPlayer();
virtual void addAIPlayer();
@@ -68,23 +74,25 @@
* Functions to access the current search results
* The int parameter should be 0 <= int < getNResults
*************************/
- const Results& getResults() const { return m_results; };
- /// Place a temporary word on the board for preview purpose
- void testPlay(int);
- /// Remove the temporary word(s)
+ /// Place a temporary word on the board for preview purposes
+ void testPlay(unsigned int);
+ /// Remove the temporary word
void removeTestPlay();
/// Get the temporary word
wstring getTestPlayWord() const;
private:
- // Private constructor and destructor to force using the GameFactory class
+ /// Private constructor and destructor to force using the GameFactory class
Training(const Dictionary &iDic);
- virtual ~Training();
- // Search results, with all the possible rounds
- Round m_testRound;
+ void endTurn();
+
+ /// Search results, with all the possible rounds
Results m_results;
+
+ /// Round corresponding to the last test play (if any)
+ Round m_testRound;
};
#endif /* _TRAINING_H_ */
Index: game/turn.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/turn.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- game/turn.cpp 22 Jan 2006 12:23:53 -0000 1.11
+++ game/turn.cpp 8 Jan 2008 13:52:40 -0000 1.12
@@ -1,67 +1,57 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file turn.cpp
- * \brief Game turn (= id + pldrack + round)
+ * \brief Game turn (= id + pldrack + move)
* \author Antoine Fraboulet
* \date 2005
*/
-#include <string>
-#include "pldrack.h"
-#include "round.h"
#include "turn.h"
+// FIXME: move set to an invalid value. It would be better to get rid of this
+// constructor completely
Turn::Turn()
+ : m_num(0), m_playerId(0), m_move(L"", L"")
{
- m_num = 0;
- m_playerId = 0;
- m_pldrack = PlayedRack();
- m_round = Round();
}
-Turn::Turn(int iNum, int iPlayerId,
- const PlayedRack& iPldRack, const Round& iRound)
- : m_num(iNum), m_playerId(iPlayerId), m_pldrack(iPldRack), m_round(iRound)
-{
-}
-#if 0
-void Turn::operator=(const Turn &iOther)
+Turn::Turn(unsigned int iNum, unsigned int iPlayerId,
+ const PlayedRack& iPldRack, const Move& iMove)
+ : m_num(iNum), m_playerId(iPlayerId), m_pldrack(iPldRack), m_move(iMove)
{
- m_num = iOther.m_num;
- m_playerId = iOther.m_playerId;
- m_pldrack = iOther.m_pldrack;
- m_round = iOther.m_round;
}
-#endif
+
wstring Turn::toString(bool iShowExtraSigns) const
{
- wstring rs = L"";
+ wstring rs;
if (iShowExtraSigns)
{
// TODO
}
- rs = rs + m_pldrack.toString() + L" " + m_round.toString();
+ rs = rs + m_pldrack.toString() + L" " + m_move.toString();
return rs;
}
Index: game/turn.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/turn.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- game/turn.h 22 Jan 2006 12:23:53 -0000 1.9
+++ game/turn.h 8 Jan 2008 13:52:40 -0000 1.10
@@ -1,25 +1,27 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
/**
* \file turn.h
- * \brief Game turn (= id + pldrack + round)
+ * \brief Game turn (= id + pldrack + move)
* \author Antoine Fraboulet
* \date 2005
*/
@@ -27,35 +29,45 @@
#ifndef _TURN_H
#define _TURN_H
+#include <string>
+#include "pldrack.h"
+#include "move.h"
+
+using std::wstring;
+
+
+/**
+ * A Turn is the information about one 'move' done by a player.
+ * It consists of the player who played, the rack, and the actual move.
+ * A turn also has an id (XXX: currently never read)
+ *
+ * This class has no logic, it is merely there to aggregate corresponding
+ * data.
+ */
class Turn
{
public:
Turn();
- Turn(int iNum, int iPlayerId,
- const PlayedRack& iPldRack, const Round& iRound);
- virtual ~Turn() {};
+ Turn(unsigned int iNum, unsigned int iPlayerId,
+ const PlayedRack& iPldRack, const Move& iMove);
- void setNum(int iNum) { m_num = iNum; }
- void setPlayer(int iPlayerId) { m_playerId = iPlayerId; }
+ void setNum(unsigned int iNum) { m_num = iNum; }
+ void setPlayer(unsigned int iPlayerId) { m_playerId = iPlayerId; }
void setPlayedRack(const PlayedRack& iPldRack) { m_pldrack = iPldRack; }
- void setRound(const Round& iRound) { m_round = iRound; }
+ void setMove(const Move& iMove) { m_move = iMove; }
- int getNum() const { return m_num; }
- int getPlayer() const { return m_playerId; }
+ unsigned int getNum() const { return m_num; }
+ unsigned int getPlayer() const { return m_playerId; }
const PlayedRack& getPlayedRack() const { return m_pldrack; }
- const Round& getRound() const { return m_round; }
+ const Move& getMove() const { return m_move; }
-#if 0
- void operator=(const Turn &iOther);
-#endif
wstring toString(bool iShowExtraSigns = false) const;
private:
- int m_num;
- int m_playerId;
+ unsigned int m_num;
+ unsigned int m_playerId;
PlayedRack m_pldrack;
- Round m_round;
-
+ Move m_move;
};
#endif
Index: m4/.cvsignore
===================================================================
RCS file: /cvsroot/eliot/eliot/m4/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- m4/.cvsignore 27 Feb 2005 20:11:53 -0000 1.1
+++ m4/.cvsignore 8 Jan 2008 13:52:40 -0000 1.2
@@ -1,18 +1,30 @@
codeset.m4
gettext.m4
+glibc2.m4
glibc21.m4
iconv.m4
intdiv0.m4
+intl.m4
+intldir.m4
+intmax.m4
inttypes-pri.m4
-inttypes.m4
inttypes_h.m4
-isc-posix.m4
lcmessage.m4
lib-ld.m4
lib-link.m4
lib-prefix.m4
+lock.m4
+longdouble.m4
+longlong.m4
+nls.m4
+po.m4
+printf-posix.m4
progtest.m4
+size_max.m4
stdint_h.m4
uintmax_t.m4
ulonglong.m4
-
+visibility.m4
+wchar_t.m4
+wint_t.m4
+xsize.m4
Index: po/.cvsignore
===================================================================
RCS file: /cvsroot/eliot/eliot/po/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- po/.cvsignore 6 Feb 2005 22:18:11 -0000 1.1
+++ po/.cvsignore 8 Jan 2008 13:52:40 -0000 1.2
@@ -1,6 +1,7 @@
Makefile
Makefile.in
Makefile.in.in
+Makevars.template
POTFILES
*.mo
*.gmo
@@ -8,3 +9,9 @@
*.sin
*.header
Rules-quot
+stamp-po
address@hidden
address@hidden
address@hidden
address@hidden
+
Index: po/LINGUAS
===================================================================
RCS file: /cvsroot/eliot/eliot/po/LINGUAS,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- po/LINGUAS 6 Feb 2005 22:18:11 -0000 1.1
+++ po/LINGUAS 8 Jan 2008 13:52:40 -0000 1.2
@@ -1 +1 @@
-fr
+fr address@hidden address@hidden
Index: po/POTFILES.in
===================================================================
RCS file: /cvsroot/eliot/eliot/po/POTFILES.in,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- po/POTFILES.in 1 Jan 2006 19:34:31 -0000 1.3
+++ po/POTFILES.in 8 Jan 2008 13:52:40 -0000 1.4
@@ -1,16 +1,20 @@
-./dic/automaton.c
+./dic/automaton.cpp
./dic/automaton.h
-./dic/compdic.c
-./dic/dic.c
+./dic/header.cpp
+./dic/header.h
+./dic/dic.cpp
./dic/dic.h
./dic/dic_internals.h
-./dic/dic_search.c
-./dic/dic_search.h
-./dic/hashtable.c
+./dic/dic_search.cpp
+./dic/hashtable.cpp
./dic/hashtable.h
-./dic/listdic.c
-./dic/regexp.c
+./dic/regexp.cpp
./dic/regexp.h
+./dic/tile.cpp
+./dic/tile.h
+./dic/compdic.cpp
+./dic/listdic.cpp
+./dic/regexpmain.cpp
./game/bag.cpp
./game/bag.h
./game/board.cpp
@@ -39,11 +43,9 @@
./game/results.h
./game/round.cpp
./game/round.h
-./game/tile.cpp
-./game/tile.h
./game/training.cpp
./game/training.h
-./utils/eliottxt.cpp
+#./utils/eliottxt.cpp
./utils/game_io.h
./utils/game_io.cpp
./utils/ncurses.cpp
@@ -68,4 +70,3 @@
./wxwin/printout.cc
./wxwin/searchpanel.h
./wxwin/searchpanel.cc
-./config.h
Index: po/eliot.pot
===================================================================
RCS file: /cvsroot/eliot/eliot/po/eliot.pot,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- po/eliot.pot 2 Apr 2005 22:04:59 -0000 1.6
+++ po/eliot.pot 8 Jan 2008 13:52:40 -0000 1.7
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2005-04-03 00:04+0200\n"
+"POT-Creation-Date: 2007-12-23 23:08+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <address@hidden>\n"
"Language-Team: LANGUAGE <address@hidden>\n"
@@ -16,247 +16,1163 @@
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: utils/ncurses.cpp:184
-msgid " Scores "
+#: dic/header.cpp:317 dic/header.cpp:318
+msgid "Unknown (old format)"
msgstr ""
-#: utils/ncurses.cpp:190
+#: dic/header.cpp:492
+#, c-format
+msgid "dictionary name: %s\n"
+msgstr ""
+
+#: dic/header.cpp:497
+#, c-format
+msgid "compressed on: %s\n"
+msgstr ""
+
+#: dic/header.cpp:501
+#, c-format
+msgid "compressed on: Unknown date (old format)\n"
+msgstr ""
+
+#: dic/header.cpp:503
+#, c-format
+msgid "compressed using a binary compiled by: %s\n"
+msgstr ""
+
+#: dic/header.cpp:504
+#, c-format
+msgid "dictionary type: %s\n"
+msgstr ""
+
+#: dic/header.cpp:505
+#, c-format
+msgid "letters: %s\n"
+msgstr ""
+
+#: dic/header.cpp:506
+#, c-format
+msgid "number of letters: %d\n"
+msgstr ""
+
+#: dic/header.cpp:507
+#, c-format
+msgid "number of words: %d\n"
+msgstr ""
+
+#: dic/header.cpp:508
+#, c-format
+msgid "header size: %u bytes\n"
+msgstr ""
+
+#: dic/header.cpp:510
+#, c-format
+msgid "root: %d (edge)\n"
+msgstr ""
+
+#: dic/header.cpp:511
+#, c-format
+msgid "nodes: %d used + %d saved\n"
+msgstr ""
+
+#: dic/header.cpp:512
+#, c-format
+msgid "edges: %d used + %d saved\n"
+msgstr ""
+
+#: dic/header.cpp:514
+#, c-format
+msgid "letter | points | frequency | vowel | consonant\n"
+msgstr ""
+
+#: dic/compdic.cpp:392
+msgid "Mandatory options:"
+msgstr ""
+
+#: dic/compdic.cpp:393
+msgid " -d, --dicname <string> Set the dictionary name and version"
+msgstr ""
+
+#: dic/compdic.cpp:394
+msgid ""
+" -l, --letters <string> Path to the file containing the letters (see below)"
+msgstr ""
+
+#: dic/compdic.cpp:395
+msgid ""
+" -i, --input <string> Path to the uncompressed dictionary file (encoded "
+"in UTF-8)"
+msgstr ""
+
+#: dic/compdic.cpp:396
+msgid ""
+" -o, --output <string Path to the generated compressed dictionary file"
+msgstr ""
+
+#: dic/compdic.cpp:397
+msgid "Other options:"
+msgstr ""
+
+#: dic/compdic.cpp:398
+msgid " -h, --help Print this help and exit"
+msgstr ""
+
+#: dic/compdic.cpp:399
+msgid "Example:"
+msgstr ""
+
+#: dic/compdic.cpp:400
+msgid " -d 'ODS 5.0' -l letters.txt -i ods5.txt -o ods5.dawg"
+msgstr ""
+
+#: dic/compdic.cpp:402
+msgid ""
+"The file containing the letters (--letters switch) must be UTF-8 encoded."
+msgstr ""
+
+#: dic/compdic.cpp:403
+msgid ""
+"Each line corresponds to one letter, and must contain 5 fields separated "
+"with "
+msgstr ""
+
+#: dic/compdic.cpp:404
+msgid "one or more space(s)."
+msgstr ""
+
+#: dic/compdic.cpp:405
+msgid " - 1st field: the letter itself"
+msgstr ""
+
+#: dic/compdic.cpp:406
+msgid " - 2nd field: the points of the letter"
+msgstr ""
+
+#: dic/compdic.cpp:407
+msgid ""
+" - 3rd field: the frequency of the letter (how many letters of this kind in "
+"the game)"
+msgstr ""
+
+#: dic/compdic.cpp:408
+msgid ""
+" - 4th field: 1 if the letter is considered as a vowel in Scrabble game, 0 "
+"otherwise"
+msgstr ""
+
+#: dic/compdic.cpp:409
+msgid ""
+" - 5th field: 1 if the letter is considered as a consonant in Scrabble game, "
+"0 otherwise"
+msgstr ""
+
+#: dic/compdic.cpp:410
+msgid "Example for french:"
+msgstr ""
+
+#: dic/compdic.cpp:411
+msgid "A 1 9 1 0"
+msgstr ""
+
+#: dic/compdic.cpp:412
+msgid "[...]"
+msgstr ""
+
+#: dic/compdic.cpp:413
+msgid "Z 10 1 0 1"
+msgstr ""
+
+#: dic/compdic.cpp:414
+msgid "? 0 2 1 1"
+msgstr ""
+
+#: dic/compdic.cpp:484
+msgid "A mandatory option is missing"
+msgstr ""
+
+#: dic/compdic.cpp:492
+msgid "Cannot stat uncompressed dictionary "
+msgstr ""
+
+#: dic/compdic.cpp:500
+msgid "Cannot open output file "
+msgstr ""
+
+#: dic/compdic.cpp:548
+#, c-format
+msgid " Load time: %.3f s\n"
+msgstr ""
+
+#: dic/compdic.cpp:549
+#, c-format
+msgid " Compression time: %.3f s\n"
+msgstr ""
+
+#: dic/compdic.cpp:551
+#, c-format
+msgid " Maximum recursion level reached: %d\n"
+msgstr ""
+
+#: dic/listdic.cpp:100
+#, c-format
+msgid "offset binary | structure\n"
+msgstr ""
+
+#: dic/listdic.cpp:109
+#, c-format
+msgid "usage: %s [-a|-h|-l|-x] dictionary\n"
+msgstr ""
+
+#: dic/listdic.cpp:110
+#, c-format
+msgid " -a: print all\n"
+msgstr ""
+
+#: dic/listdic.cpp:111
+#, c-format
+msgid " -h: print header\n"
+msgstr ""
+
+#: dic/listdic.cpp:112
+#, c-format
+msgid " -l: print dictionary word list\n"
+msgstr ""
+
+#: dic/listdic.cpp:113
+#, c-format
+msgid " -x: print dictionary in hex\n"
+msgstr ""
+
+#: dic/regexpmain.cpp:100
+#, c-format
+msgid "usage: %s dictionary"
+msgstr ""
+
+#: dic/regexpmain.cpp:101
+msgid " dictionary: path to eliot dawg dictionary"
+msgstr ""
+
+#: dic/regexpmain.cpp:136
+msgid "enter a regular expression:"
+msgstr ""
+
+#: dic/regexpmain.cpp:148
+msgid "result:"
+msgstr ""
+
+#: utils/ncurses.cpp:270
+msgid "Scores"
+msgstr ""
+
+#: utils/ncurses.cpp:276
#, c-format
msgid "Player %d: %d"
msgstr ""
-#: utils/ncurses.cpp:198
-msgid " Racks "
+#: utils/ncurses.cpp:285
+msgid "Racks"
msgstr ""
-#: utils/ncurses.cpp:204
+#: utils/ncurses.cpp:292
#, c-format
-msgid "Player %d: %s"
+msgid "Player %d: %ls"
msgstr ""
-#: utils/ncurses.cpp:215 utils/ncurses.cpp:218
+#: utils/ncurses.cpp:303 utils/ncurses.cpp:306
msgid "Search complete"
msgstr ""
-#: utils/ncurses.cpp:229
-msgid " Search results "
+#: utils/ncurses.cpp:316
+msgid "Search results"
msgstr ""
-#: utils/ncurses.cpp:258
-msgid " History of the game "
+#: utils/ncurses.cpp:345
+msgid "History of the game"
msgstr ""
-#: utils/ncurses.cpp:265
+#: utils/ncurses.cpp:351
msgid " N | RACK | SOLUTION | REF | PTS | P | BONUS"
msgstr ""
-#: utils/ncurses.cpp:296
-msgid " Help "
+#: utils/ncurses.cpp:390
+msgid "(PASS)"
msgstr ""
-#: utils/ncurses.cpp:301
+#: utils/ncurses.cpp:416
+msgid "Help"
+msgstr ""
+
+#: utils/ncurses.cpp:420
msgid "[Global]"
msgstr ""
-#: utils/ncurses.cpp:302
+#: utils/ncurses.cpp:421
msgid " h, H, ? Show/hide help box"
msgstr ""
-#: utils/ncurses.cpp:303
+#: utils/ncurses.cpp:422
msgid " y, Y Show/hide history of the game"
msgstr ""
-#: utils/ncurses.cpp:304
+#: utils/ncurses.cpp:423
+msgid ""
+" b, B Show/hide contents of the bag (including letters of the "
+"racks)"
+msgstr ""
+
+#: utils/ncurses.cpp:424
msgid " e, E Show/hide dots on empty squares of the board"
msgstr ""
-#: utils/ncurses.cpp:305
+#: utils/ncurses.cpp:425
msgid " d, D Check the existence of a word in the dictionary"
msgstr ""
-#: utils/ncurses.cpp:306
+#: utils/ncurses.cpp:426
msgid " j, J Play a word"
msgstr ""
-#: utils/ncurses.cpp:307
+#: utils/ncurses.cpp:427
msgid " s, S Save the game"
msgstr ""
-#: utils/ncurses.cpp:308
+#: utils/ncurses.cpp:428
msgid " l, L Load a game"
msgstr ""
-#: utils/ncurses.cpp:309
+#: utils/ncurses.cpp:429
msgid " q, Q Quit"
msgstr ""
-#: utils/ncurses.cpp:312
+#: utils/ncurses.cpp:432
msgid "[Training mode]"
msgstr ""
-#: utils/ncurses.cpp:313
+#: utils/ncurses.cpp:433
msgid " * Take a random rack"
msgstr ""
-#: utils/ncurses.cpp:314
+#: utils/ncurses.cpp:434
msgid " + Complete the current rack randomly"
msgstr ""
-#: utils/ncurses.cpp:315
+#: utils/ncurses.cpp:435
msgid " t, T Set the rack manually"
msgstr ""
-#: utils/ncurses.cpp:316
+#: utils/ncurses.cpp:436
msgid " c, C Compute all the possible words"
msgstr ""
-#: utils/ncurses.cpp:317
+#: utils/ncurses.cpp:437
msgid " r, R Show/hide search results"
msgstr ""
-#: utils/ncurses.cpp:320
+#: utils/ncurses.cpp:440
msgid "[Duplicate mode]"
msgstr ""
-#: utils/ncurses.cpp:321
+#: utils/ncurses.cpp:441
msgid " n, N Switch to the next human player"
msgstr ""
-#: utils/ncurses.cpp:324
+#: utils/ncurses.cpp:444
msgid "[Free game mode]"
msgstr ""
-#: utils/ncurses.cpp:325
+#: utils/ncurses.cpp:445
msgid " p, P Pass your turn (with or without changing letters)"
msgstr ""
-#: utils/ncurses.cpp:328
+#: utils/ncurses.cpp:448
msgid "[Miscellaneous]"
msgstr ""
-#: utils/ncurses.cpp:329
+#: utils/ncurses.cpp:449
msgid " <up>, <down> Navigate in a box line by line"
msgstr ""
-#: utils/ncurses.cpp:330
+#: utils/ncurses.cpp:450
msgid " <pgup>, <pgdown> Navigate in a box page by page"
msgstr ""
-#: utils/ncurses.cpp:331
+#: utils/ncurses.cpp:451
msgid " Ctrl-l Refresh the screen"
msgstr ""
-#: utils/ncurses.cpp:339
-msgid " Play a word "
+#: utils/ncurses.cpp:462 wxwin/auxframes.cc:148
+msgid "Bag"
+msgstr ""
+
+#: utils/ncurses.cpp:469
+msgid " LETTER | POINTS | FREQUENCY | REMAINING"
+msgstr ""
+
+#: utils/ncurses.cpp:522
+msgid "Play a word"
msgstr ""
#. TRANSLATORS: Align the : when translating "Played word:" and
#. "Coordinates:". For example:
#. Pl. word :
#. Coordinates:
-#: utils/ncurses.cpp:340 utils/ncurses.cpp:348
+#: utils/ncurses.cpp:523 utils/ncurses.cpp:531
msgid "Played word:"
msgstr ""
-#: utils/ncurses.cpp:341 utils/ncurses.cpp:349
+#: utils/ncurses.cpp:524 utils/ncurses.cpp:532
msgid "Coordinates:"
msgstr ""
-#: utils/ncurses.cpp:363
+#: utils/ncurses.cpp:546
msgid "Incorrect or misplaced word"
msgstr ""
-#: utils/ncurses.cpp:373
-msgid " Dictionary "
+#: utils/ncurses.cpp:556
+msgid "Dictionary"
msgstr ""
-#: utils/ncurses.cpp:374
+#: utils/ncurses.cpp:557
msgid "Enter the word to check:"
msgstr ""
-#: utils/ncurses.cpp:383
+#: utils/ncurses.cpp:566
#, c-format
-msgid "The word '%s' exists"
+msgid "The word '%ls' exists"
msgstr ""
-#: utils/ncurses.cpp:385
+#: utils/ncurses.cpp:568
#, c-format
-msgid "The word '%s' does not exist"
+msgid "The word '%ls' does not exist"
msgstr ""
-#: utils/ncurses.cpp:395
-msgid " Save the game "
+#: utils/ncurses.cpp:578 wxwin/mainframe.cc:460 wxwin/mainframe.cc:468
+msgid "Save the game"
msgstr ""
-#: utils/ncurses.cpp:396 utils/ncurses.cpp:425
+#: utils/ncurses.cpp:579 utils/ncurses.cpp:609
msgid "Enter the file name:"
msgstr ""
-#: utils/ncurses.cpp:406
+#: utils/ncurses.cpp:589
#, c-format
-msgid "Cannot open file %s for writing"
+msgid "Cannot open file %ls for writing"
msgstr ""
-#: utils/ncurses.cpp:413
+#: utils/ncurses.cpp:597
#, c-format
-msgid "Game saved in %s"
+msgid "Game saved in '%ls'"
msgstr ""
-#: utils/ncurses.cpp:424
-msgid " Load a game "
+#: utils/ncurses.cpp:608 wxwin/mainframe.cc:269 wxwin/mainframe.cc:390
+#: wxwin/mainframe.cc:414
+msgid "Load a game"
msgstr ""
-#: utils/ncurses.cpp:435
+#: utils/ncurses.cpp:619
#, c-format
-msgid "Cannot open file %s for reading"
+msgid "Cannot open file '%ls' for reading"
msgstr ""
-#: utils/ncurses.cpp:443
+#: utils/ncurses.cpp:627
#, c-format
msgid "Invalid saved game"
msgstr ""
-#: utils/ncurses.cpp:447
+#: utils/ncurses.cpp:632
#, c-format
msgid "Game loaded"
msgstr ""
-#: utils/ncurses.cpp:462
-msgid " Pass your turn "
+#: utils/ncurses.cpp:647
+msgid "Pass your turn"
msgstr ""
-#: utils/ncurses.cpp:463
+#: utils/ncurses.cpp:648
msgid "Enter the letters to change:"
msgstr ""
-#: utils/ncurses.cpp:472
+#: utils/ncurses.cpp:657
msgid "Cannot pass the turn"
msgstr ""
-#: utils/ncurses.cpp:482
-msgid " Set rack "
+#: utils/ncurses.cpp:667
+msgid "Set rack"
msgstr ""
-#: utils/ncurses.cpp:483
+#: utils/ncurses.cpp:668
msgid "Enter the new letters:"
msgstr ""
-#: utils/ncurses.cpp:798
+#: utils/ncurses.cpp:677
+msgid "Cannot take these letters from the bag"
+msgstr ""
+
+#: utils/ncurses.cpp:1071
msgid "Training mode"
msgstr ""
-#: utils/ncurses.cpp:800
+#: utils/ncurses.cpp:1073
msgid "Free game mode"
msgstr ""
-#: utils/ncurses.cpp:802
+#: utils/ncurses.cpp:1075
msgid "Duplicate mode"
msgstr ""
-#: utils/ncurses.cpp:805
+#: utils/ncurses.cpp:1078
msgid "Joker game"
msgstr ""
-#: utils/ncurses.cpp:806
+#: utils/ncurses.cpp:1079
msgid "[h for help]"
msgstr ""
+
+#: wxwin/auxframes.cc:123
+msgid "Grid"
+msgstr ""
+
+#: wxwin/auxframes.cc:203
+msgid "Search"
+msgstr ""
+
+#: wxwin/auxframes.cc:234
+msgid "Check"
+msgstr ""
+
+#: wxwin/auxframes.cc:239
+msgid "Word to check"
+msgstr ""
+
+#: wxwin/auxframes.cc:257 wxwin/configdb.cc:203 wxwin/searchpanel.cc:107
+msgid "No dictionary"
+msgstr ""
+
+#: wxwin/auxframes.cc:261
+msgid "exists"
+msgstr ""
+
+#: wxwin/auxframes.cc:263
+msgid "doesn't exist"
+msgstr ""
+
+#: wxwin/auxframes.cc:304
+msgid "Copy"
+msgstr ""
+
+#: wxwin/auxframes.cc:348 wxwin/mainframe.cc:487 wxwin/mainframe.cc:507
+#: wxwin/mainframe.cc:538
+msgid "No on going game"
+msgstr ""
+
+#: wxwin/auxframes.cc:363 wxwin/searchpanel.cc:119
+msgid "No result"
+msgstr ""
+
+#: wxwin/auxframes.cc:409
+msgid "Rack: "
+msgstr ""
+
+#: wxwin/auxframes.cc:525 wxwin/mainframe.cc:319
+msgid "Game history"
+msgstr ""
+
+#: wxwin/auxframes.cc:557 wxwin/mainframe.cc:321
+msgid "Results"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:62
+msgid "left"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:63
+msgid "centered"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:64
+msgid "right"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:118
+msgid "Alignment"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:120
+msgid "Spacing"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:124 wxwin/confdimdlg.cc:135
+msgid "Font..."
+msgstr ""
+
+#: wxwin/confdimdlg.cc:129
+msgid "Title column "
+msgstr ""
+
+#: wxwin/confdimdlg.cc:140
+msgid "Text column "
+msgstr ""
+
+#: wxwin/confdimdlg.cc:150
+msgid "Column heading"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:154
+msgid "Alignment of the column heading"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:158
+msgid "Spacing of the heading characters"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:167
+msgid "Inner dimension of the column (in mm)"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:176
+msgid "Alignment of the column text"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:180
+msgid "Characters spacing"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:231
+msgid "Title spc. top"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:233
+msgid "Text spc. top"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:235
+msgid "Text spc. left"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:252
+msgid "Title spc. bot."
+msgstr ""
+
+#: wxwin/confdimdlg.cc:254
+msgid "Text spc. bot."
+msgstr ""
+
+#: wxwin/confdimdlg.cc:256
+msgid "Text spc. right"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:286
+msgid "Printer"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:288
+msgid "Configure the printer"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:290
+msgid "Page"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:292
+msgid "Configure the dimensions of the page"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:298
+msgid "Cancel the last changes"
+msgstr ""
+
+#: wxwin/confdimdlg.cc:304 wxwin/confsearch.cc:42
+msgid "Save the changes"
+msgstr ""
+
+#: wxwin/configdb.cc:322
+msgid "Nb"
+msgstr ""
+
+#: wxwin/configdb.cc:323 wxwin/mainframe.cc:174
+msgid "Rack"
+msgstr ""
+
+#: wxwin/configdb.cc:324
+msgid "Solution"
+msgstr ""
+
+#: wxwin/configdb.cc:325 wxwin/gfxresult.cc:69
+msgid "Pos"
+msgstr ""
+
+#: wxwin/configdb.cc:326 wxwin/gfxresult.cc:70
+msgid "Pts"
+msgstr ""
+
+#: wxwin/confsearch.cc:36
+msgid "Search on joker in 7+1 panel"
+msgstr ""
+
+#: wxwin/confsearch.cc:37
+msgid "Check rack validity"
+msgstr ""
+
+#: wxwin/confsearch.cc:40
+msgid "Cancel last changes"
+msgstr ""
+
+#: wxwin/gfxresult.cc:67
+msgid "Word"
+msgstr ""
+
+#: wxwin/gfxresult.cc:71
+msgid "Results of the search"
+msgstr ""
+
+#: wxwin/mainframe.cc:205
+msgid " Rack "
+msgstr ""
+
+#: wxwin/mainframe.cc:206
+msgid " Complement "
+msgstr ""
+
+#: wxwin/mainframe.cc:207
+msgid " Search "
+msgstr ""
+
+#: wxwin/mainframe.cc:208
+msgid " Back "
+msgstr ""
+
+#: wxwin/mainframe.cc:209
+msgid " Play "
+msgstr ""
+
+#: wxwin/mainframe.cc:211
+msgid "Random rack"
+msgstr ""
+
+#: wxwin/mainframe.cc:212
+msgid "Random complement of the rack"
+msgstr ""
+
+#: wxwin/mainframe.cc:213
+msgid "Search with the current rack"
+msgstr ""
+
+#: wxwin/mainframe.cc:214
+msgid "Go back one turn"
+msgstr ""
+
+#: wxwin/mainframe.cc:215
+msgid "Play the selected word"
+msgstr ""
+
+#: wxwin/mainframe.cc:266
+msgid "&New game\tctrl+n"
+msgstr ""
+
+#: wxwin/mainframe.cc:266
+msgid "Start a new game"
+msgstr ""
+
+#: wxwin/mainframe.cc:267
+msgid "New &joker game\tctrl+j"
+msgstr ""
+
+#: wxwin/mainframe.cc:267
+msgid "Start a new joker game"
+msgstr ""
+
+#: wxwin/mainframe.cc:269
+msgid "&Load...\tctrl+l"
+msgstr ""
+
+#: wxwin/mainframe.cc:270
+msgid "&Save as...\tctrl+s"
+msgstr ""
+
+#: wxwin/mainframe.cc:270
+msgid "Save the current game"
+msgstr ""
+
+#: wxwin/mainframe.cc:272
+msgid "&Print...\tctrl+p"
+msgstr ""
+
+#: wxwin/mainframe.cc:272
+msgid "Print this game"
+msgstr ""
+
+#: wxwin/mainframe.cc:273
+msgid "Print pre&view..."
+msgstr ""
+
+#: wxwin/mainframe.cc:273
+msgid "Print preview of the game"
+msgstr ""
+
+#: wxwin/mainframe.cc:275
+msgid "Print in PostS&cript..."
+msgstr ""
+
+#: wxwin/mainframe.cc:275
+msgid "Print in a PostScript file"
+msgstr ""
+
+#: wxwin/mainframe.cc:278
+msgid "&Quit"
+msgstr ""
+
+#: wxwin/mainframe.cc:278
+msgid "Quit Eliot"
+msgstr ""
+
+#: wxwin/mainframe.cc:281
+msgid "&Dictionary..."
+msgstr ""
+
+#: wxwin/mainframe.cc:281 wxwin/mainframe.cc:589
+msgid "Choose a dictionary"
+msgstr ""
+
+#: wxwin/mainframe.cc:282
+msgid "&Search..."
+msgstr ""
+
+#: wxwin/mainframe.cc:282
+msgid "Search options"
+msgstr ""
+
+#: wxwin/mainframe.cc:285
+msgid "&Background..."
+msgstr ""
+
+#: wxwin/mainframe.cc:285
+msgid "Background color"
+msgstr ""
+
+#: wxwin/mainframe.cc:286
+msgid "L&ines..."
+msgstr ""
+
+#: wxwin/mainframe.cc:286
+msgid "Color of the lines"
+msgstr ""
+
+#: wxwin/mainframe.cc:288
+msgid "&Played letters..."
+msgstr ""
+
+#: wxwin/mainframe.cc:288
+msgid "Color of the letters played on the board"
+msgstr ""
+
+#: wxwin/mainframe.cc:289
+msgid "&Temporary letters..."
+msgstr ""
+
+#: wxwin/mainframe.cc:289
+msgid "Color of the letters of the temporary word"
+msgstr ""
+
+#: wxwin/mainframe.cc:290
+msgid "B&ackground of played letters..."
+msgstr ""
+
+#: wxwin/mainframe.cc:290
+msgid "Background color of the letters played on the board"
+msgstr ""
+
+#: wxwin/mainframe.cc:291
+msgid "Ba&ckground of temporary letters..."
+msgstr ""
+
+#: wxwin/mainframe.cc:291
+msgid "Background color of the temporary letters on the board"
+msgstr ""
+
+#: wxwin/mainframe.cc:293
+msgid "Double &letter..."
+msgstr ""
+
+#: wxwin/mainframe.cc:293
+msgid "Color of the \"double letter\" squares"
+msgstr ""
+
+#: wxwin/mainframe.cc:294
+msgid "Triple l&etter..."
+msgstr ""
+
+#: wxwin/mainframe.cc:294
+msgid "Color of the \"triple letter\" squares"
+msgstr ""
+
+#: wxwin/mainframe.cc:295
+msgid "Double &word..."
+msgstr ""
+
+#: wxwin/mainframe.cc:295
+msgid "Color of the \"double word\" squares"
+msgstr ""
+
+#: wxwin/mainframe.cc:296
+msgid "Triple w&ord..."
+msgstr ""
+
+#: wxwin/mainframe.cc:296
+msgid "Color of the \"triple word\" squares"
+msgstr ""
+
+#: wxwin/mainframe.cc:298
+msgid "&Default colors"
+msgstr ""
+
+#: wxwin/mainframe.cc:298
+msgid "Restore the default colors"
+msgstr ""
+
+#: wxwin/mainframe.cc:301
+msgid "&Search letters..."
+msgstr ""
+
+#: wxwin/mainframe.cc:301
+msgid "Font for the search"
+msgstr ""
+
+#: wxwin/mainframe.cc:304 wxwin/mainframe.cc:328
+msgid "&Game"
+msgstr ""
+
+#: wxwin/mainframe.cc:304
+msgid "Configuration of the game"
+msgstr ""
+
+#: wxwin/mainframe.cc:305
+msgid "&Fonts"
+msgstr ""
+
+#: wxwin/mainframe.cc:305
+msgid "Configuration of the fonts"
+msgstr ""
+
+#: wxwin/mainframe.cc:306
+msgid "&Colors"
+msgstr ""
+
+#: wxwin/mainframe.cc:306
+msgid "Configuration of the colors"
+msgstr ""
+
+#: wxwin/mainframe.cc:307
+msgid "&Printing..."
+msgstr ""
+
+#: wxwin/mainframe.cc:307
+msgid "Configuration of the printing parameters"
+msgstr ""
+
+#: wxwin/mainframe.cc:310
+msgid "&Board"
+msgstr ""
+
+#: wxwin/mainframe.cc:310
+msgid "Game board"
+msgstr ""
+
+#: wxwin/mainframe.cc:311
+msgid "Ba&g"
+msgstr ""
+
+#: wxwin/mainframe.cc:311
+msgid "Remaining letters in the bag"
+msgstr ""
+
+#: wxwin/mainframe.cc:312
+msgid "&Check"
+msgstr ""
+
+#: wxwin/mainframe.cc:312
+msgid "Check a word in the dictionary"
+msgstr ""
+
+#: wxwin/mainframe.cc:313
+msgid "&Search"
+msgstr ""
+
+#: wxwin/mainframe.cc:313
+msgid "Search in the dictionary"
+msgstr ""
+
+#: wxwin/mainframe.cc:315
+msgid "&Rack + 1"
+msgstr ""
+
+#: wxwin/mainframe.cc:315
+msgid "Letters of the rack plus one"
+msgstr ""
+
+#: wxwin/mainframe.cc:316
+msgid "R&accords"
+msgstr ""
+
+#: wxwin/mainframe.cc:316
+msgid "Raccords on a word of the search"
+msgstr ""
+
+#: wxwin/mainframe.cc:317
+msgid "&Benjamins"
+msgstr ""
+
+#: wxwin/mainframe.cc:317
+msgid "Benjamins on a word of the search"
+msgstr ""
+
+#: wxwin/mainframe.cc:319
+msgid "Game &history"
+msgstr ""
+
+#: wxwin/mainframe.cc:321
+msgid "R&esults"
+msgstr ""
+
+#: wxwin/mainframe.cc:325
+msgid "&About..."
+msgstr ""
+
+#: wxwin/mainframe.cc:325 wxwin/mainframe.cc:718
+msgid "About Eliot"
+msgstr ""
+
+#: wxwin/mainframe.cc:329
+msgid "&Settings"
+msgstr ""
+
+#: wxwin/mainframe.cc:330
+msgid "&Windows"
+msgstr ""
+
+#: wxwin/mainframe.cc:331
+msgid "&Help"
+msgstr ""
+
+#: wxwin/mainframe.cc:355 wxwin/mainframe.cc:393
+msgid "No dictionary selected"
+msgstr ""
+
+#: wxwin/mainframe.cc:355 wxwin/mainframe.cc:393 wxwin/mainframe.cc:487
+#: wxwin/mainframe.cc:507 wxwin/mainframe.cc:538
+msgid "Eliot: error"
+msgstr ""
+
+#: wxwin/mainframe.cc:413
+msgid "Cannot open "
+msgstr ""
+
+#: wxwin/mainframe.cc:425 wxwin/mainframe.cc:434
+msgid "Error while loading the game"
+msgstr ""
+
+#: wxwin/mainframe.cc:426
+msgid "Invalid game"
+msgstr ""
+
+#: wxwin/mainframe.cc:435
+msgid "The game is empty"
+msgstr ""
+
+#: wxwin/mainframe.cc:467
+msgid "Cannot create "
+msgstr ""
+
+#: wxwin/mainframe.cc:496 wxwin/mainframe.cc:560
+msgid "Printing not done"
+msgstr ""
+
+#: wxwin/mainframe.cc:496 wxwin/mainframe.cc:524
+msgid "Printing"
+msgstr ""
+
+#: wxwin/mainframe.cc:519
+msgid "Print preview problem.\n"
+msgstr ""
+
+#: wxwin/mainframe.cc:520
+msgid "The printer may not be correctly initialized"
+msgstr ""
+
+#: wxwin/mainframe.cc:521
+msgid "Print preview"
+msgstr ""
+
+#: wxwin/mainframe.cc:542
+msgid "Print to a PostScript file"
+msgstr ""
+
+#: wxwin/mainframe.cc:561 wxwin/mainframe.cc:567
+msgid "PostScript printing"
+msgstr ""
+
+#: wxwin/mainframe.cc:566
+msgid "Cannot initialize PostScript printer"
+msgstr ""
+
+#: wxwin/mainframe.cc:714
+msgid ""
+"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."
+msgstr ""
+
+#: wxwin/mainframe.cc:912
+msgid "turn:"
+msgstr ""
+
+#: wxwin/mainframe.cc:913
+msgid "points:"
+msgstr ""
+
+#: wxwin/mainframe.cc:948
+msgid ""
+"The bag doesn't contain enough letters\n"
+"for a new rack."
+msgstr ""
+
+#: wxwin/mainframe.cc:949 wxwin/mainframe.cc:953 wxwin/mainframe.cc:957
+msgid "Rack validation"
+msgstr ""
+
+#: wxwin/mainframe.cc:952
+msgid "The rack must contain at least 2 consonants and 2 vowels."
+msgstr ""
+
+#: wxwin/mainframe.cc:956
+msgid "The rack contains invalid letters for the current dictionary"
+msgstr ""
+
+#: wxwin/mainframe.cc:960
+msgid "The rack has been modified manually"
+msgstr ""
+
+#: wxwin/searchpanel.cc:146 wxwin/searchpanel.cc:190
+#, c-format
+msgid "The search is limited to %d letters"
+msgstr ""
+
+#: wxwin/searchpanel.cc:301
+msgid "Minimum length"
+msgstr ""
+
+#: wxwin/searchpanel.cc:303
+msgid "Maximum length"
+msgstr ""
+
+#: wxwin/searchpanel.cc:366
+msgid "Cross words"
+msgstr ""
+
+#: wxwin/searchpanel.cc:367
+msgid "Plus 1"
+msgstr ""
+
+#: wxwin/searchpanel.cc:368
+msgid "Regular expressions"
+msgstr ""
Index: po/fr.po
===================================================================
RCS file: /cvsroot/eliot/eliot/po/fr.po,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- po/fr.po 2 Apr 2005 22:04:59 -0000 1.6
+++ po/fr.po 8 Jan 2008 13:52:40 -0000 1.7
@@ -8,271 +8,1265 @@
msgstr ""
"Project-Id-Version: eliot 1.4\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2005-04-03 00:04+0200\n"
+"POT-Creation-Date: 2007-12-23 23:08+0100\n"
"PO-Revision-Date: 2005-02-06 20:03+0100\n"
"Last-Translator: Olivier Teuliere <address@hidden>\n"
"Language-Team: French <address@hidden>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: utils/ncurses.cpp:184
-msgid " Scores "
-msgstr " Scores "
+#: dic/header.cpp:317 dic/header.cpp:318
+msgid "Unknown (old format)"
+msgstr "Inconnu (vieux format)"
-#: utils/ncurses.cpp:190
+#: dic/header.cpp:492
+#, c-format
+msgid "dictionary name: %s\n"
+msgstr "Nom du dictionnaire : %s\n"
+
+#: dic/header.cpp:497
+#, c-format
+msgid "compressed on: %s\n"
+msgstr "Compressé le : %s\n"
+
+#: dic/header.cpp:501
+#, c-format
+msgid "compressed on: Unknown date (old format)\n"
+msgstr "Compressé le : Date inconnue (vieux format)\n"
+
+#: dic/header.cpp:503
+#, c-format
+msgid "compressed using a binary compiled by: %s\n"
+msgstr "Compressé avec un binaire compilé par : %s\n"
+
+#: dic/header.cpp:504
+#, c-format
+msgid "dictionary type: %s\n"
+msgstr "Type de dictionnaire : %s\n"
+
+#: dic/header.cpp:505
+#, c-format
+msgid "letters: %s\n"
+msgstr "Lettres : %s\n"
+
+#: dic/header.cpp:506
+#, c-format
+msgid "number of letters: %d\n"
+msgstr "Nombre de lettres : %d\n"
+
+#: dic/header.cpp:507
+#, c-format
+msgid "number of words: %d\n"
+msgstr "Nombre de mots : %d\n"
+
+#: dic/header.cpp:508
+#, c-format
+msgid "header size: %u bytes\n"
+msgstr "Taille du header : %u octets\n"
+
+#: dic/header.cpp:510
+#, c-format
+msgid "root: %d (edge)\n"
+msgstr "Racine : %d (arcs)\n"
+
+#: dic/header.cpp:511
+#, c-format
+msgid "nodes: %d used + %d saved\n"
+msgstr "Noeuds : %d utilisés + %d évités\n"
+
+#: dic/header.cpp:512
+#, c-format
+msgid "edges: %d used + %d saved\n"
+msgstr "Arcs : %d utilisés + %d évités\n"
+
+#: dic/header.cpp:514
+#, c-format
+msgid "letter | points | frequency | vowel | consonant\n"
+msgstr "lettre | points | frequence | voye. | consonne\n"
+
+#: dic/compdic.cpp:392
+msgid "Mandatory options:"
+msgstr "Options obligatoires :"
+
+#: dic/compdic.cpp:393
+msgid " -d, --dicname <string> Set the dictionary name and version"
+msgstr " -d, --dicname <string> Choisir le nom et la version du dictionnaire"
+
+#: dic/compdic.cpp:394
+msgid ""
+" -l, --letters <string> Path to the file containing the letters (see below)"
+msgstr ""
+" -l, --letters <string> Chemin vers un fichier contenant les lettres (voir "
+"ci-dessous)"
+
+#: dic/compdic.cpp:395
+msgid ""
+" -i, --input <string> Path to the uncompressed dictionary file (encoded "
+"in UTF-8)"
+msgstr ""
+" -i, --input <string> Chemin vers le fichier de dictionnaire non "
+"compressé (encodé en UTF-8)"
+
+#: dic/compdic.cpp:396
+msgid ""
+" -o, --output <string Path to the generated compressed dictionary file"
+msgstr ""
+" -o, --output <string Chemin vers le fichier de dictionnaire compressé "
+"généré"
+
+#: dic/compdic.cpp:397
+msgid "Other options:"
+msgstr "Autres options :"
+
+#: dic/compdic.cpp:398
+msgid " -h, --help Print this help and exit"
+msgstr " -h, --help Affiche cette aide et quitte"
+
+#: dic/compdic.cpp:399
+msgid "Example:"
+msgstr "Exemple :"
+
+#: dic/compdic.cpp:400
+msgid " -d 'ODS 5.0' -l letters.txt -i ods5.txt -o ods5.dawg"
+msgstr " -d 'ODS 5.0' -l lettres.txt -i ods5.txt -o ods5.dawg"
+
+#: dic/compdic.cpp:402
+msgid ""
+"The file containing the letters (--letters switch) must be UTF-8 encoded."
+msgstr ""
+"Le fichier contenant les lettres (option --letters) doit être encodé en
UTF-"
+"8."
+
+#: dic/compdic.cpp:403
+msgid ""
+"Each line corresponds to one letter, and must contain 5 fields separated "
+"with "
+msgstr ""
+"Chaque ligne correspond à une lettre, et doit contenir 5 champs séparés
par "
+
+#: dic/compdic.cpp:404
+msgid "one or more space(s)."
+msgstr "un ou plusieurs espace(s)."
+
+#: dic/compdic.cpp:405
+msgid " - 1st field: the letter itself"
+msgstr " - 1er champ : la lettre elle-même"
+
+#: dic/compdic.cpp:406
+msgid " - 2nd field: the points of the letter"
+msgstr " - 2e champ : les points de cette lettre"
+
+#: dic/compdic.cpp:407
+msgid ""
+" - 3rd field: the frequency of the letter (how many letters of this kind in "
+"the game)"
+msgstr ""
+" - 3e champ : la fréquance de la lettre (nombre de lettres de ce genre dans "
+"le jeu)"
+
+#: dic/compdic.cpp:408
+msgid ""
+" - 4th field: 1 if the letter is considered as a vowel in Scrabble game, 0 "
+"otherwise"
+msgstr ""
+" - 4e champ : 1 si la lettre est considérée comme une voyelle au jeu de "
+"Scrabble, 0 sinon"
+
+#: dic/compdic.cpp:409
+msgid ""
+" - 5th field: 1 if the letter is considered as a consonant in Scrabble game, "
+"0 otherwise"
+msgstr ""
+" - 5e champ : 1 si la lettre est considérée comme une consonne au jeu de "
+"Scrabble, 0 sinon"
+
+#: dic/compdic.cpp:410
+msgid "Example for french:"
+msgstr "Exemple pour le Français :"
+
+#: dic/compdic.cpp:411
+msgid "A 1 9 1 0"
+msgstr "A 1 9 1 0"
+
+#: dic/compdic.cpp:412
+msgid "[...]"
+msgstr "[...]"
+
+#: dic/compdic.cpp:413
+msgid "Z 10 1 0 1"
+msgstr "Z 10 1 0 1"
+
+#: dic/compdic.cpp:414
+msgid "? 0 2 1 1"
+msgstr "? 0 2 1 1"
+
+#: dic/compdic.cpp:484
+msgid "A mandatory option is missing"
+msgstr "Une option obligatoire est manquante"
+
+#: dic/compdic.cpp:492
+msgid "Cannot stat uncompressed dictionary "
+msgstr "Impossible de trouver le dictionnaire non compressé "
+
+#: dic/compdic.cpp:500
+msgid "Cannot open output file "
+msgstr "Impossible d'ouvrir le fichier d'output "
+
+#: dic/compdic.cpp:548
+#, c-format
+msgid " Load time: %.3f s\n"
+msgstr " Temps de chargement : %.3f s\n"
+
+#: dic/compdic.cpp:549
+#, c-format
+msgid " Compression time: %.3f s\n"
+msgstr " Temps de compression : %.3f s\n"
+
+#: dic/compdic.cpp:551
+#, c-format
+msgid " Maximum recursion level reached: %d\n"
+msgstr " Niveau maximum de rcursion atteint : %d\n"
+
+#: dic/listdic.cpp:100
+#, c-format
+msgid "offset binary | structure\n"
+msgstr "offset binaire | structure\n"
+
+#: dic/listdic.cpp:109
+#, c-format
+msgid "usage: %s [-a|-h|-l|-x] dictionary\n"
+msgstr "Usage : %s [-a|-h|-l|-x] dictionnaire\n"
+
+#: dic/listdic.cpp:110
+#, c-format
+msgid " -a: print all\n"
+msgstr " -a : affiche tout\n"
+
+#: dic/listdic.cpp:111
+#, c-format
+msgid " -h: print header\n"
+msgstr " -h : affiche l'en-tête\n"
+
+#: dic/listdic.cpp:112
+#, c-format
+msgid " -l: print dictionary word list\n"
+msgstr " -l : affiche la liste de mots du dictionnaire\n"
+
+#: dic/listdic.cpp:113
+#, c-format
+msgid " -x: print dictionary in hex\n"
+msgstr " -x : affiche le dictionnaire en hexadécimal\n"
+
+#: dic/regexpmain.cpp:100
+#, c-format
+msgid "usage: %s dictionary"
+msgstr "Usage : %s dictionnaire"
+
+#: dic/regexpmain.cpp:101
+msgid " dictionary: path to eliot dawg dictionary"
+msgstr " dictionnaire : chemin vers un dictionnaire de type dawg pour Eliot"
+
+#: dic/regexpmain.cpp:136
+msgid "enter a regular expression:"
+msgstr "Entrer une expression régulière :"
+
+#: dic/regexpmain.cpp:148
+msgid "result:"
+msgstr "résultat :"
+
+#: utils/ncurses.cpp:270
+msgid "Scores"
+msgstr "Scores"
+
+#: utils/ncurses.cpp:276
#, c-format
msgid "Player %d: %d"
msgstr "Joueur %d : %d"
-#: utils/ncurses.cpp:198
-msgid " Racks "
-msgstr " Tirages "
+#: utils/ncurses.cpp:285
+msgid "Racks"
+msgstr "Tirages"
-#: utils/ncurses.cpp:204
+#: utils/ncurses.cpp:292
#, c-format
-msgid "Player %d: %s"
-msgstr "Joueur %d : %s"
+msgid "Player %d: %ls"
+msgstr "Joueur %d : %ls"
-#: utils/ncurses.cpp:215 utils/ncurses.cpp:218
+#: utils/ncurses.cpp:303 utils/ncurses.cpp:306
msgid "Search complete"
-msgstr "Recherche terminée"
+msgstr "Recherche terminée"
-#: utils/ncurses.cpp:229
-msgid " Search results "
-msgstr " Résultats de la recherche "
+#: utils/ncurses.cpp:316
+msgid "Search results"
+msgstr "Résultats de la recherche"
-#: utils/ncurses.cpp:258
-msgid " History of the game "
-msgstr " Historique de la partie "
+#: utils/ncurses.cpp:345
+msgid "History of the game"
+msgstr "Historique de la partie"
-#: utils/ncurses.cpp:265
+#: utils/ncurses.cpp:351
msgid " N | RACK | SOLUTION | REF | PTS | P | BONUS"
msgstr " N | TIRAGE | SOLUTION | REF | PTS | J | BONUS"
-#: utils/ncurses.cpp:296
-msgid " Help "
-msgstr " Aide "
+#: utils/ncurses.cpp:390
+msgid "(PASS)"
+msgstr "(PASSE)"
+
+#: utils/ncurses.cpp:416
+msgid "Help"
+msgstr "Aide"
-#: utils/ncurses.cpp:301
+#: utils/ncurses.cpp:420
msgid "[Global]"
-msgstr "[Général]"
+msgstr "[Général]"
-#: utils/ncurses.cpp:302
+#: utils/ncurses.cpp:421
msgid " h, H, ? Show/hide help box"
-msgstr " h, H, ? Afficher/cacher la boîte d'aide"
+msgstr " h, H, ? Afficher/cacher la boîte d'aide"
-#: utils/ncurses.cpp:303
+#: utils/ncurses.cpp:422
msgid " y, Y Show/hide history of the game"
msgstr " y, Y Afficher/cacher l'historique de la partie"
-#: utils/ncurses.cpp:304
+#: utils/ncurses.cpp:423
+msgid ""
+" b, B Show/hide contents of the bag (including letters of the "
+"racks)"
+msgstr ""
+" b, B Afficher/cacher le contenu du sac (avec les lettres des "
+"tirages)"
+
+#: utils/ncurses.cpp:424
msgid " e, E Show/hide dots on empty squares of the board"
msgstr ""
" e, E Afficher/cacher les points sur les cases vides du "
"plateau de jeu"
-#: utils/ncurses.cpp:305
+#: utils/ncurses.cpp:425
msgid " d, D Check the existence of a word in the dictionary"
-msgstr " d, D Vérifier l'existence d'un mot dans le dictionnaire"
+msgstr " d, D Vérifier l'existence d'un mot dans le
dictionnaire"
-#: utils/ncurses.cpp:306
+#: utils/ncurses.cpp:426
msgid " j, J Play a word"
msgstr " j, J Jouer un mot"
-#: utils/ncurses.cpp:307
+#: utils/ncurses.cpp:427
msgid " s, S Save the game"
-msgstr " s, S Sauver la partie"
+msgstr " s, S Sauvegarder la partie"
-#: utils/ncurses.cpp:308
+#: utils/ncurses.cpp:428
msgid " l, L Load a game"
msgstr " l, L Charger une partie"
-#: utils/ncurses.cpp:309
+#: utils/ncurses.cpp:429
msgid " q, Q Quit"
msgstr " q, Q Quitter"
-#: utils/ncurses.cpp:312
+#: utils/ncurses.cpp:432
msgid "[Training mode]"
-msgstr "[Mode entraînement]"
+msgstr "[Mode entraînement]"
-#: utils/ncurses.cpp:313
+#: utils/ncurses.cpp:433
msgid " * Take a random rack"
-msgstr " * Tirage aléatoire"
+msgstr " * Tirage aléatoire"
-#: utils/ncurses.cpp:314
+#: utils/ncurses.cpp:434
msgid " + Complete the current rack randomly"
-msgstr " + Compléter le tirage courant de manière aléatoire"
+msgstr " + Compléter le tirage courant de manière
aléatoire"
-#: utils/ncurses.cpp:315
+#: utils/ncurses.cpp:435
msgid " t, T Set the rack manually"
msgstr " t, T Entrer le tirage manuellement"
-#: utils/ncurses.cpp:316
+#: utils/ncurses.cpp:436
msgid " c, C Compute all the possible words"
msgstr " c, C Calculer tous les mots possibles"
-#: utils/ncurses.cpp:317
+#: utils/ncurses.cpp:437
msgid " r, R Show/hide search results"
-msgstr " r, R Afficher/cacher les résultats de la recherche"
+msgstr " r, R Afficher/cacher les résultats de la recherche"
-#: utils/ncurses.cpp:320
+#: utils/ncurses.cpp:440
msgid "[Duplicate mode]"
msgstr "[Mode duplicate]"
-#: utils/ncurses.cpp:321
+#: utils/ncurses.cpp:441
msgid " n, N Switch to the next human player"
msgstr " n, N Passer au joueur humain suivant"
-#: utils/ncurses.cpp:324
+#: utils/ncurses.cpp:444
msgid "[Free game mode]"
msgstr "[Mode partie libre]"
-#: utils/ncurses.cpp:325
+#: utils/ncurses.cpp:445
msgid " p, P Pass your turn (with or without changing letters)"
msgstr ""
" p, P Passer son tour (en changeant ou pas certaines lettres)"
-#: utils/ncurses.cpp:328
+#: utils/ncurses.cpp:448
msgid "[Miscellaneous]"
msgstr "[Divers]"
-#: utils/ncurses.cpp:329
+#: utils/ncurses.cpp:449
msgid " <up>, <down> Navigate in a box line by line"
-msgstr " <haut>, <bas> Naviguer dans une boîte ligne par ligne"
+msgstr " <haut>, <bas> Naviguer dans une boîte ligne par ligne"
-#: utils/ncurses.cpp:330
+#: utils/ncurses.cpp:450
msgid " <pgup>, <pgdown> Navigate in a box page by page"
-msgstr " <pgup>, <pgdown> Naviguer dans une boîte page par page"
+msgstr " <pgup>, <pgdown> Naviguer dans une boîte page par page"
-#: utils/ncurses.cpp:331
+#: utils/ncurses.cpp:451
msgid " Ctrl-l Refresh the screen"
-msgstr " Ctrl-l Rafraîchir l'écran"
+msgstr " Ctrl-l Rafraîchir l'écran"
-#: utils/ncurses.cpp:339
-msgid " Play a word "
-msgstr " Jouer un mot "
+#: utils/ncurses.cpp:462 wxwin/auxframes.cc:148
+msgid "Bag"
+msgstr "Sac"
+
+#: utils/ncurses.cpp:469
+msgid " LETTER | POINTS | FREQUENCY | REMAINING"
+msgstr " LETTRE | POINTS |Â FREQUENCE | RESTANT"
+
+#: utils/ncurses.cpp:522
+msgid "Play a word"
+msgstr "Jouer un mot"
#. TRANSLATORS: Align the : when translating "Played word:" and
#. "Coordinates:". For example:
#. Pl. word :
#. Coordinates:
-#: utils/ncurses.cpp:340 utils/ncurses.cpp:348
+#: utils/ncurses.cpp:523 utils/ncurses.cpp:531
msgid "Played word:"
-msgstr "Mot joué :"
+msgstr "Mot joué :"
-#: utils/ncurses.cpp:341 utils/ncurses.cpp:349
+#: utils/ncurses.cpp:524 utils/ncurses.cpp:532
msgid "Coordinates:"
-msgstr "Coordonnées :"
+msgstr "Coordonnées :"
-#: utils/ncurses.cpp:363
+#: utils/ncurses.cpp:546
msgid "Incorrect or misplaced word"
-msgstr "Mot incorrect ou mal placé"
+msgstr "Mot incorrect ou mal placé"
-#: utils/ncurses.cpp:373
-msgid " Dictionary "
-msgstr " Dictionnaire "
+#: utils/ncurses.cpp:556
+msgid "Dictionary"
+msgstr "Dictionnaire"
-#: utils/ncurses.cpp:374
+#: utils/ncurses.cpp:557
msgid "Enter the word to check:"
-msgstr "Entrer le mot à vérifier:"
+msgstr "Entrer le mot à vérifier:"
-#: utils/ncurses.cpp:383
+#: utils/ncurses.cpp:566
#, c-format
-msgid "The word '%s' exists"
-msgstr "Le mot '%s' existe"
+msgid "The word '%ls' exists"
+msgstr "Le mot '%ls' existe"
-#: utils/ncurses.cpp:385
+#: utils/ncurses.cpp:568
#, c-format
-msgid "The word '%s' does not exist"
-msgstr "Le mot '%s' n'existe pas"
+msgid "The word '%ls' does not exist"
+msgstr "Le mot '%ls' n'existe pas"
-#: utils/ncurses.cpp:395
-msgid " Save the game "
-msgstr " Sauver la partie "
+#: utils/ncurses.cpp:578 wxwin/mainframe.cc:460 wxwin/mainframe.cc:468
+msgid "Save the game"
+msgstr "Sauvegarder la partie"
-#: utils/ncurses.cpp:396 utils/ncurses.cpp:425
+#: utils/ncurses.cpp:579 utils/ncurses.cpp:609
msgid "Enter the file name:"
msgstr "Entrer le nom du fichier :"
-#: utils/ncurses.cpp:406
+#: utils/ncurses.cpp:589
#, c-format
-msgid "Cannot open file %s for writing"
-msgstr "Impossible d'ouvrir le fichier %s en écriture"
+msgid "Cannot open file %ls for writing"
+msgstr "Impossible d'ouvrir le fichier %ls en écriture"
-#: utils/ncurses.cpp:413
+#: utils/ncurses.cpp:597
#, c-format
-msgid "Game saved in %s"
-msgstr "Partie sauvée dans %s"
+msgid "Game saved in '%ls'"
+msgstr "Partie sauvée dans '%ls'"
-#: utils/ncurses.cpp:424
-msgid " Load a game "
-msgstr " Charger une partie "
+#: utils/ncurses.cpp:608 wxwin/mainframe.cc:269 wxwin/mainframe.cc:390
+#: wxwin/mainframe.cc:414
+msgid "Load a game"
+msgstr "Charger une partie"
-#: utils/ncurses.cpp:435
+#: utils/ncurses.cpp:619
#, c-format
-msgid "Cannot open file %s for reading"
-msgstr "Impossible d'ouvrir le fichier %s en lecture"
+msgid "Cannot open file '%ls' for reading"
+msgstr "Impossible d'ouvrir le fichier '%ls' en lecture"
-#: utils/ncurses.cpp:443
+#: utils/ncurses.cpp:627
#, c-format
msgid "Invalid saved game"
-msgstr "Partie sauvée invalide"
+msgstr "Partie sauvée invalide"
-#: utils/ncurses.cpp:447
+#: utils/ncurses.cpp:632
#, c-format
msgid "Game loaded"
-msgstr "Partie chargée"
+msgstr "Partie chargée"
-#: utils/ncurses.cpp:462
-msgid " Pass your turn "
-msgstr " Passer son tour "
+#: utils/ncurses.cpp:647
+msgid "Pass your turn"
+msgstr "Passer son tour"
-#: utils/ncurses.cpp:463
+#: utils/ncurses.cpp:648
msgid "Enter the letters to change:"
-msgstr "Entrer les lettres à changer:"
+msgstr "Entrer les lettres à changer:"
-#: utils/ncurses.cpp:472
+#: utils/ncurses.cpp:657
msgid "Cannot pass the turn"
msgstr "Impossible de passer le tour"
-#: utils/ncurses.cpp:482
-msgid " Set rack "
-msgstr " Choix du tirage "
+#: utils/ncurses.cpp:667
+msgid "Set rack"
+msgstr "Choix du tirage"
-#: utils/ncurses.cpp:483
+#: utils/ncurses.cpp:668
msgid "Enter the new letters:"
msgstr "Entrer les nouvelles lettres:"
-#: utils/ncurses.cpp:798
+#: utils/ncurses.cpp:677
+msgid "Cannot take these letters from the bag"
+msgstr "Impossible de retirer ces lettres du sac"
+
+#: utils/ncurses.cpp:1071
msgid "Training mode"
-msgstr "Mode entraînement"
+msgstr "Mode entraînement"
-#: utils/ncurses.cpp:800
+#: utils/ncurses.cpp:1073
msgid "Free game mode"
msgstr "Mode partie libre"
-#: utils/ncurses.cpp:802
+#: utils/ncurses.cpp:1075
msgid "Duplicate mode"
msgstr "Mode duplicate"
-#: utils/ncurses.cpp:805
+#: utils/ncurses.cpp:1078
msgid "Joker game"
msgstr "Partie joker"
-#: utils/ncurses.cpp:806
+#: utils/ncurses.cpp:1079
msgid "[h for help]"
msgstr "[h pour l'aide]"
+#: wxwin/auxframes.cc:123
+msgid "Grid"
+msgstr "Grille"
+
+#: wxwin/auxframes.cc:203
+msgid "Search"
+msgstr "Recherche"
+
+#: wxwin/auxframes.cc:234
+msgid "Check"
+msgstr "Vérification"
+
+#: wxwin/auxframes.cc:239
+msgid "Word to check"
+msgstr "Mot à vérifier"
+
+#: wxwin/auxframes.cc:257 wxwin/configdb.cc:203 wxwin/searchpanel.cc:107
+msgid "No dictionary"
+msgstr "Pas de dictionnaire"
+
+#: wxwin/auxframes.cc:261
+msgid "exists"
+msgstr "existe"
+
+#: wxwin/auxframes.cc:263
+msgid "doesn't exist"
+msgstr "n'existe pas"
+
+#: wxwin/auxframes.cc:304
+msgid "Copy"
+msgstr "Copier"
+
+#: wxwin/auxframes.cc:348 wxwin/mainframe.cc:487 wxwin/mainframe.cc:507
+#: wxwin/mainframe.cc:538
+msgid "No on going game"
+msgstr "Pas de partie en cours"
+
+#: wxwin/auxframes.cc:363 wxwin/searchpanel.cc:119
+msgid "No result"
+msgstr "Pas de résultat"
+
+#: wxwin/auxframes.cc:409
+msgid "Rack: "
+msgstr "Tirage :"
+
+#: wxwin/auxframes.cc:525 wxwin/mainframe.cc:319
+msgid "Game history"
+msgstr "Historique de la partie"
+
+#: wxwin/auxframes.cc:557 wxwin/mainframe.cc:321
+msgid "Results"
+msgstr "Résultats"
+
+#: wxwin/confdimdlg.cc:62
+msgid "left"
+msgstr "gauche"
+
+#: wxwin/confdimdlg.cc:63
+msgid "centered"
+msgstr "centré"
+
+#: wxwin/confdimdlg.cc:64
+msgid "right"
+msgstr "droite"
+
+#: wxwin/confdimdlg.cc:118
+msgid "Alignment"
+msgstr "Justification"
+
+#: wxwin/confdimdlg.cc:120
+msgid "Spacing"
+msgstr "Espacement"
+
+#: wxwin/confdimdlg.cc:124 wxwin/confdimdlg.cc:135
+msgid "Font..."
+msgstr "Police..."
+
+#: wxwin/confdimdlg.cc:129
+msgid "Title column "
+msgstr "titre colomne "
+
+#: wxwin/confdimdlg.cc:140
+msgid "Text column "
+msgstr "Texte colomne "
+
+#: wxwin/confdimdlg.cc:150
+msgid "Column heading"
+msgstr "Titre de la colomne"
+
+#: wxwin/confdimdlg.cc:154
+msgid "Alignment of the column heading"
+msgstr "Justification du titre de la colomne"
+
+#: wxwin/confdimdlg.cc:158
+msgid "Spacing of the heading characters"
+msgstr "Espacement des caractères du titre"
+
+#: wxwin/confdimdlg.cc:167
+msgid "Inner dimension of the column (in mm)"
+msgstr "Dimension interne de la colomne (en mm)"
+
+#: wxwin/confdimdlg.cc:176
+msgid "Alignment of the column text"
+msgstr "Justification du texte de la colomne"
+
+#: wxwin/confdimdlg.cc:180
+msgid "Characters spacing"
+msgstr "Espacement des caractères"
+
+#: wxwin/confdimdlg.cc:231
+msgid "Title spc. top"
+msgstr "Titre esp. haut"
+
+#: wxwin/confdimdlg.cc:233
+msgid "Text spc. top"
+msgstr "Texte esp. haut"
+
+#: wxwin/confdimdlg.cc:235
+msgid "Text spc. left"
+msgstr "Texte esp. gauche"
+
+#: wxwin/confdimdlg.cc:252
+msgid "Title spc. bot."
+msgstr "Titre esp. bas"
+
+#: wxwin/confdimdlg.cc:254
+msgid "Text spc. bot."
+msgstr "Texte esp. bas"
+
+#: wxwin/confdimdlg.cc:256
+msgid "Text spc. right"
+msgstr "Text esp. droite"
+
+#: wxwin/confdimdlg.cc:286
+msgid "Printer"
+msgstr "Imprimante"
+
+#: wxwin/confdimdlg.cc:288
+msgid "Configure the printer"
+msgstr "Configuration de l'imprimante"
+
+#: wxwin/confdimdlg.cc:290
+msgid "Page"
+msgstr "Page"
+
+#: wxwin/confdimdlg.cc:292
+msgid "Configure the dimensions of the page"
+msgstr "Configuration des dimensions de la page"
+
+#: wxwin/confdimdlg.cc:298
+msgid "Cancel the last changes"
+msgstr "Annuler les derniers changements"
+
+#: wxwin/confdimdlg.cc:304 wxwin/confsearch.cc:42
+msgid "Save the changes"
+msgstr "Sauvegarder les changements"
+
+#: wxwin/configdb.cc:322
+msgid "Nb"
+msgstr "Num"
+
+#: wxwin/configdb.cc:323 wxwin/mainframe.cc:174
+msgid "Rack"
+msgstr "Tirage"
+
+#: wxwin/configdb.cc:324
+msgid "Solution"
+msgstr "Solution"
+
+#: wxwin/configdb.cc:325 wxwin/gfxresult.cc:69
+msgid "Pos"
+msgstr "Pos"
+
+#: wxwin/configdb.cc:326 wxwin/gfxresult.cc:70
+msgid "Pts"
+msgstr "Pts"
+
+#: wxwin/confsearch.cc:36
+msgid "Search on joker in 7+1 panel"
+msgstr "Rechercher sur joker dans la fenêtre 7+1"
+
+#: wxwin/confsearch.cc:37
+msgid "Check rack validity"
+msgstr "Vérifier la validité du tirage"
+
+#: wxwin/confsearch.cc:40
+msgid "Cancel last changes"
+msgstr "Annuler les derniers changements"
+
+#: wxwin/gfxresult.cc:67
+msgid "Word"
+msgstr "Mot"
+
+#: wxwin/gfxresult.cc:71
+msgid "Results of the search"
+msgstr "Résultats de la recherche"
+
+#: wxwin/mainframe.cc:205
+msgid " Rack "
+msgstr " Tirage "
+
+#: wxwin/mainframe.cc:206
+msgid " Complement "
+msgstr " Complément "
+
+#: wxwin/mainframe.cc:207
+msgid " Search "
+msgstr " Rechercher "
+
+#: wxwin/mainframe.cc:208
+msgid " Back "
+msgstr " Arrière "
+
+#: wxwin/mainframe.cc:209
+msgid " Play "
+msgstr " Jouer "
+
+#: wxwin/mainframe.cc:211
+msgid "Random rack"
+msgstr "Tirage aléatoire"
+
+#: wxwin/mainframe.cc:212
+msgid "Random complement of the rack"
+msgstr "Complément aléatoire du tirage"
+
+#: wxwin/mainframe.cc:213
+msgid "Search with the current rack"
+msgstr "Recherche sur le tirage courant"
+
+#: wxwin/mainframe.cc:214
+msgid "Go back one turn"
+msgstr "Revenir un coup en arrière"
+
+#: wxwin/mainframe.cc:215
+msgid "Play the selected word"
+msgstr "Jouer le mot selectionné"
+
+#: wxwin/mainframe.cc:266
+msgid "&New game\tctrl+n"
+msgstr "&Nouvelle partie\tctrl+n"
+
+#: wxwin/mainframe.cc:266
+msgid "Start a new game"
+msgstr "Démarrer une nouvelle partie"
+
+#: wxwin/mainframe.cc:267
+msgid "New &joker game\tctrl+j"
+msgstr "Nouvelle partie &joker\tctrl+j"
+
+#: wxwin/mainframe.cc:267
+msgid "Start a new joker game"
+msgstr "Démarrer une nouvelle partie joker"
+
+#: wxwin/mainframe.cc:269
+msgid "&Load...\tctrl+l"
+msgstr "&Charger...\tctrl+l"
+
+#: wxwin/mainframe.cc:270
+msgid "&Save as...\tctrl+s"
+msgstr "&Enregistrer sous...\tctrl+s"
+
+#: wxwin/mainframe.cc:270
+msgid "Save the current game"
+msgstr "Sauvegarder la partie en cours"
+
+#: wxwin/mainframe.cc:272
+msgid "&Print...\tctrl+p"
+msgstr "&Imprimer...\tctrl+p"
+
+#: wxwin/mainframe.cc:272
+msgid "Print this game"
+msgstr "Imprimer la partie en cours"
+
+#: wxwin/mainframe.cc:273
+msgid "Print pre&view..."
+msgstr "&Aperçu avant impression..."
+
+#: wxwin/mainframe.cc:273
+msgid "Print preview of the game"
+msgstr "Aperçu avant impression de la partie"
+
+#: wxwin/mainframe.cc:275
+msgid "Print in PostS&cript..."
+msgstr "Imprimer au format &PostScript..."
+
+#: wxwin/mainframe.cc:275
+msgid "Print in a PostScript file"
+msgstr "Imprimer dans un fichier PostScript"
+
+#: wxwin/mainframe.cc:278
+msgid "&Quit"
+msgstr "&Quitter"
+
+#: wxwin/mainframe.cc:278
+msgid "Quit Eliot"
+msgstr "Quitter Eliot"
+
+#: wxwin/mainframe.cc:281
+msgid "&Dictionary..."
+msgstr "&Dictionnaire..."
+
+#: wxwin/mainframe.cc:281 wxwin/mainframe.cc:589
+msgid "Choose a dictionary"
+msgstr "Choisir un dictionnaire"
+
+#: wxwin/mainframe.cc:282
+msgid "&Search..."
+msgstr "&Recherche..."
+
+#: wxwin/mainframe.cc:282
+msgid "Search options"
+msgstr "Options de recherche"
+
+#: wxwin/mainframe.cc:285
+msgid "&Background..."
+msgstr "&Fond..."
+
+#: wxwin/mainframe.cc:285
+msgid "Background color"
+msgstr "Couleur de fond"
+
+#: wxwin/mainframe.cc:286
+msgid "L&ines..."
+msgstr "L&ignes..."
+
+#: wxwin/mainframe.cc:286
+msgid "Color of the lines"
+msgstr "Couleur des lignes"
+
+#: wxwin/mainframe.cc:288
+msgid "&Played letters..."
+msgstr "Lettres &jouées..."
+
+#: wxwin/mainframe.cc:288
+msgid "Color of the letters played on the board"
+msgstr "Couleur des lettres jouées sur la grille"
+
+#: wxwin/mainframe.cc:289
+msgid "&Temporary letters..."
+msgstr "Lettres &temporaires..."
+
+#: wxwin/mainframe.cc:289
+msgid "Color of the letters of the temporary word"
+msgstr "Couleur des lettres du mot temporaire"
+
+#: wxwin/mainframe.cc:290
+msgid "B&ackground of played letters..."
+msgstr "Fo&nd des lettres jouées..."
+
+#: wxwin/mainframe.cc:290
+msgid "Background color of the letters played on the board"
+msgstr "Couleur de fond des lettres jouées sur la grille"
+
+#: wxwin/mainframe.cc:291
+msgid "Ba&ckground of temporary letters..."
+msgstr "Fon&d des lettres temporaires..."
+
+#: wxwin/mainframe.cc:291
+msgid "Background color of the temporary letters on the board"
+msgstr "Couleur de fond des lettres temporaires sur la grille"
+
+#: wxwin/mainframe.cc:293
+msgid "Double &letter..."
+msgstr "&Lettre compte double..."
+
+#: wxwin/mainframe.cc:293
+msgid "Color of the \"double letter\" squares"
+msgstr "Couleur des cases \"mot compte double\""
+
+#: wxwin/mainframe.cc:294
+msgid "Triple l&etter..."
+msgstr "L&ettre compte triple..."
+
+#: wxwin/mainframe.cc:294
+msgid "Color of the \"triple letter\" squares"
+msgstr "Couleur des cases \"mot compte triple\""
+
+#: wxwin/mainframe.cc:295
+msgid "Double &word..."
+msgstr "&Mot compte double..."
+
+#: wxwin/mainframe.cc:295
+msgid "Color of the \"double word\" squares"
+msgstr "Couleur des cases \"mot compte double\""
+
+#: wxwin/mainframe.cc:296
+msgid "Triple w&ord..."
+msgstr "M&ot compte triple..."
+
+#: wxwin/mainframe.cc:296
+msgid "Color of the \"triple word\" squares"
+msgstr "Couleur des cases \"mot compte triple\""
+
+#: wxwin/mainframe.cc:298
+msgid "&Default colors"
+msgstr "&Couleurs d'origine"
+
+#: wxwin/mainframe.cc:298
+msgid "Restore the default colors"
+msgstr "Restaurer les couleurs d'origine"
+
+#: wxwin/mainframe.cc:301
+msgid "&Search letters..."
+msgstr "&Lettres de recherche..."
+
+#: wxwin/mainframe.cc:301
+msgid "Font for the search"
+msgstr "Police de caractères pour la recherche"
+
+#: wxwin/mainframe.cc:304 wxwin/mainframe.cc:328
+msgid "&Game"
+msgstr "&Partie"
+
+#: wxwin/mainframe.cc:304
+msgid "Configuration of the game"
+msgstr "Configuration de la partie"
+
+#: wxwin/mainframe.cc:305
+msgid "&Fonts"
+msgstr "P&olices de caractères"
+
+#: wxwin/mainframe.cc:305
+msgid "Configuration of the fonts"
+msgstr "Configuration des polices de caractères"
+
+#: wxwin/mainframe.cc:306
+msgid "&Colors"
+msgstr "&Couleurs"
+
+#: wxwin/mainframe.cc:306
+msgid "Configuration of the colors"
+msgstr "Configuration des couleurs"
+
+#: wxwin/mainframe.cc:307
+msgid "&Printing..."
+msgstr "&Impression..."
+
+#: wxwin/mainframe.cc:307
+msgid "Configuration of the printing parameters"
+msgstr "Configuration des paramètres d'impression"
+
+#: wxwin/mainframe.cc:310
+msgid "&Board"
+msgstr "&Grille"
+
+#: wxwin/mainframe.cc:310
+msgid "Game board"
+msgstr "Plateau de jeu"
+
+#: wxwin/mainframe.cc:311
+msgid "Ba&g"
+msgstr "&Sac"
+
+#: wxwin/mainframe.cc:311
+msgid "Remaining letters in the bag"
+msgstr "Lettres restantes dans le sac"
+
+#: wxwin/mainframe.cc:312
+msgid "&Check"
+msgstr "&Vérification"
+
+#: wxwin/mainframe.cc:312
+msgid "Check a word in the dictionary"
+msgstr "Vérifier l'existence d'un mot dans le dictionnaire"
+
+#: wxwin/mainframe.cc:313
+msgid "&Search"
+msgstr "&Recherche"
+
+#: wxwin/mainframe.cc:313
+msgid "Search in the dictionary"
+msgstr "Recherche dans le dictionnaire"
+
+#: wxwin/mainframe.cc:315
+msgid "&Rack + 1"
+msgstr "&Tirage + 1"
+
+#: wxwin/mainframe.cc:315
+msgid "Letters of the rack plus one"
+msgstr "Lettres du tirage plus une"
+
+#: wxwin/mainframe.cc:316
+msgid "R&accords"
+msgstr "R&accords"
+
+#: wxwin/mainframe.cc:316
+msgid "Raccords on a word of the search"
+msgstr "Raccords sur un mot de la recherche"
+
+#: wxwin/mainframe.cc:317
+msgid "&Benjamins"
+msgstr "&Benjamins"
+
+#: wxwin/mainframe.cc:317
+msgid "Benjamins on a word of the search"
+msgstr "Benjamins sur un mot de la recherche"
+
+#: wxwin/mainframe.cc:319
+msgid "Game &history"
+msgstr "&Historique de la partie"
+
+#: wxwin/mainframe.cc:321
+msgid "R&esults"
+msgstr "Ré&sultats"
+
+#: wxwin/mainframe.cc:325
+msgid "&About..."
+msgstr "Ã &propos..."
+
+#: wxwin/mainframe.cc:325 wxwin/mainframe.cc:718
+msgid "About Eliot"
+msgstr "Ã propos d'Eliot"
+
+#: wxwin/mainframe.cc:329
+msgid "&Settings"
+msgstr "&Paramètres"
+
+#: wxwin/mainframe.cc:330
+msgid "&Windows"
+msgstr "&Fenêtres"
+
+#: wxwin/mainframe.cc:331
+msgid "&Help"
+msgstr "&Aide"
+
+#: wxwin/mainframe.cc:355 wxwin/mainframe.cc:393
+msgid "No dictionary selected"
+msgstr "Pas de dictionnaire sélectionné"
+
+#: wxwin/mainframe.cc:355 wxwin/mainframe.cc:393 wxwin/mainframe.cc:487
+#: wxwin/mainframe.cc:507 wxwin/mainframe.cc:538
+msgid "Eliot: error"
+msgstr "Eliot : erreur"
+
+#: wxwin/mainframe.cc:413
+msgid "Cannot open "
+msgstr "Impossible d'ouvrir "
+
+#: wxwin/mainframe.cc:425 wxwin/mainframe.cc:434
+msgid "Error while loading the game"
+msgstr "Erreur pendant le chargement de la partie"
+
+#: wxwin/mainframe.cc:426
+msgid "Invalid game"
+msgstr "Partie invalide"
+
+#: wxwin/mainframe.cc:435
+msgid "The game is empty"
+msgstr "La partie est vide"
+
+#: wxwin/mainframe.cc:467
+msgid "Cannot create "
+msgstr "Impossible de créer "
+
+#: wxwin/mainframe.cc:496 wxwin/mainframe.cc:560
+msgid "Printing not done"
+msgstr "Impression non effectuée"
+
+#: wxwin/mainframe.cc:496 wxwin/mainframe.cc:524
+msgid "Printing"
+msgstr "Impression"
+
+#: wxwin/mainframe.cc:519
+msgid "Print preview problem.\n"
+msgstr "Problème avec l'aperçu avant impression.\n"
+
+#: wxwin/mainframe.cc:520
+msgid "The printer may not be correctly initialized"
+msgstr "Il se peut que l'imprimante soit mal initialisée"
+
+#: wxwin/mainframe.cc:521
+msgid "Print preview"
+msgstr "Aperçu avant impression"
+
+#: wxwin/mainframe.cc:542
+msgid "Print to a PostScript file"
+msgstr "Imprimer dans un fichier PostScript"
+
+#: wxwin/mainframe.cc:561 wxwin/mainframe.cc:567
+msgid "PostScript printing"
+msgstr "Impression PostScript"
+
+#: wxwin/mainframe.cc:566
+msgid "Cannot initialize PostScript printer"
+msgstr "Impossible d'initialiser l'impression PostScript"
+
+#: wxwin/mainframe.cc:714
+msgid ""
+"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."
+msgstr ""
+"Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le "
+"modifier selon les termes de la licence \"GNU General Public License\" "
+"publiée par la Free Software Fundation ; soit la version 2 de la Licence, "
+"soit (comme vous le préférez), n'importe quelle version ultérieure."
+
+#: wxwin/mainframe.cc:912
+msgid "turn:"
+msgstr "coup :"
+
+#: wxwin/mainframe.cc:913
+msgid "points:"
+msgstr "points :"
+
+#: wxwin/mainframe.cc:948
+msgid ""
+"The bag doesn't contain enough letters\n"
+"for a new rack."
+msgstr ""
+"Le sac ne contient pas assez de lettres\n"
+"pour un nouveau tirage."
+
+#: wxwin/mainframe.cc:949 wxwin/mainframe.cc:953 wxwin/mainframe.cc:957
+msgid "Rack validation"
+msgstr "Validation du tirage"
+
+#: wxwin/mainframe.cc:952
+msgid "The rack must contain at least 2 consonants and 2 vowels."
+msgstr "Le tirage doit contenir au moins 2 consonnes et 2 voyelles."
+
+#: wxwin/mainframe.cc:956
+msgid "The rack contains invalid letters for the current dictionary"
+msgstr ""
+"Le tirage contient des lettres incorrectes pour le dictionnaire courant"
+
+#: wxwin/mainframe.cc:960
+msgid "The rack has been modified manually"
+msgstr "Le tirage a été modifié manuellement"
+
+#: wxwin/searchpanel.cc:146 wxwin/searchpanel.cc:190
+#, c-format
+msgid "The search is limited to %d letters"
+msgstr "La recherche est limitée à %d lettres"
+
+#: wxwin/searchpanel.cc:301
+msgid "Minimum length"
+msgstr "Longueur minimum"
+
+#: wxwin/searchpanel.cc:303
+msgid "Maximum length"
+msgstr "Longueur maximum"
+
+#: wxwin/searchpanel.cc:366
+msgid "Cross words"
+msgstr "Mots croisés"
+
+#: wxwin/searchpanel.cc:367
+msgid "Plus 1"
+msgstr "Plus 1"
+
+#: wxwin/searchpanel.cc:368
+msgid "Regular expressions"
+msgstr "Expressions régulières"
+
+#~ msgid " Racks "
+#~ msgstr " Tirages "
+
+#~ msgid " Help "
+#~ msgstr " Aide "
+
+#~ msgid " Save the game "
+#~ msgstr " Sauvegarder la partie "
+
+#~ msgid " Load a game "
+#~ msgstr " Charger une partie "
+
+#~ msgid "The rack must contain at least 2 consonants and 2 vowels\n"
+#~ msgstr "Le tirage doit contenir au moins 2 consonnes et 2 voyelles\n"
+
+#~ msgid "but the bag doesn't contain enough letters.\n"
+#~ msgstr "mais le sac ne contient plus assez de lettres.\n"
+
+#~ msgid "&Configuration"
+#~ msgstr "&Configuration"
+
+#~ msgid "Game"
+#~ msgstr "Partie"
+
+#~ msgid "Word counts double..."
+#~ msgstr "Mot compte double..."
+
+#~ msgid "Word counts triple..."
+#~ msgstr "Mot compte triple..."
+
+#~ msgid "Letter counts double..."
+#~ msgstr "Lettre compte double..."
+
+#~ msgid "Color of the \"letter counts double\" squares"
+#~ msgstr "Couleur des cases \"lettre compte double\""
+
+#~ msgid "Letter counts triple..."
+#~ msgstr "Lettre compte triple..."
+
+#~ msgid "Color of the \"letter counts triple\" squares"
+#~ msgstr "Couleur des cases \"lettre compte triple\""
+
+#, fuzzy
+#~ msgid "Fonte des lettres"
+#~ msgstr "Entrer les nouvelles lettres:"
+
+#~ msgid "Game..."
+#~ msgstr "Partie..."
+
+#, fuzzy
+#~ msgid "Results..."
+#~ msgstr "Résultat"
+
+#, fuzzy
+#~ msgid "Dictionnaire"
+#~ msgstr " Dictionnaire "
+
#~ msgid "Usage: eliotcurses /path/to/ods4.dawg\n"
#~ msgstr "Usage: eliotcurses /chemin vers/ods4.dawg\n"
#~ msgid "Played word: "
-#~ msgstr "Mot joué :"
-
-#~ msgid "Training"
-#~ msgstr "Entraînement"
+#~ msgstr "Mot joué :"
#~ msgid "Duplicate"
#~ msgstr "Duplicate"
Index: test/.cvsignore
===================================================================
RCS file: /cvsroot/eliot/eliot/test/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/.cvsignore 16 Apr 2005 15:47:59 -0000 1.1
+++ test/.cvsignore 8 Jan 2008 13:52:41 -0000 1.2
@@ -1 +1,2 @@
*.run
+load_saved_game.elt
Index: test/driver
===================================================================
RCS file: /cvsroot/eliot/eliot/test/driver,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- test/driver 5 Nov 2006 13:34:27 -0000 1.6
+++ test/driver 8 Jan 2008 13:52:41 -0000 1.7
@@ -20,6 +20,12 @@
training_bag 0 # randseed unused
# Enter a rack, then display all the possibilities
training_search 0 # randseed unused
+# Display the benjamins for several words
+training_benj 0 # randseed unused
+# Display the "raccords" for several words
+training_racc 0 # randseed unused
+# Test the 7 + 1 feature
+training_7pl1 0 # randseed unused
# Several ways of getting a rack and playing a word
training_play 4
# Training rack+search+play+back
@@ -47,6 +53,8 @@
# 2 AI players
duplicate_2_ai 5
+# 2 human players, one IA, with manual change of human player
+duplicate_humans_ai 6
#################
# Free game mode
Index: test/duplicate_2_ai.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/duplicate_2_ai.input,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/duplicate_2_ai.input 16 Apr 2005 15:47:59 -0000 1.1
+++ test/duplicate_2_ai.input 8 Jan 2008 13:52:41 -0000 1.2
@@ -3,6 +3,7 @@
a T
a l
a p
+a g
q
q
Index: test/duplicate_2_ai.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/duplicate_2_ai.ref,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- test/duplicate_2_ai.ref 1 Jan 2006 19:25:10 -0000 1.3
+++ test/duplicate_2_ai.ref 8 Jan 2008 13:52:41 -0000 1.4
@@ -3,14 +3,14 @@
mode duplicate
[?] pour l'aide
commande> a S
-Joueur 0: 866
-Joueur 1: 866
+Joueur 0: 918
+Joueur 1: 918
commande> a T
-Joueur 0: RTTUW
-Joueur 1: RTTUW
+Joueur 0: DQRU
+Joueur 1: DQRU
commande> a l
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 1 0 1 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0
commande> a p
Eliot 1.5
@@ -20,30 +20,50 @@
N | RACK | SOLUTION | REF | PTS | P | BONUS
===|==========|=================|=====|=====|===|======
- 1 | EA?AEBF | FABAcEE | H4 | 80 | 0 | *
- 2 | LMUAEYE | YEBLE | 6F | 38 | 0 |
- 3 | AMU+JEIG | MEJUGEAI | 9G | 78 | 0 | *
- 4 | LEHNMGA | HALE | 8L | 46 | 0 |
- 5 | GMN+NSEO | MENSONGE | O1 | 83 | 0 | *
- 6 | ARAURIU | RAIRA | 5B | 21 | 0 |
- 7 | UU+TSDEA | RUSTAUDE | B5 | 63 | 0 | *
- 8 | ONIAVPD | VIDA | A12 | 45 | 0 |
- 9 | NOP+SONE | PENONS | K1 | 33 | 0 |
- 10 | O+OXTOLN | LUX | J8 | 32 | 0 |
- 11 | NOOOT+SZ | ZOOS | 11E | 38 | 0 |
- 12 | NOT+MIAI | DOMINAIT | 14A | 74 | 0 | *
- 13 | CERPFEO | FEROCE | 15G | 47 | 0 |
- 14 | P+BSVQIU | PIQUAS | C1 | 32 | 0 |
- 15 | BV+ETLIE | LEVITE | A1 | 39 | 0 |
- 16 | B+RLD?UC | PUBLiC | 1C | 36 | 0 |
- 17 | DR+NTERR | DENREE | 2J | 22 | 0 |
- 18 | RRT+TUKE | TREK | 13F | 36 | 0 |
- 19 | RTU+THWI | HAI | 7G | 23 | 0 |
+ 1 | ?EBAAEF | FABAcEE | H4 | 80 | 0 | *
+ 2 | KEELIFE | KIEF | 10F | 36 | 0 |
+ 3 | EEEL+IJX | FIXEE | 4H | 34 | 0 |
+ 4 | EJL+RANS | JEANS | 11D | 49 | 0 |
+ 5 | LR+OAHPU | LOPE | 9E | 29 | 0 |
+ 6 | AHRU+OAE | HOUE | 12A | 40 | 0 |
+ 7 | AAR+AVOC | HAVA | A12 | 30 | 0 |
+ 8 | ACOR+WDN | WAX | J2 | 41 | 0 |
+ 9 | -VNIALZO | OZONAI | B10 | 48 | 0 |
+ 10 | LV+NDULU | VIN | I3 | 21 | 0 |
+ 11 | DLLUU+NO | DUNE | K1 | 22 | 0 |
+ 12 | LLOU+DAM | DOUMA | 1K | 24 | 0 |
+ 13 | DLL+TOBI | MOLLIT | N1 | 18 | 0 |
+ 14 | -ELTCUBE | CUBEBE | 6F | 31 | 0 |
+ 15 | -PE?STIE | SEPTImE | L6 | 85 | 0 | *
+ 16 | LNRSISE | SERINS | J10 | 29 | 0 |
+ 17 | L+RGYAET | STYLER | 15J | 75 | 0 |
+ 18 | AG+CURGI | CARGUE | N10 | 30 | 0 |
+ 19 | GI+EDRSS | DEGRISAS | 7B | 79 | 0 | *
+ 20 | TOEHLRT | PHOT | 8L | 27 | 0 |
+ 21 | ELRT+NME | REMELENT | C2 | 70 | 0 | *
+ 22 | QDRMUTI | MITAN | 5E | 20 | 0 |
- Total: 866
+ Total: 918
-Rack 0: RTTUW
-Rack 1: RTTUW
+Rack 0: DQRU
+Rack 1: DQRU
+commande> a g
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ A - - - - - - - - - - - H A V A
+ B - - - - - - D - - O Z O N A I
+ C - R E M E L E N T - - U - - -
+ D - - - - - - G - - - J E - - -
+ E - - - - M - R - L - E - - - -
+ F - - - - I C I - O K A - - - -
+ G - - - - T U S - P I N - - - -
+ H - - - F A B A c E E S - - - -
+ I - - V I N E S - - F - - - - -
+ J - W A X - B - - - S E R I N S
+ K D U N E - E - - - - - - - - T
+ L O - - E - S E P T I m E - - Y
+ M U - - - - - - H - - - - - - L
+ N M O L L I T - O - C A R G U E
+ O A - - - - - - T - - - - - - R
commande> q
fin du mode duplicate
commande> q
Index: test/freegame_3_ai.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_3_ai.input,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/freegame_3_ai.input 16 Apr 2005 15:47:59 -0000 1.1
+++ test/freegame_3_ai.input 8 Jan 2008 13:52:41 -0000 1.2
@@ -2,6 +2,7 @@
a T
a S
a p
+a g
q
q
Index: test/freegame_3_ai.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_3_ai.ref,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- test/freegame_3_ai.ref 1 Jan 2006 19:25:10 -0000 1.3
+++ test/freegame_3_ai.ref 8 Jan 2008 13:52:41 -0000 1.4
@@ -4,12 +4,12 @@
[?] pour l'aide
commande> a T
Joueur 0:
-Joueur 1: DEPKAS
-Joueur 2: DILMQ
+Joueur 1: ADLT
+Joueur 2: AIU
commande> a S
-Joueur 0: 398
-Joueur 1: 266
-Joueur 2: 205
+Joueur 0: 319
+Joueur 1: 286
+Joueur 2: 303
commande> a p
Eliot 1.5
@@ -20,31 +20,51 @@
N | RACK | SOLUTION | REF | PTS | P | BONUS
===|==========|=================|=====|=====|===|======
- 1 | RTADHIR | HARDI | H4 | 26 | 0 |
- 2 | ANO?EEA | ANEE | I4 | 18 | 1 |
- 3 | WIG?TEN | IWaN | J1 | 38 | 2 |
- 4 | RT+NTEIU | INTUITER | 1F | 77 | 0 | *
- 5 | AO?+TFBA | BAFOuAT | J7 | 69 | 1 | *
- 6 | EGT+OSTR | GROTTES | 9B | 70 | 2 | *
- 7 | UEEOERE | GOUREE | B9 | 18 | 0 |
- 8 | EAMIZUO | INTUITEREZ | 1F | 57 | 1 |
- 9 | XRUMGRQ | GRAUX | 12H | 34 | 2 |
- 10 | EE+ONLAS | ENOLATES | E4 | 82 | 0 | *
- 11 | AIMOU+NN | NOMINAUX | L5 | 69 | 1 | *
- 12 | MQR+LIHJ | HI | F6 | 28 | 2 |
- 13 | PLCYEFE | CAPEYE | 3I | 52 | 0 |
- 14 | EVLETDE | VOLETE | D8 | 39 | 1 |
- 15 | JLMQR+OB | ROB | O3 | 25 | 2 |
- 16 | FL+UUSML | FULL | D1 | 26 | 0 |
- 17 | DE+ICPEV | VICE | C2 | 32 | 1 |
- 18 | JLMQ+DSI | JANS | 5G | 24 | 2 |
- 19 | MSU+SAAI | ASSUMAI | 15A | 85 | 0 | *
+ 1 | RAHITRD | HARDI | H4 | 26 | 0 |
+ 2 | ?TIEXFA | FAXAIEnT | 5E | 126 | 1 | *
+ 3 | ATOSBUF | BOUTEFAS | J1 | 73 | 2 | *
+ 4 | RT+AREEN | RENTERAI | 8A | 77 | 0 | *
+ 5 | RZUGNSS | AZURS | F5 | 34 | 1 |
+ 6 | MIMLLOP | PLOMB | 1F | 30 | 2 |
+ 7 | EEMNETV | VETEMENT | L3 | 76 | 0 | *
+ 8 | GNRS+PEN | REPS | 11I | 25 | 1 |
+ 9 | ILM+HSVI | VIZIR | 6D | 33 | 2 |
+ 10 | AWELOUB | WEB | J10 | 34 | 0 |
+ 11 | GNN+EELE | EGEENNE | B8 | 20 | 1 |
+ 12 | HLMS+OJC | LOCHS | 13F | 30 | 2 |
+ 13 | AELOU+TA | TAULE | A11 | 27 | 0 |
+ 14 | L+ADSALY | LYS | M1 | 34 | 1 |
+ 15 | JM+U?EKO | TOKaJ | D8 | 40 | 2 |
+ 16 | AO+QRSED | COQ | H13 | 36 | 0 |
+ 17 | AADL+INN | YIN | 2M | 24 | 1 |
+ 18 | EMU+IGRO | GOUMIER | 2B | 82 | 2 | *
+ 19 | ADERS+IC | ENCRAIS | O1 | 30 | 0 |
+ 20 | AADLN+TE | ANE | E10 | 28 | 1 |
+ 21 | EUIAU | TUEE | 4J | 18 | 2 |
+ 22 | D | DU | D1 | 5 | 0 |
- Total: 869
+ Total: 908
Rack 0:
-Rack 1: DEP+KAS
-Rack 2: DILMQ
+Rack 1: ADLT
+Rack 2: AIU
+commande> a g
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ A - - - - - - - R - - T A U L E
+ B - G - - - - - E G E E N N E -
+ C - O - - - - - N - - - - - - -
+ D D U - - - V - T O K a J - - -
+ E - M - - F I - E - A N E - - -
+ F P I - - A Z U R S - - - L - -
+ G L E - - X I - A - - - - O - -
+ H O R - H A R D I - - - - C O Q
+ I M - - - I - - - - - R - H - -
+ J B O U T E F A S - W E B S - -
+ K - - - U n - - - - - P - - - -
+ L - - V E T E M E N T S - - - -
+ M L Y S E - - - - - - - - - - -
+ N - I - - - - - - - - - - - - -
+ O E N C R A I S - - - - - - - -
commande> q
fin du mode partie libre
commande> q
Index: test/freegame_change.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_change.input,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/freegame_change.input 16 Apr 2005 15:47:59 -0000 1.1
+++ test/freegame_change.input 8 Jan 2008 13:52:41 -0000 1.2
@@ -2,14 +2,15 @@
a T
p JID
a T
-p auouel
+p aowalt
a T
-p WX
+p MA
a T
-p WA
+p MN
a T
-p KEEEAAI
+p SGEEEAI
a T
+a p
q
q
Index: test/freegame_change.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_change.ref,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- test/freegame_change.ref 24 Dec 2005 17:50:11 -0000 1.2
+++ test/freegame_change.ref 8 Jan 2008 13:52:41 -0000 1.3
@@ -3,28 +3,46 @@
mode partie libre
[?] pour l'aide
commande> a T
-Joueur 0: NEIJEDN
-Joueur 1: UUEALEO
+Joueur 0: JNNEDEI
+Joueur 1: TLAEOWA
commande> p JID
commande> a T
-Joueur 0: EENNWTA
-Joueur 1: UUEALEO
-commande> p auouel
+Joueur 0: EENNMEN
+Joueur 1: TLAEOWA
+commande> p aowalt
commande> a T
-Joueur 0: EENNWTA
-Joueur 1: EEAKEIA
-commande> p WX
+Joueur 0: EENNMEN
+Joueur 1: EEEGAIS
+commande> p MA
commande> a T
-Joueur 0: EENNWTA
-Joueur 1: EEAKEIA
-commande> p WA
+Joueur 0: EENNMEN
+Joueur 1: EEEGAIS
+commande> p MN
commande> a T
-Joueur 0: EENNTOD
-Joueur 1: EEAKEIA
-commande> p KEEEAAI
+Joueur 0: EEENNER
+Joueur 1: EEEGAIS
+commande> p SGEEEAI
commande> a T
-Joueur 0: EENNTOD
-Joueur 1: UNLEUSS
+Joueur 0: EEENNER
+Joueur 1: HAAUAUO
+commande> a p
+Eliot 1.5
+
+Game type: Free game
+Player 0: Human
+Player 1: Human
+
+ N | RACK | SOLUTION | REF | PTS | P | BONUS
+ ===|==========|=================|=====|=====|===|======
+ 1 | JNNEDEI | (-JID) | - | 0 | 0 |
+ 2 | TLAEOWA | (-AOWALT) | - | 0 | 1 |
+ 3 | EENN+MEN | (-MN) | - | 0 | 0 |
+ 4 | E+EEGAIS | (-SGEEEAI) | - | 0 | 1 |
+
+ Total: 0
+
+Rack 0: EEENN+ER
+Rack 1: HAAUAUO
commande> q
fin du mode partie libre
commande> q
Index: test/freegame_passing.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_passing.input,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/freegame_passing.input 16 Apr 2005 15:47:59 -0000 1.1
+++ test/freegame_passing.input 8 Jan 2008 13:52:41 -0000 1.2
@@ -2,6 +2,9 @@
a S
p
p
+a t
+p UIET
+a t
p
p
p
@@ -22,6 +25,9 @@
p
p
p
+p
+a S
+a T
a p
q
q
Index: test/freegame_passing.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_passing.ref,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- test/freegame_passing.ref 1 Jan 2006 19:25:10 -0000 1.3
+++ test/freegame_passing.ref 8 Jan 2008 13:52:41 -0000 1.4
@@ -7,6 +7,11 @@
Joueur 1: 0
commande> p
commande> p
+commande> a t
+EGISSTU
+commande> p UIET
+commande> a t
+GSSTAUV
commande> p
commande> p
commande> p
@@ -27,6 +32,13 @@
commande> p
commande> p
commande> p
+commande> p
+commande> a S
+Joueur 0: -11
+Joueur 1: 777
+commande> a T
+Joueur 0: AGSSTUV
+Joueur 1:
commande> a p
Eliot 1.5
@@ -36,28 +48,59 @@
N | RACK | SOLUTION | REF | PTS | P | BONUS
===|==========|=================|=====|=====|===|======
- 1 | RENLOHL | HERON | H4 | 24 | 1 |
- 2 | LL+XUORC | OCREUX | 5E | 34 | 1 |
- 3 | LL+NAECT | CALLENT | I7 | 73 | 1 | *
- 4 | DIBB?EM | BIBENDuM | 12E | 78 | 1 | *
- 5 | TOEOMLZ | TOMIEZ | F9 | 38 | 1 |
- 6 | LO+ESLSI | SOLEILS | M6 | 73 | 1 | *
- 7 | UEGTVAW | VAGUEZ | 14A | 38 | 1 |
- 8 | TW+LAEPU | PAVE | A12 | 36 | 1 |
- 9 | LTUW+FAA | FATWA | N2 | 42 | 1 |
- 10 | LU+JAEYU | LAYE | O1 | 61 | 1 |
- 11 | JUU+SENI | JEUNE | H11 | 47 | 1 |
- 12 | ISU+RMPN | SPRAY | 3K | 32 | 1 |
- 13 | IMNU+AIV | VLAN | 8L | 33 | 1 |
- 14 | IIMU+UQE | QUI | B10 | 30 | 1 |
- 15 | EIMU+RNF | UNIFORME | E1 | 62 | 1 | *
- 16 | ODITREE | ETOURDIE | 1B | 80 | 1 | *
- 17 | TEN?IKR | jERKE | 8A | 69 | 1 |
+ 1 | SEUTISG | (PASS) | - | 0 | 0 |
+ 2 | LXCORNU | ROUX | H8 | 26 | 1 |
+ 3 | EGISSTU | (PASS) | - | 0 | 0 |
+ 4 | CLN+?BEC | CiNECLUB | 10B | 75 | 1 | *
+ 5 | EGISSTU | (-UIET) | - | 0 | 0 |
+ 6 | LLESYEO | YOLES | J6 | 52 | 1 |
+ 7 | GSS+TAUV | (PASS) | - | 0 | 0 |
+ 8 | EL+AAOGT | GALETA | 11A | 29 | 1 |
+ 9 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 10 | O+RTEUMI | MORUTIER | 8A | 80 | 1 | *
+ 11 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 12 | EUNPFUP | PFUT | E5 | 18 | 1 |
+ 13 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 14 | ENPU+FTE | FETE | 12B | 33 | 1 |
+ 15 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 16 | NPU+NSIM | LUPINS | 8J | 33 | 1 |
+ 17 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 18 | MN+UEWOI | WON | N6 | 32 | 1 |
+ 19 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 20 | EIMNU+MI | IMMUNS | O3 | 23 | 1 |
+ 21 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 22 | EI+IDRED | BIRDIE | I10 | 22 | 1 |
+ 23 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 24 | DE+RJAAT | DEJETA | 15H | 45 | 1 |
+ 25 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 26 | AR+ENQEE | CAFRE | B10 | 20 | 1 |
+ 27 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 28 | AEENQ+BR | BADERNE | 13G | 26 | 1 |
+ 29 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 30 | Q+EAZAEL | ZEN | L11 | 24 | 1 |
+ 31 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 32 | AAELQ+RA | ALEA | I3 | 16 | 1 |
+ 33 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 34 | AQR+LDEH | ADHERAI | 3I | 22 | 1 |
+ 35 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 36 | LQ+SI?AI | QuASI | N10 | 65 | 1 |
+ 37 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 38 | IL+TVHEO | OHE | 4K | 29 | 1 |
+ 39 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 40 | ILTV+ONK | KOHOL | K1 | 34 | 1 |
+ 41 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 42 | INTV+SIN | NAYS | 6H | 31 | 1 |
+ 43 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 44 | IINTV | TIKI | 1I | 14 | 1 |
+ 45 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 46 | NV | VU | D7 | 10 | 1 |
+ 47 | AGSSTUV | (PASS) | - | 0 | 0 |
+ 48 | N | NI | M7 | 7 | 1 |
- Total: 850
+ Total: 766
-Rack 0: EGISSTU
-Rack 1: INT+ESDO
+Rack 0: AGSSTUV
+Rack 1:
commande> q
fin du mode partie libre
commande> q
Index: test/load_saved_game.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/load_saved_game.ref,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/load_saved_game.ref 1 Jan 2006 19:25:10 -0000 1.1
+++ test/load_saved_game.ref 8 Jan 2008 13:52:41 -0000 1.2
@@ -12,16 +12,16 @@
LMUAEYE
commande> r
commande> a r
- 1: YEBLE 38 6F
- 2: BAYLE 36 6H
- 3: AMYLE 35 10D
- 4: ELYME 35 10D
- 5: ELYME 35 10H
+ 1: AY 46 I6
+ 2: YEBLE 38 6F
+ 3: MAYE 36 I3
+ 4: BAYLE 36 6H
+ 5: AMYLE 35 10D
6: BAYE 35 6H
- 7: BEY 34 6H
- 8: LAYEE 34 10D
- 9: YUE 32 10F
- 10: AMYLE 30 5H
+ 7: ELYME 35 10D
+ 8: ELYME 35 10H
+ 9: LAYE 34 I3
+ 10: LAYEE 34 10D
commande> n 2
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -30,13 +30,13 @@
C - - - - - - - - - - - - - - -
D - - - - - - - - - - - - - - -
E - - - - - - - - - - - - - - -
- F - - - - - - - - - - - - - - -
- G - - - - - - - - - - - - - - -
+ F - - - - - Y - - - - - - - - -
+ G - - - - - E - - - - - - - - -
H - - - F A B A c E E - - - - -
- I - - - - - A - - - - - - - - -
- J - - - - - Y - - - - - - - - -
- K - - - - - L - - - - - - - - -
- L - - - - - E - - - - - - - - -
+ I - - - - - L - - - - - - - - -
+ J - - - - - E - - - - - - - - -
+ K - - - - - - - - - - - - - - -
+ L - - - - - - - - - - - - - - -
M - - - - - - - - - - - - - - -
N - - - - - - - - - - - - - - -
O - - - - - - - - - - - - - - -
@@ -48,19 +48,19 @@
commande>
commande> +
commande> a t
-AMUJEIG
+EELMUJE
commande> r
commande> a r
- 1: MEJUGEAI * 78 9G
- 2: MEJUGEAI * 72 9C
- 3: MEJUGEAI * 71 10G
- 4: MEJUGEAI * 71 10C
- 5: MEJUGEAI * 69 J5
- 6: MEJUGEAI * 69 J1
- 7: JUGEA 37 5B
- 8: JUGEAI 37 5J
- 9: JAUGE 35 5J
- 10: JUGEA 35 5J
+ 1: JUMEL 38 J2
+ 2: JUMELEE 33 10B
+ 3: JUMELA 28 5C
+ 4: JUMELEE 25 9C
+ 5: JUMELE 24 G10
+ 6: JUMEL 23 G10
+ 7: JUMELE 23 9C
+ 8: JEU 19 9G
+ 9: JEU 19 G10
+ 10: JUMELEE 19 10E
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -69,50 +69,50 @@
C - - - - - - - - - - - - - - -
D - - - - - - - - - - - - - - -
E - - - - - - - - - - - - - - -
- F - - - - - Y - - - - - - - - -
- G - - - - - E - - M - - - - - -
+ F - - - - - - - - - - - - - - -
+ G - - - - - - - - - - - - - - -
H - - - F A B A c E E - - - - -
- I - - - - - L - - J - - - - - -
- J - - - - - E - - U - - - - - -
- K - - - - - - - - G - - - - - -
- L - - - - - - - - E - - - - - -
- M - - - - - - - - A - - - - - -
- N - - - - - - - - I - - - - - -
+ I - - - - - A Y - - - - - - - -
+ J - J U M E L - - - - - - - - -
+ K - - - - - - - - - - - - - - -
+ L - - - - - - - - - - - - - - -
+ M - - - - - - - - - - - - - - -
+ N - - - - - - - - - - - - - - -
O - - - - - - - - - - - - - - -
commande>
commande> +
commande> a t
-LEHNMGA
+EEIGLEH
commande> r
commande> a r
- 1: HALE 46 8L
- 2: MALE 30 8L
- 3: ENGAMA 30 5C
- 4: HALA 27 5E
- 5: LAME 26 8L
- 6: HAN 25 8M
- 7: HELA 25 5C
- 8: GLANA 25 5D
- 9: EMANA 25 5D
- 10: EGALA 25 5D
+ 1: HELIEE 34 K5
+ 2: HELEE 32 K5
+ 3: EGAYEE 32 7F
+ 4: EGAYE 31 7F
+ 5: HELE 30 K5
+ 6: LAYEE 29 7G
+ 7: LAYE 28 7G
+ 8: HUILEE 26 3I
+ 9: HE 26 K5
+ 10: HUILE 24 3I
commande> n 3
commande>
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
A - - - - - - - - - - - - - - -
B - - - - - - - - - - - - - - -
- C - - - - E - - - - - - - - - -
- D - - - - N - - - - - - - - - -
- E - - - - G - - - - - - - - - -
- F - - - - A Y - - - - - - - - -
- G - - - - M E - - M - - - - - -
+ C - - - - - - - - - - - - - - -
+ D - - - - - - - - - - - - - - -
+ E - - - - - - - - - - - - - - -
+ F - - - - - - E - - - - - - - -
+ G - - - - - - G - - - - - - - -
H - - - F A B A c E E - - - - -
- I - - - - - L - - J - - - - - -
- J - - - - - E - - U - - - - - -
- K - - - - - - - - G - - - - - -
- L - - - - - - - - E - - - - - -
- M - - - - - - - - A - - - - - -
- N - - - - - - - - I - - - - - -
+ I - - - - - A Y - - - - - - - -
+ J - J U M E L E - - - - - - - -
+ K - - - - - - E - - - - - - - -
+ L - - - - - - - - - - - - - - -
+ M - - - - - - - - - - - - - - -
+ N - - - - - - - - - - - - - - -
O - - - - - - - - - - - - - - -
commande> a p
Eliot 1.5
@@ -123,16 +123,16 @@
N | RACK | SOLUTION | REF | PTS | P | BONUS
===|==========|=================|=====|=====|===|======
1 | EA?AEBF | FABAcEE | H4 | 80 | 0 | *
- 2 | LMUAEYE | YEBLE | 6F | 38 | 0 |
- 3 | AMU+JEIG | MEJUGEAI | 9G | 78 | 0 | *
- 4 | LEHNMGA | ENGAMA | 5C | 30 | 0 |
+ 2 | LMUAEYE | AY | I6 | 46 | 0 |
+ 3 | EELMU+JE | JUMEL | J2 | 38 | 0 |
+ 4 | EE+IGLEH | EGAYEE | 7F | 32 | 0 |
- Total: 226
+ Total: 196
-Rack 0: HL
+Rack 0: HIL
commande> a l
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
- 5 1 2 3 9 1 0 2 7 0 1 4 1 5 6 2 1 6 6 6 5 2 1 1 0 1 1
+ 6 1 2 3 9 1 1 2 8 0 1 4 2 6 6 2 1 6 6 6 5 2 1 1 0 1 1
commande>
commande> s load_saved_game.elt
commande> q
@@ -145,18 +145,18 @@
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
A - - - - - - - - - - - - - - -
B - - - - - - - - - - - - - - -
- C - - - - E - - - - - - - - - -
- D - - - - N - - - - - - - - - -
- E - - - - G - - - - - - - - - -
- F - - - - A Y - - - - - - - - -
- G - - - - M E - - M - - - - - -
+ C - - - - - - - - - - - - - - -
+ D - - - - - - - - - - - - - - -
+ E - - - - - - - - - - - - - - -
+ F - - - - - - E - - - - - - - -
+ G - - - - - - G - - - - - - - -
H - - - F A B A c E E - - - - -
- I - - - - - L - - J - - - - - -
- J - - - - - E - - U - - - - - -
- K - - - - - - - - G - - - - - -
- L - - - - - - - - E - - - - - -
- M - - - - - - - - A - - - - - -
- N - - - - - - - - I - - - - - -
+ I - - - - - A Y - - - - - - - -
+ J - J U M E L E - - - - - - - -
+ K - - - - - - E - - - - - - - -
+ L - - - - - - - - - - - - - - -
+ M - - - - - - - - - - - - - - -
+ N - - - - - - - - - - - - - - -
O - - - - - - - - - - - - - - -
commande> a p
Eliot 1.5
@@ -167,16 +167,16 @@
N | RACK | SOLUTION | REF | PTS | P | BONUS
===|==========|=================|=====|=====|===|======
1 | EA?AEBF | FABAcEE | H4 | 80 | 0 | *
- 2 | LMUAEYE | YEBLE | 6F | 38 | 0 |
- 3 | AMU+JEIG | MEJUGEAI | 9G | 78 | 0 | *
- 4 | LEHNMGA | ENGAMA | 5C | 30 | 0 |
+ 2 | LMUAEYE | AY | I6 | 46 | 0 |
+ 3 | EELMU+JE | JUMEL | J2 | 38 | 0 |
+ 4 | EE+IGLEH | EGAYEE | 7F | 32 | 0 |
- Total: 226
+ Total: 196
-Rack 0: HL
+Rack 0: HIL
commande> a l
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
- 5 1 2 3 9 1 0 2 7 0 1 4 1 5 6 2 1 6 6 6 5 2 1 1 0 1 1
+ 6 1 2 3 9 1 1 2 8 0 1 4 2 6 6 2 1 6 6 6 5 2 1 1 0 1 1
commande>
commande> q
fin du mode entraînement
Index: test/regexp.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/regexp.ref,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/regexp.ref 1 Jan 2006 19:25:10 -0000 1.1
+++ test/regexp.ref 8 Jan 2008 13:52:41 -0000 1.2
@@ -2,6 +2,10 @@
commande> x a.* 50
search for a.* (50,1,15)
aa
+aalenien
+aalenienne
+aaleniennes
+aaleniens
aas
abaca
abacas
@@ -47,14 +51,14 @@
abaisseriez
abaisserions
abaisserons
-abaisseront
-abaisses
-abaisseur
-abaisseurs
50 printed results
commande> x a.* 200
search for a.* (200,1,15)
aa
+aalenien
+aalenienne
+aaleniennes
+aaleniens
aas
abaca
abacas
@@ -250,10 +254,6 @@
abattant
abattants
abatte
-abattee
-abattees
-abattement
-abattements
200 printed results
commande> x .*a.*e.*i.*o.*u.* 50 10
search for .*a.*e.*i.*o.*u.* (50,10,15)
@@ -329,13 +329,13 @@
anthophages
bishop
bishops
+bronchopathie
+bronchopathies
cenesthopathie
cenesthopathies
chop
chopa
chopai
-chopaient
-chopais
50 printed results
commande> x a.*b 50
search for a.*b (50,1,15)
@@ -352,13 +352,14 @@
bob
bulb
cab
+cheb
cineclub
club
cob
coulomb
crib
cuproplomb
-13 printed results
+14 printed results
commande> x [abc]*b
search for [abc]*b (50,1,15)
cab
@@ -378,6 +379,7 @@
bob
bulb
cab
+cheb
cineclub
club
cob
@@ -386,14 +388,17 @@
cuproplomb
dab
deb
+dub
fob
guib
hidjab
+hijab
hub
jab
job
kebab
kob
+lamb
lob
mahaleb
mihrab
@@ -417,16 +422,14 @@
surplomb
toubab
toubib
-tub
-videoclub
-web
-winstub
50 printed results
commande> x .*(cba)+b
search for .*(cba)+b (50,1,15)
0 printed results
commande> x .*(nn)+.*
search for .*(nn)+.* (50,1,15)
+aalenienne
+aaleniennes
abandonna
abandonnai
abandonnaient
@@ -475,11 +478,10 @@
abandonniques
abandonnons
abbevillienne
-abbevilliennes
-abelienne
50 printed results
commande> x .*(nn)+.*x 200
search for .*(nn)+.*x (200,1,15)
+actionnariaux
annaux
anneaux
baronniaux
@@ -515,6 +517,7 @@
panneaux
paonneaux
pigeonneaux
+pitonneux
poissonneux
precautionneux
processionnaux
@@ -535,5 +538,5 @@
vallonneux
vanneaux
vicennaux
-55 printed results
+57 printed results
commande> q
Index: test/regression.pl
===================================================================
RCS file: /cvsroot/eliot/eliot/test/regression.pl,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/regression.pl 16 Apr 2005 15:47:59 -0000 1.1
+++ test/regression.pl 8 Jan 2008 13:52:41 -0000 1.2
@@ -3,9 +3,19 @@
use strict;
use warnings;
+use Cwd 'abs_path';
+
+my $root_path = $0;
+$root_path =~ s/regression.pl/../;
+$root_path = abs_path($root_path);
+
+#Â Change to the test/ directory, because some scenarii expect
+# to find saved games in there
+chdir("$root_path/test");
+
my $driver_file = "driver";
-# Look for ~/ods4.dawg
-my $ods = "$ENV{HOME}/ods4.dawg";
+# Look for ~/ods5.dawg
+my $ods = "$ENV{HOME}/ods5.dawg";
# File extensions
my $input_ext = ".input";
@@ -16,18 +26,18 @@
# Find the dictionary
if (not -f $ods)
{
- die "Cannot find dictionary: $!";
+ die "Cannot find dictionary $ods: $!";
}
# Find the text interface
my $eliottxt;
-if (-x "../utils/eliottxt")
+if (-x "$root_path/utils/eliottxt")
{
- $eliottxt = "../utils/eliottxt";
+ $eliottxt = "$root_path/utils/eliottxt";
}
-elsif (-x "../utils/eliottxt.exe")
+elsif (-x "$root_path/utils/eliottxt.exe")
{
- $eliottxt = "../utils/eliottxt.exe";
+ $eliottxt = "$root_path/utils/eliottxt.exe";
}
else
{
Index: test/training_back.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_back.input,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/training_back.input 27 Dec 2005 01:04:49 -0000 1.1
+++ test/training_back.input 8 Jan 2008 13:52:41 -0000 1.2
@@ -9,17 +9,22 @@
a r
n 2
a g
+a s
n -1
+a s
a g
a p
n -1
+a s
a p
a g
a l
n -1
+a s
*
r
n 1
+a s
a l
a p
q
Index: test/training_back.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_back.ref,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- test/training_back.ref 1 Jan 2006 19:25:10 -0000 1.2
+++ test/training_back.ref 8 Jan 2008 13:52:42 -0000 1.3
@@ -12,16 +12,16 @@
LMUAEYE
commande> r
commande> a r
- 1: YEBLE 38 6F
- 2: BAYLE 36 6H
- 3: AMYLE 35 10D
- 4: ELYME 35 10D
- 5: ELYME 35 10H
+ 1: AY 46 I6
+ 2: YEBLE 38 6F
+ 3: MAYE 36 I3
+ 4: BAYLE 36 6H
+ 5: AMYLE 35 10D
6: BAYE 35 6H
- 7: BEY 34 6H
- 8: LAYEE 34 10D
- 9: YUE 32 10F
- 10: AMYLE 30 5H
+ 7: ELYME 35 10D
+ 8: ELYME 35 10H
+ 9: LAYE 34 I3
+ 10: LAYEE 34 10D
commande> n 2
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -30,17 +30,21 @@
C - - - - - - - - - - - - - - -
D - - - - - - - - - - - - - - -
E - - - - - - - - - - - - - - -
- F - - - - - - - - - - - - - - -
- G - - - - - - - - - - - - - - -
+ F - - - - - Y - - - - - - - - -
+ G - - - - - E - - - - - - - - -
H - - - F A B A c E E - - - - -
- I - - - - - A - - - - - - - - -
- J - - - - - Y - - - - - - - - -
- K - - - - - L - - - - - - - - -
- L - - - - - E - - - - - - - - -
+ I - - - - - L - - - - - - - - -
+ J - - - - - E - - - - - - - - -
+ K - - - - - - - - - - - - - - -
+ L - - - - - - - - - - - - - - -
M - - - - - - - - - - - - - - -
N - - - - - - - - - - - - - - -
O - - - - - - - - - - - - - - -
+commande> a s
+118
commande> n -1
+commande> a s
+80
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
A - - - - - - - - - - - - - - -
@@ -72,6 +76,8 @@
Rack 0: LMUAEYE
commande> n -1
+commande> a s
+0
commande> a p
Eliot 1.5
@@ -105,9 +111,13 @@
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
9 2 2 3 15 2 2 2 8 1 1 5 3 6 6 2 1 6 6 6 6 2 1 1 1 1 2
commande> n -1
+commande> a s
+0
commande> *
commande> r
commande> n 1
+commande> a s
+14
commande> a l
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
9 2 2 3 13 1 2 2 7 1 1 5 3 6 6 2 1 6 6 6 6 2 1 1 1 1 2
Index: test/training_cross.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_cross.ref,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/training_cross.ref 1 Jan 2006 19:25:10 -0000 1.1
+++ test/training_cross.ref 8 Jan 2008 13:52:42 -0000 1.2
@@ -46,15 +46,15 @@
commande> r
commande> a r
1: KIMONO 38 6F
- 2: AMOK 34 6G
- 3: MOKA 34 6H
- 4: MOKO 34 6H
- 5: MAKI 34 6H
- 6: KAMI 34 6F
- 7: KINA 33 I3
+ 2: KEMIA 37 6F
+ 3: MOKO 34 6H
+ 4: AMOK 34 6G
+ 5: MOKA 34 6H
+ 6: MAKI 34 6H
+ 7: KAMI 34 6F
8: KINE 33 I3
- 9: KAN 29 I3
- 10: OKA 27 I2
+ 9: KINA 33 I3
+ 10: KAN 29 I3
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -88,9 +88,9 @@
4: SWEAT 32 L6
5: ETAIES 31 L1
6: AISEE 29 L4
- 7: ETAIS 27 L2
+ 7: TAIES 27 L2
8: TAISE 27 L3
- 9: TAIES 27 L2
+ 9: ETAIS 27 L2
10: WESTIE 27 9F
commande> n 1
commande> a g
@@ -124,8 +124,8 @@
3: LAVASSE * 78 10G
4: VASSALE * 75 K9
5: LAVASSE * 73 9C
- 6: LAVASSE * 72 9D
- 7: LAVASSE * 72 K9
+ 6: LAVASSE * 72 K9
+ 7: LAVASSE * 72 9D
8: VASSALE * 67 G8
9: LAVASSE * 64 G8
10: EVASAS 35 10I
@@ -160,12 +160,12 @@
2: BIQUE 42 8K
3: OTIQUE 39 8J
4: TIQUE 36 8K
- 5: BEQUET 30 N9
- 6: MAQUE 29 K9
- 7: EMBUT 29 M1
- 8: MOQUE 28 11D
- 9: QUETE 28 N6
- 10: TAQUE 26 K9
+ 5: BAQUET 34 K9
+ 6: BAQUE 32 K9
+ 7: BEQUET 30 N9
+ 8: EMBUT 29 M1
+ 9: MAQUE 29 K9
+ 10: MOQUE 28 11D
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -196,13 +196,13 @@
1: OMNIBUS * 94 O4
2: EMBUIONS * 84 14H
3: BITUMONS * 62 15F
- 4: SIMOUN 38 O10
- 5: BOUSIN 38 O7
- 6: NIMBUS 38 O5
- 7: BISON 35 O8
- 8: BISOU 35 O8
- 9: BOUMS 35 O6
- 10: IMBUS 35 O6
+ 4: NIMBUS 38 O5
+ 5: SIMOUN 38 O10
+ 6: BOUSIN 38 O7
+ 7: IMBUS 35 O6
+ 8: BISON 35 O8
+ 9: BISOU 35 O8
+ 10: BOUMS 35 O6
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -236,9 +236,9 @@
4: AXEZ 44 K10
5: IXEE 33 14E
6: EXPIEZ 32 14D
- 7: ZEE 32 14F
- 8: ZOE 32 14F
- 9: EXPIEZ 32 14H
+ 7: GEX 32 5K
+ 8: EXPIEZ 32 14H
+ 9: EPIEZ 32 N10
10: EXPIE 32 N10
commande> n 1
commande> a g
@@ -306,14 +306,14 @@
commande> a r
1: VAINCU 28 13C
2: VAINC 25 K9
- 3: CONVOI 24 11D
- 4: CAVAI 24 K9
- 5: CONVIA 23 7A
- 6: VAGIN 23 K9
- 7: CONVIA 22 13J
+ 3: VACOA 25 K9
+ 4: CONVOI 24 11D
+ 5: CAVAI 24 K9
+ 6: CONVIA 23 7A
+ 7: VAGIN 23 K9
8: VINA 22 7C
9: CAVA 22 K9
- 10: CANE 21 7E
+ 10: CONVIA 22 13J
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -349,8 +349,8 @@
6: AGRESSA 20 D7
7: OSES 19 11H
8: OSAS 19 11H
- 9: ESSORA 18 7A
- 10: GERA 18 7C
+ 9: AGES 18 5J
+ 10: GOSSERA 18 D7
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -386,8 +386,8 @@
6: JEUDIS 30 C3
7: JUDD 29 N1
8: JAR 29 K9
- 9: JUPE 28 12L
- 10: JARD 28 D12
+ 9: JARD 28 D12
+ 10: JUPE 28 12L
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -422,9 +422,9 @@
5: DYADES 36 C3
6: DYADE 34 D11
7: LAYES 34 B4
- 8: DELAYA 34 D10
- 9: YAWL 34 4J
- 10: DRAYE 30 E7
+ 8: YAWL 34 4J
+ 9: DELAYA 34 D10
+ 10: ALYA 33 F8
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -453,14 +453,14 @@
commande> r
commande> a r
1: HEU 32 10B
- 2: BEDE 31 10B
- 3: HE 31 10B
+ 2: HE 31 10B
+ 3: BEDE 31 10B
4: BEE 29 10B
- 5: DEB 28 10B
- 6: IDEE 27 10A
- 7: HIEE 27 10A
- 8: HUEE 27 10A
- 9: BUEE 26 10A
+ 5: BE 28 10B
+ 6: DEB 28 10B
+ 7: IDEE 27 10A
+ 8: HIEE 27 10A
+ 9: HUEE 27 10A
10: HIE 26 10A
commande> n 1
commande> a g
@@ -491,13 +491,13 @@
commande> a r
1: CIEL 25 D1
2: CLE 22 12D
- 3: BLINDE 19 F10
- 4: ALBEDO 18 K10
- 5: DEY 18 7A
- 6: DELAVASSES 18 10F
- 7: LAIC 18 D12
- 8: BLIND 18 F10
- 9: CAID 18 D12
+ 3: BLE 22 12D
+ 4: BEY 20 7A
+ 5: BLINDE 19 F10
+ 6: BIPE 18 12L
+ 7: CAID 18 D12
+ 8: LAIC 18 D12
+ 9: BLIND 18 F10
10: CIBLE 18 4B
commande> n 1
commande> a g
@@ -529,13 +529,13 @@
1: BRADeRIE * 86 A1
2: BRIARDEs * 61 A2
3: BAuDRIER * 60 A2
- 4: BRoCARD 33 1A
- 5: pARFUMEE 33 H1
- 6: CRoBARD 33 1D
- 7: CRABIeR 30 1D
- 8: BICARRe 30 1B
+ 4: pARFUMEE 33 H1
+ 5: CRoBARD 33 1D
+ 6: BRoCARD 33 1A
+ 7: BICARRe 30 1B
+ 8: CRABIeR 30 1D
9: CIBARe 27 1D
- 10: DuRCIRA 27 1A
+ 10: CRoBAR 27 1D
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -568,10 +568,10 @@
3: CAUDEE 27 1D
4: DAW 25 4J
5: CETEAU 24 1D
- 6: CADET 24 1D
- 7: CAGEE 24 1D
- 8: CEDAT 24 1D
- 9: CAUDE 24 1D
+ 6: CEDAT 24 1D
+ 7: QUETE 24 12H
+ 8: CAUDE 24 1D
+ 9: CAGUE 24 1D
10: CAGET 24 1D
commande> n 1
commande> a g
@@ -601,14 +601,14 @@
commande> r
commande> a r
1: CERcLAGE * 80 1D
- 2: RELEGuAT * 77 15A
- 3: GELERAiT * 77 15A
- 4: GALEREnT * 77 15A
- 5: dEREGLAT * 77 15A
- 6: REGALEnT * 77 15A
- 7: AiGRELET * 77 15A
- 8: REGELAiT * 77 15A
- 9: REGELAnT * 77 15A
+ 2: REGELAnT * 77 15A
+ 3: REGELAiT * 77 15A
+ 4: REGALEnT * 77 15A
+ 5: RELEGuAT * 77 15A
+ 6: GELERAiT * 77 15A
+ 7: dEREGLAT * 77 15A
+ 8: AiGRELET * 77 15A
+ 9: GALEREnT * 77 15A
10: GREnELAT * 74 15A
commande> n 1
commande> a g
@@ -645,8 +645,8 @@
6: FLAN 21 14A
7: FAN 19 14B
8: FANON 18 11E
- 9: FLA 17 14A
- 10: NAKFA 17 F4
+ 9: NAKFA 17 F4
+ 10: FLA 17 14A
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -714,12 +714,12 @@
1: FANON 23 I3
2: KRAFT 19 F6
3: FRET 19 14A
- 4: REAI 18 E10
+ 4: REFAIT 18 13J
5: FANON 18 11E
- 6: FREON 18 11E
- 7: REFAIT 18 13J
- 8: FERAIT 18 13J
- 9: FRETIN 18 13J
+ 6: FRETIN 18 13J
+ 7: FERAIT 18 13J
+ 8: FREON 18 11E
+ 9: REAI 18 E10
10: EN 18 I13
commande> n 1
commande> a g
@@ -750,14 +750,14 @@
commande> a r
1: ET 18 I13
2: RELAVASSES 15 10F
- 3: VAINCUE 13 13C
+ 3: SE 13 M10
4: EX 13 11M
- 5: SE 13 M10
+ 5: VAINCUE 13 13C
6: TREK 13 F3
- 7: TEK 12 F4
- 8: TES 11 M8
- 9: RE 11 E10
- 10: TET 11 14B
+ 7: KEA 12 F6
+ 8: TEK 12 F4
+ 9: TET 11 14B
+ 10: RE 11 E10
commande> n 1
commande> a g
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Index: test/training_cross2.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_cross2.ref,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/training_cross2.ref 5 Nov 2006 13:34:27 -0000 1.1
+++ test/training_cross2.ref 8 Jan 2008 13:52:42 -0000 1.2
@@ -79,7 +79,7 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c7518: 1][005c7518:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c751c: 1][005c751c:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ir [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000202: 4][00184000:
1][00200222: 2][01384100: 1][01384100:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Index: test/training_cross3.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_cross3.ref,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/training_cross3.ref 5 Nov 2006 13:34:27 -0000 1.1
+++ test/training_cross3.ref 8 Jan 2008 13:52:42 -0000 1.2
@@ -45,7 +45,7 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c7518: 1][005c7518:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c751c: 1][005c751c:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ir [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000202: 4][00184000:
1][00200222: 2][01384100: 1][01384100:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
@@ -114,7 +114,7 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c7518: 1][005c7518:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c751c: 1][005c751c:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ir [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000202: 4][00184000:
1][00200222: 2][01384100: 1][01384100:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
@@ -150,7 +150,7 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:13][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c7518: 1][005c7518:
1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c751c: 1][005c751c:
1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ir [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000202: 4][00184000:
1][00200222: 2][01384100: 1][01384100:
1][00000000:13][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
@@ -165,7 +165,7 @@
Cc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ec
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00208222:
1][00000000:-1][00208222:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c7518:
1][00000000:-1][01384100:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c751c:
1][00000000:-1][01384100:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Gc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:10][00000000:-1][00200000:10][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Hc
[ffffffff:-1][ffffffff:-1][00000000:10][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:10][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ic
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
@@ -184,7 +184,7 @@
Br
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Cr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:13][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
4][010d714e: 1][00000000: 2][00000000:-1][00008000: 1][005c795a: 0][010d714e:
1][00200020: 1][ffffffff:-1][ffffffff:-1]
+ Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
4][010d714e: 1][00000000: 2][00000000:-1][00008000: 1][005c795e: 0][010d714e:
1][00200020: 1][ffffffff:-1][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][ffffffff:-1][ffffffff:-1]
Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 6][01451010: 2][00200000: 3][00000000:-1][00200222: 1][02284302:
0][00005040: 1][00200022: 1][ffffffff:-1][ffffffff:-1]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
@@ -220,7 +220,7 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:13][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c7518: 1][005c7518:
1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Gr [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000200: 4][00ddf036:
1][00000000: 2][005c751c: 1][005c751c:
1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ir [ffffffff:-1][ffffffff:-1][ffffffff:-1][00000202: 4][00184000:
1][00200222: 2][01384100: 1][01384100:
1][00000000:13][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
@@ -235,7 +235,7 @@
Cc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ec
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00208222:
1][00000000:-1][00208222:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c7518:
1][00000000:-1][01384100:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c751c:
1][00000000:-1][01384100:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Gc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:10][00000000:-1][00200000:10][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Hc
[ffffffff:-1][ffffffff:-1][00000000:10][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:10][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ic
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Index: test/training_joker2.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_joker2.ref,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- test/training_joker2.ref 5 Nov 2006 17:04:39 -0000 1.2
+++ test/training_joker2.ref 8 Jan 2008 13:52:42 -0000 1.3
@@ -46,20 +46,20 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000008:
6][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:16][00000000:-1][ffffffff:-1]
- Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795a: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
+ Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795e: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Ir
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00200222:
1][02284302: 1][00000222: 3][00000000:-1][040c0020: 6][00000000:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00080200:12][00002020:
5][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][ffffffff:-1][00000000:-1]
Kr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Lr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Mr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00080000:
8]
- Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c7518: 1]
+ Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c751c: 1]
Or
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
-
Ac
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Bc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Cc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
4][00000000:-1][00280022:
4][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c7518:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c751c:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ec
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008000:
1][00000000:-1][00200222:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00200022: 1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008022:
4][00000000:-1][00008222: 4]
Gc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][00000000:11][00000000:-1][00000000:-1][00080000:11]
@@ -67,20 +67,20 @@
Ic
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000004:
5][00000000:-1][00000000:-1][00000000: 5][ffffffff:-1][00608022:
1][00000000:-1][00210800: 2][00000000:-1]
Jc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00008000: 3][00000000:-1]
Kc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
9][00000000:-1][00000000:-1][00000000:12][00000000:-1]
- Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
+ Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00002048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
Mc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000144:
2][00000000:-1][00000000:-1][00080220: 2][ffffffff:-1]
Nc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040: 1][ffffffff:-1][ffffffff:-1]
Oc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:15][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
commande> r
commande> a r
1: SaUGRENU * 82 E4
- 2: eNjUGUES * 66 D8
- 3: NUaGEUSe * 66 D1
+ 2: NUaGEUSe * 66 D1
+ 3: eNjUGUES * 66 D8
4: GUEUSANt * 66 11C
5: GUeUSENt * 64 D6
- 6: NUaGeUSE * 64 D4
+ 6: ENjUGUeS * 64 D2
7: GUEUSeNt * 64 D3
- 8: ENjUGUeS * 64 D2
+ 8: NUaGeUSE * 64 D4
9: GUeUSENT * 62 F1
10: GUEUSeNT * 60 F1
commande> q
Index: test/training_rosace.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_rosace.ref,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- test/training_rosace.ref 5 Nov 2006 17:24:32 -0000 1.2
+++ test/training_rosace.ref 8 Jan 2008 13:52:42 -0000 1.3
@@ -64,20 +64,20 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000008:
6][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:16][00000000:-1][ffffffff:-1]
- Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795a: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
+ Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795e: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Ir
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00200222:
1][02284302: 1][00000222: 3][00000000:-1][040c0020: 6][00000000:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00080200:12][00002020:
5][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][ffffffff:-1][00000000:-1]
Kr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Lr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Mr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00080000:
8]
- Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c7518: 1]
+ Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c751c: 1]
Or
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
-
Ac
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Bc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Cc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
4][00000000:-1][00280022:
4][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c7518:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c751c:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ec
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008000:
1][00000000:-1][00200222:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00200022: 1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008022:
4][00000000:-1][00008222: 4]
Gc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][00000000:11][00000000:-1][00000000:-1][00080000:11]
@@ -85,7 +85,7 @@
Ic
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000004:
5][00000000:-1][00000000:-1][00000000: 5][ffffffff:-1][00608022:
1][00000000:-1][00210800: 2][00000000:-1]
Jc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00008000: 3][00000000:-1]
Kc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
9][00000000:-1][00000000:-1][00000000:12][00000000:-1]
- Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
+ Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00002048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
Mc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000144:
2][00000000:-1][00000000:-1][00080220: 2][ffffffff:-1]
Nc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040: 1][ffffffff:-1][ffffffff:-1]
Oc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:15][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
@@ -139,20 +139,20 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000008:
6][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:16][00000000:-1][ffffffff:-1]
- Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795a: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
+ Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795e: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Ir
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00200222:
1][02284302: 1][00000222: 3][00000000:-1][040c0020: 6][00000000:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00080200:12][00002020:
5][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][ffffffff:-1][00000000:-1]
Kr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Lr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Mr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00080000:
8]
- Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c7518: 1]
+ Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c751c: 1]
Or
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
-
Ac
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Bc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Cc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
4][00000000:-1][00280022:
4][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c7518:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c751c:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ec
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008000:
1][00000000:-1][00200222:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00200022: 1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008022:
4][00000000:-1][00008222: 4]
Gc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][00000000:11][00000000:-1][00000000:-1][00080000:11]
@@ -160,7 +160,7 @@
Ic
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000004:
5][00000000:-1][00000000:-1][00000000: 5][ffffffff:-1][00608022:
1][00000000:-1][00210800: 2][00000000:-1]
Jc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00008000: 3][00000000:-1]
Kc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
9][00000000:-1][00000000:-1][00000000:12][00000000:-1]
- Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
+ Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00002048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
Mc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000144:
2][00000000:-1][00000000:-1][00080220: 2][ffffffff:-1]
Nc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040: 1][ffffffff:-1][ffffffff:-1]
Oc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:15][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
@@ -169,13 +169,13 @@
commande>
commande> a r
1: SaUGRENU * 82 E4
- 2: ENjUGUES * 66 D8
- 3: NUaGEUSE * 66 D1
+ 2: NUaGEUSE * 66 D1
+ 3: ENjUGUES * 66 D8
4: GUEUSANt * 66 11C
5: GUEUSENt * 64 D6
- 6: NUaGEUSE * 64 D4
+ 6: ENjUGUES * 64 D2
7: GUEUSENt * 64 D3
- 8: ENjUGUES * 64 D2
+ 8: NUaGEUSE * 64 D4
9: GUeUSENT * 62 F1
10: GUEUSeNT * 60 F1
commande>
@@ -186,20 +186,20 @@
Dr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Er
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000008:
6][ffffffff:-1]
Fr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:16][00000000:-1][ffffffff:-1]
- Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795a: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
+ Gr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:
5][00608022: 1][005c795e: 1][00008000: 3][00000000:-1][00000000:-1][00000000:
8]
Hr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Ir
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00200222:
1][02284302: 1][00000222: 3][00000000:-1][040c0020: 6][00000000:-1]
Jr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00080200:12][00002020:
5][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][ffffffff:-1][00000000:-1]
Kr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Lr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00000000:-1]
Mr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][ffffffff:-1][00080000:
8]
- Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c7518: 1]
+ Nr
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:26][00000000:
3][005c751c: 1]
Or
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
-
Ac
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:12][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Bc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Cc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
4][00000000:-1][00280022:
4][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
- Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c7518:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
+ Dc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][005c751c:
0][00000000:-1][01384100:
0][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Ec
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008000:
1][00000000:-1][00200222:
1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1]
Fc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00200022: 1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00008022:
4][00000000:-1][00008222: 4]
Gc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040:
1][ffffffff:-1][ffffffff:-1][00000000:11][00000000:-1][00000000:-1][00080000:11]
@@ -207,7 +207,7 @@
Ic
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000004:
5][00000000:-1][00000000:-1][00000000: 5][ffffffff:-1][00608022:
1][00000000:-1][00210800: 2][00000000:-1]
Jc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00200020:
1][00000000:-1][00008000: 3][00000000:-1]
Kc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:
9][00000000:-1][00000000:-1][00000000:12][00000000:-1]
- Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
+ Lc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00002048:
2][00000000:-1][00000000:-1][00004000: 3][00000000:-1]
Mc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000144:
2][00000000:-1][00000000:-1][00080220: 2][ffffffff:-1]
Nc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][010d714e:
1][00000000:-1][00005040: 1][ffffffff:-1][ffffffff:-1]
Oc
[ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][ffffffff:-1][00000000:15][00000000:-1][00000000:-1][00000000:-1][00000000:-1]
Index: test/training_search.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_search.ref,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- test/training_search.ref 5 Nov 2006 17:04:39 -0000 1.4
+++ test/training_search.ref 8 Jan 2008 13:52:42 -0000 1.5
@@ -8,847 +8,892 @@
commande> r
commande> a r 1000
1: SPItZ 50 H8
- 2: ZINcS 46 H4
+ 2: ZaNIS 46 H4
3: ZaINS 46 H4
- 4: ZaNIS 46 H4
- 5: QuIZ 38 H8
- 6: QuIZ 38 H5
- 7: QuIZ 38 H6
- 8: QuIZ 38 H7
- 9: SPItZ 32 H4
- 10: ZIPS 30 H5
- 11: SPItZ 30 H5
+ 4: ZINcS 46 H4
+ 5: QuIZ 38 H7
+ 6: QuIZ 38 H8
+ 7: QuIZ 38 H5
+ 8: QuIZ 38 H6
+ 9: QINgS 38 H4
+ 10: SPItZ 32 H4
+ 11: SPItZ 30 H6
12: ZIPS 30 H6
- 13: SPItZ 30 H6
- 14: ZIPS 30 H7
- 15: ZIPS 30 H8
- 16: SPItZ 30 H7
- 17: ZIPs 28 H8
- 18: ZaNIS 28 H8
- 19: ZIP 28 H6
- 20: ZIPs 28 H6
- 21: ZIP 28 H8
- 22: ZaINS 28 H8
- 23: NaZIS 28 H8
- 24: ZuPS 28 H7
- 25: ZiPS 28 H8
- 26: ZINcS 28 H8
- 27: ZuPS 28 H5
- 28: ZIPs 28 H5
- 29: ZiPS 28 H7
- 30: ZIP 28 H7
- 31: ZuPS 28 H8
- 32: ZuPS 28 H6
- 33: NaZIS 28 H4
- 34: ZiPS 28 H6
- 35: ZiPS 28 H5
- 36: ZIPs 28 H7
- 37: ZaINS 26 H7
- 38: ZINcS 26 H7
- 39: ZaNIS 26 H7
- 40: ZaNIS 26 H5
- 41: ZiP 26 H7
- 42: ZaINS 26 H5
- 43: NaZIS 26 H5
- 44: ZaNIS 26 H6
- 45: ZaINS 26 H6
- 46: NaZIS 26 H6
- 47: ZuP 26 H7
- 48: ZINcS 26 H5
- 49: ZuP 26 H8
- 50: ZiP 26 H8
- 51: ZiP 26 H6
- 52: ZuP 26 H6
- 53: NaZIS 26 H7
- 54: ZINcS 26 H6
- 55: bINZ 24 H5
- 56: ZaNI 24 H7
- 57: NaZI 24 H5
- 58: NIeZ 24 H8
- 59: ZIpS 24 H5
- 60: NIeZ 24 H7
- 61: ZaIN 24 H7
- 62: ZISt 24 H5
- 63: bINZ 24 H6
- 64: ZISt 24 H7
- 65: ZIpS 24 H7
- 66: NIeZ 24 H5
- 67: ZIgS 24 H7
- 68: NIeZ 24 H6
- 69: NaZI 24 H7
- 70: bINZ 24 H8
- 71: ZINc 24 H7
- 72: bINZ 24 H7
- 73: ZINc 24 H8
- 74: ZIgS 24 H8
- 75: ZeNS 24 H5
- 76: ZeNS 24 H6
- 77: ZeNS 24 H8
- 78: ZIgS 24 H6
- 79: ZINc 24 H6
+ 13: ZIPS 30 H8
+ 14: SPItZ 30 H5
+ 15: ZIPS 30 H5
+ 16: ZIPS 30 H7
+ 17: SPItZ 30 H7
+ 18: ZIPs 28 H7
+ 19: ZiPS 28 H7
+ 20: ZuPS 28 H7
+ 21: ZaINS 28 H8
+ 22: ZIP 28 H7
+ 23: ZiPS 28 H8
+ 24: NaZIS 28 H8
+ 25: ZaNIS 28 H8
+ 26: ZIPs 28 H8
+ 27: ZuPS 28 H8
+ 28: ZiPS 28 H6
+ 29: ZiPS 28 H5
+ 30: ZIPs 28 H5
+ 31: ZuPS 28 H6
+ 32: NaZIS 28 H4
+ 33: ZIP 28 H8
+ 34: ZuPS 28 H5
+ 35: ZIPs 28 H6
+ 36: ZINcS 28 H8
+ 37: ZIP 28 H6
+ 38: ZiP 26 H6
+ 39: ZiP 26 H8
+ 40: ZaINS 26 H7
+ 41: ZINcS 26 H7
+ 42: ZaNIS 26 H7
+ 43: NaZIS 26 H6
+ 44: ZuP 26 H6
+ 45: NaZIS 26 H7
+ 46: ZINcS 26 H5
+ 47: ZiP 26 H7
+ 48: ZINcS 26 H6
+ 49: ZuP 26 H7
+ 50: ZuP 26 H8
+ 51: ZaINS 26 H6
+ 52: ZaNIS 26 H6
+ 53: ZaNIS 26 H5
+ 54: ZaINS 26 H5
+ 55: NaZIS 26 H5
+ 56: bINZ 24 H7
+ 57: NIeZ 24 H8
+ 58: ZaIN 24 H8
+ 59: NaZI 24 H7
+ 60: NIeZ 24 H5
+ 61: ZISt 24 H8
+ 62: ZINc 24 H8
+ 63: NIeZ 24 H6
+ 64: ZIpS 24 H8
+ 65: ZIgS 24 H8
+ 66: ZeNS 24 H8
+ 67: ZaNI 24 H8
+ 68: NIeZ 24 H7
+ 69: NaZI 24 H6
+ 70: NaZI 24 H5
+ 71: ZIgS 24 H5
+ 72: ZISt 24 H6
+ 73: ZIpS 24 H6
+ 74: QINgS 24 H8
+ 75: ZINc 24 H6
+ 76: ZIgS 24 H6
+ 77: ZINc 24 H5
+ 78: ZeNS 24 H5
+ 79: ZeNS 24 H6
80: ZaNI 24 H5
- 81: ZeNS 24 H7
- 82: ZaNI 24 H8
- 83: ZIpS 24 H8
- 84: ZIpS 24 H6
- 85: ZISt 24 H8
- 86: NaZI 24 H8
- 87: ZISt 24 H6
- 88: ZaIN 24 H5
- 89: ZaIN 24 H8
- 90: ZaNI 24 H6
- 91: ZIgS 24 H5
- 92: NaZI 24 H6
- 93: ZaIN 24 H6
- 94: ZINc 24 H5
- 95: ZIg 22 H7
- 96: ZeN 22 H7
- 97: rIZ 22 H8
- 98: NeZ 22 H6
- 99: ZeN 22 H8
-100: ZIg 22 H8
-101: ZIp 22 H8
-102: NeZ 22 H7
-103: rIZ 22 H6
+ 81: ZaIN 24 H5
+ 82: ZaNI 24 H6
+ 83: ZaIN 24 H6
+ 84: ZISt 24 H7
+ 85: ZIpS 24 H7
+ 86: bINZ 24 H8
+ 87: ZINc 24 H7
+ 88: ZIgS 24 H7
+ 89: ZeNS 24 H7
+ 90: ZaNI 24 H7
+ 91: ZaIN 24 H7
+ 92: NaZI 24 H8
+ 93: ZIpS 24 H5
+ 94: ZISt 24 H5
+ 95: bINZ 24 H5
+ 96: bINZ 24 H6
+ 97: QINS 22 H8
+ 98: ZIg 22 H8
+ 99: QINgS 22 H6
+100: ZeN 22 H8
+101: QINS 22 H6
+102: QINgS 22 H5
+103: QINS 22 H5
104: rIZ 22 H7
-105: ZIp 22 H7
-106: NeZ 22 H8
-107: ZIg 22 H6
-108: ZeN 22 H6
-109: ZIp 22 H6
-110: cINQ 20 H8
-111: cINQ 20 H7
-112: cINQ 20 H6
-113: cINQ 20 H5
-114: PISaN 18 H4
-115: PIoNS 18 H4
-116: PuNIS 18 H4
-117: QuI 18 H7
-118: QuI 18 H6
-119: PINeS 18 H4
-120: PoINS 18 H4
-121: QuI 18 H8
-122: PaINS 18 H4
-123: PeINS 18 H4
-124: PeNIS 18 H4
-125: PIaNS 18 H4
-126: PIaNS 14 H8
-127: SPINs 14 H4
-128: SaPIN 14 H4
-129: sPINS 14 H8
-130: SuPIN 14 H8
-131: PaINS 14 H8
-132: PINeS 14 H8
-133: SaPIN 14 H8
-134: PeINS 14 H8
-135: PeNIS 14 H8
-136: PuNIS 14 H8
-137: PIoNS 14 H8
-138: SuPIN 14 H4
-139: PoINS 14 H8
-140: PISaN 14 H8
-141: PIoNS 12 H7
-142: PINS 12 H7
-143: PINeS 12 H7
-144: sPINS 12 H5
-145: SPIN 12 H8
-146: SPINs 12 H8
-147: PIaNS 12 H7
-148: PeNIS 12 H7
-149: PeINS 12 H7
-150: PaINS 12 H7
-151: sPINS 12 H4
-152: SPINs 12 H5
-153: PIaNS 12 H6
-154: SPIN 12 H7
-155: SPINs 12 H7
-156: PISaN 12 H6
-157: PuNIS 12 H5
-158: PIoNS 12 H5
-159: SuPIN 12 H7
-160: PISaN 12 H5
-161: PIaNS 12 H5
-162: PuNIS 12 H6
-163: SaPIN 12 H6
-164: SaPIN 12 H5
-165: SaPIN 12 H7
-166: PoINS 12 H6
-167: PoINS 12 H5
-168: SuPIN 12 H5
-169: PINS 12 H8
-170: PuNIS 12 H7
-171: PeNIS 12 H5
-172: PaINS 12 H6
-173: PIoNS 12 H6
-174: SPIN 12 H5
-175: PINS 12 H5
-176: SuPIN 12 H6
-177: PeINS 12 H5
-178: PINeS 12 H5
-179: SPIN 12 H6
-180: SPINs 12 H6
-181: PeNIS 12 H6
-182: PaINS 12 H5
-183: PeINS 12 H6
-184: PINS 12 H6
-185: sPINS 12 H7
-186: PISaN 12 H7
-187: sPINS 12 H6
-188: PoINS 12 H7
-189: PINeS 12 H6
-190: SPIs 10 H5
-191: PuIS 10 H5
-192: kIPS 10 H5
-193: IPeS 10 H7
-194: PuNI 10 H6
-195: SPIc 10 H5
-196: lISP 10 H6
-197: SPIs 10 H6
-198: SkIP 10 H5
-199: PuIS 10 H6
-200: lISP 10 H7
-201: PSI 10 H6
-202: SlIP 10 H5
-203: SlIP 10 H6
-204: PrIS 10 H5
-205: SIPo 10 H7
-206: IPeS 10 H5
-207: mIPS 10 H5
-208: kIPS 10 H7
-209: mIPS 10 H6
-210: SkIP 10 H7
-211: SlIP 10 H7
-212: SPiN 10 H6
-213: IPeS 10 H6
-214: kIPS 10 H6
-215: SIPo 10 H6
-216: SPI 10 H6
-217: SPIc 10 H6
-218: SIPo 10 H5
-219: SPIn 10 H6
-220: mIPS 10 H7
-221: SkIP 10 H6
-222: SPIn 10 H5
-223: PuNI 10 H5
-224: lISP 10 H5
-225: PoIS 10 H7
-226: PrIS 10 H7
-227: PSI 10 H7
-228: PuIS 10 H7
-229: PuNI 10 H7
-230: PaIN 10 H6
-231: PaIS 10 H6
-232: PInS 10 H5
-233: PINs 10 H5
-234: PaNS 10 H6
-235: PINe 10 H5
-236: PIlS 10 H5
-237: PaIN 10 H5
-238: PaIS 10 H5
-239: PaNS 10 H5
-240: PIaN 10 H6
-241: PIcS 10 H6
-242: PIeS 10 H6
-243: PIfS 10 H6
-244: PIlS 10 H6
-245: PIN 10 H6
-246: PINe 10 H6
-247: PINs 10 H6
-248: PInS 10 H6
-249: PIoN 10 H6
-250: PIS 10 H6
-251: PISe 10 H6
-252: PIaN 10 H5
-253: PIcS 10 H5
-254: PIeS 10 H5
-255: PIfS 10 H5
-256: PrIS 10 H6
-257: PoIS 10 H5
-258: PoIS 10 H6
-259: PlIS 10 H5
-260: PlIS 10 H6
-261: PiNS 10 H5
-262: PiNS 10 H6
-263: PISe 10 H5
-264: SPiN 10 H7
-265: PIoN 10 H5
-266: SPIs 10 H7
-267: SPIn 10 H7
-268: SPIc 10 H7
-269: SPI 10 H7
-270: PaIN 10 H7
-271: PaIS 10 H7
-272: PaNS 10 H7
-273: PIaN 10 H7
-274: PIcS 10 H7
-275: PIeS 10 H7
-276: PIfS 10 H7
-277: PIlS 10 H7
-278: PIN 10 H7
-279: PINe 10 H7
-280: PINs 10 H7
-281: PInS 10 H7
-282: PIoN 10 H7
-283: PIS 10 H7
-284: PISe 10 H7
-285: PiNS 10 H7
-286: PlIS 10 H7
-287: PlIS 10 H8
-288: PoIS 10 H8
-289: PrIS 10 H8
-290: PSI 10 H8
-291: PuIS 10 H8
-292: PuNI 10 H8
-293: SIPo 10 H8
-294: SkIP 10 H8
-295: SlIP 10 H8
-296: SPI 10 H8
-297: SPIc 10 H8
-298: SPIn 10 H8
-299: SPIs 10 H8
-300: SPiN 10 H8
-301: sPIN 10 H8
-302: sPIS 10 H8
-303: tIPS 10 H8
-304: tIPS 10 H5
-305: tIPS 10 H6
-306: tIPS 10 H7
-307: zIPS 10 H8
-308: sPIS 10 H5
-309: aPIS 10 H7
-310: aSPI 10 H7
-311: sPIN 10 H5
-312: sPIS 10 H6
-313: aPIS 10 H6
-314: zIPS 10 H5
-315: zIPS 10 H6
-316: zIPS 10 H7
-317: aPIS 10 H8
-318: aSPI 10 H8
-319: bIPS 10 H8
-320: ePIS 10 H8
-321: IPeS 10 H8
-322: kIPS 10 H8
-323: lISP 10 H8
-324: mIPS 10 H8
-325: PaIN 10 H8
-326: PaIS 10 H8
-327: PaNS 10 H8
-328: PIaN 10 H8
-329: PIcS 10 H8
-330: PIeS 10 H8
-331: PIfS 10 H8
-332: PIlS 10 H8
-333: PIN 10 H8
-334: PINe 10 H8
-335: PINs 10 H8
-336: PInS 10 H8
-337: PIoN 10 H8
-338: PIS 10 H8
-339: PISe 10 H8
-340: PiNS 10 H8
-341: sPIN 10 H6
-342: bIPS 10 H5
-343: aSPI 10 H5
-344: ePIS 10 H5
-345: bIPS 10 H7
-346: ePIS 10 H7
-347: aSPI 10 H6
-348: ePIS 10 H6
-349: aPIS 10 H5
-350: bIPS 10 H6
-351: SPiN 10 H5
-352: sPIS 10 H7
-353: sPIN 10 H7
-354: PaS 8 H7
-355: SPa 8 H8
-356: PhI 8 H7
-357: PI 8 H7
-358: SPi 8 H8
-359: bIP 8 H6
-360: PIc 8 H7
-361: PIf 8 H7
-362: IPe 8 H6
-363: PIe 8 H7
-364: PIn 8 H8
-365: sPI 8 H7
-366: PaN 8 H7
-367: SPi 8 H6
-368: PIs 8 H6
-369: PIu 8 H6
-370: ePI 8 H7
-371: PIf 8 H8
-372: sPI 8 H8
-373: PIe 8 H8
-374: PIc 8 H8
-375: ePI 8 H6
-376: PI 8 H8
-377: PhI 8 H8
-378: tIP 8 H8
-379: PaS 8 H8
-380: PuS 8 H8
-381: PaS 8 H6
-382: SPa 8 H6
-383: PaN 8 H6
-384: PsI 8 H8
-385: PuS 8 H7
-386: PSy 8 H8
-387: PSt 8 H8
-388: SeP 8 H8
-389: PSi 8 H8
-390: PsI 8 H7
-391: PSy 8 H7
-392: PSt 8 H7
-393: PSi 8 H7
-394: sPI 8 H6
-395: PhI 8 H6
-396: PlI 8 H7
-397: PiS 8 H7
-398: PlI 8 H8
-399: PiN 8 H7
-400: PIc 8 H6
-401: PIu 8 H7
-402: PIs 8 H7
-403: PiS 8 H8
-404: PIe 8 H6
-405: PIf 8 H6
-406: PiN 8 H8
-407: PIu 8 H8
-408: PIn 8 H7
-409: PIs 8 H8
-410: IPe 8 H7
-411: PIn 8 H6
-412: kIP 8 H6
-413: kIP 8 H8
-414: IPe 8 H8
-415: tIP 8 H7
-416: PSi 8 H6
-417: zIP 8 H8
-418: PSt 8 H6
-419: PSy 8 H6
-420: PsI 8 H6
-421: SeP 8 H6
-422: bIP 8 H7
-423: hIP 8 H8
-424: PuS 8 H6
-425: ePI 8 H8
-426: SPa 8 H7
-427: aPI 8 H7
-428: bIP 8 H8
-429: zIP 8 H7
-430: aPI 8 H8
-431: zIP 8 H6
-432: SeP 8 H7
-433: aPI 8 H6
-434: SPi 8 H7
-435: PiN 8 H6
-436: hIP 8 H7
-437: PiS 8 H6
-438: PlI 8 H6
-439: PaN 8 H8
-440: tIP 8 H6
-441: hIP 8 H6
-442: kIP 8 H7
-443: SNIf 6 H7
-444: pINS 6 H6
-445: gINS 6 H7
-446: pINS 6 H5
-447: IbNS 6 H6
-448: IbNS 6 H5
-449: IbNS 6 H7
-450: NuIS 6 H8
-451: fINS 6 H7
-452: oINS 6 H8
-453: SIeN 6 H7
-454: fINS 6 H5
-455: SeIN 6 H7
-456: SkIN 6 H7
-457: aNIS 6 H8
-458: fINS 6 H6
-459: SaIN 6 H7
-460: Pu 6 H8
-461: gINS 6 H6
-462: lINS 6 H8
-463: mINS 6 H8
-464: SpIN 6 H5
-465: INSu 6 H7
-466: IoNS 6 H8
-467: gINS 6 H5
-468: NaIS 6 H8
-469: NIaS 6 H8
-470: IoNS 6 H7
-471: INSu 6 H8
-472: NIdS 6 H8
-473: Pi 6 H8
-474: IbNS 6 H8
-475: NIeS 6 H8
-476: NIfS 6 H8
-477: gINS 6 H8
-478: fINS 6 H8
-479: SpIN 6 H6
-480: NItS 6 H8
-481: pINS 6 H7
-482: SoIN 6 H7
+105: rIZ 22 H6
+106: rIZ 22 H8
+107: NeZ 22 H8
+108: NeZ 22 H6
+109: ZeN 22 H6
+110: QINS 22 H7
+111: QINgS 22 H7
+112: ZIp 22 H8
+113: ZIp 22 H7
+114: NeZ 22 H7
+115: ZIp 22 H6
+116: ZIg 22 H7
+117: ZIg 22 H6
+118: ZeN 22 H7
+119: QIN 20 H8
+120: QIN 20 H6
+121: QINs 20 H6
+122: QiNS 20 H5
+123: QiNS 20 H6
+124: QInS 20 H6
+125: QInS 20 H5
+126: QINs 20 H5
+127: QINg 20 H6
+128: QINg 20 H5
+129: cINQ 20 H5
+130: QINs 20 H7
+131: QInS 20 H7
+132: QINg 20 H7
+133: QIN 20 H7
+134: QiNS 20 H8
+135: QiNS 20 H7
+136: QInS 20 H8
+137: QINs 20 H8
+138: cINQ 20 H7
+139: cINQ 20 H8
+140: cINQ 20 H6
+141: QINg 20 H8
+142: QIn 18 H6
+143: QiN 18 H8
+144: QIn 18 H8
+145: QuI 18 H8
+146: QiN 18 H6
+147: QuI 18 H6
+148: PeINS 18 H4
+149: PISaN 18 H4
+150: PeNIS 18 H4
+151: PIaNS 18 H4
+152: PaINS 18 H4
+153: PINeS 18 H4
+154: PuNIS 18 H4
+155: QuI 18 H7
+156: PoINS 18 H4
+157: QiN 18 H7
+158: PIoNS 18 H4
+159: QIn 18 H7
+160: SaPIN 14 H8
+161: sPINS 14 H8
+162: SuPIN 14 H4
+163: SPINs 14 H4
+164: PaINS 14 H8
+165: PeINS 14 H8
+166: PeNIS 14 H8
+167: PIaNS 14 H8
+168: SaPIN 14 H4
+169: PINeS 14 H8
+170: PIoNS 14 H8
+171: PISaN 14 H8
+172: SuPIN 14 H8
+173: PoINS 14 H8
+174: PuNIS 14 H8
+175: PIoNS 12 H5
+176: PoINS 12 H7
+177: PISaN 12 H5
+178: SPINs 12 H8
+179: PINS 12 H5
+180: PINeS 12 H5
+181: PIaNS 12 H5
+182: PISaN 12 H6
+183: PuNIS 12 H7
+184: PIoNS 12 H6
+185: PaINS 12 H6
+186: PINS 12 H6
+187: PINeS 12 H6
+188: PaINS 12 H5
+189: PIaNS 12 H6
+190: PeNIS 12 H5
+191: PeINS 12 H5
+192: PeNIS 12 H6
+193: PeINS 12 H6
+194: PIaNS 12 H7
+195: SPIN 12 H7
+196: SPINs 12 H7
+197: PeNIS 12 H7
+198: PeINS 12 H7
+199: PINS 12 H8
+200: SuPIN 12 H7
+201: SaPIN 12 H6
+202: SaPIN 12 H5
+203: PaINS 12 H7
+204: SPIN 12 H6
+205: SPINs 12 H6
+206: SPIN 12 H5
+207: SPINs 12 H5
+208: SuPIN 12 H6
+209: SuPIN 12 H5
+210: sPINS 12 H7
+211: sPINS 12 H6
+212: sPINS 12 H5
+213: sPINS 12 H4
+214: PoINS 12 H6
+215: PoINS 12 H5
+216: PIoNS 12 H7
+217: PISaN 12 H7
+218: SPIN 12 H8
+219: SaPIN 12 H7
+220: PuNIS 12 H5
+221: PINS 12 H7
+222: PINeS 12 H7
+223: PuNIS 12 H6
+224: PiNS 10 H7
+225: mIPS 10 H5
+226: mIPS 10 H6
+227: mIPS 10 H7
+228: lISP 10 H5
+229: PaIS 10 H6
+230: PaNS 10 H6
+231: PaIN 10 H5
+232: PISe 10 H7
+233: PaIS 10 H5
+234: lISP 10 H6
+235: PaNS 10 H5
+236: lISP 10 H7
+237: kIPS 10 H5
+238: kIPS 10 H6
+239: kIPS 10 H7
+240: IPeS 10 H5
+241: IPeS 10 H6
+242: PrIS 10 H7
+243: PSI 10 H7
+244: PuIS 10 H7
+245: PIlS 10 H7
+246: PIfS 10 H7
+247: PIeS 10 H7
+248: PuNI 10 H7
+249: PIcS 10 H7
+250: PoIS 10 H7
+251: PaIN 10 H6
+252: PIaN 10 H7
+253: PIN 10 H7
+254: PINe 10 H7
+255: PlIS 10 H7
+256: PaNS 10 H7
+257: PaIS 10 H7
+258: PINs 10 H7
+259: PaIN 10 H7
+260: PInS 10 H7
+261: PIoN 10 H7
+262: PIS 10 H7
+263: SPIn 10 H6
+264: SPIc 10 H6
+265: SPI 10 H6
+266: SlIP 10 H5
+267: SlIP 10 H6
+268: SkIP 10 H5
+269: SkIP 10 H6
+270: SIPo 10 H5
+271: SIPo 10 H6
+272: SPiN 10 H7
+273: SPIs 10 H7
+274: SPIn 10 H7
+275: SPIc 10 H7
+276: SPI 10 H7
+277: SlIP 10 H7
+278: SkIP 10 H7
+279: SIPo 10 H7
+280: zIPS 10 H5
+281: zIPS 10 H6
+282: zIPS 10 H7
+283: tIPS 10 H5
+284: tIPS 10 H6
+285: tIPS 10 H7
+286: sPIS 10 H5
+287: sPIN 10 H5
+288: sPIS 10 H6
+289: sPIN 10 H6
+290: sPIS 10 H7
+291: sPIN 10 H7
+292: SPiN 10 H5
+293: SPIs 10 H5
+294: SPIn 10 H5
+295: SPIc 10 H5
+296: SPiN 10 H6
+297: SPIs 10 H6
+298: PIlS 10 H5
+299: PIfS 10 H5
+300: PIeS 10 H5
+301: PIcS 10 H5
+302: PIaN 10 H5
+303: PISe 10 H6
+304: PIS 10 H6
+305: PIoN 10 H6
+306: PInS 10 H6
+307: PINs 10 H6
+308: PINe 10 H6
+309: PIN 10 H6
+310: PIlS 10 H6
+311: PIfS 10 H6
+312: PIeS 10 H6
+313: PIcS 10 H6
+314: PIaN 10 H6
+315: PuNI 10 H5
+316: PuIS 10 H5
+317: PuNI 10 H6
+318: PuIS 10 H6
+319: PSI 10 H6
+320: PrIS 10 H5
+321: PrIS 10 H6
+322: PoIS 10 H5
+323: PoIS 10 H6
+324: PlIS 10 H5
+325: PlIS 10 H6
+326: PiNS 10 H5
+327: PiNS 10 H6
+328: PISe 10 H5
+329: PIoN 10 H5
+330: PInS 10 H5
+331: PINs 10 H5
+332: PINe 10 H5
+333: SPiN 10 H8
+334: SPIs 10 H8
+335: lISP 10 H8
+336: SPIn 10 H8
+337: SPIc 10 H8
+338: SPI 10 H8
+339: kIPS 10 H8
+340: PaIN 10 H8
+341: PaIS 10 H8
+342: SlIP 10 H8
+343: IPeS 10 H8
+344: SkIP 10 H8
+345: PaNS 10 H8
+346: SIPo 10 H8
+347: PIaN 10 H8
+348: PIcS 10 H8
+349: PIeS 10 H8
+350: ePIS 10 H5
+351: ePIS 10 H6
+352: ePIS 10 H7
+353: bIPS 10 H5
+354: bIPS 10 H6
+355: bIPS 10 H7
+356: aSPI 10 H5
+357: aSPI 10 H6
+358: aPIS 10 H5
+359: aPIS 10 H6
+360: aSPI 10 H7
+361: aPIS 10 H7
+362: zIPS 10 H8
+363: tIPS 10 H8
+364: sPIS 10 H8
+365: mIPS 10 H8
+366: sPIN 10 H8
+367: PSI 10 H8
+368: PrIS 10 H8
+369: PoIS 10 H8
+370: PlIS 10 H8
+371: PIfS 10 H8
+372: bIPS 10 H8
+373: aSPI 10 H8
+374: IPeS 10 H7
+375: PIlS 10 H8
+376: aPIS 10 H8
+377: PIN 10 H8
+378: PiNS 10 H8
+379: PINe 10 H8
+380: PINs 10 H8
+381: PInS 10 H8
+382: PISe 10 H8
+383: PIS 10 H8
+384: PIoN 10 H8
+385: PuNI 10 H8
+386: PuIS 10 H8
+387: ePIS 10 H8
+388: bIP 8 H6
+389: SPa 8 H7
+390: PuS 8 H7
+391: bIP 8 H7
+392: PaN 8 H6
+393: PaS 8 H6
+394: PIn 8 H8
+395: PiN 8 H8
+396: SPi 8 H7
+397: aPI 8 H6
+398: PIe 8 H8
+399: PhI 8 H6
+400: SeP 8 H8
+401: PIc 8 H6
+402: aPI 8 H7
+403: PuS 8 H8
+404: ePI 8 H6
+405: PIf 8 H8
+406: PIn 8 H7
+407: ePI 8 H7
+408: tIP 8 H6
+409: tIP 8 H7
+410: PIs 8 H7
+411: PIu 8 H7
+412: PiN 8 H7
+413: PiS 8 H7
+414: PlI 8 H7
+415: PIs 8 H8
+416: PIu 8 H8
+417: PSi 8 H7
+418: PSt 8 H7
+419: PSy 8 H7
+420: PsI 8 H7
+421: PI 8 H8
+422: PiS 8 H8
+423: PiS 8 H6
+424: PhI 8 H8
+425: PlI 8 H6
+426: PuS 8 H6
+427: PlI 8 H8
+428: PaS 8 H8
+429: SPa 8 H8
+430: SeP 8 H6
+431: PSt 8 H8
+432: PaN 8 H8
+433: PsI 8 H6
+434: PSi 8 H8
+435: PSi 8 H6
+436: PSt 8 H6
+437: PSy 8 H6
+438: PIe 8 H6
+439: sPI 8 H6
+440: PIf 8 H6
+441: PsI 8 H8
+442: zIP 8 H8
+443: PIn 8 H6
+444: sPI 8 H7
+445: PIs 8 H6
+446: PIu 8 H6
+447: PIc 8 H8
+448: tIP 8 H8
+449: SeP 8 H7
+450: SPa 8 H6
+451: sPI 8 H8
+452: SPi 8 H6
+453: PSy 8 H8
+454: SPi 8 H8
+455: PiN 8 H6
+456: kIP 8 H6
+457: aPI 8 H8
+458: hIP 8 H7
+459: hIP 8 H6
+460: bIP 8 H8
+461: kIP 8 H7
+462: kIP 8 H8
+463: IPe 8 H8
+464: IPe 8 H7
+465: hIP 8 H8
+466: IPe 8 H6
+467: PaN 8 H7
+468: PaS 8 H7
+469: zIP 8 H7
+470: PIc 8 H7
+471: zIP 8 H6
+472: ePI 8 H8
+473: PIe 8 H7
+474: PIf 8 H7
+475: PhI 8 H7
+476: PI 8 H7
+477: SkIN 6 H8
+478: NIeS 6 H7
+479: SNIf 6 H8
+480: NIfS 6 H7
+481: SoIN 6 H8
+482: mINS 6 H6
483: NItS 6 H7
484: SeIN 6 H6
-485: yINS 6 H8
-486: SaIN 6 H5
-487: NuIS 6 H7
-488: SaIN 6 H6
+485: lINS 6 H7
+486: lINS 6 H8
+487: SaIN 6 H7
+488: NuIS 6 H7
489: NaIS 6 H6
-490: NaIS 6 H5
-491: tINS 6 H6
-492: vINS 6 H8
-493: tINS 6 H5
-494: NIaS 6 H6
-495: SpIN 6 H7
-496: NIdS 6 H6
-497: uNIS 6 H8
-498: NIeS 6 H6
-499: NIfS 6 H6
-500: NItS 6 H6
-501: NIaS 6 H5
-502: NIdS 6 H5
-503: NIeS 6 H5
-504: NIfS 6 H5
-505: lINS 6 H6
-506: SkIN 6 H5
-507: aNIS 6 H5
-508: lINS 6 H5
-509: lINS 6 H7
-510: aNIS 6 H6
-511: SkIN 6 H6
-512: mINS 6 H7
-513: SNIf 6 H6
-514: mINS 6 H6
-515: SNIf 6 H5
-516: SIeN 6 H5
-517: mINS 6 H5
-518: NaIS 6 H7
-519: aNIS 6 H7
-520: tINS 6 H7
-521: NIaS 6 H7
-522: SIeN 6 H6
-523: NIdS 6 H7
-524: SeIN 6 H5
-525: NIeS 6 H7
-526: NIfS 6 H7
-527: IoNS 6 H5
-528: IoNS 6 H6
-529: uNIS 6 H5
-530: SoIN 6 H8
-531: SNIf 6 H8
-532: SoIN 6 H5
-533: INSu 6 H5
-534: SkIN 6 H8
-535: vINS 6 H7
-536: vINS 6 H6
-537: Pi 6 H7
-538: INSu 6 H6
-539: vINS 6 H5
-540: SIeN 6 H8
-541: yINS 6 H7
-542: Pu 6 H7
-543: SeIN 6 H8
-544: yINS 6 H6
-545: SaIN 6 H8
-546: yINS 6 H5
-547: pINS 6 H8
-548: NItS 6 H5
-549: tINS 6 H8
-550: SpIN 6 H8
-551: NuIS 6 H6
-552: uNIS 6 H6
-553: uNIS 6 H7
-554: NuIS 6 H5
-555: oINS 6 H5
-556: oINS 6 H6
-557: oINS 6 H7
-558: SoIN 6 H6
-559: vIS 4 H6
-560: SoN 4 H6
-561: yIN 4 H7
-562: SpI 4 H6
-563: SkI 4 H6
-564: SkI 4 H7
-565: SIx 4 H7
-566: uNI 4 H7
-567: SIs 4 H7
-568: SIr 4 H7
-569: yIN 4 H6
-570: SIl 4 H7
-571: uNS 4 H6
-572: tIN 4 H6
-573: sIS 4 H7
-574: vIN 4 H7
-575: SeN 4 H6
-576: SaI 4 H6
-577: SoI 4 H6
-578: uNI 4 H6
-579: uNS 4 H7
-580: SIc 4 H6
-581: vIS 4 H7
-582: sIS 4 H6
-583: SIl 4 H6
-584: vIN 4 H6
-585: SoN 4 H7
-586: tIN 4 H7
-587: SIr 4 H6
-588: SoI 4 H7
-589: SIs 4 H6
-590: SpI 4 H7
-591: SIx 4 H6
-592: aIS 4 H7
-593: yIN 4 H8
-594: vIS 4 H8
-595: vIN 4 H8
-596: uNS 4 H8
-597: uNI 4 H8
-598: tIN 4 H8
-599: sIS 4 H8
-600: SpI 4 H8
-601: SoN 4 H8
-602: SoI 4 H8
-603: SkI 4 H8
-604: SIx 4 H8
-605: SIs 4 H8
-606: SIr 4 H8
-607: SIl 4 H8
-608: SIc 4 H8
-609: SI 4 H8
-610: gIS 4 H6
-611: gIN 4 H6
-612: gIS 4 H7
-613: gIN 4 H7
-614: fIS 4 H6
-615: fIN 4 H6
-616: fIS 4 H7
-617: fIN 4 H7
-618: dIS 4 H6
-619: dIN 4 H6
-620: dIS 4 H7
-621: dIN 4 H7
-622: cIS 4 H6
-623: cIS 4 H7
-624: bIS 4 H6
-625: bIS 4 H7
-626: aNS 4 H6
-627: aIS 4 H6
-628: aNS 4 H7
-629: lIS 4 H8
-630: lIN 4 H8
-631: kSI 4 H8
-632: ISo 4 H8
-633: IoN 4 H8
-634: IN 4 H8
-635: IlS 4 H8
-636: IfS 4 H8
-637: IbN 4 H8
-638: gIS 4 H8
-639: gIN 4 H8
-640: fIS 4 H8
-641: fIN 4 H8
-642: dIS 4 H8
-643: dIN 4 H8
-644: cIS 4 H8
-645: bIS 4 H8
-646: aNS 4 H8
-647: aIS 4 H8
-648: SeN 4 H8
-649: SaI 4 H8
-650: rIS 4 H8
-651: pSI 4 H8
-652: pIS 4 H8
-653: pIN 4 H8
-654: NuS 4 H8
-655: NuI 4 H8
-656: NoS 4 H8
-657: NIt 4 H8
-658: NIf 4 H8
-659: NIe 4 H8
-660: NId 4 H8
-661: NIb 4 H8
-662: NIa 4 H8
-663: NI 4 H8
-664: NeS 4 H8
-665: mIS 4 H8
-666: mIN 4 H8
-667: lIS 4 H6
-668: mIN 4 H7
-669: pSI 4 H6
-670: mIS 4 H7
-671: mIN 4 H6
-672: pIS 4 H6
-673: pIN 4 H6
-674: mIS 4 H6
-675: pSI 4 H7
-676: NeS 4 H7
-677: pIS 4 H7
-678: pIN 4 H7
-679: NI 4 H7
-680: NIa 4 H7
-681: NIb 4 H7
-682: NId 4 H7
-683: NIe 4 H7
-684: NIf 4 H7
-685: NIt 4 H7
-686: NoS 4 H7
-687: NuI 4 H7
-688: NuS 4 H6
-689: NuI 4 H6
-690: NuS 4 H7
-691: NeS 4 H6
-692: NoS 4 H6
-693: NIa 4 H6
-694: NIt 4 H6
-695: NIf 4 H6
-696: NIe 4 H6
-697: NIb 4 H6
-698: NId 4 H6
-699: IbN 4 H7
-700: SIc 4 H7
-701: IfS 4 H7
-702: IlS 4 H7
-703: IN 4 H7
-704: SI 4 H7
-705: SeN 4 H7
-706: IoN 4 H7
-707: ISo 4 H7
-708: IbN 4 H6
-709: IfS 4 H6
-710: IlS 4 H6
-711: IoN 4 H6
-712: ISo 4 H6
-713: SaI 4 H7
-714: rIS 4 H6
-715: lIN 4 H7
-716: lIS 4 H7
-717: rIS 4 H7
-718: kSI 4 H6
-719: lIN 4 H6
-720: kSI 4 H7
-721: rI 2 H7
-722: aN 2 H8
-723: hI 2 H8
-724: Si 2 H7
-725: aI 2 H8
-726: aS 2 H8
-727: bI 2 H8
-728: Ne 2 H8
-729: Na 2 H8
-730: If 2 H8
-731: nI 2 H7
-732: cI 2 H8
-733: mI 2 H8
-734: oN 2 H7
-735: oS 2 H7
-736: lI 2 H8
-737: pI 2 H7
-738: fI 2 H8
-739: Il 2 H8
-740: iN 2 H8
-741: eS 2 H8
-742: eN 2 H8
-743: Se 2 H7
-744: In 2 H8
-745: Sa 2 H7
-746: uN 2 H8
-747: uN 2 H7
-748: mI 2 H7
-749: uS 2 H8
-750: vS 2 H8
-751: xI 2 H8
-752: aI 2 H7
-753: aN 2 H7
-754: lI 2 H7
-755: aS 2 H7
-756: bI 2 H7
-757: iN 2 H7
-758: cI 2 H7
-759: sI 2 H7
-760: eN 2 H7
-761: eS 2 H7
-762: fI 2 H7
-763: In 2 H7
-764: Il 2 H7
-765: If 2 H7
-766: hI 2 H7
-767: Su 2 H7
-768: Ni 2 H8
-769: No 2 H8
-770: Nu 2 H8
-771: nI 2 H8
-772: oN 2 H8
-773: oS 2 H8
-774: pI 2 H8
-775: Nu 2 H7
-776: rI 2 H8
-777: No 2 H7
-778: Sa 2 H8
-779: Ni 2 H7
-780: Se 2 H8
-781: xI 2 H7
-782: vS 2 H7
-783: Si 2 H8
-784: Ne 2 H7
-785: Na 2 H7
-786: Su 2 H8
-787: sI 2 H8
-788: uS 2 H7
+490: Pu 6 H8
+491: IbNS 6 H7
+492: mINS 6 H7
+493: NaIS 6 H5
+494: fINS 6 H8
+495: SpIN 6 H8
+496: oINS 6 H8
+497: aSIN 6 H8
+498: NuIS 6 H8
+499: NIaS 6 H6
+500: mINS 6 H8
+501: gINS 6 H5
+502: SeIN 6 H7
+503: tINS 6 H8
+504: SaIN 6 H5
+505: SIeN 6 H5
+506: INSu 6 H7
+507: lINS 6 H6
+508: qINS 6 H8
+509: SkIN 6 H6
+510: SaIN 6 H8
+511: SIeN 6 H6
+512: IoNS 6 H7
+513: SeIN 6 H8
+514: SkIN 6 H5
+515: lINS 6 H5
+516: mINS 6 H5
+517: gINS 6 H8
+518: qINS 6 H7
+519: SIeN 6 H8
+520: NaIS 6 H7
+521: pINS 6 H5
+522: SNIf 6 H6
+523: pINS 6 H6
+524: SNIf 6 H5
+525: SoIN 6 H6
+526: pINS 6 H7
+527: qINS 6 H6
+528: SoIN 6 H5
+529: pINS 6 H8
+530: qINS 6 H5
+531: IbNS 6 H8
+532: SeIN 6 H5
+533: INSu 6 H8
+534: NIaS 6 H7
+535: IoNS 6 H8
+536: NIdS 6 H7
+537: oINS 6 H5
+538: oINS 6 H6
+539: Pu 6 H7
+540: SNIf 6 H7
+541: NIaS 6 H8
+542: vINS 6 H7
+543: oINS 6 H7
+544: Pi 6 H8
+545: IbNS 6 H5
+546: NuIS 6 H5
+547: SkIN 6 H7
+548: aSIN 6 H5
+549: NuIS 6 H6
+550: vINS 6 H6
+551: aSIN 6 H6
+552: IbNS 6 H6
+553: NItS 6 H5
+554: NaIS 6 H8
+555: fINS 6 H7
+556: tINS 6 H5
+557: uNIS 6 H7
+558: fINS 6 H6
+559: tINS 6 H6
+560: INSu 6 H6
+561: INSu 6 H5
+562: Pi 6 H7
+563: fINS 6 H5
+564: tINS 6 H7
+565: uNIS 6 H6
+566: IoNS 6 H6
+567: IoNS 6 H5
+568: SoIN 6 H7
+569: gINS 6 H7
+570: uNIS 6 H5
+571: vINS 6 H8
+572: NItS 6 H8
+573: SaIN 6 H6
+574: SIeN 6 H7
+575: NIdS 6 H6
+576: NIfS 6 H8
+577: yINS 6 H6
+578: yINS 6 H8
+579: NIeS 6 H6
+580: yINS 6 H7
+581: NIeS 6 H8
+582: yINS 6 H5
+583: aNIS 6 H7
+584: SpIN 6 H7
+585: NIfS 6 H6
+586: vINS 6 H5
+587: NItS 6 H6
+588: NIaS 6 H5
+589: NIdS 6 H5
+590: SpIN 6 H5
+591: NIeS 6 H5
+592: SpIN 6 H6
+593: aSIN 6 H7
+594: gINS 6 H6
+595: NIdS 6 H8
+596: aNIS 6 H6
+597: aNIS 6 H8
+598: uNIS 6 H8
+599: aNIS 6 H5
+600: NIfS 6 H5
+601: dIS 4 H8
+602: aIS 4 H8
+603: dIN 4 H8
+604: SaI 4 H6
+605: aNS 4 H8
+606: SpI 4 H7
+607: SIc 4 H6
+608: bIS 4 H8
+609: SeN 4 H6
+610: cIS 4 H8
+611: NoS 4 H8
+612: SpI 4 H6
+613: NIt 4 H8
+614: sIS 4 H7
+615: yIN 4 H6
+616: NIf 4 H8
+617: sIS 4 H6
+618: yIN 4 H7
+619: NIe 4 H8
+620: NId 4 H8
+621: vIS 4 H6
+622: vIN 4 H6
+623: NIb 4 H8
+624: vIS 4 H7
+625: vIN 4 H7
+626: uNS 4 H6
+627: NIa 4 H8
+628: NI 4 H8
+629: tIN 4 H7
+630: uNI 4 H6
+631: NeS 4 H8
+632: tIN 4 H6
+633: uNS 4 H7
+634: uNI 4 H7
+635: fIN 4 H8
+636: fIS 4 H8
+637: SIl 4 H6
+638: SIr 4 H6
+639: SIs 4 H6
+640: SIx 4 H6
+641: SkI 4 H6
+642: gIN 4 H8
+643: gIS 4 H8
+644: SoI 4 H6
+645: SoN 4 H6
+646: IbN 4 H8
+647: IfS 4 H8
+648: IlS 4 H8
+649: IN 4 H8
+650: IoN 4 H8
+651: ISo 4 H8
+652: kSI 4 H8
+653: lIN 4 H8
+654: lIS 4 H8
+655: mIN 4 H8
+656: NuS 4 H8
+657: NuI 4 H8
+658: mIS 4 H8
+659: fIS 4 H7
+660: fIN 4 H7
+661: IlS 4 H7
+662: IN 4 H7
+663: dIS 4 H6
+664: dIN 4 H6
+665: dIS 4 H7
+666: dIN 4 H7
+667: cIS 4 H6
+668: cIS 4 H7
+669: mIS 4 H6
+670: bIS 4 H6
+671: bIS 4 H7
+672: mIN 4 H6
+673: aNS 4 H6
+674: aIS 4 H6
+675: mIS 4 H7
+676: aNS 4 H7
+677: aIS 4 H7
+678: yIN 4 H8
+679: mIN 4 H7
+680: vIS 4 H8
+681: vIN 4 H8
+682: IoN 4 H7
+683: uNS 4 H8
+684: uNI 4 H8
+685: lIS 4 H6
+686: lIN 4 H6
+687: NIt 4 H7
+688: NIf 4 H7
+689: NIe 4 H7
+690: NoS 4 H7
+691: NId 4 H7
+692: NuI 4 H7
+693: NuS 4 H7
+694: NIb 4 H7
+695: IbN 4 H7
+696: NeS 4 H6
+697: NIa 4 H6
+698: NIa 4 H7
+699: NIb 4 H6
+700: NId 4 H6
+701: NIe 4 H6
+702: gIS 4 H6
+703: NIf 4 H6
+704: NI 4 H7
+705: NIt 4 H6
+706: NoS 4 H6
+707: NuI 4 H6
+708: NuS 4 H6
+709: IfS 4 H7
+710: NeS 4 H7
+711: gIN 4 H6
+712: gIS 4 H7
+713: gIN 4 H7
+714: fIS 4 H6
+715: fIN 4 H6
+716: SI 4 H8
+717: SeN 4 H8
+718: kSI 4 H7
+719: SaI 4 H8
+720: IbN 4 H6
+721: rIS 4 H8
+722: qIN 4 H8
+723: pSI 4 H8
+724: pIS 4 H8
+725: pIN 4 H8
+726: ISo 4 H6
+727: qIN 4 H7
+728: qIN 4 H6
+729: IoN 4 H6
+730: rIS 4 H7
+731: rIS 4 H6
+732: SaI 4 H7
+733: IlS 4 H6
+734: SeN 4 H7
+735: SI 4 H7
+736: SIc 4 H7
+737: SIl 4 H7
+738: SIr 4 H7
+739: IfS 4 H6
+740: SIs 4 H7
+741: SIx 4 H7
+742: SkI 4 H7
+743: SoI 4 H7
+744: SoN 4 H7
+745: tIN 4 H8
+746: sIS 4 H8
+747: lIS 4 H7
+748: lIN 4 H7
+749: kSI 4 H6
+750: SpI 4 H8
+751: SoN 4 H8
+752: SoI 4 H8
+753: SkI 4 H8
+754: ISo 4 H7
+755: SIx 4 H8
+756: SIs 4 H8
+757: SIr 4 H8
+758: SIl 4 H8
+759: SIc 4 H8
+760: pIN 4 H7
+761: pIS 4 H7
+762: pSI 4 H7
+763: pIN 4 H6
+764: pSI 4 H6
+765: pIS 4 H6
+766: cI 2 H8
+767: If 2 H7
+768: Na 2 H7
+769: aI 2 H8
+770: hI 2 H8
+771: eN 2 H8
+772: lI 2 H7
+773: bI 2 H8
+774: In 2 H8
+775: mI 2 H7
+776: Il 2 H7
+777: eS 2 H8
+778: fI 2 H8
+779: aN 2 H8
+780: In 2 H7
+781: Ne 2 H7
+782: iN 2 H7
+783: aS 2 H8
+784: Il 2 H8
+785: If 2 H8
+786: xI 2 H8
+787: vS 2 H8
+788: sI 2 H7
+789: Ni 2 H8
+790: uS 2 H8
+791: No 2 H8
+792: uN 2 H8
+793: Nu 2 H8
+794: sI 2 H8
+795: nI 2 H8
+796: Su 2 H8
+797: oN 2 H8
+798: oS 2 H8
+799: Si 2 H8
+800: pI 2 H7
+801: Se 2 H8
+802: Sa 2 H8
+803: rI 2 H8
+804: pI 2 H8
+805: rI 2 H7
+806: Sa 2 H7
+807: Se 2 H7
+808: Su 2 H7
+809: Si 2 H7
+810: iN 2 H8
+811: Ni 2 H7
+812: No 2 H7
+813: lI 2 H8
+814: Nu 2 H7
+815: mI 2 H8
+816: hI 2 H7
+817: Na 2 H8
+818: xI 2 H7
+819: vS 2 H7
+820: nI 2 H7
+821: oN 2 H7
+822: oS 2 H7
+823: uS 2 H7
+824: uN 2 H7
+825: fI 2 H7
+826: eS 2 H7
+827: Ne 2 H8
+828: eN 2 H7
+829: cI 2 H7
+830: bI 2 H7
+831: aS 2 H7
+832: aN 2 H7
+833: aI 2 H7
commande> j QuIZ H6
commande> t E?
commande> r
commande> a r 50
1: ZEn 12 9H
- 2: ZEf 12 9H
- 3: ZEe 12 9H
- 4: ZEc 12 9H
- 5: rEZ 12 9F
- 6: nEZ 12 9F
- 7: lEZ 12 9F
- 8: fEZ 12 9F
- 9: ZoE 11 9H
- 10: ZeE 11 9H
- 11: QuE 11 6H
- 12: Eh 5 G7
- 13: En 5 G7
- 14: Es 5 G7
- 15: Ex 5 G7
- 16: pIE 2 8G
- 17: oIE 2 8G
- 18: nIE 2 8G
- 19: mIE 2 8G
- 20: lIE 2 8G
- 21: hIE 2 8G
- 22: fIE 2 8G
- 23: aIE 2 8G
- 24: pEu 2 7F
- 25: lEu 2 7F
- 26: jEu 2 7F
- 27: hEu 2 7F
- 28: fEu 2 7F
- 29: rIE 2 8G
- 30: vIE 2 8G
- 31: EpI 2 8F
- 32: lEI 2 8F
- 33: IdE 2 8H
- 34: IlE 2 8H
- 35: IpE 2 8H
- 36: IrE 2 8H
- 37: IvE 2 8H
- 38: IxE 2 8H
- 39: Eu 2 7G
- 40: duE 2 7G
- 41: buE 2 7G
- 42: Eue 2 7G
- 43: Euh 2 7G
- 44: Eus 2 7G
- 45: Eut 2 7G
- 46: Eux 2 7G
- 47: euE 2 7G
- 48: guE 2 7G
- 49: huE 2 7G
- 50: luE 2 7G
+ 2: ZEk 12 9H
+ 3: ZEf 12 9H
+ 4: ZEe 12 9H
+ 5: ZEc 12 9H
+ 6: rEZ 12 9F
+ 7: nEZ 12 9F
+ 8: lEZ 12 9F
+ 9: fEZ 12 9F
+ 10: ZoE 11 9H
+ 11: ZeE 11 9H
+ 12: QuE 11 6H
+ 13: Eh 5 G7
+ 14: En 5 G7
+ 15: Es 5 G7
+ 16: Ex 5 G7
+ 17: pIE 2 8G
+ 18: oIE 2 8G
+ 19: nIE 2 8G
+ 20: mIE 2 8G
+ 21: lIE 2 8G
+ 22: hIE 2 8G
+ 23: fIE 2 8G
+ 24: aIE 2 8G
+ 25: pEu 2 7F
+ 26: lEu 2 7F
+ 27: jEu 2 7F
+ 28: hEu 2 7F
+ 29: fEu 2 7F
+ 30: rIE 2 8G
+ 31: vIE 2 8G
+ 32: EpI 2 8F
+ 33: lEI 2 8F
+ 34: IdE 2 8H
+ 35: IlE 2 8H
+ 36: IpE 2 8H
+ 37: IrE 2 8H
+ 38: IvE 2 8H
+ 39: IxE 2 8H
+ 40: Eue 2 7G
+ 41: Eu 2 7G
+ 42: duE 2 7G
+ 43: buE 2 7G
+ 44: suE 2 7G
+ 45: ruE 2 7G
+ 46: tuE 2 7G
+ 47: quE 2 7G
+ 48: puE 2 7G
+ 49: vuE 2 7G
+ 50: nuE 2 7G
commande> q
fin du mode entraînement
commande> q
Index: utils/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- utils/Makefile.am 4 Nov 2005 20:00:06 -0000 1.9
+++ utils/Makefile.am 8 Jan 2008 13:52:42 -0000 1.10
@@ -16,24 +16,26 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-top_srcdir = @top_srcdir@
+localedir = $(datadir)/locale
+AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"
+
+INCLUDES = -I$(top_srcdir)/dic -I$(top_srcdir)/game -I../intl
-I$(top_srcdir)/intl
-INCLUDES = -I$(top_srcdir)/dic -I$(top_srcdir)/game -I$(top_srcdir)/intl
noinst_PROGRAMS =
+bin_PROGRAMS =
if BUILD_TEXT
noinst_PROGRAMS += eliottxt
eliottxt_SOURCES = game_io.h game_io.cpp eliottxt.cpp
-eliottxt_LDADD = ../game/libgame.a ../dic/libdic.a -lreadline
+eliottxt_LDADD = $(top_builddir)/game/libgame.a $(top_builddir)/dic/libdic.a
@LIBINTL@
+if HAS_READLINE
+eliottxt_LDADD += -lreadline
+endif
endif
if BUILD_NCURSES
-noinst_PROGRAMS += eliotcurses
-eliotcurses_SOURCES = ncurses.cpp
-eliotcurses_LDADD = ../game/libgame.a ../dic/libdic.a -lncurses @LIBINTL@
+bin_PROGRAMS += eliotcurses
+eliotcurses_SOURCES = ncurses.cpp ncurses.h
+eliotcurses_LDADD = ../game/libgame.a ../dic/libdic.a -lncursesw @LIBINTL@
endif
-datadir = @datadir@
-localedir = $(datadir)/locale
-DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
-
Index: utils/eliottxt.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/eliottxt.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- utils/eliottxt.cpp 4 Aug 2007 20:01:27 -0000 1.18
+++ utils/eliottxt.cpp 8 Jan 2008 13:52:42 -0000 1.19
@@ -18,19 +18,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
+#include "config.h"
+
+#include <wchar.h>
+#include <fstream>
+#include <iostream>
#include <stdlib.h>
-#include <stdio.h>
#include <time.h>
#include <string.h>
#include <locale.h>
#include <wctype.h>
-#include <wchar.h>
-#include <fstream>
-#include <readline/readline.h>
-#include <readline/history.h>
+#if HAVE_READLINE_READLINE_H
+# include <stdio.h>
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif
#include "dic.h"
-#include "dic_search.h"
#include "regexp.h"
#include "game_io.h"
#include "game_factory.h"
@@ -41,8 +45,6 @@
/* A static variable for holding the line. */
-static char *line_read = NULL;
-/* Wide version of the line */
static wchar_t *wline_read = NULL;
/**
@@ -51,20 +53,16 @@
*/
wchar_t *rl_gets()
{
+#if HAVE_READLINE_READLINE_H
// If the buffer has already been allocated, return the memory to the free
// pool
- if (line_read)
- {
- free(line_read);
- line_read = NULL;
- }
if (wline_read)
{
delete[] wline_read;
- wline_read = NULL;
}
// Get a line from the user
+ static char *line_read;
line_read = readline("commande> ");
// If the line has any text in it, save it on the history
@@ -78,7 +76,28 @@
return NULL;
wline_read = new wchar_t[len + 1];
- len = mbstowcs(wline_read, line_read, len + 1);
+ mbstowcs(wline_read, line_read, len + 1);
+
+ if (line_read)
+ {
+ free(line_read);
+ }
+#else
+ if (!cin.good())
+ return NULL;
+
+ cout << "commande> ";
+ string line;
+ std::getline(cin, line);
+
+ // Get the needed length (we _can't_ use string::size())
+ size_t len = mbstowcs(NULL, line.c_str(), 0);
+ if (len == (size_t)-1)
+ return NULL;
+
+ wline_read = new wchar_t[len + 1];
+ mbstowcs(wline_read, line.c_str(), len + 1);
+#endif
return wline_read;
}
@@ -86,7 +105,7 @@
wchar_t * next_token_alpha(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
{
- wchar_t *token = wcstok(cmd, delim, state);
+ wchar_t *token = _wcstok(cmd, delim, state);
if (token == NULL)
return NULL;
int i;
@@ -99,7 +118,7 @@
wchar_t * next_token_alphanum(wchar_t *cmd, const wchar_t *delim, wchar_t
**state)
{
- wchar_t *token = wcstok(cmd, delim, state);
+ wchar_t *token = _wcstok(cmd, delim, state);
if (token == NULL)
return NULL;
int i;
@@ -112,7 +131,7 @@
wchar_t * next_token_alphaplusjoker(wchar_t *cmd, const wchar_t *delim,
wchar_t **state)
{
- wchar_t *token = wcstok(cmd, delim, state);
+ wchar_t *token = _wcstok(cmd, delim, state);
if (token == NULL)
return NULL;
int i;
@@ -128,7 +147,7 @@
wchar_t * next_token_digit(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
{
- wchar_t *token = wcstok(cmd, delim, state);
+ wchar_t *token = _wcstok(cmd, delim, state);
if (token == NULL)
return NULL;
int i;
@@ -141,7 +160,7 @@
wchar_t * next_token_cross(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
{
- wchar_t *token = wcstok(cmd, delim, state);
+ wchar_t *token = _wcstok(cmd, delim, state);
if (token == NULL)
return NULL;
int i;
@@ -156,7 +175,7 @@
wchar_t * next_token_filename(wchar_t *cmd, const wchar_t *delim, wchar_t
**state)
{
- wchar_t *token = wcstok(cmd, delim, state);
+ wchar_t *token = _wcstok(cmd, delim, state);
if (token == NULL)
return NULL;
int i;
@@ -169,13 +188,15 @@
}
-void eliottxt_get_cross(const Dictionary &iDic, wchar_t *cros)
+void eliottxt_get_cross(const Dictionary &iDic, const wstring &iCros)
{
- wchar_t wordlist[RES_CROS_MAX][DIC_WORD_MAX];
- Dic_search_Cros(iDic, cros, wordlist);
- for (int i = 0; i < RES_CROS_MAX && wordlist[i][0]; i++)
+ list<wstring> wordList;
+ iDic.searchCross(iCros, wordList);
+
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
{
- printf(" %s\n", convertToMb(wordlist[i]).c_str());
+ printf(" %s\n", convertToMb(*it).c_str());
}
}
@@ -198,6 +219,10 @@
printf(" S -- score de tous les joueurs\n");
printf(" t -- tirage\n");
printf(" d [] : vérifier le mot []\n");
+ printf(" b [b|p|r] [] : effectuer une recherche speciale à partir de
[]\n");
+ printf(" b -- benjamins\n");
+ printf(" p -- 7 + 1\n");
+ printf(" r -- raccords\n");
printf(" * : tirage aléatoire\n");
printf(" + : tirage aléatoire ajouts\n");
printf(" t [] : changer le tirage\n");
@@ -278,7 +303,7 @@
void display_data(const Game &iGame, const wchar_t *delim, wchar_t **state)
{
- wchar_t *token;
+ const wchar_t *token;
token = next_token_alpha(NULL, delim, state);
if (token == NULL)
@@ -365,7 +390,7 @@
void loop_training(Training &iGame)
{
- wchar_t *token;
+ const wchar_t *token;
wchar_t *state;
wchar_t *commande = NULL;
wchar_t delim[] = L" \t";
@@ -376,7 +401,7 @@
while (quit == 0)
{
commande = rl_gets();
- token = wcstok(commande, delim, &state);
+ token = _wcstok(commande, delim, &state);
if (token)
{
switch (token[0])
@@ -387,13 +412,65 @@
case L'a':
display_data(iGame, delim, &state);
break;
+ case L'b':
+ token = next_token_alpha(NULL, delim, &state);
+ if (token == NULL)
+ help_training();
+ else
+ {
+ const wchar_t *word = next_token_alpha(NULL, delim,
&state);
+ if (word == NULL)
+ help_training();
+ else
+ {
+ switch (token[0])
+ {
+ case L'b':
+ {
+ list<wstring> wordList;
+ iGame.getDic().searchBenj(word, wordList);
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it !=
wordList.end(); ++it)
+ cout << convertToMb(*it) << endl;
+ break;
+ }
+ case L'p':
+ {
+ map<wchar_t, list<wstring> > wordMap;
+ iGame.getDic().search7pl1(word, wordMap,
false);
+ map<wchar_t, list<wstring>
>::const_iterator it;
+ for (it = wordMap.begin(); it !=
wordMap.end(); ++it)
+ {
+ if (it->first)
+ cout << "+" <<
convertToMb(it->first) << endl;
+ list<wstring>::const_iterator itWord;;
+ for (itWord = it->second.begin();
itWord != it->second.end(); itWord++)
+ {
+ cout << " " <<
convertToMb(*itWord) << endl;
+ }
+ }
+ break;
+ }
+ case L'r':
+ {
+ list<wstring> wordList;
+ iGame.getDic().searchRacc(word, wordList);
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it !=
wordList.end(); ++it)
+ cout << convertToMb(*it) << endl;
+ break;
+ }
+ }
+ }
+ }
+ break;
case L'd':
token = next_token_alpha(NULL, delim, &state);
if (token == NULL)
help_training();
else
{
- if (Dic_search_word(iGame.getDic(), token))
+ if (iGame.getDic().searchWord(token))
{
printf("le mot -%s- existe\n",
convertToMb(token).c_str());
@@ -499,7 +576,7 @@
void loop_freegame(FreeGame &iGame)
{
- wchar_t *token;
+ const wchar_t *token;
wchar_t *state;
wchar_t *commande = NULL;
wchar_t delim[] = L" \t";
@@ -510,7 +587,7 @@
while (quit == 0)
{
commande = rl_gets();
- token = wcstok(commande, delim, &state);
+ token = _wcstok(commande, delim, &state);
if (token)
{
switch (token[0])
@@ -527,7 +604,7 @@
help_freegame();
else
{
- if (Dic_search_word(iGame.getDic(), token))
+ if (iGame.getDic().searchWord(token))
{
printf("le mot -%s- existe\n",
convertToMb(token).c_str());
@@ -566,7 +643,7 @@
if (token == NULL)
token = L"";
- if (iGame.pass(token, iGame.currPlayer()) != 0)
+ if (iGame.pass(token) != 0)
break;
break;
case L's':
@@ -600,7 +677,7 @@
void loop_duplicate(Duplicate &iGame)
{
- wchar_t *token;
+ const wchar_t *token;
wchar_t *state;
wchar_t *commande = NULL;
wchar_t delim[] = L" \t";
@@ -611,7 +688,7 @@
while (quit == 0)
{
commande = rl_gets();
- token = wcstok(commande, delim, &state);
+ token = _wcstok(commande, delim, &state);
if (token)
{
switch (token[0])
@@ -628,7 +705,7 @@
help_duplicate();
else
{
- if (Dic_search_word(iGame.getDic(), token))
+ if (iGame.getDic().searchWord(token))
{
printf("le mot -%s- existe\n",
convertToMb(token).c_str());
@@ -667,10 +744,14 @@
help_duplicate();
else
{
+ int n = _wtoi(token);
+ if (n < 0 || n >= (int)iGame.getNPlayers())
+ {
+ fprintf(stderr, "Numéro de joueur invalide\n");
+ break;
+ }
int res = iGame.setPlayer(_wtoi(token));
if (res == 1)
- fprintf(stderr, "Numéro de joueur invalide\n");
- else if (res == 2)
fprintf(stderr, "Impossible de choisir un joueur
non humain\n");
}
break;
@@ -703,7 +784,8 @@
}
-void eliot_regexp_build_default_llist(struct search_RegE_list_t &llist)
+void eliot_regexp_build_default_llist(const Dictionary &iDic,
+ struct search_RegE_list_t &llist)
{
memset(&llist, 0, sizeof(llist));
@@ -727,8 +809,8 @@
memset(llist.letters[i], 0, sizeof(llist.letters[i]));
}
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = iDic.getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
if (! it->isJoker() && ! it->isEmpty())
@@ -763,16 +845,14 @@
#define DIC_RE_MAX (3*DIC_WORD_MAX) // yes, it's 3
struct search_RegE_list_t llist;
- eliot_regexp_build_default_llist(llist);
-
- wchar_t *exp, *cnres, *clmin, *clmax;
+ eliot_regexp_build_default_llist(iDic, llist);
- exp = wcstok(NULL, delim, state);
- cnres = wcstok(NULL, delim, state);
- clmin = wcstok(NULL, delim, state);
- clmax = wcstok(NULL, delim, state);
+ wchar_t *regexp = _wcstok(NULL, delim, state);
+ wchar_t *cnres = _wcstok(NULL, delim, state);
+ wchar_t *clmin = _wcstok(NULL, delim, state);
+ wchar_t *clmax = _wcstok(NULL, delim, state);
- if (exp == NULL)
+ if (regexp == NULL)
{
return;
}
@@ -791,18 +871,17 @@
return;
}
- wchar_t re[DIC_RE_MAX];
- wcsncpy(re, exp, DIC_RE_MAX);
- wchar_t buff[RES_REGE_MAX][DIC_WORD_MAX];
-
- printf("search for %s (%d,%d,%d)\n", convertToMb(exp).c_str(),
+ printf("search for %s (%d,%d,%d)\n", convertToMb(regexp).c_str(),
nres, lmin, lmax);
- Dic_search_RegE(iDic, re, buff, &llist);
+
+ list<wstring> wordList;
+ iDic.searchRegExp(regexp, wordList, &llist);
int nresult = 0;
- for (int i = 0; i < RES_REGE_MAX && i < nres && buff[i][0]; i++)
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end() && nresult < nres; it++)
{
- printf("%s\n", convertToMb(buff[i]).c_str());
+ printf("%s\n", convertToMb(*it).c_str());
nresult++;
}
printf("%d printed results\n", nresult);
@@ -811,7 +890,7 @@
void main_loop(const Dictionary &iDic)
{
- wchar_t *token;
+ const wchar_t *token;
wchar_t *state;
wchar_t *commande = NULL;
wchar_t delim[] = L" \t";
@@ -821,7 +900,7 @@
while (quit == 0)
{
commande = rl_gets();
- token = wcstok(commande, delim, &state);
+ token = _wcstok(commande, delim, &state);
if (token)
{
switch (token[0])
@@ -960,13 +1039,11 @@
int main(int argc, char *argv[])
{
- char dic_path[100];
+ string dicPath;
// Let the user choose the locale
setlocale(LC_ALL, "");
- Dictionary dic = NULL;
-
if (argc != 2 && argc != 3)
{
fprintf(stdout, "Usage: eliot /chemin/vers/ods4.dawg [random_seed]\n");
@@ -974,39 +1051,12 @@
}
else
{
- strcpy(dic_path, argv[1]);
+ dicPath = argv[1];
}
- switch (Dic_load(&dic, dic_path))
+ try
{
- case 0:
- /* Normal case */
- break;
- case 1:
- printf("chargement: problème d'ouverture de %s\n", argv[1]);
- exit(1);
- break;
- case 2:
- printf("chargement: mauvais en-tete de dictionnaire\n");
- exit(2);
- break;
- case 3:
- printf("chargement: problème 3 d'allocation mémoire\n");
- exit(3);
- break;
- case 4:
- printf("chargement: problème 4 d'alocation mémoire\n");
- exit(4);
- break;
- case 5:
- printf("chargement: problème de lecture des arcs du
dictionnaire\n");
- exit(5);
- break;
- default:
- printf("chargement: problème non-repertorié\n");
- exit(6);
- break;
- }
+ Dictionary dic(dicPath);
if (argc == 3)
srand(atoi(argv[2]));
@@ -1016,13 +1066,14 @@
main_loop(dic);
GameFactory::Destroy();
- Dic_destroy(dic);
-
- // Free the readline static variable and its wide equivalent
- if (line_read)
- free(line_read);
+ // Free the readline static variable
if (wline_read)
delete[] wline_read;
+ }
+ catch (std::exception &e)
+ {
+ cerr << e.what() << endl;
+ }
return 0;
}
Index: utils/game_io.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/game_io.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- utils/game_io.cpp 4 Aug 2007 20:01:27 -0000 1.11
+++ utils/game_io.cpp 8 Jan 2008 13:52:42 -0000 1.12
@@ -20,8 +20,9 @@
#include <iomanip>
#include <string>
-#include "stdlib.h"
+#include <stdlib.h>
+#include <dic.h>
#include "game_io.h"
#include "game.h"
#include "training.h"
@@ -45,8 +46,11 @@
out << " " << (char)(row - BOARD_MIN + 'A') << " ";
for (col = BOARD_MIN; col <= BOARD_MAX; col++)
{
- char l = iGame.getBoard().getChar(row, col);
- out << setw(3) << (l ? l : '-');
+ wchar_t l = iGame.getBoard().getChar(row, col);
+ if (l == 0)
+ out << " -";
+ else
+ out << padAndConvert(wstring(1, l), 3);
}
out << endl;
}
@@ -93,11 +97,13 @@
out << " " << (char)(row - BOARD_MIN + 'A') << " ";
for (col = BOARD_MIN; col <= BOARD_MAX; col++)
{
- char l = iGame.getBoard().getChar(row, col);
+ wchar_t l = iGame.getBoard().getChar(row, col);
bool j = (iGame.getBoard().getCharAttr(row, col) & ATTR_JOKER);
- out << " " << (j ? '.' : (l ? ' ' : '-'));
- out << (l ? l : '-');
+ if (l == 0)
+ out << " " << (j ? "." : "--");
+ else
+ out << " " << (j ? "." : " ") << convertToMb(l);
}
out << endl;
}
@@ -118,9 +124,9 @@
out << " " << (char)(row - BOARD_MIN + 'A') << " ";
for (col = BOARD_MIN; col <= BOARD_MAX; col++)
{
- char l = iGame.getBoard().getChar(row, col);
+ wchar_t l = iGame.getBoard().getChar(row, col);
if (l != 0)
- out << " " << l;
+ out << padAndConvert(wstring(1, l), 3);
else
{
int wm = iGame.getBoard().getWordMultiplier(row, col);
@@ -172,12 +178,12 @@
void GameIO::printNonPlayed(ostream &out, const Game &iGame)
{
- const list<Tile>& allTiles = Tile::getAllTiles();
- list<Tile>::const_iterator it;
+ const vector<Tile>& allTiles = iGame.getDic().getAllTiles();
+ vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
- if (iGame.getBag().in(it->toChar()) > 9)
+ if (iGame.getBag().in(*it) > 9)
out << " ";
out << setw(2) << convertToMb(it->toChar());
}
@@ -185,7 +191,7 @@
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
- out << " " << iGame.getBag().in(it->toChar());
+ out << " " << iGame.getBag().in(*it);
}
out << endl;
}
@@ -199,7 +205,7 @@
void GameIO::printAllRacks(ostream &out, const Game &iGame)
{
- for (int j = 0; j < iGame.getNPlayers(); j++)
+ for (unsigned int j = 0; j < iGame.getNPlayers(); j++)
{
out << "Joueur " << j << ": ";
out <<
convertToMb(iGame.getPlayer(j).getCurrentRack().toString(PlayedRack::RACK_SIMPLE))
<< endl;
@@ -241,7 +247,7 @@
void GameIO::printAllPoints(ostream &out, const Game &iGame)
{
- for (int i = 0; i < iGame.getNPlayers(); i++)
+ for (unsigned int i = 0; i < iGame.getNPlayers(); i++)
{
out << "Joueur " << i << ": "
<< setw(4) << iGame.getPlayer(i).getPoints() << endl;
Index: utils/ncurses.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/ncurses.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- utils/ncurses.cpp 29 Jan 2006 12:40:49 -0000 1.22
+++ utils/ncurses.cpp 8 Jan 2008 13:52:42 -0000 1.23
@@ -30,7 +30,6 @@
#include "ncurses.h"
#include "dic.h"
-#include "dic_search.h"
#include "game_factory.h"
#include "training.h"
#include "duplicate.h"
@@ -43,48 +42,126 @@
using namespace std;
-CursesIntf::CursesIntf(WINDOW *win, Game& iGame)
- : m_win(win), m_game(&iGame), m_state(DEFAULT), m_dying(false),
- m_boxStart(0), m_boxLines(0), m_boxLinesData(0), m_boxY(0),
- m_showDots(false)
+Box::Box(WINDOW *win, int y, int x, int h, int w,
+ unsigned int iHeadingLines)
+ : m_win(win), m_x(x), m_y(y), m_w(w), m_h(h),
+ m_topLine(y + 1 + iHeadingLines),
+ m_nbLines(h - 2 - iHeadingLines), m_dataStart(0), m_dataSize(0)
{
}
-CursesIntf::~CursesIntf()
+void Box::draw(const string& iTitle) const
{
- GameFactory::Instance()->releaseGame(*m_game);
- GameFactory::Destroy();
+ if (m_w > 3 && m_h > 2)
+ {
+ // Add one space before and after the title for readability
+ string title;
+ if (!iTitle.empty())
+ title = " " + iTitle + " ";
+ unsigned int l = title.size();
+ // Truncate the title if needed
+ if ((int)l > m_w - 2)
+ l = m_w - 2;
+
+ mvwaddch(m_win, m_y, m_x, ACS_ULCORNER);
+ mvwhline(m_win, m_y, m_x + 1, ACS_HLINE, (m_w - l - 2)/2);
+ mvwprintw(m_win,m_y, m_x + 1 + (m_w - l - 2)/2, "%s", title.c_str());
+ mvwhline(m_win, m_y, m_x + (m_w - l)/2 + l,
+ ACS_HLINE, m_w - 1 - ((m_w - l)/2 + l));
+ mvwaddch(m_win, m_y, m_x + m_w - 1, ACS_URCORNER);
+
+ mvwvline(m_win, m_y + 1, m_x, ACS_VLINE, m_h - 2);
+ mvwvline(m_win, m_y + 1, m_x + m_w - 1, ACS_VLINE, m_h - 2);
+
+ mvwaddch(m_win, m_y + m_h - 1, m_x, ACS_LLCORNER);
+ mvwhline(m_win, m_y + m_h - 1, m_x + 1, ACS_HLINE, m_w - 2);
+ mvwaddch(m_win, m_y + m_h - 1, m_x + m_w - 1, ACS_LRCORNER);
+ }
}
-void CursesIntf::drawBox(WINDOW *win, int y, int x, int h, int w,
- const string& iTitle)
+void Box::printDataLine(int n, int x, const char *fmt, ...) const
{
- if (w > 3 && h > 2)
+ if (n < getFirstLine() || n >= getLastLine() || m_w <= x - m_x + 1)
+ return;
+
+ va_list vl_args;
+ char *buf = NULL;
+ va_start(vl_args, fmt);
+ vasprintf(&buf, fmt, vl_args);
+ va_end(vl_args);
+
+ if (buf == NULL)
{
- int i_len = iTitle.size();
+ return;
+ }
- if (i_len > w - 2) i_len = w - 2;
+ mvwprintw(m_win, m_topLine + n - m_dataStart, x, "%s",
+ truncString(buf, m_w - 1 - x + m_x).c_str());
+ free(buf);
+}
- mvwaddch(win, y, x, ACS_ULCORNER);
- mvwhline(win, y, x+1, ACS_HLINE, ( w-i_len-2)/2);
- mvwprintw(win,y, x+1+(w-i_len-2)/2, "%s", iTitle.c_str());
- mvwhline(win, y, x+(w-i_len)/2+i_len,
- ACS_HLINE, w - 1 - ((w-i_len)/2+i_len));
- mvwaddch(win, y, x+w-1,ACS_URCORNER);
- mvwvline(win, y+1, x, ACS_VLINE, h-2);
- mvwvline(win, y+1, x+w-1, ACS_VLINE, h-2);
+bool Box::scrollOneLineUp()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart == 0)
+ return false;
+ m_dataStart--;
+ return true;
+}
- mvwaddch(win, y+h-1, x, ACS_LLCORNER);
- mvwhline(win, y+h-1, x+1, ACS_HLINE, w - 2);
- mvwaddch(win, y+h-1, x+w-1, ACS_LRCORNER);
- }
+
+bool Box::scrollOneLineDown()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart >= m_dataSize - 1)
+ return false;
+ m_dataStart++;
+ return true;
+}
+
+
+bool Box::scrollOnePageUp()
+{
+ if (m_dataSize <= m_nbLines)
+ return false;
+ m_dataStart -= m_nbLines;
+ if (m_dataStart < 0)
+ m_dataStart = 0;
+ return true;
+}
+
+
+bool Box::scrollOnePageDown()
+{
+ if (m_dataSize <= m_nbLines)
+ return false;
+ m_dataStart += m_nbLines;
+ if (m_dataStart > m_dataSize - 1)
+ m_dataStart = m_dataSize - 1;
+ return true;
+}
+
+
+bool Box::scrollBeginning()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart == 0)
+ return false;
+ m_dataStart = 0;
+ return true;
+}
+
+
+bool Box::scrollEnd()
+{
+ if (m_dataSize <= m_nbLines || m_dataStart == m_dataSize - 1)
+ return false;
+ m_dataStart = m_dataSize - 1;
+ return true;
}
-void CursesIntf::clearRect(WINDOW *win, int y, int x, int h, int w)
+void Box::clearRect(WINDOW *win, int y, int x, int h, int w)
{
for (int i = 0; i < h; i++)
{
@@ -93,32 +170,30 @@
}
-void CursesIntf::boxPrint(WINDOW *win, int y, int x, const char *fmt, ...)
+CursesIntf::CursesIntf(WINDOW *win, Game& iGame)
+ : m_win(win), m_game(&iGame), m_state(DEFAULT), m_dying(false),
+ m_box(win, 0, 0, 0, 0), m_showDots(false)
{
- if (y < m_boxStart || y - m_boxStart >= m_boxLines)
- return;
+}
- va_list vl_args;
- char *buf = NULL;
- va_start(vl_args, fmt);
- vasprintf(&buf, fmt, vl_args);
- va_end(vl_args);
- if (buf == NULL)
- {
- return;
- }
- mvwprintw(win, m_boxY + y - m_boxStart, x, "%s", buf);
+CursesIntf::~CursesIntf()
+{
+ GameFactory::Instance()->releaseGame(*m_game);
+ GameFactory::Destroy();
}
-void CursesIntf::drawStatus(WINDOW *win, int y, int x,
- const string& iMessage, bool error)
+void CursesIntf::drawStatus(WINDOW *win, const string& iMessage, bool error)
{
+ int cols;
+ int lines;
+ getmaxyx(win, lines, cols);
+ int x = 0;
+ int y = lines - 1;
if (error)
wattron(win, COLOR_PAIR(COLOR_YELLOW));
- mvwprintw(win, y, x, iMessage.c_str());
- whline(win, ' ', COLS - x - 1 - iMessage.size());
+ mvwprintw(win, y, x, truncOrPad(iMessage, cols).c_str());
if (error)
wattron(win, COLOR_PAIR(COLOR_WHITE));
}
@@ -127,7 +202,8 @@
void CursesIntf::drawBoard(WINDOW *win, int y, int x) const
{
// Box around the board
- drawBox(win, y + 1, x + 3, 17, 47, "");
+ Box box(win, y + 1, x + 3, 17, 47);
+ box.draw();
// Print the coordinates
for (int i = 0; i < 15; i++)
@@ -161,14 +237,20 @@
mvwprintw(win, y + row + 1, x + 3 * col + 1, " ");
// Now add the letter
- char c = m_game->getBoard().getChar(row, col);
+ wchar_t c = m_game->getBoard().getChar(row, col);
if (c)
{
- if (islower(c))
- mvwaddch(win, y + row + 1, x + 3 * col + 2,
- c | A_BOLD | COLOR_PAIR(COLOR_GREEN));
+ cchar_t cc;
+ if (iswlower(c))
+ {
+ setcchar(&cc, &c, A_BOLD, COLOR_GREEN, NULL);
+ mvwadd_wch(win, y + row + 1, x + 3 * col + 2, &cc);
+ }
else
- mvwaddch(win, y + row + 1, x + 3 * col + 2, c);
+ {
+ setcchar(&cc, &c, 0, 0, NULL);
+ mvwadd_wch(win, y + row + 1, x + 3 * col + 2, &cc);
+ }
}
else
{
@@ -184,8 +266,9 @@
void CursesIntf::drawScoresRacks(WINDOW *win, int y, int x) const
{
- drawBox(win, y, x, m_game->getNPlayers() + 2, 25, _(" Scores "));
- for (int i = 0; i < m_game->getNPlayers(); i++)
+ Box box(win, y, x, m_game->getNPlayers() + 2, 25);
+ box.draw(_("Scores"));
+ for (unsigned int i = 0; i < m_game->getNPlayers(); i++)
{
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
attron(A_BOLD);
@@ -196,16 +279,17 @@
}
// Distance between the 2 boxes
- int yOff = m_game->getNPlayers() + 3;
+ unsigned int yOff = m_game->getNPlayers() + 3;
- drawBox(win, y + yOff, x, m_game->getNPlayers() + 2, 25, _(" Racks "));
- for (int i = 0; i < m_game->getNPlayers(); i++)
+ Box box2(win, y + yOff, x, m_game->getNPlayers() + 2, 25);
+ box2.draw(_("Racks"));
+ for (unsigned int i = 0; i < m_game->getNPlayers(); i++)
{
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
attron(A_BOLD);
- string rack =
convertToMb(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,
- _("Player %d: %s"), i, rack.c_str());
+ _("Player %d: %ls"), i, rack.c_str());
if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
attroff(A_BOLD);
// Force to refresh the whole rack
@@ -223,127 +307,219 @@
}
-void CursesIntf::drawResults(WINDOW *win, int y, int x)
+void CursesIntf::drawResults(Box &ioBox) const
{
if (m_game->getMode() != Game::kTRAINING)
return;
Training *tr_game = static_cast<Training*>(m_game);
- int h = 17;
- drawBox(win, y, x, h, 25, _(" Search results "));
- m_boxY = y + 1;
- m_boxLines = h - 2;
- m_boxLinesData = tr_game->getResults().size();
+ ioBox.draw(_("Search results"));
+ ioBox.setDataSize(tr_game->getResults().size());
- int i;
+ unsigned int i;
const Results& res = tr_game->getResults();
- for (i = m_boxStart; i < res.size() &&
- i < m_boxStart + m_boxLines; i++)
+ int x = ioBox.getLeft();
+ for (i = (unsigned int)ioBox.getFirstLine();
+ i < res.size() && i < (unsigned int)ioBox.getLastLine(); i++)
{
const Round &r = res.get(i);
wstring coord = r.getCoord().toString();
- boxPrint(win, i, x + 1, "%3d %s%s %3s",
+ ioBox.printDataLine(i, x, "%3d %s %3s",
r.getPoints(),
- convertToMb(r.getWord()).c_str(),
- string(h - 3 - r.getWordLen(), ' ').c_str(),
+ padAndConvert(r.getWord(), ioBox.getWidth() - 9,
false).c_str(),
convertToMb(coord).c_str());
}
// Complete the list with empty lines, to avoid trails
- for (; i < m_boxStart + m_boxLines; i++)
+ for (; i < (unsigned int)ioBox.getLastLine(); i++)
{
- boxPrint(win, i, x + 1, string(23, ' ').c_str());
+ ioBox.printDataLine(i, x + 1, string(ioBox.getWidth(), ' ').c_str());
}
}
-void CursesIntf::drawHistory(WINDOW *win, int y, int x)
+void CursesIntf::drawHistory(Box &ioBox) const
{
// To allow pseudo-scrolling, without leaving trails
- clear();
+ ioBox.clearData();
- drawBox(win, y, x, LINES - y, COLS - x, _(" History of the game "));
- m_boxY = y + 1;
- m_boxLines = LINES - y - 2;
- m_boxLinesData = m_game->getHistory().getSize();
+ ioBox.draw(_("History of the game"));
+ ioBox.setDataSize((int)m_game->getHistory().getSize());
+ int x = ioBox.getLeft();
+ int y = ioBox.getTop();
// Heading
- boxPrint(win, m_boxStart, x + 2,
- _(" N | RACK | SOLUTION | REF | PTS | P | BONUS"));
- mvwhline(win, y + 2, x + 2, ACS_HLINE, 55);
+ string heading = truncString(_(" N | RACK | SOLUTION | REF |
PTS | P | BONUS"),
+ ioBox.getWidth() - 1);
+ mvwprintw(m_win, y, x + 1, "%s", heading.c_str());
+ mvwhline(m_win, y + 1, x + 1, ACS_HLINE, heading.size());
int i;
- for (i = m_boxStart + 0; i < m_game->getHistory().getSize() &&
- i < m_boxStart + m_boxLines; i++)
+ for (i = ioBox.getFirstLine();
+ i < (int)m_game->getHistory().getSize() && i < ioBox.getLastLine();
i++)
{
const Turn& t = m_game->getHistory().getTurn(i);
- const Round& r = t.getRound();
- string word = convertToMb(r.getWord());
- string coord = convertToMb(r.getCoord().toString());
- boxPrint(win, i + 2, x + 2,
- "%2d %8s %s%s %3s %3d %1d %c",
- i + 1, convertToMb(t.getPlayedRack().toString()).c_str(),
- word.c_str(), string(15 - word.size(), ' ').c_str(),
- coord.c_str(), r.getPoints(),
+ const Move& m = t.getMove();
+ if (m.getType() == Move::VALID_ROUND)
+ {
+ // The move corresponds to a played round: display it
+ const Round &r = m.getRound();
+ wstring coord = r.getCoord().toString();
+ ioBox.printDataLine(i, x,
+ " %2d %s %s %s %3d %1d %c",
+ i + 1, padAndConvert(t.getPlayedRack().toString(), 8).c_str(),
+ padAndConvert(r.getWord(), 15, false).c_str(),
+ padAndConvert(coord, 3).c_str(), r.getPoints(),
t.getPlayer(), r.getBonus() ? '*' : ' ');
}
- mvwvline(win, y + 1, x + 5, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 16, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 34, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 40, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 46, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
- mvwvline(win, y + 1, x + 50, ACS_VLINE, min(i + 2 - m_boxStart,
m_boxLines));
+ else if (m.getType() == Move::INVALID_WORD)
+ {
+ // The move corresponds to an invalid word: display it
+ wstring invWord = L"<" + m.getBadWord() + L">";
+ ioBox.printDataLine(i, x,
+ " %2d %s %s %s %3d %1d",
+ i + 1, padAndConvert(t.getPlayedRack().toString(), 8).c_str(),
+ padAndConvert(invWord, 15, false).c_str(),
+ padAndConvert(m.getBadCoord(), 3).c_str(), m.getScore(),
+ t.getPlayer());
+ }
+ else
+ {
+ // The move corresponds to a passed turn or changed letters
+ wstring action;
+ if (m.getType() == Move::PASS)
+ action = convertToWc(_("(PASS)"));
+ else if (m.getType() == Move::CHANGE_LETTERS)
+ action = L"(-" + m.getChangedLetters() + L")";
+
+ ioBox.printDataLine(i, x,
+ " %2d %s %s %s %3d %1d",
+ i + 1, padAndConvert(t.getPlayedRack().toString(), 8).c_str(),
+ padAndConvert(action, 15, false).c_str(),
+ " - ", m.getScore(), t.getPlayer());
+ }
+ }
+ int nbLines = min(i + 2 - ioBox.getFirstLine(),
+ ioBox.getLastLine() - ioBox.getFirstLine() + 2);
+ mvwvline(m_win, y, x + 4, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 15, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 33, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 39, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 45, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 49, ACS_VLINE, nbLines);
}
-void CursesIntf::drawHelp(WINDOW *win, int y, int x)
+void CursesIntf::drawHelp(Box &ioBox) const
{
// To allow pseudo-scrolling, without leaving trails
- clear();
-
- drawBox(win, y, x, LINES - y, COLS - x, _(" Help "));
- m_boxY = y + 1;
- m_boxLines = LINES - y - 2;
+ ioBox.clearData();
+ ioBox.draw(_("Help"));
+ int x = ioBox.getLeft() + 1;
int n = 0;
- boxPrint(win, n++, x + 2, _("[Global]"));
- boxPrint(win, n++, x + 2, _(" h, H, ? Show/hide help box"));
- boxPrint(win, n++, x + 2, _(" y, Y Show/hide history of the
game"));
- boxPrint(win, n++, x + 2, _(" e, E Show/hide dots on empty
squares of the board"));
- boxPrint(win, n++, x + 2, _(" d, D Check the existence of a
word in the dictionary"));
- boxPrint(win, n++, x + 2, _(" j, J Play a word"));
- boxPrint(win, n++, x + 2, _(" s, S Save the game"));
- boxPrint(win, n++, x + 2, _(" l, L Load a game"));
- boxPrint(win, n++, x + 2, _(" q, Q Quit"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Training mode]"));
- boxPrint(win, n++, x + 2, _(" * Take a random rack"));
- boxPrint(win, n++, x + 2, _(" + Complete the current rack
randomly"));
- boxPrint(win, n++, x + 2, _(" t, T Set the rack manually"));
- boxPrint(win, n++, x + 2, _(" c, C Compute all the possible
words"));
- boxPrint(win, n++, x + 2, _(" r, R Show/hide search
results"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Duplicate mode]"));
- boxPrint(win, n++, x + 2, _(" n, N Switch to the next human
player"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Free game mode]"));
- boxPrint(win, n++, x + 2, _(" p, P Pass your turn (with or
without changing letters)"));
- boxPrint(win, n++, x + 2, "");
-
- boxPrint(win, n++, x + 2, _("[Miscellaneous]"));
- boxPrint(win, n++, x + 2, _(" <up>, <down> Navigate in a box line by
line"));
- boxPrint(win, n++, x + 2, _(" <pgup>, <pgdown> Navigate in a box page by
page"));
- boxPrint(win, n++, x + 2, _(" Ctrl-l Refresh the screen"));
+ ioBox.printDataLine(n++, x, _("[Global]"));
+ ioBox.printDataLine(n++, x, _(" h, H, ? Show/hide help box"));
+ ioBox.printDataLine(n++, x, _(" y, Y Show/hide history of
the game"));
+ ioBox.printDataLine(n++, x, _(" b, B Show/hide contents of
the bag (including letters of the racks)"));
+ ioBox.printDataLine(n++, x, _(" e, E Show/hide dots on empty
squares of the board"));
+ ioBox.printDataLine(n++, x, _(" d, D Check the existence of
a word in the dictionary"));
+ ioBox.printDataLine(n++, x, _(" j, J Play a word"));
+ ioBox.printDataLine(n++, x, _(" s, S Save the game"));
+ ioBox.printDataLine(n++, x, _(" l, L Load a game"));
+ ioBox.printDataLine(n++, x, _(" q, Q Quit"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Training mode]"));
+ ioBox.printDataLine(n++, x, _(" * Take a random rack"));
+ ioBox.printDataLine(n++, x, _(" + Complete the current
rack randomly"));
+ ioBox.printDataLine(n++, x, _(" t, T Set the rack
manually"));
+ ioBox.printDataLine(n++, x, _(" c, C Compute all the
possible words"));
+ ioBox.printDataLine(n++, x, _(" r, R Show/hide search
results"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Duplicate mode]"));
+ ioBox.printDataLine(n++, x, _(" n, N Switch to the next
human player"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Free game mode]"));
+ ioBox.printDataLine(n++, x, _(" p, P Pass your turn (with or
without changing letters)"));
+ ioBox.printDataLine(n++, x, "");
+
+ ioBox.printDataLine(n++, x, _("[Miscellaneous]"));
+ ioBox.printDataLine(n++, x, _(" <up>, <down> Navigate in a box line
by line"));
+ ioBox.printDataLine(n++, x, _(" <pgup>, <pgdown> Navigate in a box page
by page"));
+ ioBox.printDataLine(n++, x, _(" Ctrl-l Refresh the screen"));
+
+ ioBox.setDataSize(n);
+}
+
- m_boxLinesData = n;
+void CursesIntf::drawBag(Box &ioBox) const
+{
+ // To allow pseudo-scrolling, without leaving trails
+ ioBox.clearData();
+
+ ioBox.draw(_("Bag"));
+ vector<Tile> allTiles = m_game->getDic().getAllTiles();
+ ioBox.setDataSize(allTiles.size());
+ int x = ioBox.getLeft();
+ int y = ioBox.getTop();
+
+ // Heading
+ string heading = truncString(_(" LETTER | POINTS | FREQUENCY | REMAINING"),
+ ioBox.getWidth() - 1);
+ mvwprintw(m_win, y, x + 1, "%s", heading.c_str());
+ mvwhline(m_win, y + 1, x + 1, ACS_HLINE, heading.size());
+
+ int i;
+ for (i = ioBox.getFirstLine(); i < (int)allTiles.size() && i <
ioBox.getLastLine(); i++)
+ {
+ ioBox.printDataLine(i, ioBox.getLeft() + 1,
+ " %s %2d %2d %s",
+ padAndConvert(wstring(1, allTiles[i].toChar()),
2).c_str(),
+ allTiles[i].getPoints(),
+ allTiles[i].maxNumber(),
+
convertToMb(wstring(m_game->getBag().in(allTiles[i]),
+
allTiles[i].toChar())).c_str());
+ }
+
+ int nbLines = min(i + 2 - ioBox.getFirstLine(),
+ ioBox.getLastLine() - ioBox.getFirstLine() + 2);
+ mvwvline(m_win, y, x + 9, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 18, ACS_VLINE, nbLines);
+ mvwvline(m_win, y, x + 30, ACS_VLINE, nbLines);
+}
+
+
+void CursesIntf::setState(State iState)
+{
+ // Clear the previous box
+ m_box.clear();
+
+ // Get the size of the screen (better than using COLS and LINES directly,
+ // according to the manual)
+ int lines;
+ int cols;
+ getmaxyx(m_win, lines, cols);
+
+ m_state = iState;
+ if (m_state == DEFAULT)
+ m_box = Box(m_win, 0, 0, 0, 0);
+ else if (m_state == RESULTS)
+ m_box = Box(m_win, 3, 54, 17, 25);
+ else if (m_state == HISTORY)
+ m_box = Box(m_win, 1, 0, lines - 1, cols, 2);
+ else if (m_state == HELP)
+ m_box = Box(m_win, 1, 0, lines - 1, cols);
+ else if (m_state == BAG)
+ m_box = Box(m_win, 1, 0, lines - 1, cols, 2);
}
void CursesIntf::playWord(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Play a word "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Play a word"));
mvwprintw(win, y + 1, x + 2, _("Played word:"));
mvwprintw(win, y + 2, x + 2, _("Coordinates:"));
wrefresh(win);
@@ -360,86 +536,87 @@
else
xOff = l2 + 3;
- string word, coord;
+ wstring word, coord;
if (readString(win, y + 1, x + xOff, 15, word) &&
readString(win, y + 2, x + xOff, 3, coord))
{
- int res = m_game->play(convertToWc(coord), convertToWc(word));
+ int res = m_game->play(coord, word);
if (res)
{
- drawStatus(win, LINES - 1, 0, _("Incorrect or misplaced word"));
+ drawStatus(win, _("Incorrect or misplaced word"));
}
}
- m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::checkWord(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Dictionary "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Dictionary"));
mvwprintw(win, y + 1, x + 2, _("Enter the word to check:"));
wrefresh(win);
- string word;
+ wstring word;
if (readString(win, y + 2, x + 2, 15, word))
{
- int res = Dic_search_word(m_game->getDic(), convertToWc(word).c_str());
+ bool res = m_game->getDic().searchWord(word);
char s[100];
if (res)
- snprintf(s, 100, _("The word '%s' exists"), word.c_str());
+ snprintf(s, 100, _("The word '%ls' exists"), word.c_str());
else
- snprintf(s, 100, _("The word '%s' does not exist"), word.c_str());
- drawStatus(win, LINES - 1, 0, s);
+ snprintf(s, 100, _("The word '%ls' does not exist"), word.c_str());
+ drawStatus(win, s, false);
}
- m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::saveGame(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Save the game "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Save the game"));
mvwprintw(win, y + 1, x + 2, _("Enter the file name:"));
wrefresh(win);
- string filename;
+ wstring filename;
if (readString(win, y + 2, x + 2, 28, filename, kFILENAME))
{
- ofstream fout(filename.c_str());
+ ofstream fout(convertToMb(filename).c_str());
char s[100];
if (fout.rdstate() == ios::failbit)
{
- snprintf(s, 100, _("Cannot open file %s for writing"),
+ snprintf(s, 100, _("Cannot open file %ls for writing"),
filename.c_str());
+ drawStatus(win, s);
}
else
{
- m_game->save(fout);
+ m_game->save(fout, Game::FILE_FORMAT_ADVANCED);
fout.close();
- snprintf(s, 100, _("Game saved in %s"), filename.c_str());
+ snprintf(s, 100, _("Game saved in '%ls'"), filename.c_str());
+ drawStatus(win, s, false);
}
- drawStatus(win, LINES - 1, 0, s);
}
- m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::loadGame(WINDOW *win, int y, int x)
{
- drawBox(win, y, x, 4, 32, _(" Load a game "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Load a game"));
mvwprintw(win, y + 1, x + 2, _("Enter the file name:"));
wrefresh(win);
- string filename;
+ wstring filename;
if (readString(win, y + 2, x + 2, 28, filename, kFILENAME))
{
char s[100];
FILE *fin;
- if ((fin = fopen(filename.c_str(), "r")) == NULL)
+ if ((fin = fopen(convertToMb(filename).c_str(), "r")) == NULL)
{
- snprintf(s, 100, _("Cannot open file %s for reading"),
+ snprintf(s, 100, _("Cannot open file '%ls' for reading"),
filename.c_str());
}
else
@@ -448,118 +625,184 @@
if (loaded == NULL)
{
snprintf(s, 100, _("Invalid saved game"));
+ drawStatus(win, s);
}
else
{
snprintf(s, 100, _("Game loaded"));
GameFactory::Instance()->releaseGame(*m_game);
m_game = loaded;
+ drawStatus(win, s, false);
}
fclose(fin);
}
- drawStatus(win, LINES - 1, 0, s);
}
- m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::passTurn(WINDOW *win, int y, int x, FreeGame &iGame)
{
- drawBox(win, y, x, 4, 32, _(" Pass your turn "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Pass your turn"));
mvwprintw(win, y + 1, x + 2, _("Enter the letters to change:"));
wrefresh(win);
- string letters;
+ wstring letters;
if (readString(win, y + 2, x + 2, 7, letters))
{
- int res = iGame.pass(convertToWc(letters), m_game->currPlayer());
+ int res = iGame.pass(letters);
if (res)
{
- drawStatus(win, LINES - 1, 0, _("Cannot pass the turn"));
+ drawStatus(win, _("Cannot pass the turn"));
}
}
- m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
void CursesIntf::setRack(WINDOW *win, int y, int x, Training &iGame)
{
- drawBox(win, y, x, 4, 32, _(" Set rack "));
+ Box box(win, y, x, 4, 32);
+ box.draw(_("Set rack"));
mvwprintw(win, y + 1, x + 2, _("Enter the new letters:"));
wrefresh(win);
- string letters;
+ wstring letters;
if (readString(win, y + 2, x + 2, 7, letters, kJOKER))
{
- iGame.setRackManual(false, convertToWc(letters));
+ int res = iGame.setRackManual(false, letters);
+ if (res)
+ {
+ drawStatus(win, _("Cannot take these letters from the bag"));
+ }
}
m_state = DEFAULT;
- clearRect(win, y, x, 4, 32);
+ box.clear();
}
-bool CursesIntf::readString(WINDOW *win, int y, int x, int n, string &oString,
+bool CursesIntf::readString(WINDOW *win, int y, int x, int n, wstring &oString,
unsigned int flag)
{
- int c;
+ // Save the initial position
+ int x0 = x;
+ wint_t c;
wmove(win, y, x);
curs_set(1);
- while ((c = getch()) != 0)
+ int res;
+ // Position in the string before which to insert the next character
+ // (the character will be added at the end if pos == oString.size())
+ unsigned int pos = 0;
+ while ((res = get_wch(&c)) != ERR)
{
if (c == 0x1b ) // Esc
{
curs_set(0);
return false;
}
- else if (c == KEY_ENTER || c == 0xD)
+ else if ((c == KEY_ENTER && res == KEY_CODE_YES) || c == 0xD)
{
curs_set(0);
return true;
}
else if (c == 0x0c) // Ctrl-L
{
-// clear();
redraw(win);
wmove(win, y, x);
}
- else if (c == KEY_BACKSPACE && oString.size() > 0)
+ else if (c == 0x0b) // Ctrl-K
+ {
+ // Remove everything after the cursor position
+ int len = oString.size() - pos;
+ oString = oString.erase(pos);
+ mvwprintw(win, y, x, string(len, ' ').c_str());
+ wmove(win, y, x);
+ }
+ else if (c == 0x15) // Ctrl-U
+ {
+ // Remove everything before the cursor position
+ oString.erase(0, pos);
+ int len = pos;
+ x = x0;
+ pos = 0;
+ mvwprintw(win, y, x0, "%s", convertToMb(oString + wstring(len, L'
')).c_str());
+ wmove(win, y, x);
+ }
+ else if (res == KEY_CODE_YES)
+ {
+ if (c == KEY_BACKSPACE && pos != 0)
+ {
+ x--;
+ pos--;
+ oString.erase(pos, 1);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString + L"
").c_str());
+ wmove(win, y, x);
+ }
+ else if (c == KEY_DC)
+ {
+ oString.erase(pos, 1);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString + L"
").c_str());
+ wmove(win, y, x);
+ }
+ else if (c == KEY_LEFT && pos != 0)
{
x--;
- mvwprintw(win, y, x, " ");
+ pos--;
wmove(win, y, x);
- oString.erase(oString.size() - 1);
}
- else if (isalnum(c) && oString.size() < (unsigned int)n)
+ else if (c == KEY_RIGHT && pos != oString.size())
{
- mvwprintw(win, y, x, "%c", c);
x++;
- oString += (char)c;
+ pos++;
+ wmove(win, y, x);
+ }
+ else if (c == KEY_HOME)
+ {
+ x = x0;
+ pos = 0;
+ wmove(win, y, x);
+ }
+ else if (c == KEY_END)
+ {
+ x = x0 + oString.size();
+ pos = oString.size();
+ wmove(win, y, x);
}
else
+ beep();
+ }
+ else if (res == OK && iswalnum(c) && oString.size() < (unsigned int)n)
{
- if (flag & kJOKER && c == '?')
+ x++;
+ oString.insert(pos++, 1, c);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString).c_str());
+ wmove(win, y, x);
+ }
+ else if (flag & kJOKER && c == L'?')
{
- mvwprintw(win, y, x, "%c", c);
x++;
- oString += (char)c;
+ oString.insert(pos++, 1, c);
+ mvwprintw(win, y, x0, "%s", convertToMb(oString).c_str());
+ wmove(win, y, x);
}
- if (flag & kFILENAME)
+ else if (flag & kFILENAME)
{
- if (c == '/' || c == '.' || c == '-' || c == '_' || c == ' ')
+ if (c == L'/' || c == L'.' || c == L'-' || c == L'_' || c == L' ')
{
- mvwprintw(win, y, x, "%c", c);
x++;
- oString += (char)c;
- }
+ oString += c;
+ mvwprintw(win, y, x0, "%s", convertToMb(oString).c_str());
+ wmove(win, y, x);
}
+ else
+ beep();
}
-// else
-// mvwprintw(win, 0, 0, "%3d", c);
+ else
+ beep();
}
curs_set(0);
- return 0;
+ return false;
}
@@ -568,15 +811,30 @@
switch (iKey)
{
case '*':
+ if (m_state != DEFAULT)
+ {
+ setState(DEFAULT);
+ redraw(m_win);
+ }
iGame.setRackRandom(false, Game::RACK_ALL);
return 1;
case '+':
+ if (m_state != DEFAULT)
+ {
+ setState(DEFAULT);
+ redraw(m_win);
+ }
iGame.setRackRandom(false, Game::RACK_NEW);
return 1;
case 't':
case 'T':
+ if (m_state != DEFAULT)
+ {
+ setState(DEFAULT);
+ redraw(m_win);
+ }
setRack(m_win, 22, 10, iGame);
return 1;
@@ -623,8 +881,11 @@
int CursesIntf::handleKey(int iKey)
{
- if (m_state == DEFAULT)
- {
+ // Remove any error message in the status line
+ if (m_state == DEFAULT || m_state == RESULTS)
+ drawStatus(m_win, "", false);
+
+ // Handle game-specific keys
int res;
if (m_game->getMode() == Game::kTRAINING)
{
@@ -638,53 +899,30 @@
{
res = handleKeyForGame(iKey, (FreeGame&)*m_game);
}
-
if (res != 2)
return res;
- }
- else // m_state is in {HELP, RESULTS, HISTORY}
+
+ // Handle scrolling keys
+ if (m_state != DEFAULT)
{
switch (iKey)
{
case KEY_HOME:
- if (m_boxLinesData <= m_boxLines && m_boxStart > 0)
- return 0;
- m_boxStart = 0;
- return 1;
+ return m_box.scrollBeginning() ? 1 : 0;
case KEY_END:
- if (m_boxLinesData <= m_boxLines &&
- m_boxStart < m_boxLinesData - 1)
- return 0;
- m_boxStart = m_boxLinesData - 1;
- return 1;
+ return m_box.scrollEnd() ? 1 : 0;
case KEY_UP:
- if (m_boxLinesData <= m_boxLines || m_boxStart <= 0)
- return 0;
- m_boxStart--;
- return 1;
+ return m_box.scrollOneLineUp() ? 1 : 0;
case KEY_DOWN:
- if (m_boxLinesData <= m_boxLines ||
- m_boxStart >= m_boxLinesData - 1)
- return 0;
- m_boxStart++;
- return 1;
+ return m_box.scrollOneLineDown() ? 1 : 0;
case KEY_PPAGE:
- if (m_boxLinesData <= m_boxLines)
- return 0;
- m_boxStart -= m_boxLines;
- if (m_boxStart < 0)
- m_boxStart = 0;
- return 1;
+ return m_box.scrollOnePageUp() ? 1 : 0;
case KEY_NPAGE:
- if (m_boxLinesData <= m_boxLines)
- return 0;
- m_boxStart += m_boxLines;
- if (m_boxStart > m_boxLinesData - 1)
- m_boxStart = m_boxLinesData - 1;
- return 1;
+ return m_box.scrollOnePageDown() ? 1 : 0;
}
}
+ // Handle other global keys
switch (iKey)
{
// Toggle help
@@ -692,10 +930,9 @@
case 'H':
case '?':
if (m_state == HELP)
- m_state = DEFAULT;
+ setState(DEFAULT);
else
- m_state = HELP;
- m_boxStart = 0;
+ setState(HELP);
clear();
return 1;
@@ -703,10 +940,9 @@
case 'y':
case 'Y':
if (m_state == HISTORY)
- m_state = DEFAULT;
+ setState(DEFAULT);
else
- m_state = HISTORY;
- m_boxStart = 0;
+ setState(HISTORY);
clear();
return 1;
@@ -714,13 +950,25 @@
case 'r':
case 'R':
if (m_game->getMode() != Game::kTRAINING)
+ {
+ beep();
return 0;
+ }
if (m_state == RESULTS)
- m_state = DEFAULT;
+ setState(DEFAULT);
else
- m_state = RESULTS;
- m_boxStart = 0;
- clearRect(m_win, 3, 54, 30, 25);
+ setState(RESULTS);
+ Box::clearRect(m_win, 3, 54, 30, 25);
+ return 1;
+
+ // Toggle bag
+ case 'b':
+ case 'B':
+ if (m_state == BAG)
+ setState(DEFAULT);
+ else
+ setState(BAG);
+ clear();
return 1;
// Toggle dots display
@@ -729,49 +977,63 @@
m_showDots = !m_showDots;
return 1;
+ // Ctrl-L should clear and redraw the screen
+ case 0x0c:
+ clear();
+ // Force the re-definition of the current box
+ setState(m_state);
+ return 1;
+
// Check a word in the dictionary
case 'd':
case 'D':
- if (m_state != DEFAULT)
- return 0;
+ if (m_state != DEFAULT && m_state != RESULTS)
+ {
+ setState(DEFAULT);
+ redraw(m_win);
+ }
checkWord(m_win, 22, 10);
- return 1;
+ return 0;
// Play a word
case 'j':
case 'J':
- if (m_state != DEFAULT)
- return 0;
+ if (m_state != DEFAULT && m_state != RESULTS)
+ {
+ setState(DEFAULT);
+ redraw(m_win);
+ }
playWord(m_win, 22, 10);
return 1;
- // Ctrl-L should clear and redraw the screen
- case 0x0c:
- clear();
- return 1;
-
case 'l':
case 'L':
if (m_state != DEFAULT)
- return 0;
+ {
+ setState(DEFAULT);
+ redraw(m_win);
+ }
loadGame(m_win, 22, 10);
return 1;
case 's':
case 'S':
if (m_state != DEFAULT)
- return 0;
+ {
+ setState(DEFAULT);
+ redraw(m_win);
+ }
saveGame(m_win, 22, 10);
- return 1;
+ return 0;
// Quit
case 'q':
case 'Q':
- case 0x1b: // Esc
m_dying = true;
return 0;
default:
+ beep();
return 0;
}
}
@@ -786,16 +1048,20 @@
}
else if (m_state == RESULTS)
{
- drawResults(win, 3, 54);
+ drawResults(m_box);
drawBoard(win, 2, 0);
}
else if (m_state == HELP)
{
- drawHelp(win, 1, 0);
+ drawHelp(m_box);
}
else if (m_state == HISTORY)
{
- drawHistory(win, 1, 0);
+ drawHistory(m_box);
+ }
+ else if (m_state == BAG)
+ {
+ drawBag(m_box);
}
// Title
@@ -811,8 +1077,11 @@
if (m_game->getVariant() == Game::kJOKER)
variant = string(" - ") + _("Joker game");
string title = "Eliot (" + mode + variant + ") " + _("[h for help]");
- mvwprintw(win, 0, 0, title.c_str());
- whline(win, ' ', COLS - title.size());
+
+ int lines;
+ int cols;
+ getmaxyx(m_win, lines, cols);
+ mvwprintw(win, 0, 0, truncOrPad(title, cols).c_str());
attroff(A_REVERSE);
wrefresh(win);
@@ -821,7 +1090,7 @@
int main(int argc, char ** argv)
{
-#ifdef HAVE_SETLOCALE
+#if HAVE_SETLOCALE
// Set locale via LC_ALL
setlocale(LC_ALL, "");
#endif
@@ -861,7 +1130,7 @@
init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
- init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_RED);
init_pair(COLOR_BLUE, COLOR_BLACK, COLOR_BLUE);
init_pair(COLOR_CYAN, COLOR_BLACK, COLOR_CYAN);
@@ -872,7 +1141,7 @@
// Do not echo
noecho();
- // mainIntf will take care of destroying game for us.
+ // mainIntf will take care of destroying game for us
CursesIntf mainIntf(wBoard, *game);
mainIntf.redraw(wBoard);
Index: utils/ncurses.h
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/ncurses.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- utils/ncurses.h 4 Nov 2005 20:00:06 -0000 1.6
+++ utils/ncurses.h 8 Jan 2008 13:52:42 -0000 1.7
@@ -20,7 +20,7 @@
#ifndef _NCURSES_H_
#define _NCURSES_H_
-#include <curses.h>
+#include <ncursesw/curses.h>
#include <string>
class Game;
@@ -29,6 +29,70 @@
class FreeGame;
using std::string;
+using std::wstring;
+
+
+class Box
+{
+ public:
+ // Create a titled box with the specified position and size,
+ // containing iHeadingLines non-scrolling lines.
+ // The number of data to display (with the printLine() method)
+ // can be set later using the setDataSize() method.
+ Box(WINDOW *win, int y, int x, int h, int w,
+ unsigned int iHeadingLines = 0);
+
+ // Simply draw the box (without any content)
+ void draw(const string& iTitle = "") const;
+
+ // Print data line number n (starting at 0), taking care of
+ // the current scrolling state
+ void printDataLine(int n, int x, const char *fmt, ...) const;
+
+ // Set the number of lines of the data to display
+ void setDataSize(unsigned int iNbLines) { m_dataSize = iNbLines; }
+
+ // Control scrolling
+ // Return true if redrawing is needed, false otherwise
+ bool scrollOneLineUp();
+ bool scrollOneLineDown();
+ bool scrollOnePageUp();
+ bool scrollOnePageDown();
+ bool scrollBeginning();
+ bool scrollEnd();
+
+ // Clear the box completely
+ void clear() const { clearRect(m_win, m_y, m_x, m_h, m_w); }
+ // Clear the scrolling zone of the box
+ void clearData() const { clearRect(m_win, m_topLine, m_x + 1,
+ m_nbLines, getWidth()); }
+ // Clear an arbitrary rectangular zone
+ static void clearRect(WINDOW *win, int y, int x, int h, int w);
+
+ // First line of data to display (included)
+ int getFirstLine() const { return m_dataStart; }
+ // Last line of data to display (excluded)
+ int getLastLine() const { return m_dataStart + m_nbLines; }
+
+ // First line inside the box
+ int getTop() const { return m_y + 1; }
+ // First column available for writing
+ int getLeft() const { return m_x + 1; }
+ // Client width
+ int getWidth() const { return m_w - 2; }
+
+ private:
+ WINDOW *m_win;
+ int m_x;
+ int m_y;
+ int m_w;
+ int m_h;
+ string m_title;
+ int m_topLine;
+ int m_nbLines;
+ int m_dataStart;
+ int m_dataSize;
+};
/**
@@ -52,28 +116,27 @@
DEFAULT, // Default state
HELP, // Help panel is shown
HISTORY, // Game history panel is shown
- RESULTS // Search results panel is shown
+ RESULTS, // Search results panel is shown
+ BAG // Bag contents panel is shown
};
- // Draw a titled box with the specified position and size
- static void drawBox(WINDOW *win, int y, int x, int h, int w,
- const string& iTitle);
- // Clear a rectangular zone
- static void clearRect(WINDOW *win, int y, int x, int h, int w);
- // Print a line in a box, taking care of the current offset
- void boxPrint(WINDOW *win, int y, int x, const char *fmt, ...);
+
// Write a message in the "status line"
- void drawStatus(WINDOW *win, int y, int x,
- const string& iMessage, bool error = true);
+ void drawStatus(WINDOW *win, const string& iMessage, bool error = true);
// Draw the board, with the coordinates
void drawBoard(WINDOW *win, int y, int x) const;
// Draw the boxes for scores and racks
void drawScoresRacks(WINDOW *win, int y, int x) const;
// Draw the results panel
- void drawResults(WINDOW *win, int y, int x);
+ void drawResults(Box &ioBox) const;
// Draw the history panel
- void drawHistory(WINDOW *win, int y, int x);
+ void drawHistory(Box &ioBox) const;
// Draw the help panel
- void drawHelp(WINDOW *win, int y, int x);
+ void drawHelp(Box &ioBox) const;
+ // Draw the bag panel
+ void drawBag(Box &ioBox) const;
+
+ // Change the inner state, and initialize the corresponding box
+ void setState(State iState);
// Draw the "Play word" box, and handle the played word
void playWord(WINDOW *win, int y, int x);
void checkWord(WINDOW *win, int y, int x);
@@ -81,17 +144,18 @@
void loadGame(WINDOW *win, int y, int x);
void passTurn(WINDOW *win, int y, int x, FreeGame &iGame);
void setRack(WINDOW *win, int y, int x, Training &iGame);
+
// Get a string from the user, with a maximum length
// The string is validated if the user presses Enter (return value: true)
// and it is cancelled if the user presses Esc (return value: false)
- bool readString(WINDOW *win, int y, int x, int n, string &oString,
+ bool readString(WINDOW *win, int y, int x, int n, wstring &oString,
unsigned int flag = 0);
// Any combination of the following constants can be used as the "flag"
// parameter of the readString() method.
// Indicate that the '?' character is accepted
static const unsigned int kJOKER = 1 << 0;
// Accept characters for a file name
- static const unsigned int kFILENAME = 1 << 0;
+ static const unsigned int kFILENAME = 1 << 1;
// Handle the key in Training mode
int handleKeyForGame(int iKey, Training &iGame);
@@ -109,14 +173,8 @@
State m_state;
// True when the user requested to quit
bool m_dying;
- // Index of the first line of data to be displayed in the current box
- int m_boxStart;
- // Number of lines of the current box (border excluded)
- int m_boxLines;
- // Number of lines of the data to be displayed in the current box
- int m_boxLinesData;
- // Index of the first line of the box where to write
- int m_boxY;
+ // Scrolling box for the current panel
+ Box m_box;
// True if dots must be shown on empty squares
bool m_showDots;
};
Index: wxwin/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/Makefile.am,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- wxwin/Makefile.am 4 Aug 2007 20:01:27 -0000 1.10
+++ wxwin/Makefile.am 8 Jan 2008 13:52:43 -0000 1.11
@@ -16,13 +16,15 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+localedir = $(datadir)/locale
+
if BUILD_WXWIDGETS
bin_PROGRAMS = eliot
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/dic -I$(top_srcdir)/game
+AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" @WX_CPPFLAGS@ ##
-Wno-strict-aliasing
-AM_CPPFLAGS = @WX_CPPFLAGS@ ## -Wno-strict-aliasing
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/dic -I$(top_srcdir)/game
eliot_SOURCES = \
configdb.cc configdb.h \
@@ -36,8 +38,7 @@
mainframe.cc mainframe.h \
main.cc ewx.h
-## eliot_CPPFLAGS=
-eliot_LDADD = @WX_LIBS@ ../dic/libdic.a ../game/libgame.a
+eliot_LDADD = @WX_LIBS@ ../game/libgame.a ../dic/libdic.a @LIBINTL@
EXTRA_DIST = \
eliot.xpm \
Index: wxwin/auxframes.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/auxframes.cc,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- wxwin/auxframes.cc 4 Aug 2007 20:01:27 -0000 1.23
+++ wxwin/auxframes.cc 8 Jan 2008 13:52:43 -0000 1.24
@@ -26,6 +26,8 @@
#include <iostream>
#include <sstream>
+#include <list>
+#include <string>
#include "wx/sizer.h"
#include "wx/button.h"
@@ -37,7 +39,6 @@
#include "ewx.h"
#include "dic.h"
-#include "dic_search.h"
#include "training.h"
#include "player.h"
#include "game.h"
@@ -119,7 +120,7 @@
/****************************************************************/
BoardFrame::BoardFrame(wxFrame* parent, Game& iGame):
- AuxFrame(parent, ID_Frame_Board, _("Grille"), FRAMEBOARD)
+ AuxFrame(parent, ID_Frame_Board, _("Grid"), FRAMEBOARD)
{
board = new GfxBoard(this, iGame);
wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
@@ -144,7 +145,7 @@
/****************************************************************/
BagFrame::BagFrame(wxFrame* parent, Game& iGame):
- AuxFrame(parent, ID_Frame_Bag, _("sac"), FRAMEBAG),
+ AuxFrame(parent, ID_Frame_Bag, _("Bag"), FRAMEBAG),
m_game(iGame)
{
tiles = new wxListCtrl(this, -1);
@@ -180,8 +181,8 @@
tiles->ClearAll();
- std::list<Tile>::const_iterator it;
- const std::list<Tile>& allTiles = Tile::getAllTiles();
+ std::vector<Tile>::const_iterator it;
+ const std::vector<Tile>& allTiles = m_game.getDic().getAllTiles();
for (index = 0, it = allTiles.begin(); it != allTiles.end(); index++, it++)
{
n = m_game.getBag().in(*it);
@@ -198,8 +199,8 @@
/* RECHERCHE */
/****************************************************************/
-SearchFrame::SearchFrame(wxFrame *parent, Dictionary _dic):
- AuxFrame(parent, ID_Frame_Search, _("recherche"), FRAMESEARCH)
+SearchFrame::SearchFrame(wxFrame *parent, const Dictionary &_dic):
+ AuxFrame(parent, ID_Frame_Search, _("Search"), FRAMESEARCH)
{
panel = new SearchPanel(this, _dic);
wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
@@ -222,20 +223,20 @@
enum
{
Word_Id,
- Result_Id,
+ Result_Id
};
BEGIN_EVENT_TABLE(VerifFrame, AuxFrame)
EVT_TEXT(Word_Id, VerifFrame::OnText)
END_EVENT_TABLE()
-VerifFrame::VerifFrame(wxFrame* parent, Dictionary _dic):
- AuxFrame(parent, ID_Frame_Verif, _("verification"), FRAMEVERIF)
+VerifFrame::VerifFrame(wxFrame* parent, const Dictionary &_dic):
+ AuxFrame(parent, ID_Frame_Verif, _("Check"), FRAMEVERIF)
{
- dic = _dic;
+ dic = &_dic;
word = new wxTextCtrl(this, Word_Id, wxT(""));
word->SetFont(config.getFont(LISTFONT));
- word->SetToolTip(_("Mot a verifier"));
+ word->SetToolTip(_("Word to check"));
result = new wxStaticText(this, Result_Id, wxT(""));
result->SetFont(config.getFont(LISTFONT));
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
@@ -253,13 +254,13 @@
{
if (dic == NULL)
{
- result->SetLabel(_("pas de dictionnaire"));
+ result->SetLabel(_("No dictionary"));
return;
}
- if (Dic_search_word(dic, word->GetValue().wc_str()))
- result->SetLabel(_("existe"));
+ if (dic->searchWord(word->GetValue().wc_str()))
+ result->SetLabel(_("exists"));
else
- result->SetLabel(_("n'existe pas"));
+ result->SetLabel(_("doesn't exist"));
}
void
@@ -300,7 +301,7 @@
listbox->SetToolTip(name);
sizer_v->Add(listbox, 1, wxEXPAND | wxALL, 1);
- button = new wxButton(this, ButtonCopyID, _("Copier"), wxPoint(0, 0),
wxSize(-1, -1));
+ button = new wxButton(this, ButtonCopyID, _("Copy"), wxPoint(0, 0),
wxSize(-1, -1));
sizer_v->Add(button, 0, wxEXPAND | wxALL, 1);
wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
@@ -344,17 +345,10 @@
if (game == NULL)
{
listbox->Clear();
- listbox->Append(_("Pas de partie en cours"));
+ listbox->Append(_("No on going game"));
//debug(" %s : Refresh end - no game\n",(const
char*)name.mb_str());
return;
}
- if (game->getDic() == NULL)
- {
- listbox->Clear();
- listbox->Append(_("Pas de dictionnaire"));
- //debug(" %s : Refresh end - no dictionnary\n",(const
char*)name.mb_str());
- return;
- }
if (show == 0)
{
//debug(" %s : Refresh end - no window\n",(const
char*)name.mb_str());
@@ -366,7 +360,7 @@
{
//debug(" %s : noresult == true\n",(const char*)name.mb_str());
listbox->Clear();
- listbox->Append(_("Aucun resultat"));
+ listbox->Append(_("No result"));
}
//debug(" %s : Refresh end\n",(const char*)name.mb_str());
}
@@ -390,27 +384,41 @@
}
savedword = rack;
- wchar_t buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
- Dic_search_7pl1(game->getDic(), rack.c_str(), buff,
config.getJokerPlus1());
+ map<wchar_t, list<wstring> > wordList;
+ game->getDic().search7pl1(rack, wordList, config.getJokerPlus1());
+
+ // Count the results
+ int sum = 0;
+ map<wchar_t, list<wstring> >::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
+ {
+ if (it->first)
+ sum += 1;
+ sum += it->second.size();
+ }
+ // For the line containing the rack
+ sum += 1;
+ noresult = (sum == 0);
listbox->Clear();
- wxString res[DIC_LETTERS*(RES_7PL1_MAX+1)];
+ if (noresult)
+ return;
+
+ wxString *res = new wxString[sum];
int resnum = 0;
- res[resnum++] = wxString(_("Tirage: ")) + wxString(wxU(rack.c_str()));
- for (int i = 0; i < DIC_LETTERS; i++)
- {
- if (i && buff[i][0][0])
+ res[resnum++] = wxString(_("Rack: ")) + wxString(wxU(rack.c_str()));
+ for (it = wordList.begin(); it != wordList.end(); it++)
{
- res[resnum++] = wxString(wxT("+")) + (wxChar)(i + 'A' - 1);
- noresult = false;
- }
- for (int j = 0; j < RES_7PL1_MAX && buff[i][j][0]; j++)
+ if (it->first)
+ res[resnum++] = wxString(wxT("+")) + wxU((wxString)it->first);
+ list<wstring>::const_iterator itWord;
+ for (itWord = it->second.begin(); itWord != it->second.end(); itWord++)
{
- res[resnum++] = wxString(wxT(" ")) + wxU(buff[i][j]);
- noresult = false;
+ res[resnum++] = wxString(wxT(" ")) + wxU(itWord->c_str());
}
}
listbox->Set(resnum, res);
+ delete[] res;
//debug(" Plus1Frame::refresh end\n");
}
@@ -424,7 +432,7 @@
if (game->getMode() != Game::kTRAINING)
return;
- std::wstring word = static_cast<Training*>(game)->getTestPlayWord();
+ wstring word = static_cast<Training*>(game)->getTestPlayWord();
if (savedword == word)
{
noresult = false; // keep old results
@@ -432,18 +440,20 @@
}
savedword = word;
//debug(" BenjFrame::refresh : %s\n",word.c_str());
- wchar_t wordlist[RES_BENJ_MAX][DIC_WORD_MAX];
- Dic_search_Benj(game->getDic(), word.c_str(), wordlist);
+ list<wstring> wordList;
+ game->getDic().searchBenj(word, wordList);
- wxString res[RES_BENJ_MAX];
+ wxString *res = new wxString[wordList.size()];
int resnum = 0;
- for (int i = 0; (i < RES_BENJ_MAX) && (wordlist[i][0]); i++)
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
{
- res[resnum++] = wxU(wordlist[i]);
+ res[resnum++] = wxU(it->c_str());
//debug(" BenjFrame : %s (%d)\n",wordlist[i],resnum);
noresult = false;
}
listbox->Set(resnum, res);
+ delete[] res;
}
@@ -457,7 +467,7 @@
if (game->getMode() != Game::kTRAINING)
return;
- std::wstring word = static_cast<Training*>(game)->getTestPlayWord();
+ wstring word = static_cast<Training*>(game)->getTestPlayWord();
if (savedword == word)
{
noresult = false; // keep old results
@@ -465,18 +475,20 @@
}
savedword = word;
//debug(" RaccFrame::refresh : %s\n",word.c_str());
- wchar_t wordlist[RES_RACC_MAX][DIC_WORD_MAX];
- Dic_search_Racc(game->getDic(), word.c_str(), wordlist);
+ list<wstring> wordList;
+ game->getDic().searchRacc(word, wordList);
- wxString res[RES_RACC_MAX];
+ wxString *res = new wxString[wordList.size()];
int resnum = 0;
- for (int i = 0; (i < RES_RACC_MAX) && (wordlist[i][0]); i++)
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
{
- res[resnum++] = wxU(wordlist[i]);
+ res[resnum++] = wxU(it->c_str());
//debug(" RaccFrame : %s (%d)\n",wordlist[i],resnum);
noresult = false;
}
listbox->Set(resnum, res);
+ delete[] res;
}
/****************************************************************/
@@ -510,7 +522,7 @@
/****************************************************************/
GameFrame::GameFrame(wxFrame* parent, Game& iGame):
- AuxFrameText(parent, ID_Frame_Game, _("partie"), FRAMEGAME, wxTE_MULTILINE
| wxTE_READONLY | wxTE_DONTWRAP),
+ AuxFrameText(parent, ID_Frame_Game, _("Game history"), FRAMEGAME,
wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP),
m_game(iGame)
{
textbox->Clear();
@@ -542,7 +554,7 @@
END_EVENT_TABLE()
ResultFrame::ResultFrame(wxFrame* parent, Game* iGame):
- AuxFrame(parent, ID_Frame_Result, _("results"), FRAMERESULT)
+ AuxFrame(parent, ID_Frame_Result, _("Results"), FRAMERESULT)
{
reslist = new GfxResult(this, (MainFrame*)parent, iGame);
Index: wxwin/auxframes.h
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/auxframes.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- wxwin/auxframes.h 4 Aug 2007 20:01:27 -0000 1.8
+++ wxwin/auxframes.h 8 Jan 2008 13:52:43 -0000 1.9
@@ -160,7 +160,7 @@
private:
SearchPanel *panel;
public:
- SearchFrame(wxFrame*, Dictionary);
+ SearchFrame(wxFrame*, const Dictionary &);
void Refresh(refresh_t force = REFRESH);
};
@@ -171,12 +171,12 @@
class VerifFrame: public AuxFrame
{
protected:
- Dictionary dic;
+ const Dictionary *dic;
wxTextCtrl *word;
wxStaticText *result;
void verif();
public:
- VerifFrame(wxFrame*, Dictionary);
+ VerifFrame(wxFrame*, const Dictionary&);
void OnText(wxCommandEvent& event);
void Refresh(refresh_t force = REFRESH);
DECLARE_EVENT_TABLE()
Index: wxwin/confdimdlg.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/confdimdlg.cc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- wxwin/confdimdlg.cc 4 Aug 2007 20:01:27 -0000 1.9
+++ wxwin/confdimdlg.cc 8 Jan 2008 13:52:43 -0000 1.10
@@ -28,8 +28,6 @@
#include "confdimdlg.h"
enum {
- Button_Ok,
- Button_Cancel,
Button_Printer,
Button_Page,
Button_Save,
@@ -39,10 +37,9 @@
BEGIN_EVENT_TABLE(ConfDimDlg,wxDialog)
EVT_CLOSE (ConfDimDlg::OnCloseWindow)
- EVT_BUTTON(Button_Ok, ConfDimDlg::OnButtonOk)
+ EVT_BUTTON(wxID_OK, ConfDimDlg::OnButtonOk)
+ EVT_BUTTON(wxID_CANCEL, ConfDimDlg::OnButtonCancel)
EVT_BUTTON(Button_Save, ConfDimDlg::OnButtonSave)
- EVT_BUTTON(Button_Ok, ConfDimDlg::OnButtonOk)
- EVT_BUTTON(Button_Cancel, ConfDimDlg::OnButtonCancel)
EVT_BUTTON(Button_Printer, ConfDimDlg::OnConfPrinter)
EVT_BUTTON(Button_Page, ConfDimDlg::OnConfPage)
EVT_BUTTON(Button_FontHeader, ConfDimDlg::OnConfFontHead)
@@ -58,14 +55,13 @@
ConfDimDlg::ConfDimDlg(wxWindow* parent, wxPrintData pd, wxPageSetupData psd)
- : wxDialog(parent, -1, wxString(wxT("Eliot : Impression")))
+ : wxDialog(parent, -1, wxString(wxT("Eliot: Printing")))
{
int i;
wxString choices[3];
- choices[0] = wxT("gauche");
-// XXX: choices[1] = wxT("centré");
- choices[1] = wxT("centre");
- choices[2] = wxT("droite");
+ choices[0] = _("left");
+ choices[1] = _("centered");
+ choices[2] = _("right");
wxStaticText* Hcomment[5];
wxRect Hcommentrect[5];
wxRect Htitlerect[5];
@@ -119,31 +115,29 @@
#define ESPSIZE wxSize(spacerect.GetRight() - spacerect.GetLeft(),-1)
- wxStaticText* justif = new
wxStaticText(this,-1,wxT("Justification"),wxPoint(0,0));
+ wxStaticText* justif = new wxStaticText(this,-1,_("Alignment"),wxPoint(0,0));
wxRect justifrect = justif->GetRect();
- wxStaticText* space = new
wxStaticText(this,-1,wxT("Espacement"),wxPoint(0,0));
+ wxStaticText* space = new wxStaticText(this,-1,_("Spacing"),wxPoint(0,0));
wxRect spacerect = space->GetRect();
// heading, first part
-// XXX: bfontheader = new
wxButton(this,Button_FontHeader,wxT("Caractères"),HFONT);
- bfontheader = new wxButton(this,Button_FontHeader,wxT("Caracteres"),HFONT);
+ bfontheader = new wxButton(this,Button_FontHeader,_("Font..."),HFONT);
wxRect bfontheadrect = bfontheader->GetRect();
for(i=0; i<5; i++)
{
wxString txt;
- txt << wxT("Titre colonne ") << (i+1);
+ txt << _("Title column ") << (i+1);
Hcomment[i] = new wxStaticText(this,-1,txt,HCOMMENT(i));
Hcommentrect[i] = Hcomment[i]->GetRect();
}
// text, first part
-// XXX: bfonttext = new
wxButton(this,Button_FontText,wxT("Caractères"),TFONT);
- bfonttext = new wxButton(this,Button_FontText,wxT("Caracteres"),TFONT);
+ bfonttext = new wxButton(this,Button_FontText,_("Font..."),TFONT);
wxRect bfonttextrect = bfonttext->GetRect();
for(i=0; i<5; i++)
{
wxString txt;
- txt << wxT("Texte colonne ") << (i+1);
+ txt << _("Text column ") << (i+1);
Tcomment[i] = new wxStaticText(this,-1,txt,TCOMMENT(i),wxSize(-1,-1));
Tcommentrect[i] = Tcomment[i]->GetRect();
}
@@ -153,16 +147,15 @@
{
Htitle[i] = new wxTextCtrl(this,-1,wxT(""),HTITLE(i),wxSize(100,-1));
Htitlerect[i] = Htitle[i]->GetRect();
- Htitle[i]->SetToolTip(wxT("Texte du titre de la colonne"));
+ Htitle[i]->SetToolTip(_("Column heading"));
Hjust[i] = new wxChoice(this,-1,HJUST(i),wxSize(-1,-1),3,choices);
Hjustrect[i] = Hjust[i]->GetRect();
- Hjust[i]->SetToolTip(wxT("Justification du titre de la colonne"));
+ Hjust[i]->SetToolTip(_("Alignment of the column heading"));
Hspaces[i] = new wxTextCtrl(this,-1,wxT("00"),HSPACES(i),ESPSIZE);
Hspacesrect[i] = Hspaces[i]->GetRect();
-// XXX: Hspaces[i]->SetToolTip(wxT("Espacement des caractères du titre"));
- Hspaces[i]->SetToolTip(wxT("Espacement des caracteres du titre"));
+ Hspaces[i]->SetToolTip(_("Spacing of the heading characters"));
}
@@ -171,8 +164,7 @@
{
Tdim[i] = new wxTextCtrl(this,-1,wxT(""),TDIM(i),wxSize(50,-1));
Tdimrect[i] = Tdim[i]->GetRect();
-// XXX: Tdim[i]->SetToolTip(wxT("Dimension intérieure de la colonne (en
mm)"));
- Tdim[i]->SetToolTip(wxT("Dimension interieure de la colonne (en mm)"));
+ Tdim[i]->SetToolTip(_("Inner dimension of the column (in mm)"));
Tunit[i] = new wxStaticText(this,-1,wxT("mm"),
wxPoint(Tdimrect[i].GetRight()+
@@ -181,12 +173,11 @@
Tjust[i] = new wxChoice(this,-1,TJUST(i),wxSize(-1,-1),3,choices);
Tjustrect[i] = Tjust[i]->GetRect();
- Tjust[i]->SetToolTip(wxT("Justification du texte de la colonne"));
+ Tjust[i]->SetToolTip(_("Alignment of the column text"));
Tspaces[i] = new wxTextCtrl(this,-1,wxT(""),TSPACES(i),ESPSIZE);
Tspacesrect[i] = Tspaces[i]->GetRect();
-// XXX: Tspaces[i]->SetToolTip(wxT("Espacement des caractères"));
- Tspaces[i]->SetToolTip(wxT("Espacement des caracteres"));
+ Tspaces[i]->SetToolTip(_("Characters spacing"));
}
justif->Move(wxPoint(Tjustrect[0].GetLeft(),bfontheadrect.GetBottom()
@@ -237,11 +228,11 @@
#define DIM wxSize(30,-1)
// Left part
- wxStaticText* dyh1text = new wxStaticText(this,-1,wxT("Titre esp.
sup."),DYH1COMMENT,wxSize(-1,-1));
+ wxStaticText* dyh1text = new wxStaticText(this,-1,_("Title spc.
top"),DYH1COMMENT,wxSize(-1,-1));
wxRect dyh1textrect = dyh1text->GetRect();
- wxStaticText* dyt1text = new wxStaticText(this,-1,wxT("Texte esp.
sup."),DYT1COMMENT,wxSize(-1,-1));
+ wxStaticText* dyt1text = new wxStaticText(this,-1,_("Text spc.
top"),DYT1COMMENT,wxSize(-1,-1));
wxRect dyt1textrect = dyt1text->GetRect();
- wxStaticText* dxbegintext = new wxStaticText(this,-1,wxT("Texte esp.
gauche."),DXBEGINCOMMENT,wxSize(-1,-1));
+ wxStaticText* dxbegintext = new wxStaticText(this,-1,_("Text spc.
left"),DXBEGINCOMMENT,wxSize(-1,-1));
wxRect dxbegintextrect = dxbegintext->GetRect();
dyh1 = new wxTextCtrl(this,-1,wxT("00"),DYH1TEXT,DIM);
@@ -258,11 +249,11 @@
wxRect dxbeginmmrect = dxbeginmm->GetRect();
// Right part
- wxStaticText* dyh2text = new wxStaticText(this,-1,wxT("Titre esp.
inf."),DYH2COMMENT,wxSize(-1,-1));
+ wxStaticText* dyh2text = new wxStaticText(this,-1,_("Title spc.
bot."),DYH2COMMENT,wxSize(-1,-1));
wxRect dyh2textrect = dyh2text->GetRect();
- wxStaticText* dyt2text = new wxStaticText(this,-1,wxT("Texte esp.
inf."),DYT2COMMENT,wxSize(-1,-1));
+ wxStaticText* dyt2text = new wxStaticText(this,-1,_("Text spc.
bot."),DYT2COMMENT,wxSize(-1,-1));
wxRect dyt2textrect = dyt2text->GetRect();
- wxStaticText* dxendtext = new wxStaticText(this,-1,wxT("Texte esp.
droit."),DXENDCOMMENT,wxSize(-1,-1));
+ wxStaticText* dxendtext = new wxStaticText(this,-1,_("Text spc.
right"),DXENDCOMMENT,wxSize(-1,-1));
wxRect dxendtextrect = dxendtext->GetRect();
dyh2 = new wxTextCtrl(this,-1,wxT("00"),DYH2TEXT,DIM);
@@ -292,25 +283,25 @@
#define BCANCELPOINT wxPoint(Tspacesrect[0].GetRight() - CANCELWIDTH,BPOS)
//#define BCANCELPOINT wxPoint(dxendmmrect.GetRight() - CANCELWIDTH,BPOS)
- bprinter = new wxButton(this,Button_Printer,wxT("Imprimante"),BPRINTERPOINT);
+ bprinter = new wxButton(this,Button_Printer,_("Printer"),BPRINTERPOINT);
wxRect bprinterrect = bprinter->GetRect();
- bprinter->SetToolTip(wxT("Configurer l'imprimante"));
+ bprinter->SetToolTip(_("Configure the printer"));
- bpage = new wxButton(this,Button_Page,wxT("Page"),BPAGEPOINT);
+ bpage = new wxButton(this,Button_Page,_("Page"),BPAGEPOINT);
// wxRect bpagerect = bpage->GetRect();
- bpage->SetToolTip(wxT("Configurer la taille de page"));
+ bpage->SetToolTip(_("Configure the dimensions of the page"));
- bcancel = new wxButton(this,Button_Cancel,wxT("Annuler"));
+ bcancel = new wxButton(this,wxID_CANCEL);
wxRect bcancelrect = bcancel->GetRect();
bcancel->Move(BCANCELPOINT);
bcancelrect = bcancel->GetRect();
- bcancel->SetToolTip(wxT("Annuler les dernier changements et quitter"));
+ bcancel->SetToolTip(_("Cancel the last changes"));
- bok = new wxButton(this,Button_Ok,wxT("OK"));
+ bok = new wxButton(this,wxID_OK);
wxRect bokrect = bok->GetRect();
bok->Move(BOKPOINT);
bokrect = bok->GetRect();
- bok->SetToolTip(wxT("Enregistrer les changements et quitter"));
+ bok->SetToolTip(_("Save the changes"));
#define DLGWIDTH (bcancelrect.GetRight() + HSPACE)
#define DLGHEIGHT (bokrect.GetBottom() + VSPACE)
Index: wxwin/configdb.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/configdb.cc,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- wxwin/configdb.cc 4 Aug 2007 20:01:27 -0000 1.8
+++ wxwin/configdb.cc 8 Jan 2008 13:52:43 -0000 1.9
@@ -25,6 +25,7 @@
*/
#include <iostream>
+#include "wx/wx.h"
#include "ewx.h"
#include "configdb.h"
#include "wx/colordlg.h"
@@ -199,7 +200,7 @@
wxString ConfigDB::getDicName()
{
- return ReadStr(DICNAME,wxT("Aucun Dictionnaire"));
+ return ReadStr(DICNAME,_("No dictionary"));
}
wxString ConfigDB::getTilePath()
@@ -318,11 +319,11 @@
wxString res;
switch (i)
{
- case 0: res = ReadStr(wxString(HNAME) + wxT("1"), wxT("Num")); break;
- case 1: res = ReadStr(wxString(HNAME) + wxT("2"), wxT("Tirage")); break;
- case 2: res = ReadStr(wxString(HNAME) + wxT("3"), wxT("Solution")); break;
- case 3: res = ReadStr(wxString(HNAME) + wxT("4"), wxT("Pos")); break;
- case 4: res = ReadStr(wxString(HNAME) + wxT("5"), wxT("Pts")); break;
+ case 0: res = ReadStr(wxString(HNAME) + wxT("1"), _("Nb")); break;
+ case 1: res = ReadStr(wxString(HNAME) + wxT("2"), _("Rack")); break;
+ case 2: res = ReadStr(wxString(HNAME) + wxT("3"), _("Solution")); break;
+ case 3: res = ReadStr(wxString(HNAME) + wxT("4"), _("Pos")); break;
+ case 4: res = ReadStr(wxString(HNAME) + wxT("5"), _("Pts")); break;
default: res = wxT(""); break;
}
return res;
Index: wxwin/confsearch.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/confsearch.cc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- wxwin/confsearch.cc 5 Nov 2005 17:33:06 -0000 1.9
+++ wxwin/confsearch.cc 8 Jan 2008 13:52:43 -0000 1.10
@@ -17,20 +17,15 @@
/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ewx.h"
+#include "wx/wx.h"
#include "wx/sizer.h"
#include "confsearch.h"
-enum {
- Button_Ok,
- Button_Cancel,
- CheckBox_Joker,
- CheckBox_Rack
-};
-BEGIN_EVENT_TABLE(ConfSearchDlg,wxDialog)
+BEGIN_EVENT_TABLE(ConfSearchDlg, wxDialog)
EVT_CLOSE (ConfSearchDlg::OnCloseWindow)
- EVT_BUTTON (Button_Ok, ConfSearchDlg::OnButtonOk)
- EVT_BUTTON (Button_Cancel, ConfSearchDlg::OnButtonCancel)
+ EVT_BUTTON (wxID_OK, ConfSearchDlg::OnButtonOk)
+ EVT_BUTTON (wxID_CANCEL, ConfSearchDlg::OnButtonCancel)
END_EVENT_TABLE()
@@ -38,14 +33,13 @@
: wxDialog(parent, -1, wxString(wxT("Configuration recherche")))
{
- joker_searching = new wxCheckBox(this,CheckBox_Joker,wxT("Recherche sur
joker dans 7+1"));
-// XXX: rack_checking = new wxCheckBox(this,CheckBox_Rack,wxT("Vérification
de la validité des tirages"));
- rack_checking = new wxCheckBox(this,CheckBox_Rack,wxT("Verification de la
validite des tirages"));
-
- bcancel = new wxButton(this,Button_Cancel,wxT("Annuler"),wxPoint(-1,-1));
- bcancel->SetToolTip(wxT("Annuler les dernier changements et quitter"));
- bok = new wxButton(this,Button_Ok,wxT("OK"),wxPoint(-1,-1));
- bok->SetToolTip(wxT("Enregistrer les changements et quitter"));
+ joker_searching = new wxCheckBox(this, wxID_ANY, _("Search on joker in 7+1
panel"));
+ rack_checking = new wxCheckBox(this, wxID_ANY, _("Check rack validity"));
+
+ bcancel = new wxButton(this, wxID_CANCEL);
+ bcancel->SetToolTip(_("Cancel last changes"));
+ bok = new wxButton(this, wxID_OK);
+ bok->SetToolTip(_("Save the changes"));
wxBoxSizer *bsizer = new wxBoxSizer( wxHORIZONTAL);
bsizer->Add(bok, 1, wxALL, 1);
@@ -63,21 +57,21 @@
readconf();
}
-void
+ void
ConfSearchDlg::readconf()
{
joker_searching->SetValue(config.getJokerPlus1());
rack_checking->SetValue(config.getRackChecking());
}
-void
+ void
ConfSearchDlg::writeconf()
{
config.setJokerPlus1(joker_searching->GetValue());
config.setRackChecking(rack_checking->GetValue());
}
-void
+ void
ConfSearchDlg::OnCloseWindow(wxCloseEvent&)
{
if (IsModal() == TRUE)
@@ -86,7 +80,7 @@
this->Destroy();
}
-void
+ void
ConfSearchDlg::OnButtonOk(wxCommandEvent&)
{
writeconf();
@@ -96,7 +90,7 @@
this->Destroy();
}
-void
+ void
ConfSearchDlg::OnButtonCancel(wxCommandEvent&)
{
if (IsModal() == TRUE)
Index: wxwin/gfxresult.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/gfxresult.cc,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- wxwin/gfxresult.cc 4 Aug 2007 20:01:27 -0000 1.7
+++ wxwin/gfxresult.cc 8 Jan 2008 13:52:43 -0000 1.8
@@ -64,11 +64,11 @@
#else
results->SetSingleStyle(wxLC_REPORT | wxLC_SINGLE_SEL);
#endif
- results->InsertColumn(0, wxT("Sol"));
+ results->InsertColumn(0, _("Word"));
results->InsertColumn(1, wxT("*"));
- results->InsertColumn(2, wxT("Pos"));
- results->InsertColumn(3, wxT("Pts"));
- results->SetToolTip(wxT("Resultats de la recherche"));
+ results->InsertColumn(2, _("Pos"));
+ results->InsertColumn(3, _("Pts"));
+ results->SetToolTip(_("Results of the search"));
wxBoxSizer *sizer_v = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizer_h = new wxBoxSizer(wxHORIZONTAL);
@@ -115,7 +115,7 @@
debug(" GfxResult::Refresh : ");
std::wstring rack = game->getCurrentPlayer().getCurrentRack().toString();
- if (savedrack != rack || static_cast<Training*>(game)->getResults().size()
!= results->GetItemCount())
+ if (savedrack != rack ||
(int)static_cast<Training*>(game)->getResults().size() !=
results->GetItemCount())
{
debug("changed (%ls -> %ls)",savedrack.c_str(),rack.c_str());
savedrack = rack;
@@ -138,16 +138,16 @@
if (game == NULL)
return;
- ((Training*)game)->search();
+ static_cast<Training*>(game)->search();
results->DeleteAllItems();
results->SetFont(config.getFont(LISTFONT));
- const Results &res = ((Training*)game)->getResults();
+ const Results &res = static_cast<Training*>(game)->getResults();
debug(" GfxResult::Search size = %d\n",res.size());
- for (int i = 0; i < res.size(); i++)
+ for (unsigned int i = 0; i < res.size(); i++)
{
- Round r = res.get(i);
+ const Round &r = res.get(i);
//debug(" adding %s\n",r.toString().c_str());
wxString pts;
wxString word = wxU(r.getWord().c_str());
@@ -170,7 +170,7 @@
if (res.size() > 0)
{
results->SetItemState(0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED
| wxLIST_MASK_STATE);
- ((Training*)game)->testPlay(0);
+ static_cast<Training*>(game)->testPlay(0);
}
}
Index: wxwin/main.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/main.cc,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- wxwin/main.cc 11 Aug 2006 22:18:33 -0000 1.10
+++ wxwin/main.cc 8 Jan 2008 13:52:43 -0000 1.11
@@ -67,19 +67,21 @@
wxConfigBase* config = wxConfigBase::Get();
config = NULL;
#ifdef ENABLE_LOCALE
- locale.Init(wxLocale::GetSystemLanguage(),
- wxLOCALE_LOAD_DEFAULT | wxLOCALE_CONV_ENCODING);
+ locale.Init();
- wxLocale::AddCatalogLookupPathPrefix(wxT("."));
- wxLocale::AddCatalogLookupPathPrefix(wxT(".."));
+ // No need to search in the current directory, it is already done by
default
+ // wxLocale::AddCatalogLookupPathPrefix(wxT("."));
+ // Search for translations in the installation directory
+ wxLocale::AddCatalogLookupPathPrefix(wxT(LOCALEDIR));
locale.AddCatalog(wxT("eliot"));
#ifdef __LINUX__
{
wxLogNull noLog;
- locale.AddCatalog(_T("fileutils"));
+ locale.AddCatalog(wxT("fileutils"));
}
#endif
#endif
+
ConfigDB configdb;
configdb.setFirstDefault();
MainFrame *mainframe = new MainFrame(configdb.getFramePos(wxT(APPNAME)),
@@ -94,7 +96,7 @@
EliotApp::OnExit()
{
GameFactory::Destroy();
- delete wxConfigBase::Set((wxConfigBase *) NULL);
+ delete wxConfigBase::Set(NULL);
return 0;
}
Index: wxwin/mainframe.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/mainframe.cc,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- wxwin/mainframe.cc 4 Aug 2007 20:01:27 -0000 1.22
+++ wxwin/mainframe.cc 8 Jan 2008 13:52:43 -0000 1.23
@@ -24,10 +24,13 @@
* \date 2005
*/
+#include "config.h"
+
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
+#include <exception>
using namespace std;
@@ -42,6 +45,7 @@
#include "dic.h"
#include "game.h"
+#include "training.h"
#include "game_factory.h"
#include "player.h"
@@ -58,6 +62,7 @@
enum
{
Menu_Game_New = 1000,
+ Menu_Game_NewJoker,
Menu_Game_Open,
Menu_Game_Save,
Menu_Game_Print,
@@ -100,9 +105,6 @@
Menu_ShowGame = (IDBASE + ID_Frame_Game),
Menu_ShowResult = (IDBASE + ID_Frame_Result),
- Menu_Quit_Apropos = 4000,
- Menu_Quit_Confirm,
-
Button_SetRack = 10000,
Button_SetNew,
Button_SetManual,
@@ -112,17 +114,19 @@
ListCtrl_ID = 11000,
Rack_ID,
- Status_ID,
+ Status_ID
};
BEGIN_EVENT_TABLE(MainFrame, wxFrame)
//
EVT_MENU(Menu_Game_New, MainFrame::OnMenuGameNew)
+ EVT_MENU(Menu_Game_NewJoker, MainFrame::OnMenuGameNew)
EVT_MENU(Menu_Game_Open, MainFrame::OnMenuGameOpen)
EVT_MENU(Menu_Game_Save, MainFrame::OnMenuGameSave)
EVT_MENU(Menu_Game_Print, MainFrame::OnMenuGamePrint)
EVT_MENU(Menu_Game_PrintPreview, MainFrame::OnMenuGamePrintPreview)
EVT_MENU(Menu_Game_PrintPS, MainFrame::OnMenuGamePrintPS)
+ EVT_MENU(wxID_EXIT, MainFrame::OnMenuGameQuit)
//
EVT_MENU(Menu_Conf_Game_Dic, MainFrame::OnMenuConfGameDic)
EVT_MENU(Menu_Conf_Game_Search, MainFrame::OnMenuConfGameSearch)
@@ -133,8 +137,7 @@
EVT_MENU_RANGE(Menu_Conf_Aspect_BoardColour_Lines,
Menu_Conf_Aspect_BoardColour_Default, MainFrame::OnMenuConfAspectBoardColour)
EVT_MENU_RANGE(Menu_ShowVerif, Menu_ShowResult, MainFrame::OnMenuShowFrame)
//
- EVT_MENU(Menu_Quit_Apropos, MainFrame::OnMenuQuitApropos)
- EVT_MENU(Menu_Quit_Confirm, MainFrame::OnMenuQuitConfirm)
+ EVT_MENU(wxID_ABOUT, MainFrame::OnMenuHelpAbout)
//
EVT_BUTTON(Button_Play, MainFrame::OnPlay)
EVT_BUTTON(Button_SetRack, MainFrame::OnSetRack)
@@ -153,39 +156,46 @@
//
// ******************************
-MainFrame::MainFrame(wxPoint __UNUSED__ pos_, wxSize size_) :
- wxFrame((wxFrame *) NULL, -1, wxT(APPNAME), wxPoint(-1, -1),
- size_, wxDEFAULT_FRAME_STYLE, wxT(APPNAME)), m_dic(NULL),
m_game(NULL)
+MainFrame::MainFrame(wxPoint __UNUSED__ pos_, wxSize size_)
+ : wxFrame((wxFrame *) NULL, -1, wxT(APPNAME), wxPoint(-1, -1),
+ size_, wxDEFAULT_FRAME_STYLE, wxT(APPNAME)),
+ m_dic(NULL), m_game(NULL)
{
#if defined(ENABLE_RESLIST_IN_MAIN)
reslist = NULL;
#endif
statusbar = NULL;
- for(int i=0 ; i < MAX_FRAME_ID; i++)
+ for (int i = 0 ; i < MAX_FRAME_ID; i++)
auxframes_ptr[i] = NULL;
- wxString dicpath = config.getDicPath();
- Dic_load(&m_dic, dicpath.mb_str());
- if (m_dic == NULL)
- {
- wxCommandEvent event;
- OnMenuConfGameDic(event);
- }
- m_game = GameFactory::Instance()->createTraining(m_dic);
- if (m_game)
- {
- m_game->start();
- }
-
wxBoxSizer *listsizer = new wxBoxSizer(wxVERTICAL);
rack = new wxTextCtrl(this, Rack_ID, wxU(""), wxPoint(-1, -1), wxSize(-1,
-1), wxTE_PROCESS_ENTER);
- listsizer->Add(rack , 0 , wxEXPAND | wxALL, 1);
- rack->SetToolTip(_("Tirage"));
+ listsizer->Add(rack, 0, wxEXPAND | wxALL, 1);
+ rack->SetToolTip(_("Rack"));
+ rack->Enable(false);
#ifdef ENABLE_RESLIST_IN_MAIN
reslist = new GfxResult(this,(MainFrame*)this,m_game);
listsizer->Add(reslist, 1, wxEXPAND | wxLEFT | wxRIGHT, 1);
#endif
+ wxString dicpath = config.getDicPath();
+ try
+ {
+ Dictionary *dic = new Dictionary(dicpath.mb_str().data());
+ m_dic = dic;
+ m_game = GameFactory::Instance()->createTraining(*m_dic);
+ if (m_game)
+ {
+ m_game->start();
+ }
+ }
+ catch (std::exception &e)
+ {
+ wxCommandEvent event;
+ // This will also start a new training game indirectly
+ OnMenuConfGameDic(event);
+ }
+
InitMenu();
statusbar = CreateStatusBar(2, 0, Status_ID);
@@ -193,17 +203,22 @@
statusbar->SetStatusWidths(2, ww);
UpdateStatusBar();
- b_rackrandomset = new wxButton(this, Button_SetRack, _(" Tirage "));
+ b_rackrandomset = new wxButton(this, Button_SetRack, _(" Rack "));
b_rackrandomnew = new wxButton(this, Button_SetNew, _(" Complement "));
- b_search = new wxButton(this, Button_Search, _(" Rechercher "));
- b_back = new wxButton(this, Button_PlayBack, _(" Arriere "));
- b_play = new wxButton(this, Button_Play, _(" Jouer "));
-
- b_rackrandomset->SetToolTip(_("Tirage aleatoire"));
- b_rackrandomnew->SetToolTip(_("Complement aleatoire du tirage"));
- b_search->SetToolTip( _("Recherche sur le tirage courant"));
- b_back->SetToolTip( _("Revenir un coup en arriere"));
- b_play->SetToolTip( _("Jouer le mot selectionne"));
+ b_search = new wxButton(this, Button_Search, _(" Search "));
+ b_back = new wxButton(this, Button_PlayBack, _(" Back "));
+ b_play = new wxButton(this, Button_Play, _(" Play "));
+
+ b_rackrandomset->SetToolTip(_("Random rack"));
+ b_rackrandomset->Enable(false);
+ b_rackrandomnew->SetToolTip(_("Random complement of the rack"));
+ b_rackrandomnew->Enable(false);
+ b_search->SetToolTip( _("Search with the current rack"));
+ b_search->Enable(false);
+ b_back->SetToolTip( _("Go back one turn"));
+ b_back->Enable(false);
+ b_play->SetToolTip( _("Play the selected word"));
+ b_play->Enable(false);
wxBoxSizer *buttonsizer = new wxBoxSizer(wxHORIZONTAL);
buttonsizer->Add(b_rackrandomset, 1, wxEXPAND | wxTOP | wxBOTTOM | wxLEFT
, 1);
@@ -242,10 +257,7 @@
m_game = NULL;
}
- if (m_dic)
- {
- Dic_destroy(m_dic);
- }
+ delete m_dic;
}
// ******************************
@@ -257,82 +269,72 @@
{
// menus
wxMenu *menu_game = new wxMenu;
- menu_game->Append(Menu_Game_New, _("Nouvelle"), _("Demarrer une nouvelle
partie"));
- menu_game->Append(Menu_Game_Open, _("Charger..."), _("Charger une
partie"));
- menu_game->Append(Menu_Game_Save, _("Sauver..."), _("Sauver cette
partie"));
+ menu_game->Append(Menu_Game_New, _("&New game\tctrl+n"), _("Start a new
game"));
+ menu_game->Append(Menu_Game_NewJoker, _("New &joker game\tctrl+j"),
_("Start a new joker game"));
menu_game->AppendSeparator();
- menu_game->Append(Menu_Game_Print, _("Imprimer..."), _("Imprimer cette
partie"));
- menu_game->Append(Menu_Game_PrintPreview, _("Preimpression"),
_("Preimpression de la partie"));
-#ifdef ENABLE_SAVE_POSTSCRIPT
+ menu_game->Append(Menu_Game_Open, _("&Load...\tctrl+l"), _("Load a game"));
+ menu_game->Append(Menu_Game_Save, _("&Save as...\tctrl+s"), _("Save the
current game"));
menu_game->AppendSeparator();
- menu_game->Append(Menu_Game_PrintPS, _("Imprimer du PostScript"),
_("Imprimer dans un fichier PostScript"));
+ menu_game->Append(Menu_Game_Print, _("&Print...\tctrl+p"), _("Print this
game"));
+ menu_game->Append(Menu_Game_PrintPreview, _("Print pre&view..."), _("Print
preview of the game"));
+#ifdef ENABLE_SAVE_POSTSCRIPT
+ menu_game->Append(Menu_Game_PrintPS, _("Print in PostS&cript..."),
_("Print in a PostScript file"));
#endif
+ menu_game->AppendSeparator();
+ menu_game->Append(wxID_EXIT, _("&Quit"), _("Quit Eliot"));
//
wxMenu *menu_conf_game = new wxMenu;
- menu_conf_game->Append(Menu_Conf_Game_Dic, _("Dictionnaire"), _("Choix du
dictionnaire"));
- menu_conf_game->Append(Menu_Conf_Game_Search, _("Recherche"), _("Options
de recherche"));
- //
- wxMenu *menu_tileback = new wxMenu;
- menu_tileback->Append(Menu_Conf_Aspect_BoardColour_Letters ,
_("Lettres jouees"), _("Lettres jouees sur la grille"));
- menu_tileback->Append(Menu_Conf_Aspect_BoardColour_TestLetters ,
_("Lettres provisoires"), _("Lettres du mot a jouer"));
- menu_tileback->AppendSeparator();
- menu_tileback->Append(Menu_Conf_Aspect_BoardColour_TileBack , _("Fonds
lettres jouees"), _("Fonds des pions sur la grille"));
- menu_tileback->Append(Menu_Conf_Aspect_BoardColour_TestTileBack, _("Fonds
lettres provisoires"), _("Fonds des pions sur la grille"));
+ menu_conf_game->Append(Menu_Conf_Game_Dic, _("&Dictionary..."), _("Choose
a dictionary"));
+ menu_conf_game->Append(Menu_Conf_Game_Search, _("&Search..."), _("Search
options"));
//
wxMenu *menu_conf_board_colour = new wxMenu;
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Background,
_("Fond"), _("Couleur du fond"));
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Lines,
_("Lignes"), _("Couleur des lignes"));
- menu_conf_board_colour->Append(Menu_Conf_Tile, _("Pions et lettres"),
menu_tileback, _("Pions et lettres"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Background,
_("&Background..."), _("Background color"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Lines,
_("L&ines..."), _("Color of the lines"));
menu_conf_board_colour->AppendSeparator();
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Letters,
_("Lettres jouees"), _("Lettres jouees sur la grille"));
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_TestLetters,
_("Lettres provisoires"), _("Lettres du mot a jouer"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Letters,
_("&Played letters..."), _("Color of the letters played on the board"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_TestLetters,
_("&Temporary letters..."), _("Color of the letters of the temporary word"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_TileBack ,
_("B&ackground of played letters..."), _("Background color of the letters
played on the board"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_TestTileBack,
_("Ba&ckground of temporary letters..."), _("Background color of the temporary
letters on the board"));
menu_conf_board_colour->AppendSeparator();
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Wx2, _("Mot
compte double"), _("Mot compte double"));
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Wx3, _("Mot
compte triple"), _("Mot compte triple"));
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Lx2, _("Lettre
compte double"), _("Lettre compte double"));
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Lx3, _("Lettre
compte triple"), _("Lettre compte triple"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Wx2, _("Double
&letter..."), _("Color of the \"double letter\" squares"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Wx3, _("Triple
l&etter..."), _("Color of the \"triple letter\" squares"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Lx2, _("Double
&word..."), _("Color of the \"double word\" squares"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Lx3, _("Triple
w&ord..."), _("Color of the \"triple word\" squares"));
menu_conf_board_colour->AppendSeparator();
- menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Default,
_("Couleurs d'origine"), _("Retrouver les couleurs d'origine"));
+ menu_conf_board_colour->Append(Menu_Conf_Aspect_BoardColour_Default,
_("&Default colors"), _("Restore the default colors"));
//
wxMenu *menu_conf_board_font = new wxMenu;
-// XXX: menu_conf_board_font->Append(Menu_Conf_Aspect_Font_Search,
_("Lettres de recherche"), _("Police de caractères pour les recherches"));
- menu_conf_board_font->Append(Menu_Conf_Aspect_Font_Search, _("Lettres de
recherche"), _("Police de caracteres pour les recherches"));
-// XXX: menu_conf_board_font->Append(Menu_Conf_Aspect_Font_Board,
_("Lettres de la grille"), _("Police de caractères de la grille"));
- menu_conf_board_font->Append(Menu_Conf_Aspect_Font_Board, _("Lettres de la
grille"), _("Police de caracteres de la grille"));
+ menu_conf_board_font->Append(Menu_Conf_Aspect_Font_Search, _("&Search
letters..."), _("Font for the search"));
//
wxMenu *menu_conf = new wxMenu;
- menu_conf->Append(Menu_Conf_Game, _("Jeu"), menu_conf_game,
_("Configuration du jeu"));
- menu_conf->Append(Menu_Conf_Aspect_Font, _("Fonte des lettres"),
menu_conf_board_font, _("Modification des fontes"));
- menu_conf->Append(Menu_Conf_Aspect_BoardColour, _("Couleurs de la
grille"), menu_conf_board_colour, _("Modification des couleurs"));
- menu_conf->Append(Menu_Conf_Print, _("Impression"), _("Dimensions de la
partie"));
+ menu_conf->Append(Menu_Conf_Game, _("&Game"), menu_conf_game,
_("Configuration of the game"));
+ menu_conf->Append(Menu_Conf_Aspect_Font, _("&Fonts"),
menu_conf_board_font, _("Configuration of the fonts"));
+ menu_conf->Append(Menu_Conf_Aspect_BoardColour, _("&Colors"),
menu_conf_board_colour, _("Configuration of the colors"));
+ menu_conf->Append(Menu_Conf_Print, _("&Printing..."), _("Configuration of
the printing parameters"));
//
wxMenu *menu_frame = new wxMenu;
- menu_frame->Append(Menu_ShowBoard, _("Grille"), _("Grille de jeu"));
-// XXX: menu_frame->Append(Menu_ShowVerif, _("Vérification"),
_("Vérification d'un mot dans le dictionnaire"));
- menu_frame->Append(Menu_ShowVerif, _("Verification"), _("Verification d'un
mot dans le dictionnaire"));
- menu_frame->Append(Menu_ShowSearch, _("Recherche"), _("Recherche dans le
dictionnaire"));
+ menu_frame->AppendCheckItem(Menu_ShowBoard, _("&Board"), _("Game board"));
+ menu_frame->AppendCheckItem(Menu_ShowBag, _("Ba&g"), _("Remaining letters
in the bag"));
+ menu_frame->AppendCheckItem(Menu_ShowVerif, _("&Check"), _("Check a word
in the dictionary"));
+ menu_frame->AppendCheckItem(Menu_ShowSearch, _("&Search"), _("Search in
the dictionary"));
menu_frame->AppendSeparator();
- menu_frame->Append(Menu_ShowPlus1, _("Tirage + 1"), _("Lettres du tirage
plus une"));
- menu_frame->Append(Menu_ShowRacc, _("Raccords"), _("Raccords sur un mot de
la recherche"));
- menu_frame->Append(Menu_ShowBenj, _("Benjamins"), _("Benjamins sur un mot
de la recherche"));
+ menu_frame->AppendCheckItem(Menu_ShowPlus1, _("&Rack + 1"), _("Letters of
the rack plus one"));
+ menu_frame->AppendCheckItem(Menu_ShowRacc, _("R&accords"), _("Raccords on
a word of the search"));
+ menu_frame->AppendCheckItem(Menu_ShowBenj, _("&Benjamins"), _("Benjamins
on a word of the search"));
menu_frame->AppendSeparator();
- menu_frame->Append(Menu_ShowBag, _("Sac"), _("Lettres restantes dans le
sac"));
- menu_frame->AppendSeparator();
- menu_frame->Append(Menu_ShowGame, _("Partie"), _("Partie"));
+ menu_frame->AppendCheckItem(Menu_ShowGame, _("Game &history"), _("Game
history"));
#ifndef ENABLE_RESLIST_IN_MAIN
- menu_frame->Append(Menu_ShowResult, _("Resultats"), _("Resultats"));
+ menu_frame->Append(Menu_ShowResult, _("R&esults"), _("Results"));
#endif
//
- wxMenu *menu_quit = new wxMenu;
- menu_quit->Append(Menu_Quit_Apropos, _("A propos..."), _("A propos
d'Eliot"));
- menu_quit->Append(Menu_Quit_Confirm, _("Quitter"), _("Quitter"));
+ wxMenu *menu_help = new wxMenu;
+ menu_help->Append(wxID_ABOUT, _("&About..."), _("About Eliot"));
//
wxMenuBar *menu_bar = new wxMenuBar;
- menu_bar->Append(menu_game, _("Partie"));
- menu_bar->Append(menu_conf, _("Configuration"));
-// XXX: menu_bar->Append(menu_frame, _("Fenêtres"));
- menu_bar->Append(menu_frame, _("Fenetres"));
- menu_bar->Append(menu_quit, _("Quitter"));
+ menu_bar->Append(menu_game, _("&Game"));
+ menu_bar->Append(menu_conf, _("&Settings"));
+ menu_bar->Append(menu_frame, _("&Windows"));
+ menu_bar->Append(menu_help, _("&Help"));
SetMenuBar(menu_bar);
}
@@ -352,11 +354,11 @@
// *******************
void
-MainFrame::OnMenuGameNew(wxCommandEvent&)
+MainFrame::OnMenuGameNew(wxCommandEvent& event)
{
if (m_dic == NULL)
{
- wxMessageBox(_("Il n'y a pas de dictionnaire selectionne"), _("Eliot:
erreur"),
+ wxMessageBox(_("No dictionary selected"), _("Eliot: error"),
wxICON_INFORMATION | wxOK);
return;
}
@@ -369,13 +371,26 @@
m_game = NULL;
}
- m_game = GameFactory::Instance()->createTraining(m_dic);
+ m_game = GameFactory::Instance()->createTraining(*m_dic);
+ // Joker game?
+ if (event.GetId() == Menu_Game_NewJoker)
+ m_game->setVariant(Game::kJOKER);
+
m_game->start();
- rack->SetValue(wxU(""));
+ rack->SetValue(wxT(""));
InitFrames();
#ifdef ENABLE_RESLIST_IN_MAIN
reslist->SetGame(m_game);
#endif
+ // Re-enable the main buttons
+ b_rackrandomset->Enable(true);
+ b_rackrandomnew->Enable(true);
+ b_search->Enable(true);
+ b_back->Enable(true);
+ b_play->Enable(true);
+ rack->Enable(true);
+
+
UpdateStatusBar();
UpdateFrames(AuxFrame::FORCE_REFRESH);
}
@@ -387,11 +402,10 @@
void
MainFrame::OnMenuGameOpen(wxCommandEvent&)
{
- wxString txt;
- wxFileDialog dialog(this, _("Ouvrir une partie"), wxT(""), wxT(""),
wxT("*"), wxOPEN);
+ wxFileDialog dialog(this, _("Load a game"), wxT(""), wxT(""), wxT("*"),
wxOPEN);
if (m_dic == NULL)
{
- wxMessageBox(_("Il n'y a pas de dictionnaire selectionne"), _("Eliot:
erreur"),
+ wxMessageBox(_("No dictionary selected"), _("Eliot: error"),
wxICON_INFORMATION | wxOK);
return;
}
@@ -410,20 +424,21 @@
if ((fin = fopen(dialog.GetPath().mb_str(), "rb")) == NULL)
{
- txt << _("Impossible d'ouvrir") << dialog.GetPath();
- wxMessageDialog msg(this, txt, _("Ouverture d'une partie"));
+ wxString txt;
+ txt << _("Cannot open ") << dialog.GetPath();
+ wxMessageDialog msg(this, txt, _("Load a game"));
msg.ShowModal();
return ;
}
- m_game = Game::load(fin, m_dic);
+ m_game = Game::load(fin, *m_dic);
fclose(fin);
if (m_game == NULL)
{
wxMessageDialog msg(this,
- _("Erreur pendant la lecture de la partie"),
- _("chargement de partie"));
+ _("Error while loading the game"),
+ _("Invalid game"));
msg.ShowModal();
return;
}
@@ -431,18 +446,13 @@
if (m_game->getHistory().getSize() == 0)
{
wxMessageDialog msg(this,
- _("Erreur pendant la lecture de la partie"),
- _("La partie est vide"));
+ _("Error while loading the game"),
+ _("The game is empty"));
msg.ShowModal();
return;
}
- std::wstring r;
-
- if (m_game->getHistory().getSize() >= 0)
- {
- r = m_game->getCurrentPlayer().getCurrentRack().toString();
- }
+ std::wstring r = m_game->getCurrentPlayer().getCurrentRack().toString();
rack->SetValue(wxU(r.c_str()));
// update gfxboard and all frames
@@ -462,16 +472,15 @@
void
MainFrame::OnMenuGameSave(wxCommandEvent& WXUNUSED(event))
{
- wxFileDialog dialog(this, _("Sauver une partie"), wxT(""), wxT(""),
wxT("*"), wxSAVE|wxOVERWRITE_PROMPT);
+ wxFileDialog dialog(this, _("Save the game"), wxT(""), wxT(""), wxT("*"),
wxSAVE|wxOVERWRITE_PROMPT);
if (dialog.ShowModal() == wxID_OK)
{
ofstream fout(dialog.GetPath().mb_str());
if (fout.rdstate() == ios::failbit)
{
wxString txt;
-// XXX: txt << _("Impossible de créer ") << dialog.GetPath();
- txt << _("Impossible de creer ") << dialog.GetPath();
- wxMessageDialog msg(this, txt, _("Sauvegarde de la partie"));
+ txt << _("Cannot create ") << dialog.GetPath();
+ wxMessageDialog msg(this, txt, _("Save the game"));
msg.ShowModal();
return ;
}
@@ -490,7 +499,7 @@
// TODO: gray out the menu instead...
if (m_game == NULL)
{
- wxMessageBox(_("Pas de partie en cours"), _("Eliot: erreur"),
+ wxMessageBox(_("No on going game"), _("Eliot: error"),
wxICON_INFORMATION | wxOK);
return;
}
@@ -498,8 +507,10 @@
wxPrinter printer(&printDialogData);
GamePrintout printout(*m_game);
if (!printer.Print(this, &printout, TRUE))
-// XXX: wxMessageBox(wxT("Impression non effectuée."));
- wxMessageBox(_("Impression non effectuee."));
+ {
+ wxMessageBox(_("Printing not done"), _("Printing"),
+ wxOK | wxICON_ERROR);
+ }
}
void
@@ -508,7 +519,7 @@
// TODO: gray out the menu instead...
if (m_game == NULL)
{
- wxMessageBox(_("Pas de partie en cours"), _("Eliot: erreur"),
+ wxMessageBox(_("No on going game"), _("Eliot: error"),
wxICON_INFORMATION | wxOK);
return;
}
@@ -520,15 +531,12 @@
if (!preview->Ok())
{
delete preview;
-// XXX: msg << _("Problème de prévisualisation.\n")
- msg << _("Probleme de previsualisation.\n")
-// XXX: << _("Il se peut que l'imprimante par défaut soit mal
initialisée");
- << _("Il se peut que l'imprimante par defaut soit mal
initialisee");
-// XXX: wxMessageBox(msg, _("Impression (prévisualisation)"), wxOK);
- wxMessageBox(msg, _("Impression (previsualisation)"), wxOK);
+ msg << _("Print preview problem.\n")
+ << _("The printer may not be correctly initialized");
+ wxMessageBox(msg, _("Print preview"), wxOK);
return;
}
- wxPreviewFrame *frame = new wxPreviewFrame(preview, this, _("Impression"),
+ wxPreviewFrame *frame = new wxPreviewFrame(preview, this, _("Printing"),
wxPoint(-1, -1), wxSize(600,
550));
frame->Centre(wxBOTH);
frame->Initialize();
@@ -542,12 +550,11 @@
// TODO: gray out the menu instead...
if (m_game == NULL)
{
- wxMessageBox(_("Pas de partie en cours"), _("Eliot: erreur"),
+ wxMessageBox(_("No on going game"), _("Eliot: error"),
wxICON_INFORMATION | wxOK);
return;
}
- wxString txt;
- wxFileDialog dialog(this, _("Imprimer dans un fichier PostScript"),
wxT(""), wxT(""), wxT("*.ps"), wxSAVE|wxOVERWRITE_PROMPT);
+ wxFileDialog dialog(this, _("Print to a PostScript file"), wxT(""),
wxT(""), wxT("*.ps"), wxSAVE|wxOVERWRITE_PROMPT);
if (dialog.ShowModal() == wxID_OK)
{
wxPrintData printdataPS;
@@ -565,76 +572,54 @@
GamePrintout printout(*m_game);
if (!printer.Print(this, &printout, FALSE))
{
-// XXX: wxMessageBox(_("Impression non effectuée."));
- wxMessageBox(_("Impression non effectuee."));
- }
- else
- {
- wxString msg;
-// XXX: msg << _("Dessin effectué dans ") << dialog.GetPath()
<< _("\n");
- msg << _("Dessin effectue dans ") << dialog.GetPath() <<
_("\n");
- wxMessageBox(msg, _("Sauvegarde PostScript"), wxOK);
+ wxMessageBox(_("Printing not done"),
+ _("PostScript printing"), wxOK | wxICON_ERROR);
}
}
else
{
- wxString msg;
- msg << _("impossible d'initialiser le traitement PostScript.\n");
- wxMessageBox(msg, _("Sauvegarde PostScript"), wxOK);
+ wxMessageBox(_("Cannot initialize PostScript printer"),
+ _("PostScript printing"), wxOK | wxICON_ERROR);
}
}
#endif
}
+void
+MainFrame::OnMenuGameQuit(wxCommandEvent& WXUNUSED(event))
+{
+ Close(TRUE);
+}
+
+
+
// *******************
-// Dictionnary Loading
+// Dictionary Loading
// *******************
void
MainFrame::OnMenuConfGameDic(wxCommandEvent& WXUNUSED(event))
{
- wxString txt, msg, dicpath;
- wxFileDialog dialog(this, _("Choisir un dictionnaire"), wxT(""),
wxT("*.dawg"), wxT("*.dawg"), wxOPEN);
+ wxFileDialog dialog(this, _("Choose a dictionary"), wxT(""),
wxT("*.dawg"), wxT("*.dawg"), wxOPEN);
if (dialog.ShowModal() == wxID_OK)
{
wxString dicpath = dialog.GetPath();
- Dictionary dic;
- int res = Dic_load(&dic, dicpath.mb_str());
- if (res == 0)
- {
- if (m_dic)
+ try
{
- Dic_destroy(m_dic);
- }
-
+ Dictionary *dic = new Dictionary(dicpath.mb_str().data());
+ delete m_dic;
m_dic = dic;
config.setDicPath(dialog.GetPath(),
::wxFileNameFromPath(dialog.GetPath()));
+ wxCommandEvent event;
+ OnMenuGameNew(event);
}
- else
- {
- switch (res)
+ catch (std::exception &e)
{
- case 0: /* cas normal */ break;
-// XXX: case 1: msg << _("chargement: problème d'ouverture de
") << dicpath << _("\n"); break;
- case 1: msg << _("chargement: probleme d'ouverture de ") <<
dicpath << _("\n"); break;
-// XXX: case 2: msg << _("chargement: mauvais en-tête de
dictionnaire\n"); break;
- case 2: msg << _("chargement: mauvais en-tete de
dictionnaire\n"); break;
-// XXX: case 3: msg << _("chargement: problème 3 d'allocation
mémoire\n"); break;
- case 3: msg << _("chargement: probleme 3 d'allocation
memoire\n"); break;
-// XXX: case 4: msg << _("chargement: problème 4 d'allocation
mémoire\n"); break;
- case 4: msg << _("chargement: probleme 4 d'allocation
memoire\n"); break;
-// XXX: case 5: msg << _("chargement: problème de lecture des
arcs du dictionnaire\n"); break;
- case 5: msg << _("chargement: probleme de lecture des arcs du
dictionnaire\n"); break;
-// XXX: default: msg << _("chargement: problème
non-répertorié\n"); break;
- default: msg << _("chargement: probleme non-repertorie\n");
break;
- }
- wxMessageDialog dlg(NULL, msg, wxT(APPNAME));
+ wxMessageDialog dlg(NULL, wxU(e.what()), wxT(APPNAME));
dlg.ShowModal();
}
}
- UpdateStatusBar();
- UpdateFrames();
}
// ****************
@@ -732,30 +717,22 @@
}
//**************************************************************************************
-// MENU QUIT
+// MENU HELP
//**************************************************************************************
void
-MainFrame::OnMenuQuitApropos(wxCommandEvent& WXUNUSED(event))
+MainFrame::OnMenuHelpAbout(wxCommandEvent& WXUNUSED(event))
{
wxString msg;
- // XXX: msg << wxT("Eliot\n© Antoine Fraboulet 1999-2004\n\n");
- msg << wxT("Eliot\nCopyright Antoine Fraboulet 1999-2006\n\n");
- msg << wxT("This program is free software; you can redistribute it and/or
modify\n");
- msg << wxT("it under the terms of the GNU General Public License as
published by\n");
- msg << wxT("the Free Software Foundation; either version 2 of the License,
or\n");
- msg << wxT("(at your option) any later version.\n\n");
- msg << wxT("Version ") << wxT(VERSION) << wxT("\n");
- wxMessageBox(msg, _("A propos d'Eliot"), wxICON_INFORMATION | wxOK);
+ msg.Printf(wxT("Eliot %s\n\n"), wxT(VERSION));
+ msg << wxT("Copyright (C) 1999-2007 - Antoine Fraboulet & Olivier
Teuliere\n\n");
+ msg << _("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.");
+ wxMessageBox(msg, _("About Eliot"), wxICON_INFORMATION | wxOK);
}
-void
-MainFrame::OnMenuQuitConfirm(wxCommandEvent& WXUNUSED(event))
-{
- Close(TRUE);
-}
-
-
//**************************************************************************************
// BUTTONS
//**************************************************************************************
@@ -837,33 +814,30 @@
return;
}
- for(int i=0 ; i < MAX_FRAME_ID; i++)
- {
- if (auxframes_ptr[i] != NULL)
+ for (int i = 0 ; i < MAX_FRAME_ID; i++)
{
debug(" delete frame %d\n",i);
delete auxframes_ptr[i];
}
- }
- auxframes_ptr[ ID_Frame_Verif ] = new VerifFrame (this, m_game->getDic());
+ auxframes_ptr[ID_Frame_Verif] = new VerifFrame (this, m_game->getDic());
debug("0 : Verif\n");
- auxframes_ptr[ ID_Frame_Search ] = new SearchFrame(this, m_game->getDic());
+ auxframes_ptr[ID_Frame_Search] = new SearchFrame(this, m_game->getDic());
debug("1 : Search\n");
- auxframes_ptr[ ID_Frame_Plus1 ] = new Plus1Frame (this, m_game);
+ auxframes_ptr[ID_Frame_Plus1] = new Plus1Frame (this, m_game);
debug("2 : Plus1\n");
- auxframes_ptr[ ID_Frame_Racc ] = new RaccFrame (this, m_game);
+ auxframes_ptr[ID_Frame_Racc] = new RaccFrame (this, m_game);
debug("3 : Racc\n");
- auxframes_ptr[ ID_Frame_Benj ] = new BenjFrame (this, m_game);
+ auxframes_ptr[ID_Frame_Benj] = new BenjFrame (this, m_game);
debug("4 : Benj\n");
- auxframes_ptr[ ID_Frame_Bag ] = new BagFrame (this, *m_game);
+ auxframes_ptr[ID_Frame_Bag] = new BagFrame (this, *m_game);
debug("5 : Bag\n");
- auxframes_ptr[ ID_Frame_Board ] = new BoardFrame (this, *m_game);
+ auxframes_ptr[ID_Frame_Board] = new BoardFrame (this, *m_game);
debug("6 : Board\n");
- auxframes_ptr[ ID_Frame_Game ] = new GameFrame (this, *m_game);
+ auxframes_ptr[ID_Frame_Game] = new GameFrame (this, *m_game);
debug("7 : Game\n");
#ifndef ENABLE_RESLIST_IN_MAIN
- auxframes_ptr[ ID_Frame_Result ] = new ResultFrame(this, m_game);
+ auxframes_ptr[ID_Frame_Result] = new ResultFrame(this, m_game);
debug("8 : Result\n");
#endif
@@ -875,6 +849,19 @@
debug("reload %d\n",i);
}
}
+
+ // Check the corresponding menu item if the window is visible
+ GetMenuBar()->Check(Menu_ShowVerif,
auxframes_ptr[ID_Frame_Verif]->IsShown());
+ GetMenuBar()->Check(Menu_ShowSearch,
auxframes_ptr[ID_Frame_Search]->IsShown());
+ GetMenuBar()->Check(Menu_ShowPlus1,
auxframes_ptr[ID_Frame_Plus1]->IsShown());
+ GetMenuBar()->Check(Menu_ShowRacc,
auxframes_ptr[ID_Frame_Racc]->IsShown());
+ GetMenuBar()->Check(Menu_ShowBenj,
auxframes_ptr[ID_Frame_Benj]->IsShown());
+ GetMenuBar()->Check(Menu_ShowBag, auxframes_ptr[ID_Frame_Bag]->IsShown());
+ GetMenuBar()->Check(Menu_ShowBoard,
auxframes_ptr[ID_Frame_Board]->IsShown());
+ GetMenuBar()->Check(Menu_ShowGame,
auxframes_ptr[ID_Frame_Game]->IsShown());
+#ifndef ENABLE_RESLIST_IN_MAIN
+ GetMenuBar()->Check(Menu_ShowResult,
auxframes_ptr[ID_Frame_Result]->IsShown());
+#endif
debug("InitFrames end ok.\n");
}
@@ -937,8 +924,8 @@
if (m_game)
{
text = wxT("");
- text << _("coup:") << (m_game->getHistory().getSize() + 1) << wxT("
");
- text << _("points:") << (m_game->getCurrentPlayer().getPoints());
+ text << _("turn:") << wxT(" ") << (m_game->getHistory().getSize()
+ 1) << wxT(" ");
+ text << _("points:") << wxT(" ") <<
(m_game->getCurrentPlayer().getPoints());
statusbar->SetStatusText(text, 1);
}
}
@@ -957,13 +944,15 @@
void
MainFrame::SetRack(Game::set_rack_mode mode, wxString srack)
{
- int res = 0;
wxString msg;
bool check = config.getRackChecking();
+ if (m_game == NULL)
+ {
+ return;
+ }
static_cast<Training*>(m_game)->removeTestPlay();
- std::wstring str = srack.c_str();
- res = static_cast<Training*>(m_game)->setRack(mode, check, str);
+ int res = static_cast<Training*>(m_game)->setRack(mode, check,
srack.c_str());
switch (res)
{
@@ -971,20 +960,19 @@
debug("SetRack Ok :: ");
break;
case 0x01:
- msg = _("Le sac ne contient pas assez de lettres\npour assurer le
tirage.");
- wxMessageBox(msg, _("Correction du tirage"), wxICON_INFORMATION |
wxOK);
+ msg = _("The bag doesn't contain enough letters\nfor a new rack.");
+ wxMessageBox(msg, _("Rack validation"), wxICON_ERROR | wxOK);
return;
case 0x02:
- msg = _("Le tirage doit contenir au moins 2 consonnes et 2
voyelles.\n");
- wxMessageBox(msg, _("Correction du tirage"), wxICON_INFORMATION |
wxOK);
+ msg = _("The rack must contain at least 2 consonants and 2
vowels.");
+ wxMessageBox(msg, _("Rack validation"), wxICON_ERROR | wxOK);
return;
case 0x03:
- msg = _("Le tirage doit contenir au moins 2 consonnes et 2
voyelles\n");
- msg += _("mais le sac ne contient plus assez de lettres.\n\n");
- wxMessageBox(msg, _("Correction du tirage"), wxICON_INFORMATION |
wxOK);
+ msg = _("The rack contains invalid letters for the current
dictionary");
+ wxMessageBox(msg, _("Rack validation"), wxICON_ERROR | wxOK);
break;
default:
- statusbar->SetStatusText(_("Le tirage a ete modifie manuellement"),
0);
+ statusbar->SetStatusText(_("The rack has been modified manually"),
0);
break;
}
@@ -998,7 +986,7 @@
void
MainFrame::Search()
{
- if (m_game == NULL || m_game->getDic() == NULL)
+ if (m_game == NULL)
{
return;
}
@@ -1030,7 +1018,7 @@
}
else
{
- int n=0;
+ int n = 0;
debug("MainFrame::Play +%d\n",n);
#ifdef ENABLE_RESLIST_IN_MAIN
n = reslist->GetSelected();
@@ -1039,7 +1027,7 @@
#endif
if (n > -1)
{
- ((Training*)m_game)->playResult(n);
+ static_cast<Training*>(m_game)->playResult(n);
}
}
wxString r =
wxU(m_game->getCurrentPlayer().getCurrentRack().toString().c_str());
@@ -1064,9 +1052,5 @@
/****************************************************************/
/****************************************************************/
-/// Local Variables:
-/// mode: c++
-/// mode: hs-minor
-/// c-basic-offset: 4
-/// indent-tabs-mode: nil
-/// End:
+/// Local Variables: / mode: c++ / mode: hs-minor / c-basic-offset: 4 /
+//indent-tabs-mode: nil / End:
Index: wxwin/mainframe.h
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/mainframe.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- wxwin/mainframe.h 1 Jan 2006 19:34:05 -0000 1.7
+++ wxwin/mainframe.h 8 Jan 2008 13:52:43 -0000 1.8
@@ -1,4 +1,4 @@
-/* Eliot */
+// Joker game?* Eliot
*/
/* Copyright (C) 1999 Antoine Fraboulet */
/* address@hidden */
/* */
@@ -34,7 +34,7 @@
{
private:
- Dictionary m_dic;
+ const Dictionary *m_dic;
Game *m_game;
ConfigDB config;
AuxFrame *auxframes_ptr[MAX_FRAME_ID];
@@ -79,6 +79,7 @@
void OnMenuGamePrint (wxCommandEvent& event);
void OnMenuGamePrintPreview (wxCommandEvent& event);
void OnMenuGamePrintPS (wxCommandEvent& event);
+ void OnMenuGameQuit (wxCommandEvent& event);
void OnMenuConfGameDic (wxCommandEvent& event);
void OnMenuConfGameSearch (wxCommandEvent& event);
@@ -90,8 +91,7 @@
void OnMenuShowFrame (wxCommandEvent& event);
- void OnMenuQuitApropos (wxCommandEvent& event);
- void OnMenuQuitConfirm (wxCommandEvent& event);
+ void OnMenuHelpAbout (wxCommandEvent& event);
// *******
// Buttons
Index: wxwin/printout.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/printout.cc,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- wxwin/printout.cc 4 Aug 2007 20:01:27 -0000 1.11
+++ wxwin/printout.cc 8 Jan 2008 13:52:43 -0000 1.12
@@ -176,14 +176,14 @@
DIM(2);
if ((numline > 0) && (numline <= NRounds))
{
- str = wxU(m_game.getHistory().getTurn(numline -
1).getRound().getWord().c_str());
+ str = wxU(m_game.getHistory().getTurn(numline -
1).getMove().getRound().getWord().c_str());
DRW(2);
}
// pos
DIM(3);
if ((numline > 0) && (numline <= NRounds))
{
- str = wxU(m_game.getHistory().getTurn(numline -
1).getRound().getCoord().toString().c_str());
+ str = wxU(m_game.getHistory().getTurn(numline -
1).getMove().getRound().getCoord().toString().c_str());
DRW(3);
}
// pts
@@ -191,7 +191,7 @@
if ((numline > 0) && (numline <= NRounds))
{
str = wxT("");
- str << m_game.getHistory().getTurn(numline - 1).getRound().getPoints();
+ str << m_game.getHistory().getTurn(numline -
1).getMove().getRound().getPoints();
DRW(4);
}
// total points
Index: wxwin/searchpanel.cc
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/searchpanel.cc,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- wxwin/searchpanel.cc 22 Jan 2006 12:23:53 -0000 1.15
+++ wxwin/searchpanel.cc 8 Jan 2008 13:52:43 -0000 1.16
@@ -29,7 +29,6 @@
#include "ewx.h"
#include "dic.h"
-#include "dic_search.h"
#include "regexp.h"
#include "searchpanel.h"
#include "tile.h"
@@ -55,7 +54,7 @@
{
protected:
ConfigDB config;
- Dictionary dic;
+ const Dictionary *dic;
wxTextCtrl *t;
wxListBox *l;
wxBoxSizer *sizer;
@@ -65,9 +64,9 @@
void panel_build();
virtual void panel_options() = 0;
public:
- SimpleSearchPanel(wxWindow* parent, int id, Dictionary d) :
wxPanel(parent,id) { dic = d; };
- virtual void compute_char(wxCommandEvent&) {};
- virtual void compute_enter(wxCommandEvent&) {};
+ SimpleSearchPanel(wxWindow* parent, int id, const Dictionary &d) :
wxPanel(parent,id) { dic = &d; }
+ virtual void compute_char(wxCommandEvent&) {}
+ virtual void compute_enter(wxCommandEvent&) {}
DECLARE_EVENT_TABLE()
};
@@ -105,7 +104,7 @@
if (dic == NULL)
{
l->Clear();
- msg << wxT("Pas de dictionnaire");
+ msg << _("No dictionary");
l->Append(msg);
return 0;
}
@@ -117,7 +116,7 @@
{
if (l->GetCount() == 0)
{
- l->Append(wxT("Aucun resultat"));
+ l->Append(_("No result"));
}
}
@@ -128,40 +127,40 @@
class PCross : public SimpleSearchPanel
{
protected:
- virtual void panel_options() {};
+ virtual void panel_options() {}
public:
- void compute_char(wxCommandEvent&) { };
+ void compute_char(wxCommandEvent&) {}
void compute_enter(wxCommandEvent&);
- PCross(wxWindow* parent, int id, Dictionary d) :
SimpleSearchPanel(parent,id,d) { panel_build(); };
+ PCross(wxWindow* parent, int id, const Dictionary &d) :
SimpleSearchPanel(parent,id,d) { panel_build(); }
};
void
PCross::compute_enter(wxCommandEvent&)
{
- int i;
- wchar_t rack[DIC_WORD_MAX];
- wchar_t buff[RES_CROS_MAX][DIC_WORD_MAX];
-
if (!check_dic())
return;
if (t->GetValue().Len() >= DIC_WORD_MAX)
{
- wxString msg = wxT("");
-// XXX: msg << wxT("La recherche est limitée à ") << DIC_WORD_MAX - 1 <<
wxT(" lettres");
- msg << wxT("La recherche est limitee a ") << DIC_WORD_MAX - 1 << wxT("
lettres");
+ wxString msg;
+ msg.Printf(_("The search is limited to %d letters"), DIC_WORD_MAX - 1);
l->Append(msg);
return;
}
+ wchar_t rack[DIC_WORD_MAX];
wcsncpy(rack, t->GetValue().wc_str(), DIC_WORD_MAX);
- Dic_search_Cros(dic,rack,buff);
+
+ list<wstring> wordList;
+ dic->searchCross(rack, wordList);
int resnum = 0;
- wxString res[RES_CROS_MAX];
- for(i=0; i < RES_CROS_MAX && buff[i][0]; i++)
- res[resnum++] = wxU(buff[i]);
+ wxString *res = new wxString[wordList.size()];
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
+ res[resnum++] = wxU(it->c_str());
l->Set(resnum,res);
+ delete[] res;
check_end();
}
@@ -172,45 +171,55 @@
class PPlus1 : public SimpleSearchPanel
{
protected:
- virtual void panel_options() {};
+ virtual void panel_options() {}
public:
- void compute_char(wxCommandEvent&) { };
+ void compute_char(wxCommandEvent&) {}
void compute_enter(wxCommandEvent&);
- PPlus1(wxWindow* parent, int id, Dictionary dic) :
SimpleSearchPanel(parent,id,dic) { panel_build(); };
+ PPlus1(wxWindow* parent, int id, const Dictionary &dic) :
SimpleSearchPanel(parent,id,dic) { panel_build(); }
};
void
PPlus1::compute_enter(wxCommandEvent&)
{
- int i,j;
- wchar_t rack[DIC_WORD_MAX];
- wchar_t buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
-
if (!check_dic())
return;
if (t->GetValue().Len() >= DIC_WORD_MAX)
{
- wxString msg = wxT("");
-// XXX: msg << wxT("La recherche est limitée à ") << DIC_WORD_MAX - 1 <<
wxT(" lettres");
- msg << wxT("La recherche est limitee a ") << DIC_WORD_MAX - 1 << wxT("
lettres");
+ wxString msg;
+ msg.Printf(_("The search is limited to %d letters"), DIC_WORD_MAX - 1);
l->Append(msg);
return;
}
- wcsncpy(rack, t->GetValue().wc_str(), DIC_WORD_MAX);
- Dic_search_7pl1(dic,rack,buff,TRUE);
+ wstring rack = t->GetValue().wc_str();
+ map<wchar_t, list<wstring> > wordList;
+ dic->search7pl1(rack, wordList, true);
+ // Count the results
+ int sum = 0;
+ map<wchar_t, list<wstring> >::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
+ {
+ if (it->first)
+ sum += 1;
+ sum += it->second.size();
+ }
+
+ wxString *res = new wxString[sum];
int resnum = 0;
- wxString res[DIC_LETTERS*(RES_7PL1_MAX+1)];
- for(i=0; i < DIC_LETTERS; i++)
+ for (it = wordList.begin(); it != wordList.end(); it++)
+ {
+ if (it->first)
+ res[resnum++] = wxString(wxT("+")) + wxU((wxString)it->first);
+ list<wstring>::const_iterator itWord;
+ for (itWord = it->second.begin(); itWord != it->second.end(); itWord++)
{
- if (i && buff[i][0][0])
- res[resnum++] = wxString(wxT("+")) + (wxChar)(i+'A'-1);
- for(j=0; j < RES_7PL1_MAX && buff[i][j][0]; j++)
- res[resnum++] = wxString(wxT(" ")) + wxU(buff[i][j]);
+ res[resnum++] = wxString(wxT(" ")) + wxU(itWord->c_str());
}
- l->Set(resnum,res);
+ }
+ l->Set(resnum, res);
+ delete[] res;
check_end();
}
@@ -228,9 +237,9 @@
virtual void build_letter_lists();
virtual void panel_options();
public:
- void compute_char(wxCommandEvent&) { };
+ void compute_char(wxCommandEvent&) {}
void compute_enter(wxCommandEvent&);
- PRegExp(wxWindow* parent, int id, Dictionary d) :
SimpleSearchPanel(parent,id,d) { panel_build(); };
+ PRegExp(wxWindow* parent, int id, const Dictionary &d) :
SimpleSearchPanel(parent,id,d) { panel_build(); }
};
void
@@ -261,8 +270,8 @@
memset(llist.letters[i],0,sizeof(llist.letters[i]));
}
- const std::list<Tile>& allTiles = Tile::getAllTiles();
- std::list<Tile>::const_iterator it;
+ const std::vector<Tile>& allTiles = dic->getAllTiles();
+ std::vector<Tile>::const_iterator it;
for (it = allTiles.begin(); it != allTiles.end(); it++)
{
if (! it->isJoker() && ! it->isEmpty())
@@ -289,9 +298,9 @@
wxStaticText *otmin;
wxStaticText *otmax;
- otmin = new wxStaticText(this,wxID_ANY,wxT("Longueur min."));
- omin = new wxTextCtrl(this,ID_OPTION1,wxT(
"1"),wxDefaultPosition,wxDefaultSize,wxTE_PROCESS_ENTER);
- otmax = new wxStaticText(this,wxID_ANY,wxT("max."));
+ otmin = new wxStaticText(this,wxID_ANY,_("Minimum length"));
+ omin = new
wxTextCtrl(this,ID_OPTION1,wxT("1"),wxDefaultPosition,wxDefaultSize,wxTE_PROCESS_ENTER);
+ otmax = new wxStaticText(this,wxID_ANY,_("Maximum length"));
omax = new
wxTextCtrl(this,ID_OPTION2,wxT("15"),wxDefaultPosition,wxDefaultSize,wxTE_PROCESS_ENTER);
wxBoxSizer *s = new wxBoxSizer( wxHORIZONTAL );
@@ -308,15 +317,13 @@
void
PRegExp::compute_enter(wxCommandEvent&)
{
- wchar_t re[DIC_RE_MAX];
- wchar_t buff[RES_REGE_MAX][DIC_WORD_MAX];
-
if (!check_dic())
return;
build_letter_lists();
- wcsncpy(re, t->GetValue().wc_str(),DIC_RE_MAX);
- debug("PRegExp::compute_enter for %ls",re);
+
+ wstring regexp = t->GetValue().wc_str();
+ debug("PRegExp::compute_enter for %ls", regexp.c_str());
int lmin = atoi((const char*)omin->GetValue().mb_str());
int lmax = atoi((const char*)omax->GetValue().mb_str());
@@ -334,14 +341,18 @@
}
debug("\n");
- Dic_search_RegE(dic,re,buff,&llist);
+ list<wstring> wordList;
+ dic->searchRegExp(regexp, wordList, &llist);
+ wxString *res = new wxString[wordList.size()];
int resnum = 0;
- wxString res[RES_REGE_MAX];
- for(int i=0; i < RES_REGE_MAX && buff[i][0]; i++)
- res[resnum++] = wxU(buff[i]);
-
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
+ {
+ res[resnum++] = wxU(it->c_str());
+ }
l->Set(resnum,res);
+ delete[] res;
check_end();
}
@@ -349,12 +360,12 @@
// ************************************************************
// ************************************************************
-SearchPanel::SearchPanel(wxFrame *parent, Dictionary dic) :
+SearchPanel::SearchPanel(wxFrame *parent, const Dictionary &dic) :
wxNotebook(parent, -1)
{
- AddPage(new PCross (this,ID_PANEL_CROSS ,dic),wxT("Mots croises"));
- AddPage(new PPlus1 (this,ID_PANEL_PLUS1 ,dic),wxT("Plus 1"));
- AddPage(new PRegExp(this,ID_PANEL_REGEXP,dic),wxT("Exp. Rationnelle"));
+ AddPage(new PCross (this,ID_PANEL_CROSS ,dic), _("Cross words"));
+ AddPage(new PPlus1 (this,ID_PANEL_PLUS1 ,dic), _("Plus 1"));
+ AddPage(new PRegExp(this,ID_PANEL_REGEXP,dic), _("Regular expressions"));
SetSelection(2);
}
Index: wxwin/searchpanel.h
===================================================================
RCS file: /cvsroot/eliot/eliot/wxwin/searchpanel.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- wxwin/searchpanel.h 26 Dec 2005 12:23:17 -0000 1.4
+++ wxwin/searchpanel.h 8 Jan 2008 13:52:43 -0000 1.5
@@ -33,7 +33,7 @@
class SearchPanel : public wxNotebook
{
public:
- SearchPanel(wxFrame*, Dictionary);
+ SearchPanel(wxFrame*, const Dictionary&);
~SearchPanel();
};
Index: dic/automaton.cpp
===================================================================
RCS file: dic/automaton.cpp
diff -N dic/automaton.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/automaton.cpp 8 Jan 2008 13:52:33 -0000 1.2
@@ -0,0 +1,603 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file automaton.c
+ * \brief (Non)Deterministic Finite AutomatonHelper for Regexp
+ * \author Antoine Fraboulet
+ * \date 2005
+ */
+
+#include "config.h"
+
+#include <set>
+#include <list>
+#include <cassert>
+#include <cstring>
+#include <cstdlib>
+#include <cstdio>
+#include <sys/types.h>
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#include <unistd.h>
+
+#include "dic.h"
+#include "regexp.h"
+#include "automaton.h"
+
+using namespace std;
+
+#ifdef DEBUG_AUTOMATON
+# define DMSG(a) (a)
+#else
+# define DMSG(a)
+#endif
+
+#define MAX_TRANSITION_LETTERS 256
+
+typedef struct automaton_state_t *astate;
+
+
+/* ************************************************** *
+ Helper class, allowing to build a NFA, then a DFA
+ * ************************************************** */
+
+class AutomatonHelper
+{
+public:
+ AutomatonHelper(astate iInitState);
+ ~AutomatonHelper();
+
+ astate getInitState() const { return m_initState; }
+#ifdef DEBUG_AUTOMATON
+ void dump(const string &iFileName) const;
+#endif
+
+ static AutomatonHelper *ps2nfa(int iInitState, int *ptl, int *PS);
+ static AutomatonHelper *nfa2dfa(const AutomatonHelper &iNfa,
+ struct search_RegE_list_t *iList);
+
+ /// List of states
+ list<astate> m_states;
+
+private:
+ /// Initial state of the automaton
+ astate m_initState;
+
+ void addState(astate s);
+ astate getState(const set<int> &iId) const;
+ void printNodes(FILE* f) const;
+ void printEdges(FILE* f) const;
+ void setAccept(astate s) const;
+ set<int> getSuccessor(const set<int> &S, int letter, struct
search_RegE_list_t *iList) const;
+};
+
+
+/* ************************************************** *
+ State handling
+ * ************************************************** */
+
+static set<int> s_state_id_create(int id);
+static string s_state_id_to_str(const set<int> &iId);
+static astate s_state_create (const set<int> &iId);
+
+struct automaton_state_t
+{
+ set<int> id;
+ int accept;
+ int id_static;
+ astate next[MAX_TRANSITION_LETTERS];
+};
+
+
+/* ************************************************** *
+ Definition of the Automaton class
+ * ************************************************** */
+
+Automaton::Automaton(int iInitState, int *ptl, int *PS, struct
search_RegE_list_t *iList)
+{
+ AutomatonHelper *nfa = AutomatonHelper::ps2nfa(iInitState, ptl, PS);
+ DMSG(printf("\n non deterministic automaton OK \n\n"));
+ DMSG(nfa->dump("auto_nfa"));
+
+ AutomatonHelper *dfa = AutomatonHelper::nfa2dfa(*nfa, iList);
+ DMSG(printf("\n deterministic automaton OK \n\n"));
+ DMSG(dfa->dump("auto_dfa"));
+
+ finalize(*dfa);
+ DMSG(printf("\n final automaton OK \n\n"));
+ DMSG(automaton_dump("auto_fin"));
+
+ delete nfa;
+ delete dfa;
+}
+
+
+Automaton::~Automaton()
+{
+ delete[] m_acceptors;
+ for (int i = 0; i <= m_nbStates; i++)
+ {
+ delete[] m_transitions[i];
+ }
+ delete[] m_transitions;
+}
+
+
+void Automaton::finalize(const AutomatonHelper &iHelper)
+{
+ /* Creation */
+ m_nbStates = iHelper.m_states.size();
+ m_acceptors = new bool[m_nbStates + 1];
+ memset(m_acceptors, 0, (m_nbStates + 1) * sizeof(bool));
+ m_transitions = new int*[m_nbStates + 1];
+ for (int i = 0; i <= m_nbStates; i++)
+ {
+ m_transitions[i] = new int[MAX_TRANSITION_LETTERS];
+ memset(m_transitions[i], 0, MAX_TRANSITION_LETTERS * sizeof(int));
+ }
+
+ /* Create new id for states */
+ list<astate>::const_iterator it;
+ int i;
+ for (i = 1, it = iHelper.m_states.begin();
+ it != iHelper.m_states.end(); it++, i++)
+ {
+ (*it)->id_static = i;
+ }
+
+ /* Build new automaton */
+ for (it = iHelper.m_states.begin(); it != iHelper.m_states.end(); it++)
+ {
+ astate s = *it;
+ int i = s->id_static;
+
+ if (s == iHelper.getInitState())
+ m_init = i;
+ if (s->accept == 1)
+ m_acceptors[i] = true;
+
+ for (int l = 0; l < MAX_TRANSITION_LETTERS; l++)
+ {
+ if (s->next[l])
+ m_transitions[i][l] = s->next[l]->id_static;
+ }
+ }
+}
+
+
+void Automaton::dump(const string &iFileName) const
+{
+ FILE *f = fopen(iFileName.c_str(), "w");
+ fprintf(f, "digraph automaton {\n");
+ for (int i = 1; i <= m_nbStates; i++)
+ {
+ fprintf(f, "\t%d [label = \"%d\"", i, i);
+ if (i == m_init)
+ fprintf(f, ", style = filled, color=lightgrey");
+ if (accept(i))
+ fprintf(f, ", shape = doublecircle");
+ fprintf(f, "];\n");
+ }
+ fprintf(f, "\n");
+ for (int i = 1; i <= m_nbStates; i++)
+ {
+ for (int l = 0; l < MAX_TRANSITION_LETTERS; l++)
+ {
+ if (m_transitions[i][l])
+ {
+ fprintf(f, "\t%d -> %d [label = \"", i, m_transitions[i][l]);
+ regexp_print_letter(f, l);
+ fprintf(f, "\"];\n");
+ }
+ }
+ }
+ fprintf(f, "fontsize=20;\n");
+ fprintf(f, "}\n");
+ fclose(f);
+
+#ifdef HAVE_SYS_WAIT_H
+ pid_t pid = fork ();
+ if (pid > 0)
+ {
+ wait(NULL);
+ }
+ else if (pid == 0)
+ {
+ execlp("dotty", "dotty", iFileName.c_str(), NULL);
+ printf("exec dotty failed\n");
+ exit(1);
+ }
+#endif
+}
+
+
+/* ************************************************** *
+ Definition of the state handling methods
+ * ************************************************** */
+
+static set<int> s_state_id_create(int id)
+{
+ set<int> l;
+ l.insert(id);
+ return l;
+}
+
+
+static string s_state_id_to_str(const set<int> &iId)
+{
+ string s;
+ set<int>::const_iterator it;
+ for (it = iId.begin(); it != iId.end(); it++)
+ {
+ char tmp[50];
+ sprintf(tmp, "%d ", *it);
+ s += tmp;
+ }
+ return s;
+}
+
+
+static astate s_state_create(const set<int> &iId)
+{
+ astate s = new automaton_state_t();
+ // TODO: use copy constructor
+ s->id = iId;
+ s->accept = 0;
+ memset(s->next, 0, sizeof(astate)*MAX_TRANSITION_LETTERS);
+ DMSG(printf("** state %s creation\n", s_state_id_to_str(iId).c_str()));
+ return s;
+}
+
+
+/* ************************************************** *
+ Definition of the AutomatonHelper class
+ * ************************************************** */
+
+AutomatonHelper::AutomatonHelper(astate iInitState)
+ : m_initState(iInitState)
+{
+}
+
+
+AutomatonHelper::~AutomatonHelper()
+{
+ list<astate>::const_iterator it;
+ for (it = m_states.begin(); it != m_states.end(); it++)
+ {
+ delete *it;
+ }
+}
+
+
+void AutomatonHelper::addState(astate s)
+{
+ m_states.push_front(s);
+ DMSG(printf("** state %s added to automaton\n",
s_state_id_to_str(s->id).c_str()));
+}
+
+
+astate AutomatonHelper::getState(const set<int> &iId) const
+{
+ list<astate>::const_iterator it;
+ for (it = m_states.begin(); it != m_states.end(); it++)
+ {
+ astate s = *it;
+ if (s->id == iId)
+ {
+ //DMSG(printf("** get state %s ok\n",
s_state_id_to_str(s->id).c_str()));
+ return s;
+ }
+ }
+ return NULL;
+}
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
+AutomatonHelper *AutomatonHelper::ps2nfa(int init_state_id, int *ptl, int *PS)
+{
+ int maxpos = PS[0];
+ astate current_state;
+ char used_letter[MAX_TRANSITION_LETTERS];
+
+
+ /* 1: init_state = root->PP */
+ set<int> temp_id0 = s_state_id_create(init_state_id);
+ astate temp_state = s_state_create(temp_id0);
+ AutomatonHelper *nfa = new AutomatonHelper(temp_state);
+ nfa->addState(temp_state);
+ list<astate> L;
+ L.push_front(temp_state);
+ /* 2: while \exist state \in state_list */
+ while (! L.empty())
+ {
+ current_state = L.front();
+ L.pop_front();
+ DMSG(printf("** current state = %s\n",
s_state_id_to_str(current_state->id).c_str()));
+ memset(used_letter, 0, sizeof(used_letter));
+ /* 3: \foreach l in \sigma | l \neq # */
+ for (int p = 1; p < maxpos; p++)
+ {
+ int current_letter = ptl[p];
+ if (used_letter[current_letter] == 0)
+ {
+ /* 4: int set = \cup { PS(pos) | pos \in state \wedge pos == l
} */
+ int ens = 0;
+ for (int pos = 1; pos <= maxpos; pos++)
+ {
+ if (ptl[pos] == current_letter &&
+ (unsigned int)*(current_state->id.begin()) & (1 <<
(pos - 1)))
+ ens |= PS[pos];
+ }
+ /* 5: transition from current_state to temp_state */
+ if (ens)
+ {
+ set<int> temp_id = s_state_id_create(ens);
+ temp_state = nfa->getState(temp_id);
+ if (temp_state == NULL)
+ {
+ temp_state = s_state_create(temp_id);
+ nfa->addState(temp_state);
+ current_state->next[current_letter] = temp_state;
+ L.push_front(temp_state);
+ }
+ else
+ {
+ current_state->next[current_letter] = temp_state;
+ }
+ }
+ used_letter[current_letter] = 1;
+ }
+ }
+ }
+
+ list<astate>::const_iterator it;
+ for (it = nfa->m_states.begin(); it != nfa->m_states.end(); it++)
+ {
+ astate s = *it;
+ if (*(s->id.begin()) & (1 << (maxpos - 1)))
+ s->accept = 1;
+ }
+
+ return nfa;
+}
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
+set<int> AutomatonHelper::getSuccessor(const set<int> &S,
+ int letter,
+ struct search_RegE_list_t *iList) const
+{
+ set<int> R, r;
+ set<int>::const_iterator it;
+ for (it = S.begin(); it != S.end(); it++) /* \forall y \in
S */
+ {
+ astate y, z;
+
+ set<int> t = s_state_id_create(*it);
+ assert(y = getState(t));
+
+ set<int> Ry; /* Ry = \empty
*/
+
+ if ((z = y->next[letter]) != NULL) /* \delta (y,z) =
l */
+ {
+ r = getSuccessor(z->id, RE_EPSILON, iList);
+ Ry.insert(r.begin(), r.end());
+ Ry.insert(z->id.begin(), z->id.end()); /* Ry = Ry \cup succ(z)
*/
+ }
+
+ /* \epsilon transition from start node */
+ if ((z = y->next[RE_EPSILON]) != NULL) /* \delta (y,z) =
\epsilon */
+ {
+ r = getSuccessor(z->id, letter, iList);
+ Ry.insert(r.begin(), r.end()); /* Ry = Ry \cup succ(z) */
+ }
+
+ if (letter < RE_FINAL_TOK)
+ {
+ for (int i = 0; i < DIC_SEARCH_REGE_LIST; i++)
+ {
+ if (iList->valid[i])
+ {
+ if (iList->letters[i][letter] && (z =
y->next[(int)iList->symbl[i]]) != NULL)
+ {
+ DMSG(printf("*** letter "));
+ DMSG(regexp_print_letter(stdout, letter));
+ DMSG(printf("is in "));
+ DMSG(regexp_print_letter(stdout, i));
+
+ r = getSuccessor(z->id, RE_EPSILON, iList);
+ Ry.insert(r.begin(), r.end());
+ Ry.insert(z->id.begin(), z->id.end());
+ }
+ }
+ }
+ }
+
+#if 0
+ if (alist_is_empty(Ry)) /* Ry = \empty
*/
+ return Ry;
+#endif
+
+ R.insert(Ry.begin(), Ry.end()); /* R = R \cup Ry
*/
+ }
+
+ return R;
+}
+
+
+void AutomatonHelper::setAccept(astate s) const
+{
+ DMSG(printf("=== setting accept for node (%s) :",
s_state_id_to_str(s->id).c_str()));
+ list<astate>::const_iterator it;
+ for (it = m_states.begin(); it != m_states.end(); it++)
+ {
+ astate ns = *it;
+ int idx = *(ns->id.begin());
+ DMSG(printf("%s ", s_state_id_to_str(ns->id).c_str()));
+ if (ns->accept && (find(s->id.begin(), s->id.end(), idx) !=
s->id.end()))
+ {
+ DMSG(printf("(ok) "));
+ s->accept = 1;
+ }
+ }
+ DMSG(printf("\n"));
+}
+
+
+AutomatonHelper *AutomatonHelper::nfa2dfa(const AutomatonHelper &iNfa,
+ struct search_RegE_list_t *iList)
+{
+ astate current_state;
+
+ list<astate> L;
+
+ // Clone the list
+ set<int> temp_id0 = iNfa.m_initState->id;
+ astate temp_state = s_state_create(temp_id0);
+ AutomatonHelper *dfa = new AutomatonHelper(temp_state);
+ dfa->addState(temp_state);
+ L.push_front(temp_state);
+ while (! L.empty())
+ {
+ current_state = L.front();
+ L.pop_front();
+ DMSG(printf("** current state = %s\n",
s_state_id_to_str(current_state->id).c_str()));
+ for (int letter = 1; letter < DIC_LETTERS; letter++)
+ {
+ // DMSG(printf("*** start successor of %s\n",
s_state_id_to_str(current_state->id).c_str()));
+
+ set<int> temp_id = iNfa.getSuccessor(current_state->id, letter,
iList);
+
+ if (! temp_id.empty())
+ {
+
+ DMSG(printf("*** successor of %s for ",
s_state_id_to_str(current_state->id).c_str()));
+ DMSG(regexp_print_letter(stdout, letter));
+ DMSG(printf(" = %s\n", s_state_id_to_str(temp_id).c_str()));
+
+ temp_state = dfa->getState(temp_id);
+
+ // DMSG(printf("*** automaton get state -%s- ok\n",
s_state_id_to_str(temp_id).c_str()));
+
+ if (temp_state == NULL)
+ {
+ temp_state = s_state_create(temp_id);
+ dfa->addState(temp_state);
+ current_state->next[letter] = temp_state;
+ L.push_front(temp_state);
+ }
+ else
+ {
+ current_state->next[letter] = temp_state;
+ }
+ }
+ }
+ }
+
+ list<astate>::const_iterator it;
+ for (it = dfa->m_states.begin(); it != dfa->m_states.end(); it++)
+ {
+ iNfa.setAccept(*it);
+ }
+
+ return dfa;
+}
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
+void AutomatonHelper::printNodes(FILE* f) const
+{
+ list<astate>::const_iterator it;
+ for (it = m_states.begin(); it != m_states.end(); it++)
+ {
+ astate s = *it;
+ string sid = s_state_id_to_str(s->id);
+ fprintf(f, "\t\"%s\" [label = \"%s\"", sid.c_str(), sid.c_str());
+ if (s == m_initState)
+ {
+ fprintf(f, ", style = filled, color=lightgrey");
+ }
+ if (s->accept)
+ {
+ fprintf(f, ", shape = doublecircle");
+ }
+ fprintf(f, "];\n");
+ }
+ fprintf(f, "\n");
+}
+
+
+void AutomatonHelper::printEdges(FILE* f) const
+{
+ list<astate>::const_iterator it;
+ for (it = m_states.begin(); it != m_states.end(); it++)
+ {
+ astate s = *it;
+ for (int letter = 0; letter < 255; letter++)
+ {
+ if (s->next[letter])
+ {
+ string sid = s_state_id_to_str(s->id);
+ fprintf(f, "\t\"%s\" -> ", sid.c_str());
+ sid = s_state_id_to_str(s->next[letter]->id);
+ fprintf(f, "\"%s\" [label = \"", sid.c_str());
+ regexp_print_letter(f, letter);
+ fprintf(f, "\"];\n");
+ }
+ }
+ }
+}
+
+
+#ifdef DEBUG_AUTOMATON
+void AutomatonHelper::dump(const string &iFileName) const
+{
+ FILE *f = fopen(iFileName.c_str(), "w");
+ fprintf(f, "digraph automaton {\n");
+ printNodes(f);
+ printEdges(f);
+ fprintf(f, "fontsize=20;\n");
+ fprintf(f, "}\n");
+ fclose(f);
+
+#ifdef HAVE_SYS_WAIT_H
+ pid_t pid = fork();
+ if (pid > 0)
+ {
+ wait(NULL);
+ }
+ else if (pid == 0)
+ {
+ execlp("dotty", "dotty", iFileName.c_str(), NULL);
+ printf("exec dotty failed\n");
+ exit(1);
+ }
+#endif
+}
+#endif
+
Index: dic/compdic.cpp
===================================================================
RCS file: dic/compdic.cpp
diff -N dic/compdic.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/compdic.cpp 8 Jan 2008 13:52:33 -0000 1.2
@@ -0,0 +1,563 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file compdic.c
+ * \brief Program used to compress a dictionary
+ * \author Antoine Fraboulet
+ * \date 1999
+ */
+
+#include "config.h"
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+#include <vector>
+#include <map>
+#include <boost/tokenizer.hpp>
+#include <getopt.h>
+#include <ctime>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <cwctype>
+#include <cstdlib>
+#include <cstdio>
+#include <cerrno>
+#include <cstring>
+
+// For ntohl & Co.
+#ifdef WIN32
+# include <winsock2.h>
+#else
+# if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+# endif
+# if HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+# endif
+#endif
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext(String)
+#else
+# define _(String) String
+#endif
+
+#include "hashtable.h"
+#include "encoding.h"
+#include "header.h"
+#include "dic_internals.h"
+#include "dic_exception.h"
+
+using namespace std;
+
+//#define DEBUG_LIST
+//#define DEBUG_OUTPUT
+//#define DEBUG_OUTPUT_L2
+#define CHECK_RECURSION
+
+
+const wchar_t* load_uncompressed(const string &iFileName, unsigned int
&ioDicSize)
+{
+ ifstream file(iFileName.c_str());
+ if (!file.is_open())
+ throw DicException("Could not open file " + iFileName);
+
+ // Place the buffer in a vector to avoid worrying about memory handling
+ vector<char> buffer(ioDicSize);
+ // Load the file data, everything in one shot
+ file.read(&buffer.front(), ioDicSize);
+ file.close();
+
+ // Buffer for the wide characters (it will use at most as many characters
+ // as the utf-8 version)
+ wchar_t *wideBuf = new wchar_t[ioDicSize];
+ unsigned int number;
+
+ try
+ {
+ number = readFromUTF8(wideBuf, ioDicSize, &buffer.front(),
+ ioDicSize, "load_uncompressed");
+ ioDicSize = number;
+ return wideBuf;
+ }
+ catch (...)
+ {
+ // Avoid leaks, and propagate the exception
+ delete[] wideBuf;
+ throw;
+ }
+}
+
+
+void readLetters(const char *iFileName, DictHeaderInfo &ioHeaderInfo)
+{
+ ifstream in(iFileName);
+ if (!in.is_open())
+ throw DicException("Could not open file " + string(iFileName));
+
+ // Use a more friendly type name
+ typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
+
+ int lineNb = 1;
+ string line;
+ while (getline(in, line))
+ {
+ // Split the lines on space characters
+ vector<string> tokens;
+ boost::char_separator<char> sep(" ");
+ Tokenizer tok(line, sep);
+ Tokenizer::iterator it;
+ for (it = tok.begin(); it != tok.end(); ++it)
+ {
+ tokens.push_back(*it);
+ }
+
+ // Ignore empty lines
+ if (tokens.empty())
+ continue;
+
+ // We expect 5 fields on the line, and the first one is a letter, so
+ // it cannot exceed 4 bytes
+ if (tokens.size() != 5 || tokens[0].size() > 4)
+ {
+ ostringstream ss;
+ ss << "readLetters: Invalid line in " << iFileName;
+ ss << " (line " << lineNb;
+ throw DicException(ss.str());
+ }
+
+#define MAX_SIZE 4
+ char buff[MAX_SIZE];
+ strncpy(buff, tokens[0].c_str(), MAX_SIZE);
+
+ wstring letter = readFromUTF8(buff, tokens[0].size(), "readLetters");
+
+ if (letter.size() != 1)
+ {
+ ostringstream ss;
+ ss << "readLetters: Invalid letter at line " << lineNb;
+ throw DicException(ss.str());
+ }
+#undef MAX_SIZE
+
+ ioHeaderInfo.letters += towupper(letter[0]);
+
+ ioHeaderInfo.points.push_back(atoi(tokens[1].c_str()));
+ ioHeaderInfo.frequency.push_back(atoi(tokens[2].c_str()));
+ ioHeaderInfo.vowels.push_back(atoi(tokens[3].c_str()));
+ ioHeaderInfo.consonants.push_back(atoi(tokens[4].c_str()));
+
+ ++lineNb;
+ }
+}
+
+
+Header skip_init_header(ostream &outfile, DictHeaderInfo &ioHeaderInfo)
+{
+ ioHeaderInfo.root = 0;
+ ioHeaderInfo.nwords = 0;
+ ioHeaderInfo.nodesused = 1;
+ ioHeaderInfo.edgesused = 1;
+ ioHeaderInfo.nodessaved = 0;
+ ioHeaderInfo.edgessaved = 0;
+
+ Header aHeader(ioHeaderInfo);
+ aHeader.write(outfile);
+ return aHeader;
+}
+
+
+void fix_header(ostream &outfile, DictHeaderInfo &ioHeaderInfo)
+{
+ ioHeaderInfo.root = ioHeaderInfo.edgesused;
+ // Go back to the beginning of the stream to overwrite the header
+ outfile.seekp(0, ios::beg);
+#if defined(WORDS_BIGENDIAN)
+#warning "**********************************************"
+#warning "compdic does not run yet on bigendian machines"
+#warning "**********************************************"
+#else
+ Header aHeader(ioHeaderInfo);
+ aHeader.write(outfile);
+#endif
+}
+
+
+// Change endianness of the pointes edges, and write them to the given ostream
+void write_node(uint32_t *ioEdges, unsigned int num, ostream &outfile)
+{
+ // Handle endianness
+ for (unsigned int i = 0; i < num; ++i)
+ {
+ ioEdges[i] = htonl(ioEdges[i]);
+ }
+
+#ifdef DEBUG_OUTPUT
+ printf("writing %d edges\n", num);
+ for (int i = 0; i < num; i++)
+ {
+#ifdef DEBUG_OUTPUT_L2
+ printf("ptr=%2d t=%d l=%d chr=%2d (%c)\n",
+ ioEdges[i].ptr, ioEdges[i].term, ioEdges[i].last,
+ ioEdges[i].chr, ioEdges[i].chr -1 +'a');
+#endif
+ outfile.write((char*)(ioEdges + i), sizeof(DicEdge));
+ }
+#else
+ outfile.write((char*)ioEdges, num * sizeof(DicEdge));
+#endif
+}
+
+#define MAX_STRING_LENGTH 200
+
+
+#define MAX_EDGES 2000
+/* ods3: ?? */
+/* ods4: 1746 */
+
+// Hashing function for a vector of DicEdge, based on the hashing function
+// of the HashTable
+struct HashVector
+{
+ unsigned int operator()(const vector<DicEdge> &iKey) const
+ {
+ if (iKey.empty())
+ return 0;
+ return HashPtr(&iKey.front(), iKey.size() * sizeof(DicEdge));
+ }
+};
+
+#ifdef CHECK_RECURSION
+class IncDec
+{
+ public:
+ IncDec(int &ioCounter)
+ : m_counter(ioCounter)
+ {
+ m_counter++;
+ }
+
+ ~IncDec()
+ {
+ m_counter--;
+ }
+ private:
+ int &m_counter;
+};
+
+int current_rec = 0;
+int max_rec = 0;
+#endif
+
+/* global variables */
+HashTable<vector<DicEdge>, unsigned int, HashVector> *global_hashtable;
+
+wchar_t global_stringbuf[MAX_STRING_LENGTH]; /* Space for current string */
+wchar_t* global_endstring; /* Marks END of current string */
+const wchar_t* global_input;
+const wchar_t* global_endofinput;
+#ifdef CHECK_RECURSION
+map<int, vector<DicEdge> > global_mapfordepth;
+#endif
+
+/**
+ * Makenode takes a prefix (as position relative to stringbuf) and
+ * returns an index of the start node of a dawg that recognizes all
+ * words beginning with that prefix. String is a pointer (relative
+ * to stringbuf) indicating how much of iPrefix is matched in the
+ * input.
+ * @param iPrefix: prefix to work on
+ * @param outfile: stream where to write the nodes
+ * @param ioHeaderInfo: information needed to build the final header, updated
+ * during the processing
+ * @param iHeader: temporary header, used only to do the conversion between
+ * the (wide) chars and their corresponding internal code
+ */
+unsigned int makenode(const wchar_t *iPrefix, ostream &outfile,
+ DictHeaderInfo &ioHeaderInfo, const Header &iHeader)
+{
+#ifdef CHECK_RECURSION
+ IncDec inc(current_rec);
+ if (current_rec > max_rec)
+ max_rec = current_rec;
+#endif
+
+#ifdef CHECK_RECURSION
+ // Instead of creating a vector, try to reuse an existing one
+ vector<DicEdge> &edges = global_mapfordepth[current_rec];
+ edges.reserve(MAX_EDGES);
+ edges.clear();
+#else
+ vector<DicEdge> edges;
+ // Optimize allocation
+ edges.reserve(MAX_EDGES);
+#endif
+ DicEdge newEdge;
+
+ while (iPrefix == global_endstring)
+ {
+ // More edges out of node
+ newEdge.ptr = 0;
+ newEdge.term = 0;
+ newEdge.last = 0;
+ newEdge.chr = iHeader.getCodeFromChar(*global_endstring++ =
*global_input++);
+ edges.push_back(newEdge);
+
+ // End of a word?
+ if (*global_input == L'\n' || *global_input == L'\r')
+ {
+ ioHeaderInfo.nwords++;
+ *global_endstring = L'\0';
+ // Mark edge as word
+ edges.back().term = 1;
+
+ // Skip \r and/or \n
+ while (global_input != global_endofinput &&
+ (*global_input == L'\n' || *global_input == L'\r'))
+ {
+ ++global_input;
+ }
+ // At the end of input?
+ if (global_input == global_endofinput)
+ break;
+
+ global_endstring = global_stringbuf;
+ while (*global_endstring == *global_input)
+ {
+ global_endstring++;
+ global_input++;
+ }
+ }
+ // Make dawg pointed to by this edge
+ edges.back().ptr =
+ makenode(iPrefix + 1, outfile, ioHeaderInfo, iHeader);
+ }
+
+ int numedges = edges.size();
+ if (numedges == 0)
+ {
+ // Special node zero - no edges
+ return 0;
+ }
+
+ // Mark the last edge
+ edges.back().last = 1;
+
+ const unsigned int *saved_position = global_hashtable->find(edges);
+ if (saved_position)
+ {
+ ioHeaderInfo.edgessaved += numedges;
+ ioHeaderInfo.nodessaved++;
+
+ return *saved_position;
+ }
+ else
+ {
+ unsigned int node_pos = ioHeaderInfo.edgesused;
+ global_hashtable->add(edges, ioHeaderInfo.edgesused);
+ ioHeaderInfo.edgesused += numedges;
+ ioHeaderInfo.nodesused++;
+ write_node(reinterpret_cast<uint32_t*>(&edges.front()),
+ numedges, outfile);
+
+ return node_pos;
+ }
+}
+
+
+void printUsage(const string &iBinaryName)
+{
+ cout << "Usage: " << iBinaryName << " [options]" << endl
+ << _("Mandatory options:") << endl
+ << _(" -d, --dicname <string> Set the dictionary name and version")
<< endl
+ << _(" -l, --letters <string> Path to the file containing the
letters (see below)") << endl
+ << _(" -i, --input <string> Path to the uncompressed dictionary
file (encoded in UTF-8)") << endl
+ << _(" -o, --output <string Path to the generated compressed
dictionary file") << endl
+ << _("Other options:") << endl
+ << _(" -h, --help Print this help and exit") << endl
+ << _("Example:") << endl
+ << " " << iBinaryName << _(" -d 'ODS 5.0' -l letters.txt -i ods5.txt
-o ods5.dawg") << endl
+ << endl
+ << _("The file containing the letters (--letters switch) must be
UTF-8 encoded.") << endl
+ << _("Each line corresponds to one letter, and must contain 5 fields
separated with ") << endl
+ << _("one or more space(s).") << endl
+ << _(" - 1st field: the letter itself") << endl
+ << _(" - 2nd field: the points of the letter") << endl
+ << _(" - 3rd field: the frequency of the letter (how many letters of
this kind in the game)") << endl
+ << _(" - 4th field: 1 if the letter is considered as a vowel in
Scrabble game, 0 otherwise") << endl
+ << _(" - 5th field: 1 if the letter is considered as a consonant in
Scrabble game, 0 otherwise") << endl
+ << _("Example for french:") << endl
+ << _("A 1 9 1 0") << endl
+ << _("[...]") << endl
+ << _("Z 10 1 0 1") << endl
+ << _("? 0 2 1 1") << endl;
+}
+
+
+int main(int argc, char* argv[])
+{
+#if HAVE_SETLOCALE
+ // Set locale via LC_ALL
+ setlocale(LC_ALL, "");
+#endif
+
+#if ENABLE_NLS
+ // Set the message domain
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+ static const struct option long_options[] =
+ {
+ {"help", no_argument, NULL, 'h'},
+ {"dicname", required_argument, NULL, 'd'},
+ {"letters", required_argument, NULL, 'l'},
+ {"input", required_argument, NULL, 'i'},
+ {"output", required_argument, NULL, 'o'},
+ {0, 0, 0, 0}
+ };
+ static const char short_options[] = "hd:l:i:o:";
+
+ bool found_d = false;
+ bool found_l = false;
+ bool found_i = false;
+ bool found_o = false;
+ string inFileName;
+ string outFileName;
+ DictHeaderInfo headerInfo;
+
+ int res;
+ int option_index = 1;
+ try
+ {
+ while ((res = getopt_long(argc, argv, short_options,
+ long_options, &option_index)) != -1)
+ {
+ switch (res)
+ {
+ case 'h':
+ printUsage(argv[0]);
+ exit(0);
+ case 'd':
+ found_d = true;
+ headerInfo.dicName = convertToWc(optarg);
+ break;
+ case 'l':
+ found_l = true;
+ readLetters(optarg, headerInfo);
+ break;
+ case 'i':
+ found_i = true;
+ inFileName = optarg;
+ break;
+ case 'o':
+ found_o = true;
+ outFileName = optarg;
+ break;
+ }
+ }
+
+ // Check mandatory options
+ if (!found_d || !found_l || !found_i || !found_o)
+ {
+ cerr << _("A mandatory option is missing") << endl;
+ printUsage(argv[0]);
+ exit(1);
+ }
+
+ struct stat stat_buf;
+ if (stat(inFileName.c_str(), &stat_buf) < 0)
+ {
+ cerr << _("Cannot stat uncompressed dictionary ") << inFileName <<
endl;
+ exit(1);
+ }
+ unsigned int dicsize = (unsigned int)stat_buf.st_size;
+
+ ofstream outfile(outFileName.c_str(), ios::out | ios::binary |
ios::trunc);
+ if (!outfile.is_open())
+ {
+ cerr << _("Cannot open output file ") << outFileName << endl;
+ exit(1);
+ }
+
+ clock_t startLoadTime = clock();
+ // FIXME: not exception safe
+ const wchar_t *uncompressed = load_uncompressed(inFileName, dicsize);
+ clock_t endLoadTime = clock();
+
+ global_input = uncompressed;
+ global_endofinput = global_input + dicsize;
+
+#define SCALE 0.6
+ global_hashtable = new HashTable<vector<DicEdge>, unsigned int,
HashVector>((unsigned int)(dicsize * SCALE));
+#undef SCALE
+
+ headerInfo.dawg = true;
+ Header tempHeader = skip_init_header(outfile, headerInfo);
+
+ DicEdge specialnode = {0, 0, 0, 0};
+ specialnode.last = 1;
+ // Temporary variable to avoid a warning when compiling with -O2
+ // (there is no warning with -O0... g++ bug?)
+ DicEdge *tmpPtr = &specialnode;
+ write_node(reinterpret_cast<uint32_t*>(tmpPtr), 1, outfile);
+
+ /*
+ * Call makenode with null (relative to stringbuf) prefix;
+ * Initialize string to null; Put index of start node on output
+ */
+ DicEdge rootnode = {0, 0, 0, 0};
+ global_endstring = global_stringbuf;
+ clock_t startBuildTime = clock();
+ rootnode.ptr = makenode(global_endstring, outfile, headerInfo,
tempHeader);
+ clock_t endBuildTime = clock();
+ // Reuse the temporary variable
+ tmpPtr = &rootnode;
+ write_node(reinterpret_cast<uint32_t*>(tmpPtr), 1, outfile);
+
+ fix_header(outfile, headerInfo);
+
+ Header aHeader(headerInfo);
+ aHeader.print();
+
+ delete global_hashtable;
+ delete[] uncompressed;
+ outfile.close();
+
+ printf(_(" Load time: %.3f s\n"), 1.0 * (endLoadTime - startLoadTime)
/ CLOCKS_PER_SEC);
+ printf(_(" Compression time: %.3f s\n"), 1.0 * (endBuildTime -
startBuildTime) / CLOCKS_PER_SEC);
+#ifdef CHECK_RECURSION
+ printf(_(" Maximum recursion level reached: %d\n"), max_rec);
+#endif
+ return 0;
+ }
+ catch (std::exception &e)
+ {
+ cerr << e.what() << endl;
+ return 1;
+ }
+
+}
+
Index: dic/dic.cpp
===================================================================
RCS file: dic/dic.cpp
diff -N dic/dic.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/dic.cpp 8 Jan 2008 13:52:34 -0000 1.2
@@ -0,0 +1,276 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file dic.c
+ * \brief Dawg dictionary
+ * \author Antoine Fraboulet & Olivier Teuliere
+ * \date 2002
+ */
+
+#include "config.h"
+
+#include <fstream>
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+#include <cctype>
+
+// For ntohl & Co.
+#ifdef WIN32
+# include <winsock2.h>
+#else
+# if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+# endif
+# if HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+# endif
+#endif
+
+#include "dic.h"
+#include "header.h"
+#include "dic_exception.h"
+#include "dic_internals.h"
+#include "tile.h"
+
+
+const Dictionary *Dictionary::m_dic = NULL;
+
+
+// Note: duplicated in header.cpp
+#if defined(WORDS_BIGENDIAN)
+static uint32_t swap4(uint32_t v)
+{
+ uint32_t r;
+ uint8_t *pv = (uint8_t*)&v;
+ uint8_t *pr = (uint8_t*)&r;
+
+ pr[0] = pv[3];
+ pr[1] = pv[2];
+ pr[2] = pv[1];
+ pr[3] = pv[0];
+
+ return r;
+}
+#endif
+
+
+Dictionary::Dictionary(const string &iPath)
+ : m_dawg(NULL)
+{
+ ifstream file(iPath.c_str(), ios::in | ios::binary);
+
+ if (!file.is_open())
+ throw DicException("Cannot open " + iPath);
+
+ // XXX: we should protect these allocations with auto_ptr
+ m_header = new Header(file);
+ m_dawg = new uint32_t[m_header->getNbEdgesUsed() + 1];
+
+ streamsize toRead = (m_header->getNbEdgesUsed() + 1) * sizeof(uint32_t);
+ file.read((char*)m_dawg, toRead);
+ if (file.gcount() != toRead)
+ {
+ delete[] m_dawg;
+ delete m_header;
+ throw DicException("Problem reading dictionary arcs");
+ }
+
+ // Handle endianness
+ convertDataToArch();
+
+ initializeTiles();
+
+ // Concatenate the uppercase and lowercase letters
+ wstring lower = m_header->getLetters();
+ std::transform(lower.begin(), lower.end(), lower.begin(), towlower);
+ m_allLetters = m_header->getLetters() + lower;
+
+ m_dic = this;
+}
+
+
+Dictionary::~Dictionary()
+{
+ delete[] m_dawg;
+ delete m_header;
+}
+
+
+void Dictionary::convertDataToArch()
+{
+ if (m_header->getVersion() == 0)
+ {
+#if defined(WORDS_BIGENDIAN)
+ for (unsigned int i = 0; i < (m_header->getNbEdgesUsed() + 1); i++)
+ {
+ m_dawg[i] = swap4(m_dawg[i]);
+ }
+#endif
+ }
+ else
+ {
+ for (unsigned int i = 0; i < (m_header->getNbEdgesUsed() + 1); i++)
+ {
+ m_dawg[i] = ntohl(m_dawg[i]);
+ }
+ }
+}
+
+
+void Dictionary::initializeTiles()
+{
+ // "Activate" the dictionary by giving the header to the Tile class
+ Tile::SetHeader(*m_header);
+
+ // XXX: temp
+ Tile::m_TheJoker = Tile(Tile::kTILE_JOKER);
+
+ m_tilesVect.reserve(m_header->getLetters().size() + 1);
+ // Create a tile for each letter in the dictionary header
+ for (unsigned int i = 0; i < m_header->getLetters().size(); ++i)
+ m_tilesVect.push_back(Tile(m_header->getLetters()[i]));
+}
+
+
+bool Dictionary::validateLetters(const wstring &iLetters,
+ const wstring &iAccepted) const
+{
+ return iLetters.empty()
+ || iLetters.find_first_not_of(m_allLetters + iAccepted) ==
string::npos;
+}
+
+
+const dic_elt_t Dictionary::getNext(const dic_elt_t &e) const
+{
+ if (!isLast(e))
+ return e + 1;
+ return 0;
+}
+
+
+const dic_elt_t Dictionary::getSucc(const dic_elt_t &e) const
+{
+ if (m_header->getVersion() == 0)
+ return reinterpret_cast<const DicEdgeOld*>(m_dawg + e)->ptr;
+ else
+ return reinterpret_cast<const DicEdge*>(m_dawg + e)->ptr;
+}
+
+
+const dic_elt_t Dictionary::getRoot() const
+{
+ return m_header->getRoot();
+}
+
+
+const dic_code_t Dictionary::getCode(const dic_elt_t &e) const
+{
+ if (m_header->getVersion() == 0)
+ return reinterpret_cast<const DicEdgeOld*>(m_dawg + e)->chr;
+ else
+ return reinterpret_cast<const DicEdge*>(m_dawg + e)->chr;
+}
+
+
+wchar_t Dictionary::getChar(const dic_elt_t &e) const
+{
+ return m_header->getCharFromCode(getCode(e));
+}
+
+
+bool Dictionary::isLast(const dic_elt_t &e) const
+{
+ if (m_header->getVersion() == 0)
+ return reinterpret_cast<const DicEdgeOld*>(m_dawg + e)->last;
+ else
+ return reinterpret_cast<const DicEdge*>(m_dawg + e)->last;
+}
+
+
+bool Dictionary::isEndOfWord(const dic_elt_t &e) const
+{
+ if (m_header->getVersion() == 0)
+ return reinterpret_cast<const DicEdgeOld*>(m_dawg + e)->term;
+ else
+ return reinterpret_cast<const DicEdge*>(m_dawg + e)->term;
+}
+
+
+unsigned int Dictionary::lookup(const dic_elt_t &root, const dic_code_t *s)
const
+{
+ unsigned int p;
+ dic_elt_t rootCopy = root;
+begin:
+ if (! *s)
+ return rootCopy;
+ if (! getSucc(rootCopy))
+ return 0;
+ p = getSucc(rootCopy);
+ do
+ {
+ if (getCode(p) == *s)
+ {
+ rootCopy = p;
+ s++;
+ goto begin;
+ }
+ else if (isLast( p))
+ {
+ return 0;
+ }
+ p = getNext(p);
+ } while (1);
+
+ return 0;
+}
+
+
+unsigned int Dictionary::charLookup(const dic_elt_t &iRoot, const wchar_t *s)
const
+{
+ unsigned int p;
+ dic_elt_t rootCopy = iRoot;
+begin:
+ if (! *s)
+ return rootCopy;
+ if (! getSucc(rootCopy))
+ return 0;
+ p = getSucc(rootCopy);
+ do
+ {
+ if (getChar(p) == *s)
+ {
+ rootCopy = p;
+ s++;
+ goto begin;
+ }
+ else if (isLast(p))
+ {
+ return 0;
+ }
+ p = getNext(p);
+ } while (1);
+
+ return 0;
+}
+
Index: dic/dic_exception.cpp
===================================================================
RCS file: dic/dic_exception.cpp
diff -N dic/dic_exception.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/dic_exception.cpp 8 Jan 2008 13:52:34 -0000 1.2
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#include "dic_exception.h"
+
+using namespace std;
+
+
+DicException::DicException(const string &iMessage)
+ : m_message(iMessage)
+{
+}
+
+
+const char *DicException::what() const throw()
+{
+ return m_message.c_str();
+}
+
Index: dic/dic_exception.h
===================================================================
RCS file: dic/dic_exception.h
diff -N dic/dic_exception.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/dic_exception.h 8 Jan 2008 13:52:34 -0000 1.2
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#ifndef _DIC_EXCEPTION_H_
+#define _DIC_EXCEPTION_H_
+
+#include <exception>
+#include <string>
+
+
+/**
+ * Exception class for the dictionary.
+ * It simply inherits from the standard exception and overrides
+ * its what() method.
+ */
+class DicException: public std::exception
+{
+ public:
+ DicException(const std::string &iMessage);
+ ~DicException() throw() {}
+ virtual const char *what() const throw();
+
+ private:
+ std::string m_message;
+};
+
+#endif
Index: dic/dic_search.cpp
===================================================================
RCS file: dic/dic_search.cpp
diff -N dic/dic_search.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/dic_search.cpp 8 Jan 2008 13:52:34 -0000 1.2
@@ -0,0 +1,566 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2002-2007 Antoine Fraboulet
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file dic_search.c
+ * \brief Dictionary lookup functions
+ * \author Antoine Fraboulet
+ * \date 2002
+ */
+
+#include <cstdlib>
+#include <cstring>
+#include <cwchar>
+#include <cwctype>
+
+#include "dic_internals.h"
+#include "dic.h"
+#include "header.h"
+#include "encoding.h"
+#include "regexp.h"
+#include "libdic_a-ery.h" /* generated by bison */
+#include "libdic_a-erl.h" /* generated by flex */
+#include "automaton.h"
+
+
+/**
+ * Function prototype for bison generated parser
+ */
+int regexpparse(yyscan_t scanner, NODE** root,
+ struct search_RegE_list_t *iList,
+ struct regexp_error_report_t *err);
+
+
+template <typename DAWG_EDGE>
+const DAWG_EDGE* Dictionary::seekEdgePtr(const wchar_t* s, const DAWG_EDGE
*eptr) const
+{
+ if (*s)
+ {
+ const DAWG_EDGE *p = getEdgeAt<DAWG_EDGE>(eptr->ptr);
+ do
+ {
+ if (p->chr == getHeader().getCodeFromChar(*s))
+ return seekEdgePtr(s + 1, p);
+ } while (!(*p++).last);
+ return getEdgeAt<DAWG_EDGE>(0);
+ }
+ else
+ return eptr;
+}
+
+
+bool Dictionary::searchWord(const wstring &iWord) const
+{
+ if (!validateLetters(iWord))
+ return false;
+
+ if (getHeader().getVersion() == 0)
+ {
+ const DicEdgeOld *e =
+ seekEdgePtr(iWord.c_str(), getEdgeAt<DicEdgeOld>(getRoot()));
+ return e->term;
+ }
+ else
+ {
+ const DicEdge *e =
+ seekEdgePtr(iWord.c_str(), getEdgeAt<DicEdge>(getRoot()));
+ return e->term;
+ }
+}
+
+
+/**
+ * Global variables for searchWordByLen:
+ *
+ * A pointer to the structure is passed as a parameter
+ * so that all the search_* variables appear to the functions
+ * as global but the code remains re-entrant.
+ * Should be better to change the algorithm ...
+ */
+
+struct params_7plus1_t
+{
+ wchar_t added_char;
+ map<wchar_t, list<wstring> > *results;
+ int search_len;
+ wchar_t search_wordtst[DIC_WORD_MAX];
+ char search_letters[63];
+};
+
+template <typename DAWG_EDGE>
+void Dictionary::searchWordByLen(struct params_7plus1_t *params,
+ int i, const DAWG_EDGE *edgeptr) const
+{
+ /* depth first search in the dictionary */
+ do
+ {
+ /* the test is false only when reach the end-node */
+ if (edgeptr->chr)
+ {
+ /* is the letter available in search_letters */
+ if (params->search_letters[edgeptr->chr])
+ {
+ params->search_wordtst[i] =
getHeader().getCharFromCode(edgeptr->chr);
+ params->search_letters[edgeptr->chr] --;
+ if (i == params->search_len)
+ {
+ if (edgeptr->term)
+ {
+
(*params->results)[params->added_char].push_back(params->search_wordtst);
+ }
+ }
+ else
+ {
+ searchWordByLen(params, i + 1,
getEdgeAt<DAWG_EDGE>(edgeptr->ptr));
+ }
+ params->search_letters[edgeptr->chr] ++;
+ params->search_wordtst[i] = L'\0';
+ }
+
+ /* the letter is of course available if we have a joker available
*/
+ if (params->search_letters[0])
+ {
+ params->search_wordtst[i] =
getHeader().getCharFromCode(edgeptr->chr);
+ params->search_letters[0] --;
+ if (i == params->search_len)
+ {
+ if (edgeptr->term)
+ {
+
(*params->results)[params->added_char].push_back(params->search_wordtst);
+ }
+ }
+ else
+ {
+ searchWordByLen(params, i + 1,
getEdgeAt<DAWG_EDGE>(edgeptr->ptr));
+ }
+ params->search_letters[0] ++;
+ params->search_wordtst[i] = L'\0';
+ }
+ }
+ } while (! (*edgeptr++).last);
+}
+
+
+template <typename DAWG_EDGE>
+void Dictionary::search7pl1Templ(const wstring &iRack,
+ map<wchar_t, list<wstring> > &oWordList,
+ bool joker) const
+{
+ if (iRack == L"" || iRack.size() > DIC_WORD_MAX)
+ return;
+
+ struct params_7plus1_t params;
+
+ for (unsigned int i = 0; i < sizeof(params.search_letters); i++)
+ params.search_letters[i] = 0;
+
+ /*
+ * the letters are verified and changed to the dic internal
+ * representation (using getCodeFromChar(*r))
+ */
+ int wordlen = 0;
+ for (const wchar_t* r = iRack.c_str(); *r; r++)
+ {
+ if (iswalpha(*r))
+ {
+ params.search_letters[getHeader().getCodeFromChar(*r)]++;
+ wordlen++;
+ }
+ else if (*r == L'?')
+ {
+ if (joker)
+ {
+ params.search_letters[0]++;
+ wordlen++;
+ }
+ else
+ {
+ oWordList[0].push_back(L"** joker **");
+ return;
+ }
+ }
+ }
+
+ if (wordlen < 1)
+ return;
+
+ const DAWG_EDGE *root_edge = getEdgeAt<DAWG_EDGE>(getRoot());
+ root_edge = getEdgeAt<DAWG_EDGE>(root_edge->ptr);
+
+ params.results = &oWordList;
+
+ /* search for all the words that can be done with the letters */
+ params.added_char = L'\0';
+ params.search_len = wordlen - 1;
+ params.search_wordtst[wordlen] = L'\0';
+ searchWordByLen(¶ms, 0, root_edge);
+
+ /* search for all the words that can be done with the letters +1 */
+ params.search_len = wordlen;
+ params.search_wordtst[wordlen + 1] = L'\0';
+ const wstring &letters = getHeader().getLetters();
+ for (unsigned int i = 0; i < letters.size(); i++)
+ {
+ params.added_char = letters[i];
+ unsigned int code = getHeader().getCodeFromChar(letters[i]);
+ params.search_letters[code]++;
+
+ searchWordByLen(¶ms, 0, root_edge);
+
+ params.search_letters[code]--;
+ }
+}
+
+
+void Dictionary::search7pl1(const wstring &iRack,
+ map<wchar_t, list<wstring> > &oWordList,
+ bool joker) const
+{
+ if (getHeader().getVersion() == 0)
+ search7pl1Templ<DicEdgeOld>(iRack, oWordList, joker);
+ else
+ search7pl1Templ<DicEdge>(iRack, oWordList, joker);
+}
+
+/****************************************/
+/****************************************/
+
+template <typename DAWG_EDGE>
+void Dictionary::searchRaccTempl(const wstring &iWord, list<wstring>
&oWordList) const
+{
+ if (iWord == L"")
+ return;
+
+ /* search_racc will try to add a letter in front and at the end of a word
*/
+
+ /* let's try for the front */
+ wchar_t wordtst[DIC_WORD_MAX];
+ wcscpy(wordtst + 1, iWord.c_str());
+ const wstring &letters = getHeader().getLetters();
+ for (unsigned int i = 0; i <= letters.size(); i++)
+ {
+ wordtst[0] = letters[i];
+ if (searchWord(wordtst))
+ oWordList.push_back(wordtst);
+ }
+
+ /* add a letter at the end */
+ int i;
+ for (i = 0; iWord[i]; i++)
+ wordtst[i] = iWord[i];
+
+ wordtst[i ] = '\0';
+ wordtst[i+1] = '\0';
+
+ const DAWG_EDGE *edge_seek =
+ seekEdgePtr(iWord.c_str(), getEdgeAt<DAWG_EDGE>(getRoot()));
+
+ /* points to what the next letter can be */
+ const DAWG_EDGE *edge = getEdgeAt<DAWG_EDGE>(edge_seek->ptr);
+
+ if (edge != getEdgeAt<DAWG_EDGE>(0))
+ {
+ do
+ {
+ if (edge->term)
+ {
+ wordtst[i] = getHeader().getCharFromCode(edge->chr);
+ oWordList.push_back(wordtst);
+ }
+ } while (!(*edge++).last);
+ }
+}
+
+
+void Dictionary::searchRacc(const wstring &iWord, list<wstring> &oWordList)
const
+{
+ if (getHeader().getVersion() == 0)
+ searchRaccTempl<DicEdgeOld>(iWord, oWordList);
+ else
+ searchRaccTempl<DicEdge>(iWord, oWordList);
+}
+
+/****************************************/
+/****************************************/
+
+template <typename DAWG_EDGE>
+void Dictionary::searchBenjTempl(const wstring &iWord, list<wstring>
&oWordList) const
+{
+ if (iWord == L"")
+ return;
+
+ wchar_t wordtst[DIC_WORD_MAX];
+ wcscpy(wordtst + 3, iWord.c_str());
+ const DAWG_EDGE *edge0, *edge1, *edge2, *edgetst;
+ edge0 = getEdgeAt<DAWG_EDGE>(getRoot());
+ edge0 = getEdgeAt<DAWG_EDGE>(edge0->ptr);
+ do
+ {
+ wordtst[0] = getHeader().getCharFromCode(edge0->chr);
+ edge1 = getEdgeAt<DAWG_EDGE>(edge0->ptr);
+ do
+ {
+ wordtst[1] = getHeader().getCharFromCode(edge1->chr);
+ edge2 = getEdgeAt<DAWG_EDGE>(edge1->ptr);
+ do
+ {
+ edgetst = seekEdgePtr(iWord.c_str(), edge2);
+ if (edgetst->term)
+ {
+ wordtst[2] = getHeader().getCharFromCode(edge2->chr);
+ oWordList.push_back(wordtst);
+ }
+ } while (!(*edge2++).last);
+ } while (!(*edge1++).last);
+ } while (!(*edge0++).last);
+}
+
+
+void Dictionary::searchBenj(const wstring &iWord, list<wstring> &oWordList)
const
+{
+ if (getHeader().getVersion() == 0)
+ searchBenjTempl<DicEdgeOld>(iWord, oWordList);
+ else
+ searchBenjTempl<DicEdge>(iWord, oWordList);
+}
+
+/****************************************/
+/****************************************/
+
+struct params_cross_t
+{
+ int wordlen;
+ wchar_t mask[DIC_WORD_MAX];
+};
+
+
+template <typename DAWG_EDGE>
+void Dictionary::searchCrossRecTempl(struct params_cross_t *params,
+ list<wstring> &oWordList,
+ const DAWG_EDGE *edgeptr) const
+{
+ const DAWG_EDGE *current = getEdgeAt<DAWG_EDGE>(edgeptr->ptr);
+
+ if (params->mask[params->wordlen] == '\0' && edgeptr->term)
+ {
+ oWordList.push_back(params->mask);
+ }
+ else if (params->mask[params->wordlen] == '.')
+ {
+ do
+ {
+ params->mask[params->wordlen] =
getHeader().getCharFromCode(current->chr);
+ params->wordlen ++;
+ searchCrossRecTempl(params, oWordList, current);
+ params->wordlen --;
+ params->mask[params->wordlen] = '.';
+ }
+ while (!(*current++).last);
+ }
+ else
+ {
+ do
+ {
+ if (current->chr ==
getHeader().getCodeFromChar(params->mask[params->wordlen]))
+ {
+ params->wordlen ++;
+ searchCrossRecTempl(params, oWordList, current);
+ params->wordlen --;
+ break;
+ }
+ }
+ while (!(*current++).last);
+ }
+}
+
+
+void Dictionary::searchCross(const wstring &iMask, list<wstring> &oWordList)
const
+{
+ if (iMask == L"")
+ return;
+
+ struct params_cross_t params;
+
+ int i;
+ for (i = 0; i < DIC_WORD_MAX && iMask[i]; i++)
+ {
+ if (iswalpha(iMask[i]))
+ params.mask[i] = towupper(iMask[i]);
+ else
+ params.mask[i] = '.';
+ }
+ params.mask[i] = '\0';
+
+ params.wordlen = 0;
+ if (getHeader().getVersion() == 0)
+ {
+ searchCrossRecTempl(¶ms, oWordList,
+ getEdgeAt<DicEdgeOld>(getRoot()));
+ }
+ else
+ {
+ searchCrossRecTempl(¶ms, oWordList,
+ getEdgeAt<DicEdge>(getRoot()));
+ }
+}
+
+/****************************************/
+/****************************************/
+
+struct params_regexp_t
+{
+ int minlength;
+ int maxlength;
+ Automaton *automaton_field;
+ struct search_RegE_list_t *charlist;
+ char word[DIC_WORD_MAX];
+ int wordlen;
+};
+
+
+template <typename DAWG_EDGE>
+void Dictionary::searchRegexpRecTempl(struct params_regexp_t *params,
+ int state,
+ const DAWG_EDGE *edgeptr,
+ list<string> &oWordList) const
+{
+ int next_state;
+ /* if we have a valid word we store it */
+ if (params->automaton_field->accept(state) && edgeptr->term)
+ {
+ int l = strlen(params->word);
+ if (params->minlength <= l &&
+ params->maxlength >= l)
+ {
+ oWordList.push_back(params->word);
+ }
+ }
+ /* we now drive the search by exploring the dictionary */
+ const DAWG_EDGE *current = getEdgeAt<DAWG_EDGE>(edgeptr->ptr);
+ do
+ {
+ /* the current letter is current->chr */
+ next_state = params->automaton_field->getNextState(state,
current->chr);
+ /* 1: the letter appears in the automaton as is */
+ if (next_state)
+ {
+ params->word[params->wordlen] = current->chr + 'a' - 1;
+ params->wordlen ++;
+ searchRegexpRecTempl(params, next_state, current, oWordList);
+ params->wordlen --;
+ params->word[params->wordlen] = '\0';
+ }
+ } while (!(*current++).last);
+}
+
+
+void Dictionary::searchRegExpInner(const string &iRegexp,
+ list<string> &oWordList,
+ struct search_RegE_list_t *iList) const
+{
+ int ptl[REGEXP_MAX+1];
+ int PS [REGEXP_MAX+1];
+
+ /* (expr)# */
+ char stringbuf[250];
+ sprintf(stringbuf, "(%s)#", iRegexp.c_str());
+ for (int i = 0; i < REGEXP_MAX; i++)
+ {
+ PS[i] = 0;
+ ptl[i] = 0;
+ }
+
+ struct regexp_error_report_t report;
+ report.pos1 = 0;
+ report.pos2 = 0;
+ report.msg[0] = '\0';
+
+ /* parsing */
+ yyscan_t scanner;
+ regexplex_init( &scanner );
+ YY_BUFFER_STATE buf = regexp_scan_string(stringbuf, scanner);
+ NODE *root = NULL;
+ int value = regexpparse(scanner , &root, iList, &report);
+ regexp_delete_buffer(buf, scanner);
+ regexplex_destroy(scanner);
+
+ if (value)
+ {
+#ifdef DEBUG_FLEX_IS_BROKEN
+ fprintf(stderr, "parser error at pos %d - %d: %s\n",
+ report.pos1, report.pos2, report.msg);
+#endif
+ regexp_delete_tree(root);
+ return ;
+ }
+
+ int n = 1;
+ int p = 1;
+ regexp_parcours(root, &p, &n, ptl);
+ PS [0] = p - 1;
+ ptl[0] = p - 1;
+
+ regexp_possuivante(root, PS);
+
+ Automaton *a = new Automaton(root->PP, ptl, PS, iList);
+ if (a)
+ {
+ struct params_regexp_t params;
+ params.minlength = iList->minlength;
+ params.maxlength = iList->maxlength;
+ params.automaton_field = a;
+ params.charlist = iList;
+ memset(params.word, '\0', sizeof(params.word));
+ params.wordlen = 0;
+ if (getHeader().getVersion() == 0)
+ {
+ searchRegexpRecTempl(¶ms, a->getInitId(),
+ getEdgeAt<DicEdgeOld>(getRoot()), oWordList);
+ }
+ else
+ {
+ searchRegexpRecTempl(¶ms, a->getInitId(),
+ getEdgeAt<DicEdge>(getRoot()), oWordList);
+ }
+
+ delete a;
+ }
+ regexp_delete_tree(root);
+}
+
+
+void Dictionary::searchRegExp(const wstring &iRegexp,
+ list<wstring> &oWordList,
+ struct search_RegE_list_t *iList) const
+{
+ if (iRegexp == L"")
+ return;
+
+ list<string> tmpWordList;
+ // Do the actual work
+ searchRegExpInner(convertToMb(iRegexp), tmpWordList, iList);
+
+ list<string>::const_iterator it;
+ for (it = tmpWordList.begin(); it != tmpWordList.end(); it++)
+ {
+ oWordList.push_back(convertToWc(*it));
+ }
+}
+
Index: dic/encoding.cpp
===================================================================
RCS file: dic/encoding.cpp
diff -N dic/encoding.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/encoding.cpp 8 Jan 2008 13:52:34 -0000 1.2
@@ -0,0 +1,396 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file encoding.cpp
+ * \brief Utility functions to ease handling of wide-character strings
+ * \author Olivier Teuliere
+ * \date 2005
+ */
+
+#include "config.h"
+
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <cstdarg>
+#include <cstring>
+#include <cwchar>
+#include <cwctype>
+#include <cerrno>
+#include <iconv.h>
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include "encoding.h"
+#include "dic_exception.h"
+
+using namespace std;
+
+
+#ifdef WIN32
+// Utility function to get the last system error as a string
+static string GetWin32Error()
+{
+ char *lpMsgBuf;
+ DWORD dw = GetLastError();
+ cerr << dw << endl;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL);
+ string msg = lpMsgBuf;
+ LocalFree(lpMsgBuf);
+ return msg;
+}
+#endif
+
+
+#if !HAVE_WCWIDTH
+// wcwidth replacement (for win32 in particular)
+// Inspired from the gnulib package, without some of the refinements
+static inline int wcwidth(wchar_t c)
+{
+ // Assume all the printable characters have width 1
+ return c == 0 ? 0 : (iswprint(c) ? 1 : -1);
+}
+#endif
+
+
+int _wtoi(const wchar_t *iWStr)
+{
+ return wcstol(iWStr, NULL, 10);
+}
+
+
+int _swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...)
+{
+ int res;
+ va_list argp;
+ va_start(argp, format);
+#ifdef WIN32
+ // Mingw32 does not take the maxlen argument
+ res = vswprintf(wcs, format, argp);
+#else
+ res = vswprintf(wcs, maxlen, format, argp);
+#endif
+ va_end(argp);
+ return res;
+}
+
+
+wchar_t *_wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)
+{
+#ifdef WIN32
+ // Mingw32 does not take the third argument
+ return wcstok(wcs, delim);
+#else
+ return wcstok(wcs, delim, ptr);
+#endif
+}
+
+
+#define _MAX_SIZE_FOR_STACK_ 30
+wstring convertToWc(const string& iStr)
+{
+#ifdef WIN32
+ // XXX: Assume the input is in UTF-8
+ return readFromUTF8(iStr.c_str(), iStr.size(), "convertToWc");
+#else
+ // Get the needed length (we _can't_ use string::size())
+ size_t len = mbstowcs(NULL, iStr.c_str(), 0);
+ if (len == (size_t)-1)
+ return L"";
+
+ // Change the allocation method depending on the length of the string
+ if (len < _MAX_SIZE_FOR_STACK_)
+ {
+ // Without multi-thread, we can use static storage
+ static wchar_t tmp[_MAX_SIZE_FOR_STACK_];
+ len = mbstowcs(tmp, iStr.c_str(), len + 1);
+ return tmp;
+ }
+ else
+ {
+ wchar_t *tmp = new wchar_t[len + 1];
+ len = mbstowcs(tmp, iStr.c_str(), len + 1);
+ wstring res = tmp;
+ delete[] tmp;
+ return res;
+ }
+#endif
+}
+
+
+string convertToMb(const wstring& iWStr)
+{
+#ifdef WIN32
+ const unsigned int size = iWStr.size() * 4;
+ char buf[size];
+ // XXX: Assume the output is in UTF-8
+ int nb = writeInUTF8(iWStr, buf, size, "convertToMb");
+ return string(buf, nb);
+#else
+ // Get the needed length (we _can't_ use wstring::size())
+ size_t len = wcstombs(NULL, iWStr.c_str(), 0);
+ if (len == (size_t)-1)
+ return "";
+
+ // Change the allocation method depending on the length of the string
+ if (len < _MAX_SIZE_FOR_STACK_)
+ {
+ // Without multi-thread, we can use static storage
+ static char tmp[_MAX_SIZE_FOR_STACK_];
+ len = wcstombs(tmp, iWStr.c_str(), len + 1);
+ return tmp;
+ }
+ else
+ {
+ char *tmp = new char[len + 1];
+ len = wcstombs(tmp, iWStr.c_str(), len + 1);
+ string res = tmp;
+ delete[] tmp;
+ return res;
+ }
+#endif
+}
+#undef _MAX_SIZE_FOR_STACK_
+
+
+string convertToMb(wchar_t iWChar)
+{
+#ifdef WIN32
+ return convertToMb(wstring(1, iWChar));
+#else
+ char res[MB_CUR_MAX + 1];
+ int len = wctomb(res, iWChar);
+ if (len == -1)
+ return "";
+ res[len] = '\0';
+
+ return res;
+#endif
+}
+
+
+string truncString(const string &iStr, unsigned int iMaxWidth)
+{
+ // Heuristic: the width of a character cannot exceed the number of
+ // bytes used to represent it (even in UTF-8)
+ if (iStr.size() <= iMaxWidth)
+ return iStr;
+ return truncAndConvert(convertToWc(iStr), iMaxWidth);
+}
+
+
+string truncAndConvert(const wstring &iWstr, unsigned int iMaxWidth)
+{
+ unsigned int width = 0;
+ unsigned int pos;
+ for (pos = 0; pos < iWstr.size(); ++pos)
+ {
+ int n = wcwidth(iWstr[pos]);
+ if (n == -1)
+ {
+ ostringstream ss;
+ ss << "truncAndConvert: non printable character: " << iWstr[pos];
+ // XXX: Should we throw an exception instead? Just ignore the
problem?
+ cerr << ss.str() << endl;;
+ //throw DicException(ss.str());
+ return convertToMb(iWstr);
+ }
+ if (width + n > iMaxWidth)
+ break;
+ width += n;
+ }
+
+ return convertToMb(iWstr.substr(0, pos));
+}
+
+
+string truncOrPad(const string &iStr, unsigned int iWidth, char iChar)
+{
+ wstring wstr = convertToWc(iStr);
+ unsigned int width = 0;
+ unsigned int pos;
+ for (pos = 0; pos < wstr.size(); ++pos)
+ {
+ int n = wcwidth(wstr[pos]);
+ if (n == -1)
+ {
+ ostringstream ss;
+ ss << "truncAndConvert: non printable character: " << wstr[pos];
+ // XXX: Should we throw an exception instead? Just ignore the
problem?
+ cerr << ss.str() << endl;;
+ //throw DicException(ss.str());
+ return convertToMb(wstr);
+ }
+ if (width + n > iWidth)
+ break;
+ width += n;
+ }
+
+ if (iWidth > width)
+ return convertToMb(wstr.substr(0, pos)) + string(iWidth - width,
iChar);
+ else
+ return convertToMb(wstr.substr(0, pos));
+}
+
+
+string padAndConvert(const wstring &iWstr, unsigned int iLength,
+ bool iLeftPad, char c)
+{
+ int width = 0;
+ for (unsigned int i = 0; i < iWstr.size(); ++i)
+ {
+ int n = wcwidth(iWstr[i]);
+ if (n == -1)
+ {
+ ostringstream ss;
+ ss << "padAndConvert: non printable character: " << iWstr[i];
+ // XXX: Should we throw an exception instead? Just ignore the
problem?
+ cerr << ss.str() << endl;;
+ //throw DicException(ss.str());
+ return convertToMb(iWstr);
+ }
+ width += n;
+ }
+
+ if ((unsigned int)width >= iLength)
+ return convertToMb(iWstr);
+ else
+ {
+ // Padding is needed
+ string s(iLength - width, c);
+ if (iLeftPad)
+ return s + convertToMb(iWstr);
+ else
+ return convertToMb(iWstr) + s;
+ }
+}
+
+
+unsigned int readFromUTF8(wchar_t *oString, unsigned int iWideSize,
+ const char *iBuffer, unsigned int iBufSize,
+ const string &iContext)
+{
+#ifdef WIN32
+ int res = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, iBuffer,
+ iBufSize, oString, iWideSize);
+ if (res == 0)
+ {
+ // Retrieve the system error message for the last-error code
+ throw DicException("readFromUTF8: MultiByteToWideChar failed (" +
+ iContext + "): " + GetWin32Error());
+ }
+ return res;
+#else
+ iconv_t handle = iconv_open("WCHAR_T", "UTF-8");
+ if (handle == (iconv_t)(-1))
+ throw DicException("readFromUTF8: iconv_open failed");
+ size_t inChars = iBufSize;
+ size_t outChars = iWideSize * sizeof(wchar_t);
+ // Use the ICONV_CONST trick because the declaration of iconv()
+ // differs depending on the implementations...
+ ICONV_CONST char *in = const_cast<ICONV_CONST char*>(iBuffer);
+ char *out = (char*)oString;
+ size_t res = iconv(handle, &in, &inChars, &out, &outChars);
+ iconv_close(handle);
+ // Problem during encoding conversion?
+ if (res == (size_t)(-1))
+ {
+ throw DicException("readFromUTF8: iconv failed (" +
+ iContext + "): " + string(strerror(errno)));
+ }
+ return iWideSize - outChars / sizeof(wchar_t);
+#endif
+}
+
+
+wstring readFromUTF8(const char *iBuffer, unsigned int iBufSize,
+ const string &iContext)
+{
+ // Temporary buffer for output
+ // We will have at most as many characters as in the UTF-8 string
+ wchar_t *wideBuf = new wchar_t[iBufSize];
+ unsigned int number;
+ try
+ {
+ number = readFromUTF8(wideBuf, iBufSize, iBuffer, iBufSize, iContext);
+ }
+ catch (...)
+ {
+ // Make sure not to leak
+ delete[] wideBuf;
+ throw;
+ }
+ // Copy the string
+ wstring res(wideBuf, number);
+ delete[] wideBuf;
+ return res;
+}
+
+
+unsigned int writeInUTF8(const wstring &iWString, char *oBuffer,
+ unsigned int iBufSize, const string &iContext)
+{
+#ifdef WIN32
+ int res = WideCharToMultiByte(CP_UTF8, 0, iWString.c_str(),
iWString.size(),
+ oBuffer, iBufSize, NULL, NULL);
+ if (res == 0)
+ {
+ DWORD dw = GetLastError();
+ cerr << dw << endl;
+ // Retrieve the system error message for the last-error code
+ throw DicException("writeInUTF8: WideCharToMultiByte failed (" +
+ iContext + "): " + GetWin32Error());
+ }
+ return res;
+#else
+ iconv_t handle = iconv_open("UTF-8", "WCHAR_T");
+ if (handle == (iconv_t)(-1))
+ throw DicException("writeInUTF8: iconv_open failed");
+ size_t length = iWString.size();
+ size_t inChars = sizeof(wchar_t) * length;
+ size_t outChars = iBufSize;
+ // Use the ICONV_CONST trick because the declaration of iconv()
+ // differs depending on the implementations...
+ // FIXME: bonus ugliness for doing 2 casts at once, and accessing string
+ // internals...
+ ICONV_CONST char *in = (ICONV_CONST char*)(&iWString[0]);
+ char *out = oBuffer;
+ size_t res = iconv(handle, &in, &inChars, &out, &outChars);
+ iconv_close(handle);
+ // Problem during encoding conversion?
+ if (res == (size_t)(-1))
+ {
+ throw DicException("writeInUTF8: iconv failed (" +
+ iContext + ")" + string(strerror(errno)));
+ }
+ // Return the number of written bytes
+ return iBufSize - outChars;
+#endif
+}
+
Index: dic/encoding.h
===================================================================
RCS file: dic/encoding.h
diff -N dic/encoding.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/encoding.h 8 Jan 2008 13:52:34 -0000 1.2
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file encoding.h
+ * \brief Utility functions to ease manipulation of wide-character strings
+ * \author Olivier Teuliere
+ * \date 2005
+ */
+
+#ifndef _ENCODING_H_
+#define _ENCODING_H_
+
+#include <string>
+
+using std::string;
+using std::wstring;
+
+
+/// Equivalent of atoi for wide-caracter strings
+int _wtoi(const wchar_t *iWStr);
+
+/// Equivalent of swprintf, but working also with mingw32
+int _swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...);
+
+/// Equivalent of wcstok, but working also with mingw32
+wchar_t *_wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr);
+
+/// Convert a multi-byte string into a wide-character string
+wstring convertToWc(const string &iStr);
+
+/// Convert a wide-character string into a multi-byte string
+string convertToMb(const wstring &iWStr);
+
+/// Convert a wide character into a multi-byte string
+string convertToMb(wchar_t iWChar);
+
+/**
+ * Truncate the given string to ensure that the number of columns needed
+ * to display it is at most iMaxWidth. If the string is already less wide,
+ * it is returned without truncation
+ */
+string truncString(const string &iStr, unsigned int iMaxWidth);
+
+/**
+ * Convert the given string into a multi-byte one. If the number of columns
+ * needed to display the resulting string is more than iMaxWidth, truncate it
+ * on the right before conversion
+ */
+string truncAndConvert(const wstring &iWStr, unsigned int iMaxWidth);
+
+/**
+ * Make sure the displayed version of iStr has a width of iWidth.
+ * If the string is too long, truncate it, if it is too short, pad it
+ * with iChar
+ */
+string truncOrPad(const string &iStr, unsigned int iWidth, char iChar = ' ');
+
+/**
+ * Convert the given string into a multi-byte one. If the number of columns
+ * needed to display the resulting string is less than iLength, pad it with
+ * the given character (defaulting to space)
+ */
+string padAndConvert(const wstring &iWstr, unsigned int iLength,
+ bool iLeftPad = true, char c = ' ');
+
+/**
+ * Utility function to convert a char* buffer encoded in UTF-8 into a
+ * wchar_t* string
+ * @param oString: where to write the converted string
+ * @param iWideSize: size available in oString (number of wchar_t)
+ * @param iBuffer: UTF-8 string to convert
+ * @param iBufSize: available size in iBuffer
+ * @param iContext: free text used in case of exception
+ * @return: number of wide chars actually written
+ */
+unsigned int readFromUTF8(wchar_t *oString, unsigned int iWideSize,
+ const char *iBuffer, unsigned int iBufSize,
+ const string &iContext);
+
+/**
+ * Same as the other readFromUTF8 function, dealing with a wstring
+ * instead of a wchar_t*. Note that it performs an additional copy
+ * of the output string...
+ * @param iBuffer: UTF-8 string to convert
+ * @param iBufSize: available size in iBuffer
+ * @param iContext: free text used in case of exception
+ * @return: the converted wide string
+ */
+wstring readFromUTF8(const char *iBuffer, unsigned int iBufSize,
+ const string &iContext);
+
+/**
+ * Utility function to convert a wstring into an UTF-8 char* buffer
+ * @param iWString: the wide string to encode
+ * @param oBuffer: where to write the encoded string
+ * @param iBufSize: available size in oBuffer
+ * @param iContext: free text used in case of exception
+ * @return: number of bytes actually written
+ */
+unsigned int writeInUTF8(const wstring &iWString, char *oBuffer,
+ unsigned int iBufSize, const string &iContext);
+
+#endif
+
Index: dic/erl.lpp
===================================================================
RCS file: dic/erl.lpp
diff -N dic/erl.lpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/erl.lpp 8 Jan 2008 13:52:35 -0000 1.2
@@ -0,0 +1,59 @@
+%{
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet
+ * Authors: Antoine Fraboulet
+ *
+ * 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
+ *****************************************************************************/
+
+#include "dic.h"
+#include "regexp.h"
+#include "libdic_a-ery.h"
+
+#define MASK_TO_REMOVE 0x1F
+
+%}
+%option prefix="regexp"
+%option outfile="lex.yy.c"
+%option header-file="libdic_a-erl.h"
+%option reentrant bison-bridge
+%option bison-locations
+%option noyywrap nounput
+
+/* TODO : remove lexer translation */
+alphabet [a-zA-Z]
+%%
+
+{alphabet} {yylval_param->c=(yytext[0]&MASK_TO_REMOVE); return LEX_CHAR;}
+"[" {return LEX_L_SQBRACKET;}
+"]" {return LEX_R_SQBRACKET;}
+"(" {return LEX_L_BRACKET;}
+")" {return LEX_R_BRACKET;}
+"^" {return LEX_HAT;}
+
+"." {return LEX_ALL;}
+":v:" {return LEX_VOWL;}
+":c:" {return LEX_CONS;}
+":1:" {return LEX_USER1;}
+":2:" {return LEX_USER2;}
+
+"?" {return LEX_QMARK;}
+"+" {return LEX_PLUS;}
+"*" {return LEX_STAR;}
+
+"#" {return LEX_SHARP;}
+%%
+
Index: dic/ery.ypp
===================================================================
RCS file: dic/ery.ypp
diff -N dic/ery.ypp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/ery.ypp 8 Jan 2008 13:52:35 -0000 1.2
@@ -0,0 +1,295 @@
+%{
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet
+ * Authors: Antoine Fraboulet
+ *
+ * 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
+ *****************************************************************************/
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <malloc.h>
+
+#include "dic.h"
+#include "regexp.h"
+#include "libdic_a-ery.h"
+#include "libdic_a-erl.h"
+
+/* ************************************************** */
+/* ************************************************** */
+/* ************************************************** */
+
+ /**
+ * function prototype for parser generated by bison
+ */
+int regexpparse(yyscan_t scanner, NODE** root,
+ struct search_RegE_list_t *list,
+ struct regexp_error_report_t *err);
+
+ /**
+ * function prototype for error reporting
+ */
+void regexperror(YYLTYPE *llocp, yyscan_t scanner, NODE** root,
+ struct search_RegE_list_t *list,
+ struct regexp_error_report_t *err,
+ char const *msg);
+
+/* ************************************************** */
+/* ************************************************** */
+/* ************************************************** */
+
+%}
+%union {
+ char c;
+ NODE *NODE_TYPE;
+ char letters[DIC_LETTERS];
+};
+
+%defines
+%name-prefix="regexp"
+%pure-parser
+%locations
+%parse-param {yyscan_t yyscanner}
+%parse-param {NODE **root}
+%parse-param {struct search_RegE_list_t *list}
+%parse-param {struct regexp_error_report_t *err}
+%lex-param {yyscan_t yyscanner}
+
+%token <c> LEX_CHAR
+%token LEX_ALL
+%token LEX_VOWL
+%token LEX_CONS
+%token LEX_USER1
+%token LEX_USER2
+
+%token LEX_L_SQBRACKET LEX_R_SQBRACKET
+%token LEX_L_BRACKET LEX_R_BRACKET
+%token LEX_HAT
+
+%token LEX_QMARK
+%token LEX_PLUS
+%token LEX_STAR
+%token LEX_SHARP
+
+%type <NODE_TYPE> var
+%type <NODE_TYPE> expr
+%type <letters> vardis
+%type <letters> exprdis
+%type <NODE_TYPE> exprdisnode
+%start start
+%%
+
+start: LEX_L_BRACKET expr LEX_R_BRACKET LEX_SHARP
+ {
+ NODE* sharp = regexp_createNODE(NODE_VAR,RE_FINAL_TOK,NULL,NULL);
+ *root = regexp_createNODE(NODE_AND,'\0',$2,sharp);
+ YYACCEPT;
+ }
+ ;
+
+
+expr : var
+ {
+ $$=$1;
+ }
+ | expr expr
+ {
+ $$=regexp_createNODE(NODE_AND,'\0',$1,$2);
+ }
+ | var LEX_QMARK
+ {
+ NODE* epsilon=regexp_createNODE(NODE_VAR,RE_EPSILON,NULL,NULL);
+ $$=regexp_createNODE(NODE_OR,'\0',$1,epsilon);
+ }
+ | var LEX_PLUS
+ {
+ $$=regexp_createNODE(NODE_PLUS,'\0',$1,NULL);
+ }
+ | var LEX_STAR
+ {
+ $$=regexp_createNODE(NODE_STAR,'\0',$1,NULL);
+ }
+/* () */
+ | LEX_L_BRACKET expr LEX_R_BRACKET
+ {
+ $$=$2;
+ }
+ | LEX_L_BRACKET expr LEX_R_BRACKET LEX_QMARK
+ {
+ NODE* epsilon=regexp_createNODE(NODE_VAR,RE_EPSILON,NULL,NULL);
+ $$=regexp_createNODE(NODE_OR,'\0',$2,epsilon);
+ }
+ | LEX_L_BRACKET expr LEX_R_BRACKET LEX_PLUS
+ {
+ $$=regexp_createNODE(NODE_PLUS,'\0',$2,NULL);
+ }
+ | LEX_L_BRACKET expr LEX_R_BRACKET LEX_STAR
+ {
+ $$=regexp_createNODE(NODE_STAR,'\0',$2,NULL);
+ }
+/* [] */
+ | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET
+ {
+ $$=$2;
+ }
+ | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET LEX_QMARK
+ {
+ NODE* epsilon=regexp_createNODE(NODE_VAR,RE_EPSILON,NULL,NULL);
+ $$=regexp_createNODE(NODE_OR,'\0',$2,epsilon);
+ }
+ | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET LEX_PLUS
+ {
+ $$=regexp_createNODE(NODE_PLUS,'\0',$2,NULL);
+ }
+ | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET LEX_STAR
+ {
+ $$=regexp_createNODE(NODE_STAR,'\0',$2,NULL);
+ }
+ ;
+
+
+
+var : LEX_CHAR
+ {
+#ifdef DEBUG_RE_PARSE
+ printf("var : lecture %c\n",$1 + 'a' -1);
+#endif
+ $$=regexp_createNODE(NODE_VAR,$1,NULL,NULL);
+ }
+ | LEX_ALL
+ {
+ $$=regexp_createNODE(NODE_VAR,RE_ALL_MATCH,NULL,NULL);
+ }
+ | LEX_VOWL
+ {
+ $$=regexp_createNODE(NODE_VAR,RE_VOWL_MATCH,NULL,NULL);
+ }
+ | LEX_CONS
+ {
+ $$=regexp_createNODE(NODE_VAR,RE_CONS_MATCH,NULL,NULL);
+ }
+ | LEX_USER1
+ {
+ $$=regexp_createNODE(NODE_VAR,RE_USR1_MATCH,NULL,NULL);
+ }
+ | LEX_USER2
+ {
+ $$=regexp_createNODE(NODE_VAR,RE_USR2_MATCH,NULL,NULL);
+ }
+ ;
+
+
+exprdisnode : exprdis
+ {
+ int i,j;
+#ifdef DEBUG_RE_PARSE
+ printf("exprdisnode : exprdis : ");
+#endif
+ for(i=RE_LIST_USER_END + 1; i < DIC_SEARCH_REGE_LIST; i++)
+ {
+ if (list->valid[i] == 0)
+ {
+ list->valid[i] = 1;
+ list->symbl[i] = RE_ALL_MATCH + i;
+ list->letters[i][0] = 0;
+ for(j=1; j < DIC_LETTERS; j++)
+ list->letters[i][j] = $1[j] ? 1 : 0;
+#ifdef DEBUG_RE_PARSE
+ printf("list %d symbl x%02x : ",i,list->symbl[i]);
+ for(j=0; j < DIC_LETTERS; j++)
+ if (list->letters[i][j])
+ printf("%c",j+'a'-1);
+ printf("\n");
+#endif
+ break;
+ }
+ }
+ $$=regexp_createNODE(NODE_VAR,list->symbl[i],NULL,NULL);
+ }
+ | LEX_HAT exprdis
+ {
+ int i,j;
+#ifdef DEBUG_RE_PARSE
+ printf("exprdisnode : HAT exprdis : ");
+#endif
+ for(i=RE_LIST_USER_END + 1; i < DIC_SEARCH_REGE_LIST; i++)
+ {
+ if (list->valid[i] == 0)
+ {
+ list->valid[i] = 1;
+ list->symbl[i] = RE_ALL_MATCH + i;
+ list->letters[i][0] = 0;
+ for(j=1; j < DIC_LETTERS; j++)
+ list->letters[i][j] = $2[j] ? 0 : 1;
+#ifdef DEBUG_RE_PARSE
+ printf("list %d symbl x%02x : ",i,list->symbl[i]);
+ for(j=0; j < DIC_LETTERS; j++)
+ if (list->letters[i][j])
+ printf("%c",j+'a'-1);
+ printf("\n");
+#endif
+ break;
+ }
+ }
+ $$=regexp_createNODE(NODE_VAR,list->symbl[i],NULL,NULL);
+ }
+ ;
+
+
+exprdis: vardis
+ {
+ memcpy($$,$1,sizeof(char)*DIC_LETTERS);
+ }
+ | vardis exprdis
+ {
+ int i;
+ for(i=0; i < DIC_LETTERS; i++)
+ $$[i] = $1[i] | $2[i];
+ }
+ ;
+
+
+
+vardis: LEX_CHAR
+ {
+ int c = $1;
+ memset($$,0,sizeof(char)*DIC_LETTERS);
+#ifdef DEBUG_RE_PARSE
+ printf("vardis : lecture %c\n",c + 'a' -1);
+#endif
+ $$[c] = 1;
+ }
+ ;
+
+
+%%
+
+#define UNUSED __attribute__((unused))
+
+void regexperror(YYLTYPE *llocp, yyscan_t UNUSED yyscanner, NODE UNUSED **root,
+ struct search_RegE_list_t UNUSED *list,
+ struct regexp_error_report_t *err, char const *msg)
+{
+ err->pos1 = llocp->first_column;
+ err->pos2 = llocp->last_column;
+ strncpy(err->msg,msg,sizeof(err->msg));
+}
+
+/*
+ * shut down the compiler
+ */
+//int yy_init_globals (yyscan_t yyscanner);
Index: dic/hashtable.cpp
===================================================================
RCS file: dic/hashtable.cpp
diff -N dic/hashtable.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/hashtable.cpp 8 Jan 2008 13:52:35 -0000 1.2
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file hashtable.c
+ * \brief Simple hashtable type
+ * \author Antoine Fraboulet
+ * \date 1999
+ */
+
+#include "hashtable.h"
+
+
+unsigned int HashPtr(const void *iPtr, unsigned int iSize)
+{
+ unsigned int key = 0;
+
+ if (iSize % sizeof(unsigned int) == 0)
+ {
+ const unsigned int *ptr =
+ reinterpret_cast<const unsigned int*>(iPtr);
+ for (unsigned int i = 0; i < (iSize / sizeof(unsigned int)); ++i)
+ key ^= (key << 3) ^ (key >> 1) ^ ptr[i];
+ }
+ else
+ {
+ const unsigned char *ptr =
+ reinterpret_cast<const unsigned char*>(iPtr);
+ for (unsigned int i = 0; i < iSize; ++i)
+ key ^= (key << 3) ^ (key >> 1) ^ ptr[i];
+ }
+ return key;
+}
+
Index: dic/hashtable.i
===================================================================
RCS file: dic/hashtable.i
diff -N dic/hashtable.i
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/hashtable.i 8 Jan 2008 13:52:35 -0000 1.2
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#include <cstdlib>
+
+#include "hashtable.h"
+
+
+template<typename KEY, typename VALUE, typename HASH_FCN>
+HashTable<KEY, VALUE, HASH_FCN>::HashTable(unsigned int iSize)
+ : m_size(iSize)
+{
+ m_nodes = new const Node*[m_size];
+ for (unsigned int i = 0; i < m_size; ++i)
+ {
+ m_nodes[i] = NULL;
+ }
+}
+
+
+template<typename KEY, typename VALUE, typename HASH_FCN>
+HashTable<KEY, VALUE, HASH_FCN>::~HashTable()
+{
+ for (unsigned int i = 0; i < m_size; ++i)
+ delete m_nodes[i];
+ delete[] m_nodes;
+}
+
+
+template<typename KEY, typename VALUE, typename HASH_FCN>
+HashTable<KEY, VALUE, HASH_FCN>::Node::Node(const KEY &iKey, const VALUE
&iValue, const Node *iNext)
+ : m_key(iKey), m_value(iValue), m_next(iNext)
+{
+}
+
+
+template<typename KEY, typename VALUE, typename HASH_FCN>
+HashTable<KEY, VALUE, HASH_FCN>::Node::~Node()
+{
+ delete m_next;
+}
+
+
+template<typename KEY, typename VALUE, typename HASH_FCN>
+const VALUE *HashTable<KEY, VALUE, HASH_FCN>::find(const KEY &iKey) const
+{
+ HASH_FCN aHashFunc;
+ unsigned int h_key = aHashFunc(iKey) % m_size;
+ for (const Node *entry = m_nodes[h_key]; entry; entry = entry->m_next)
+ {
+ // Note: we need to be able to call == on a type KEY
+ if (entry->m_key == iKey)
+ {
+ return &entry->m_value;
+ }
+ }
+ return NULL;
+}
+
+
+template<typename KEY, typename VALUE, typename HASH_FCN>
+void HashTable<KEY, VALUE, HASH_FCN>::add(const KEY &iKey, const VALUE &iValue)
+{
+ HASH_FCN aHashFunc;
+ unsigned int h_key = aHashFunc(iKey) % m_size;
+ const Node *entry = new Node(iKey, iValue, m_nodes[h_key]);
+ m_nodes[h_key] = entry;
+}
+
+// vim: ft=cpp
Index: dic/header.cpp
===================================================================
RCS file: dic/header.cpp
diff -N dic/header.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/header.cpp 8 Jan 2008 13:52:35 -0000 1.2
@@ -0,0 +1,526 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#include "config.h"
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+// For ntohl & Co.
+#ifdef WIN32
+# include <winsock2.h>
+#else
+# if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+# endif
+# if HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+# endif
+#endif
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext(String)
+#else
+# define _(String) String
+#endif
+
+#include "header.h"
+#include "encoding.h"
+#include "dic_exception.h"
+
+
+// Note: swap4 is duplicated in dic.cpp
+#if defined(WORDS_BIGENDIAN)
+static uint32_t swap4(uint32_t v)
+{
+ uint32_t r;
+ uint8_t *pv = (uint8_t*)&v;
+ uint8_t *pr = (uint8_t*)&r;
+
+ pr[0] = pv[3];
+ pr[1] = pv[2];
+ pr[2] = pv[1];
+ pr[3] = pv[0];
+
+ return r;
+}
+
+// Nothing to do on big-endian machines
+# define ntohll(x) (x)
+# define htonll(x) (x)
+#else
+static inline uint64_t htonll(uint64_t host64)
+{
+ return (((uint64_t)htonl((host64 << 32) >> 32)) << 32) | htonl(host64 >>
32);
+}
+
+static inline uint64_t ntohll(uint64_t net64)
+{
+ return htonll(net64);
+}
+#endif
+
+
+/**
+ * Keyword included in dictionary headers
+ * Implies little endian storage on words
+ */
+#define _COMPIL_KEYWORD_ "_COMPILED_DICTIONARY_"
+
+/** Old format of the header (i.e. version 0) */
+struct Dict_header_old
+{
+ /// Identification string
+ char ident[sizeof(_COMPIL_KEYWORD_)];
+ /// Version of the serialization format
+ uint8_t version;
+ /// Unused at the moment, reserved for further use
+ char unused;
+ uint32_t root;
+ uint32_t nwords;
+ /// Information about the compression
+ //@{
+ uint32_t edgesused;
+ uint32_t nodesused;
+ uint32_t nodessaved;
+ uint32_t edgessaved;
+ //@}
+};
+
+// Do not change these values, as they impact the size of the structure!
+// Note: they are chosen carefully to avoid alignment issues
+#define _MAX_USER_HOST_ 32
+#define _MAX_DIC_NAME_SIZE_ 30
+#define _MAX_LETTERS_NB_ 63
+#define _MAX_LETTERS_SIZE_ 80
+
+/** Extension of the old format (used in version 1)*/
+struct Dict_header_ext
+{
+ // Time when the dictionary was compressed
+ // (number of seconds since the Epoch)
+ uint64_t compressDate;
+ // Build information
+ char userHost[_MAX_USER_HOST_];
+ // Size taken by the build information
+ uint32_t userHostSize;
+
+ // --- we have a multiple of 64 bytes here
+
+ // Compression algorithm (1 = DAWG, 2 = GADDAG)
+ uint8_t algorithm;
+ // Variant used in the rules (XXX: currently unused)
+ uint8_t variant;
+
+ // --- we have a multiple of 64 bytes here
+
+ // Dictionary official name and version (e.g.: ODS 5.0)
+ char dicName[_MAX_DIC_NAME_SIZE_];
+ // Size taken by the dictionary name
+ uint32_t dicNameSize;
+
+ // --- we have a multiple of 64 bytes here
+
+ // Letters used in the dictionary
+ // We should have: nbLetters <= lettersSize <= _MAX_LETTERS_SIZE_
+ // and: nbLetters <= _MAX_LETTERS_NB_
+ // The letters themselves, in UTF-8
+ char letters[_MAX_LETTERS_SIZE_];
+ // Size taken by the letters
+ uint32_t lettersSize;
+ // Number of letters (XXX: in theory useless, but allows a sanity check)
+ uint32_t nbLetters;
+
+ // --- we have a multiple of 64 bytes here
+
+ // Points of the letters (indexed by their code)
+ // The "+ 1" is there for struct alignment
+ uint8_t points[_MAX_LETTERS_NB_ + 1];
+ // Frequency of the letters (indexed by their code)
+ // The "+ 1" is there for struct alignment
+ uint8_t frequency[_MAX_LETTERS_NB_ + 1];
+ // Bitfield indicating whether letters are vowels
+ uint64_t vowels;
+ // Bitfield indicating whether letters are consonants
+ uint64_t consonants;
+
+ // --- we have a multiple of 64 bytes here
+};
+
+
+Header::Header(istream &iStream)
+ : m_root(0), m_nbWords(0), m_nodesUsed(0), m_edgesUsed(0),
+ m_nodesSaved(0), m_edgesSaved(0), m_type(kDAWG)
+{
+ // Simply delegate to the read() method
+ // The code is not moved here because I find it more natural to have a
+ // read() method symmetrical to the write() one
+ read(iStream);
+ buildMapCodeFromChar();
+}
+
+
+Header::Header(const DictHeaderInfo &iInfo)
+{
+ // Use the latest serialization format
+ m_version = 1;
+
+ // Sanity checks
+ if (iInfo.letters.size() > _MAX_LETTERS_NB_)
+ {
+ ostringstream ss;
+ ss << _MAX_LETTERS_NB_;
+ throw DicException("Header::Header: Too many different letters for "
+ "the current format; only " + ss.str() +
+ " are supported");
+ }
+ if (iInfo.points.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.points and iInfo.letters");
+ }
+ if (iInfo.frequency.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.frequency and iInfo.letters");
+ }
+ if (iInfo.vowels.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.vowels and iInfo.letters");
+ }
+ if (iInfo.consonants.size() != iInfo.letters.size())
+ {
+ throw DicException("Header::Header: Different sizes for "
+ "iInfo.consonants and iInfo.letters");
+ }
+
+ m_compressDate = time(NULL);
+ m_userHost = convertToWc(ELIOT_COMPILE_BY + string("@") +
ELIOT_COMPILE_HOST);
+ m_root = iInfo.root;
+ m_nbWords = iInfo.nwords;
+ m_nodesUsed = iInfo.nodesused;
+ m_edgesUsed = iInfo.edgesused;
+ m_nodesSaved = iInfo.nodessaved;
+ m_edgesSaved = iInfo.edgessaved;
+ m_type = iInfo.dawg ? kDAWG : kGADDAG;
+ m_dicName = iInfo.dicName;
+ m_letters = iInfo.letters;
+ m_points = iInfo.points;
+ m_frequency = iInfo.frequency;
+ m_vowels = iInfo.vowels;
+ m_consonants = iInfo.consonants;
+
+ buildMapCodeFromChar();
+}
+
+
+void Header::buildMapCodeFromChar()
+{
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ // We don't differentiate uppercase and lowercase letters
+ m_mapCodeFromChar[towlower(m_letters[i])] = i + 1;
+ m_mapCodeFromChar[towupper(m_letters[i])] = i + 1;
+ }
+}
+
+
+wchar_t Header::getCharFromCode(unsigned int iCode) const
+{
+ // Safety check
+ if (iCode == 0 || iCode > m_letters.size())
+ {
+ ostringstream ss;
+ ss << iCode;
+ throw DicException("Header::getCharFromCode: no letter for code " +
ss.str());
+ }
+ return m_letters[iCode - 1];
+}
+
+
+unsigned int Header::getCodeFromChar(wchar_t iChar) const
+{
+ map<wchar_t, unsigned int>::const_iterator pair =
+ m_mapCodeFromChar.find(iChar);
+ if (pair == m_mapCodeFromChar.end())
+ {
+ throw DicException("Header::getCodeFromChar: No code for letter " +
+ convertToMb(iChar));
+ }
+ return pair->second;
+}
+
+
+void Header::read(istream &iStream)
+{
+ Dict_header_old aHeader;
+ iStream.read((char*)&aHeader, sizeof(Dict_header_old));
+ if (iStream.gcount() != sizeof(Dict_header_old))
+ throw DicException("Header::read: expected to read more bytes");
+
+ // Check the identification string
+ if (string(aHeader.ident) != _COMPIL_KEYWORD_)
+ throw DicException("Header::read: incorrect header keyword; is it a
dictionary file?");
+
+ m_version = aHeader.version;
+
+ // Handle endianness
+ if (m_version == 0)
+ {
+#if defined(WORDS_BIGENDIAN)
+ aHeader.root = swap4(aHeader.root);
+ aHeader.nwords = swap4(aHeader.nwords);
+ aHeader.nodesused = swap4(aHeader.nodesused);
+ aHeader.edgesused = swap4(aHeader.edgesused);
+ aHeader.nodessaved = swap4(aHeader.nodessaved);
+ aHeader.edgessaved = swap4(aHeader.edgessaved);
+#endif
+ m_root = aHeader.root;
+ m_nbWords = aHeader.nwords;
+ m_nodesUsed = aHeader.nodesused;
+ m_edgesUsed = aHeader.edgesused;
+ m_nodesSaved = aHeader.nodessaved;
+ m_edgesSaved = aHeader.edgessaved;
+ }
+ else
+ {
+ m_root = ntohl(aHeader.root);
+ m_nbWords = ntohl(aHeader.nwords);
+ m_nodesUsed = ntohl(aHeader.nodesused);
+ m_edgesUsed = ntohl(aHeader.edgesused);
+ m_nodesSaved = ntohl(aHeader.nodessaved);
+ m_edgesSaved = ntohl(aHeader.edgessaved);
+ }
+
+ if (m_version == 0)
+ {
+ m_compressDate = 0;
+ m_userHost = convertToWc(_("Unknown (old format)"));
+ m_dicName = convertToWc(_("Unknown (old format)"));
+
+ // In version 0, the letters, points, frequency,
+ // vowels and consonants were hard-coded...
+ m_letters = convertToWc("ABCDEFGHIJKLMNOPQRSTUVWXYZ?");
+
+ static const uint8_t Frenchpoints[] =
+ {
+ // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
+ 1,3,3,2, 1,4,2,4,1,8,10,1,2,1,1,3,8,1,1,1,1,4,10,10,10,10,0
+ };
+
+ static const uint8_t FrenchFrequency[] =
+ {
+ // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
+ 9,2,2,3,15,2,2,2,8,1, 1,5,3,6,6,2,1,6,6,6,6,2, 1, 1, 1, 1,2
+ };
+
+ // The jokers and the 'Y' can be considered both as vowels or
consonants
+ static const uint8_t FrenchVowels[] =
+ {
+ // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
+ 1,0,0,0, 1,0,0,0,1,0, 0,0,0,0,1,0,0,0,0,0,1,0, 0, 0, 1, 0,1
+ };
+
+ static const uint8_t FrenchConsonants[] =
+ {
+ // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
+ 0,1,1,1, 0,1,1,1,0,1, 1,1,1,1,0,1,1,1,1,1,0,1, 1, 1, 1, 1,1
+ };
+
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ m_points.push_back(Frenchpoints[i]);
+ m_frequency.push_back(FrenchFrequency[i]);
+ m_vowels.push_back(FrenchVowels[i]);
+ m_consonants.push_back(FrenchConsonants[i]);
+ }
+ }
+ else
+ {
+ // This header doesn't use the old serialization format, so read the
+ // extension as well
+ Dict_header_ext aHeaderExt;
+ iStream.read((char*)&aHeaderExt, sizeof(Dict_header_ext));
+ if (iStream.gcount() != sizeof(Dict_header_ext))
+ throw DicException("Header::read: expected to read more bytes");
+
+ // Handle endianness in the extension
+ aHeaderExt.compressDate = ntohll(aHeaderExt.compressDate);
+ aHeaderExt.userHostSize = ntohl(aHeaderExt.userHostSize);
+ aHeaderExt.dicNameSize = ntohl(aHeaderExt.dicNameSize);
+ aHeaderExt.lettersSize = ntohl(aHeaderExt.lettersSize);
+ aHeaderExt.nbLetters = ntohl(aHeaderExt.nbLetters);
+ aHeaderExt.vowels = ntohll(aHeaderExt.vowels);
+ aHeaderExt.consonants = ntohll(aHeaderExt.consonants);
+
+ m_compressDate = aHeaderExt.compressDate;
+
+ if (aHeaderExt.algorithm == kDAWG)
+ m_type = kDAWG;
+ else if (aHeaderExt.algorithm == kGADDAG)
+ m_type = kGADDAG;
+ else
+ throw DicException("Header::read: unrecognized algorithm type");
+
+ m_userHost = readFromUTF8(aHeaderExt.userHost, aHeaderExt.userHostSize,
+ "user and host information");
+
+ // Convert the dictionary letters from UTF-8 to wchar_t*
+ m_dicName = readFromUTF8(aHeaderExt.dicName, aHeaderExt.dicNameSize,
+ "dictionary name");
+
+ // Convert the dictionary letters from UTF-8 to wchar_t*
+ m_letters = readFromUTF8(aHeaderExt.letters, aHeaderExt.lettersSize,
+ "dictionary letters");
+ // Safety check: correct number of letters?
+ if (m_letters.size() != aHeaderExt.nbLetters)
+ {
+ throw DicException("Header::read: inconsistent header");
+ }
+
+ // Letters points and frequency
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ m_points.push_back(aHeaderExt.points[i]);
+ m_frequency.push_back(aHeaderExt.frequency[i]);
+ }
+
+ // Vowels and consonants
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ m_vowels.push_back(aHeaderExt.vowels & (1 << i));
+ m_consonants.push_back(aHeaderExt.consonants & (1 << i));
+ }
+
+ }
+}
+
+
+void Header::write(ostream &oStream) const
+{
+ Dict_header_old aHeader;
+ strcpy(aHeader.ident, _COMPIL_KEYWORD_);
+ aHeader.version = m_version;
+ aHeader.unused = 0;
+ aHeader.root = htonl(m_root);
+ aHeader.nwords = htonl(m_nbWords);
+ aHeader.nodesused = htonl(m_nodesUsed);
+ aHeader.edgesused = htonl(m_edgesUsed);
+ aHeader.nodessaved = htonl(m_nodesSaved);
+ aHeader.edgessaved = htonl(m_edgesSaved);
+
+ oStream.write((char*)&aHeader, sizeof(Dict_header_old));
+ if (!oStream.good())
+ throw DicException("Header::write: error when writing to file");
+
+ if (m_version != 0)
+ {
+ Dict_header_ext aHeaderExt;
+ aHeaderExt.compressDate = m_compressDate;
+ aHeaderExt.userHostSize =
+ writeInUTF8(m_userHost, aHeaderExt.userHost,
+ _MAX_USER_HOST_, "user and host information");
+ aHeaderExt.algorithm = m_type;
+
+ // Convert the dictionary name to UTF-8
+ aHeaderExt.dicNameSize =
+ writeInUTF8(m_dicName, aHeaderExt.dicName,
+ _MAX_DIC_NAME_SIZE_, "dictionary name");
+
+ // Convert the dictionary letters to UTF-8
+ aHeaderExt.lettersSize =
+ writeInUTF8(m_letters, aHeaderExt.letters,
+ _MAX_LETTERS_SIZE_, "dictionary letters");
+ aHeaderExt.nbLetters = (uint32_t)m_letters.size();
+
+ // Letters points and frequency
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ aHeaderExt.points[i] = m_points[i];
+ aHeaderExt.frequency[i] = m_frequency[i];
+ }
+
+ // Vowels and consonants
+ aHeaderExt.vowels = 0;
+ aHeaderExt.consonants = 0;
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ if (m_vowels[i])
+ aHeaderExt.vowels |= 1 << i;
+ if (m_consonants[i])
+ aHeaderExt.consonants |= 1 << i;
+ }
+
+ // Handle endianness in the extension
+ aHeaderExt.userHostSize = htonl(aHeaderExt.userHostSize);
+ aHeaderExt.compressDate = htonll(aHeaderExt.compressDate);
+ aHeaderExt.dicNameSize = htonl(aHeaderExt.dicNameSize);
+ aHeaderExt.lettersSize = htonl(aHeaderExt.lettersSize);
+ aHeaderExt.nbLetters = htonl(aHeaderExt.nbLetters);
+ aHeaderExt.vowels = htonll(aHeaderExt.vowels);
+ aHeaderExt.consonants = htonll(aHeaderExt.consonants);
+
+ // Write the extension
+ oStream.write((char*)&aHeaderExt, sizeof(Dict_header_ext));
+ if (!oStream.good())
+ throw DicException("Header::write: error when writing to file");
+ }
+}
+
+
+void Header::print() const
+{
+ printf(_("dictionary name: %s\n"), convertToMb(m_dicName).c_str());
+ if (m_version)
+ {
+ char buf[50];
+ strftime(buf, sizeof(buf), "%c", gmtime(&m_compressDate));
+ printf(_("compressed on: %s\n"), buf);
+ }
+ else
+ {
+ printf(_("compressed on: Unknown date (old format)\n"));
+ }
+ printf(_("compressed using a binary compiled by: %s\n"),
convertToMb(m_userHost).c_str());
+ printf(_("dictionary type: %s\n"), m_type == kDAWG ? "DAWG" : "GADDAG");
+ printf(_("letters: %s\n"), convertToMb(m_letters).c_str());
+ printf(_("number of letters: %lu\n"), (long unsigned int)m_letters.size());
+ printf(_("number of words: %d\n"), m_nbWords);
+ long unsigned int size =
+ sizeof(Dict_header_old) + (m_version ? sizeof(Dict_header_ext) : 0);
+ printf(_("header size: %lu bytes\n"), size);
+ printf(_("root: %d (edge)\n"), m_root);
+ printf(_("nodes: %d used + %d saved\n"), m_nodesUsed, m_nodesSaved);
+ printf(_("edges: %d used + %d saved\n"), m_edgesUsed, m_edgesSaved);
+ printf("===============================================\n");
+ printf(_("letter | points | frequency | vowel | consonant\n"));
+ printf("-------+--------+-----------+-------+----------\n");
+ for (unsigned int i = 0; i < m_letters.size(); ++i)
+ {
+ printf(" %s | %2d | %2d | %d | %d\n",
+ padAndConvert(wstring(1, m_letters[i]), 2).c_str(),
+ m_points[i], m_frequency[i], m_vowels[i], m_consonants[i]);
+ }
+ printf("===============================================\n");
+}
+
Index: dic/header.h
===================================================================
RCS file: dic/header.h
diff -N dic/header.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/header.h 8 Jan 2008 13:52:35 -0000 1.2
@@ -0,0 +1,191 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#ifndef _HEADER_H
+#define _HEADER_H
+
+#include <iosfwd>
+#include <map>
+#include <vector>
+#include <time.h>
+
+using namespace std;
+
+
+/**
+ * Structure used to create a Header object.
+ * Note: this structure doesn't pretend to map the way the data is stored in a
+ * file. For (de)serialization, always use a Header object
+ */
+struct DictHeaderInfo
+{
+ uint32_t root;
+ uint32_t nwords;
+ uint32_t edgesused;
+ uint32_t nodesused;
+ uint32_t nodessaved;
+ uint32_t edgessaved;
+ bool dawg;
+ wstring dicName;
+ wstring letters;
+ vector<uint8_t> points;
+ vector<uint8_t> frequency;
+ vector<bool> vowels;
+ vector<bool> consonants;
+};
+
+
+/**
+ * Dictionary header.
+ * There are 2 ways to create a Header object:
+ * - fill a DictHeaderInfo structure and give it in the constructor of the
+ * Header class (usually to call write() afterwards)
+ * - give it an input stream on a compiled dictionary
+ *
+ * The class is immutable: a Header object cannot be modified after creation.
+ *
+ * Serialization:
+ * Several formats of headers will be handled by this class, even though only
+ * the first one is handled at the moment. You can use the write() method to
+ * write the latest version of the header into a given file.
+ * When using the constructor taking an input stream, all the header versions
+ * are supported.
+ */
+class Header
+{
+public:
+
+ /// Dictionary type
+ enum DictType
+ {
+ kDAWG = 1,
+ kGADDAG = 2
+ };
+
+ /**
+ * Constructor from an input stream
+ * @param iStream: Input stream where to read the header
+ */
+ Header(istream &iStream);
+
+ /**
+ * Constructor from a filled structure
+ * @param iInfo: info needed to build the header
+ */
+ Header(const DictHeaderInfo &iInfo);
+
+ /// Return the version of the dictionary format
+ uint8_t getVersion() const { return m_version; }
+
+ /// Getters
+ //@{
+ unsigned int getRoot() const { return m_root; }
+ unsigned int getNbWords() const { return m_nbWords; }
+ unsigned int getNbNodesUsed() const { return m_nodesUsed; }
+ unsigned int getNbEdgesUsed() const { return m_edgesUsed; }
+ unsigned int getNbNodesSaved() const { return m_nodesSaved; }
+ unsigned int getNbEdgesSaved() const { return m_edgesSaved; }
+ DictType getType() const { return m_type; }
+ wstring getLetters() const { return m_letters; }
+ uint8_t getPoints(unsigned int iCode) const { return m_points[iCode -
1]; }
+ uint8_t getFrequency(unsigned int iCode) const { return
m_frequency[iCode - 1]; }
+ bool isVowel(unsigned int iCode) const { return m_vowels[iCode -
1]; }
+ bool isConsonant(unsigned int iCode) const { return
m_consonants[iCode - 1]; }
+ //@}
+
+ /**
+ * Return the letter corresponding to the given code
+ */
+ wchar_t getCharFromCode(unsigned int iCode) const;
+
+ /**
+ * Return the code corresponding to the given letter
+ */
+ unsigned int getCodeFromChar(wchar_t iChar) const;
+
+ /**
+ * Print a readable summary of the header on standard output
+ */
+ void print() const;
+
+ /**
+ * Write the header to a file, using the latest format
+ * @param oStream: Output stream where to write the header
+ * @exception: Throw a DicException in case of problem
+ */
+ void write(ostream &oStream) const;
+
+private:
+ /// Version of the serialization
+ uint8_t m_version;
+
+ wstring m_userHost;
+ time_t m_compressDate;
+
+ uint32_t m_root;
+ uint32_t m_nbWords;
+ uint32_t m_nodesUsed;
+ uint32_t m_edgesUsed;
+ uint32_t m_nodesSaved;
+ uint32_t m_edgesSaved;
+
+ /// Specify whether the dictionary is a DAWG or a GADDAG
+ DictType m_type;
+
+ /// Dictionary name (e.g.: ODS 5.0)
+ wstring m_dicName;
+
+ /// The letters constituting the words of the dictionary
+ wstring m_letters;
+
+ /// Points of the letters
+ vector<uint8_t> m_points;
+
+ /// Frequency of the letters
+ vector<uint8_t> m_frequency;
+
+ /// Vowels
+ vector<bool> m_vowels;
+
+ /// Consonants
+ vector<bool> m_consonants;
+
+ map<wchar_t, unsigned int> m_mapCodeFromChar;
+
+ /**
+ * Load the header from a file
+ * @param iStream: Input stream where to read the header
+ * @exception: Throw a DicException in case of problem
+ */
+ void read(istream &iStream);
+
+ /** Build m_mapCodeFromChar */
+ void buildMapCodeFromChar();
+};
+
+
+#endif /* _HEADER_H */
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: dic/listdic.cpp
===================================================================
RCS file: dic/listdic.cpp
diff -N dic/listdic.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/listdic.cpp 8 Jan 2008 13:52:36 -0000 1.2
@@ -0,0 +1,187 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 1999-2007 Antoine Fraboulet & Olivier Teulière
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ * Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file listdic.c
+ * \brief Program used to list a dictionary
+ * \author Antoine Fraboulet
+ * \date 1999
+ */
+
+#include "config.h"
+
+#include <fstream>
+#include <iostream>
+#include <cstring>
+#include <cstdlib>
+#include <cstdio>
+#include <cstddef>
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext(String)
+#else
+# define _(String) String
+#endif
+
+#include "header.h"
+#include "encoding.h"
+#include "dic_internals.h"
+#include "dic.h"
+
+using namespace std;
+
+
+template <typename DAWG_EDGE>
+static void print_dic_rec(ostream &out, const Dictionary &iDic, wchar_t *buf,
wchar_t *s, DAWG_EDGE i)
+{
+ if (i.term) /* edge points at a complete word */
+ {
+ *s = '\0';
+ out << convertToMb(buf) << endl;
+ }
+ if (i.ptr)
+ { /* Compute index: is it non-zero ? */
+ const DAWG_EDGE *p = reinterpret_cast<const
DAWG_EDGE*>(iDic.getEdgeAt(i.ptr));
+ do
+ { /* for each edge out of this node */
+ *s = iDic.getHeader().getCharFromCode(p->chr);
+ print_dic_rec(out, iDic, buf, s + 1, *p);
+ }
+ while (!(*p++).last);
+ }
+}
+
+
+template <typename DAWG_EDGE>
+void print_dic_list(const Dictionary &iDic)
+{
+ static wchar_t buf[80];
+ print_dic_rec(cout, iDic, buf, buf, *reinterpret_cast<const
DAWG_EDGE*>(iDic.getEdgeAt(iDic.getRoot())));
+}
+
+
+template <typename DAWG_EDGE>
+static void print_node_hex(const Dictionary &dic, int i)
+{
+ union edge_t
+ {
+ DAWG_EDGE e;
+ uint32_t s;
+ } ee;
+
+ ee.e = *reinterpret_cast<const DAWG_EDGE*>(dic.getEdgeAt(i));
+
+ printf("0x%04lx %08x |%4d ptr=%8d t=%d l=%d chr=%2d (%c)\n",
+ (unsigned long)i*sizeof(ee), (unsigned int)(ee.s),
+ i, ee.e.ptr, ee.e.term, ee.e.last, ee.e.chr, ee.e.chr +'a' -1);
+}
+
+
+template <typename DAWG_EDGE>
+void print_dic_hex(const Dictionary &iDic)
+{
+ printf(_("offset binary | structure\n"));
+ printf("------ -------- | --------------------\n");
+ for (unsigned int i = 0; i < (iDic.getHeader().getNbEdgesUsed() + 1); i++)
+ print_node_hex<DAWG_EDGE>(iDic, i);
+}
+
+
+void usage(const string &iName)
+{
+ printf(_("usage: %s [-a|-h|-l|-x] dictionary\n"), iName.c_str());
+ printf(_(" -a: print all\n"));
+ printf(_(" -h: print header\n"));
+ printf(_(" -l: print dictionary word list\n"));
+ printf(_(" -x: print dictionary in hex\n"));
+}
+
+
+int main(int argc, char *argv[])
+{
+#if HAVE_SETLOCALE
+ // Set locale via LC_ALL
+ setlocale(LC_ALL, "");
+#endif
+
+#if ENABLE_NLS
+ // Set the message domain
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+ int arg_count;
+ int option_print_all = 0;
+ int option_print_header = 0;
+ int option_print_dic_hex = 0;
+ int option_print_dic_list = 0;
+
+ if (argc < 3)
+ {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ arg_count = 1;
+ while (argv[arg_count][0] == '-')
+ {
+ switch (argv[arg_count][1])
+ {
+ case 'a': option_print_all = 1; break;
+ case 'h': option_print_header = 1; break;
+ case 'l': option_print_dic_list = 1; break;
+ case 'x': option_print_dic_hex = 1; break;
+ default: usage(argv[0]); exit(2); break;
+ }
+ arg_count++;
+ }
+
+ try
+ {
+ Dictionary dic(argv[arg_count]);
+
+ if (option_print_header || option_print_all)
+ {
+ dic.getHeader().print();
+ }
+ if (option_print_dic_hex || option_print_all)
+ {
+ if (dic.getHeader().getVersion() == 0)
+ print_dic_hex<DicEdgeOld>(dic);
+ else
+ print_dic_hex<DicEdge>(dic);
+ }
+ if (option_print_dic_list || option_print_all)
+ {
+ if (dic.getHeader().getVersion() == 0)
+ print_dic_list<DicEdgeOld>(dic);
+ else
+ print_dic_list<DicEdge>(dic);
+ }
+ return 0;
+ }
+ catch (std::exception &e)
+ {
+ cerr << e.what() << endl;
+ return 1;
+ }
+}
Index: dic/regexp.cpp
===================================================================
RCS file: dic/regexp.cpp
diff -N dic/regexp.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/regexp.cpp 8 Jan 2008 13:52:36 -0000 1.2
@@ -0,0 +1,384 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 1999-2006 Antoine Fraboulet
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file regexp.c
+ * \brief Regular Expression functions
+ * \author Antoine Fraboulet
+ * \date 2005
+ */
+
+#include "config.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#include <unistd.h>
+
+#include "dic.h"
+#include "regexp.h"
+#include "automaton.h"
+
+#ifndef PDBG
+#ifdef DEBUG_RE2
+#define PDBG(x) x
+#else
+#define PDBG(x)
+#endif
+#endif
+
+
+NODE* regexp_createNODE(int type, char v, NODE *fg, NODE *fd)
+{
+ NODE *x;
+ x=(NODE *)malloc(sizeof(NODE));
+ x->type = type;
+ x->var = v;
+ x->fd = fd;
+ x->fg = fg;
+ x->number = 0;
+ x->position = 0;
+ x->annulable = 0;
+ x->PP = 0;
+ x->DP = 0;
+ return x;
+}
+
+void regexp_delete_tree(NODE *root)
+{
+ if (root == NULL)
+ return;
+ regexp_delete_tree(root->fg);
+ regexp_delete_tree(root->fd);
+ free(root);
+}
+
+#ifdef DEBUG_RE
+static void print_node(FILE*, NODE *n, int detail);
+#endif
+
+/**
+ * computes position, annulable, PP, DP attributes
+ * @param r = root
+ * @param p = current leaf position
+ * @param n = current node number
+ * @param ptl = position to letter
+ */
+
+void regexp_parcours(NODE* r, int *p, int *n, int ptl[])
+{
+ if (r == NULL)
+ return;
+
+ regexp_parcours(r->fg, p, n, ptl);
+ regexp_parcours(r->fd, p, n, ptl);
+
+ switch (r->type)
+ {
+ case NODE_VAR:
+ r->position = *p;
+ ptl[*p] = r->var;
+ *p = *p + 1;
+ r->annulable = 0;
+ r->PP = 1 << (r->position - 1);
+ r->DP = 1 << (r->position - 1);
+ break;
+ case NODE_OR:
+ r->position = 0;
+ r->annulable = r->fg->annulable || r->fd->annulable;
+ r->PP = r->fg->PP | r->fd->PP;
+ r->DP = r->fg->DP | r->fd->DP;
+ break;
+ case NODE_AND:
+ r->position = 0;
+ r->annulable = r->fg->annulable && r->fd->annulable;
+ r->PP = (r->fg->annulable) ? (r->fg->PP | r->fd->PP) : r->fg->PP;
+ r->DP = (r->fd->annulable) ? (r->fg->DP | r->fd->DP) : r->fd->DP;
+ break;
+ case NODE_PLUS:
+ r->position = 0;
+ r->annulable = 0;
+ r->PP = r->fg->PP;
+ r->DP = r->fg->DP;
+ break;
+ case NODE_STAR:
+ r->position = 0;
+ r->annulable = 1;
+ r->PP = r->fg->PP;
+ r->DP = r->fg->DP;
+ break;
+ }
+
+ r->number = *n;
+ *n = *n + 1;
+}
+
+/**
+ * computes possuivante
+ * @param r = root
+ * @param PS = next position
+ */
+
+void regexp_possuivante(NODE* r, int PS[])
+{
+ if (r == NULL)
+ return;
+
+ regexp_possuivante(r->fg, PS);
+ regexp_possuivante(r->fd, PS);
+
+ switch (r->type)
+ {
+ case NODE_AND:
+ /************************************/
+ /* \forall p \in DP(left) */
+ /* PS[p] = PS[p] \cup PP(right) */
+ /************************************/
+ for (int pos = 1; pos <= PS[0]; pos++)
+ {
+ if (r->fg->DP & (1 << (pos-1)))
+ PS[pos] |= r->fd->PP;
+ }
+ break;
+ case NODE_PLUS:
+ /************************************/
+ /* == same as START */
+ /* \forall p \in DP(left) */
+ /* PS[p] = PS[p] \cup PP(left) */
+ /************************************/
+ for (int pos = 1; pos <= PS[0]; pos++)
+ {
+ if (r->DP & (1 << (pos-1)))
+ PS[pos] |= r->PP;
+ }
+ break;
+ case NODE_STAR:
+ /************************************/
+ /* \forall p \in DP(left) */
+ /* PS[p] = PS[p] \cup PP(left) */
+ /************************************/
+ for (int pos = 1; pos <= PS[0]; pos++)
+ {
+ if (r->DP & (1 << (pos-1)))
+ PS[pos] |= r->PP;
+ }
+ break;
+ }
+}
+
+/*////////////////////////////////////////////////
+// DEBUG only fonctions
+////////////////////////////////////////////////*/
+
+#ifdef DEBUG_RE
+void regexp_print_PS(int PS[])
+{
+ printf("** positions suivantes **\n");
+ for (int i = 1; i <= PS[0]; i++)
+ {
+ printf("%02d: 0x%08x\n", i, PS[i]);
+ }
+}
+#endif
+
+/*////////////////////////////////////////////////
+////////////////////////////////////////////////*/
+
+#ifdef DEBUG_RE
+void regexp_print_ptl(int ptl[])
+{
+ printf("** pos -> lettre: ");
+ for (int i = 1; i <= ptl[0]; i++)
+ {
+ printf("%d=%c ", i, ptl[i]);
+ }
+ printf("\n");
+}
+#endif
+
+/*////////////////////////////////////////////////
+////////////////////////////////////////////////*/
+
+void regexp_print_letter(FILE* f, char l)
+{
+ switch (l)
+ {
+ case RE_EPSILON: fprintf(f, "( & [%d])", l); break;
+ case RE_FINAL_TOK: fprintf(f, "( # [%d])", l); break;
+ case RE_ALL_MATCH: fprintf(f, "( . [%d])", l); break;
+ case RE_VOWL_MATCH: fprintf(f, "(:v: [%d])", l); break;
+ case RE_CONS_MATCH: fprintf(f, "(:c: [%d])", l); break;
+ case RE_USR1_MATCH: fprintf(f, "(:1: [%d])", l); break;
+ case RE_USR2_MATCH: fprintf(f, "(:2: [%d])", l); break;
+ default:
+ if (l < RE_FINAL_TOK)
+ fprintf(f, " (%c [%d]) ", l + 'a' - 1, l);
+ else
+ fprintf(f, " (liste %d)", l - RE_LIST_USER_END);
+ break;
+ }
+}
+
+/*////////////////////////////////////////////////
+////////////////////////////////////////////////*/
+
+void regexp_print_letter2(FILE* f, char l)
+{
+ switch (l)
+ {
+ case RE_EPSILON: fprintf(f, "&"); break;
+ case RE_FINAL_TOK: fprintf(f, "#"); break;
+ case RE_ALL_MATCH: fprintf(f, "."); break;
+ case RE_VOWL_MATCH: fprintf(f, ":v:"); break;
+ case RE_CONS_MATCH: fprintf(f, ":c:"); break;
+ case RE_USR1_MATCH: fprintf(f, ":1:"); break;
+ case RE_USR2_MATCH: fprintf(f, ":2:"); break;
+ default:
+ if (l < RE_FINAL_TOK)
+ fprintf(f, "%c", l + 'a' - 1);
+ else
+ fprintf(f, "l%d", l - RE_LIST_USER_END);
+ break;
+ }
+}
+
+/*////////////////////////////////////////////////
+////////////////////////////////////////////////*/
+
+#ifdef DEBUG_RE
+static void print_node(FILE* f, NODE *n, int detail)
+{
+ if (n == NULL)
+ return;
+
+ switch (n->type)
+ {
+ case NODE_VAR:
+ regexp_print_letter(f, n->var);
+ break;
+ case NODE_OR:
+ fprintf(f, "OR");
+ break;
+ case NODE_AND:
+ fprintf(f, "AND");
+ break;
+ case NODE_PLUS:
+ fprintf(f, "+");
+ break;
+ case NODE_STAR:
+ fprintf(f, "*");
+ break;
+ }
+ if (detail == 2)
+ {
+ fprintf(f, "\\n pos=%d\\n annul=%d\\n PP=0x%04x\\n DP=0x%04x",
+ n->position, n->annulable, n->PP, n->DP);
+ }
+}
+#endif
+
+/*////////////////////////////////////////////////
+////////////////////////////////////////////////*/
+
+#ifdef DEBUG_RE
+static void print_tree_nodes(FILE* f, NODE* n, int detail)
+{
+ if (n == NULL)
+ return;
+
+ print_tree_nodes(f, n->fg, detail);
+ print_tree_nodes(f, n->fd, detail);
+
+ fprintf(f, "%d [ label=\"", n->number);
+ print_node(f, n, detail);
+ fprintf(f, "\"];\n");
+}
+#endif
+
+/*////////////////////////////////////////////////
+////////////////////////////////////////////////*/
+
+#ifdef DEBUG_RE
+static void print_tree_edges(FILE *f, NODE *n)
+{
+ if (n == NULL)
+ return;
+
+ print_tree_edges(f, n->fg);
+ print_tree_edges(f, n->fd);
+
+ switch (n->type)
+ {
+ case NODE_OR:
+ fprintf(f, "%d -> %d;", n->number, n->fg->number);
+ fprintf(f, "%d -> %d;", n->number, n->fd->number);
+ break;
+ case NODE_AND:
+ fprintf(f, "%d -> %d;", n->number, n->fg->number);
+ fprintf(f, "%d -> %d;", n->number, n->fd->number);
+ break;
+ case NODE_PLUS:
+ case NODE_STAR:
+ fprintf(f, "%d -> %d;", n->number, n->fg->number);
+ break;
+ }
+}
+#endif
+
+/*////////////////////////////////////////////////
+////////////////////////////////////////////////*/
+
+#ifdef DEBUG_RE
+void regexp_print_tree(NODE* n, const string &iName, int detail)
+{
+ FILE *f = fopen(iName.c_str(), "w");
+ if (f == NULL)
+ return;
+ fprintf(f, "digraph %s {\n", iName.c_str());
+ print_tree_nodes(f, n, detail);
+ print_tree_edges(f, n);
+ fprintf(f, "fontsize=20;\n");
+ fprintf(f, "}\n");
+ fclose(f);
+
+#ifdef HAVE_SYS_WAIT_H
+ pid_t pid = fork();
+ if (pid > 0)
+ {
+ wait(NULL);
+ }
+ else if (pid == 0)
+ {
+ execlp("dotty", "dotty", iName.c_str(), NULL);
+ printf("exec dotty failed\n");
+ exit(1);
+ }
+#endif
+}
+#endif
+
+
+/// Local Variables:
+/// mode: hs-minor
+/// c-basic-offset: 2
+/// End:
Index: dic/regexpmain.cpp
===================================================================
RCS file: dic/regexpmain.cpp
diff -N dic/regexpmain.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/regexpmain.cpp 8 Jan 2008 13:52:36 -0000 1.2
@@ -0,0 +1,169 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Antoine Fraboulet
+ * Authors: Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
+
+/**
+ * \file regexpmain.c
+ * \brief Program used to test regexp
+ * \author Antoine Fraboulet
+ * \date 2005
+ */
+
+#include "config.h"
+
+#include <exception>
+#include <iostream>
+#include <cstdlib>
+#include <cstring>
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext(String)
+#else
+# define _(String) String
+#endif
+
+#include "dic.h"
+#include "regexp.h"
+#include "encoding.h"
+
+
+#define __UNUSED__ __attribute__((unused))
+
+/********************************************************/
+/********************************************************/
+/********************************************************/
+
+const unsigned int all_letter[DIC_LETTERS] =
+{
+ /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 */
+ /* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 */
+ /* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
+ 0,1,1,1,1, 1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1
+};
+
+const unsigned int vowels[DIC_LETTERS] =
+{
+ /* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
+ 0,1,0,0,0, 1,0,0,0,1,0, 0,0,0,0,1,0,0,0,0,0,1,0, 0, 0, 1, 0
+};
+
+const unsigned int consonants[DIC_LETTERS] =
+{
+ /* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
+ 0,0,1,1,1, 0,1,1,1,0,1, 1,1,1,1,0,1,1,1,1,1,0,1, 1, 1, 1, 1
+};
+
+void init_letter_lists(struct search_RegE_list_t *iList)
+{
+ memset (iList, 0, sizeof(*iList));
+ iList->minlength = 1;
+ iList->maxlength = 15;
+ iList->valid[0] = 1; // all letters
+ iList->symbl[0] = RE_ALL_MATCH;
+ iList->valid[1] = 1; // vowels
+ iList->symbl[1] = RE_VOWL_MATCH;
+ iList->valid[2] = 1; // consonants
+ iList->symbl[2] = RE_CONS_MATCH;
+ for (int i = 0; i < DIC_LETTERS; i++)
+ {
+ iList->letters[0][i] = all_letter[i];
+ iList->letters[1][i] = vowels[i];
+ iList->letters[2][i] = consonants[i];
+ }
+ iList->valid[3] = 0; // user defined list 1
+ iList->symbl[3] = RE_USR1_MATCH;
+ iList->valid[4] = 0; // user defined list 2
+ iList->symbl[4] = RE_USR2_MATCH;
+}
+
+/********************************************************/
+/********************************************************/
+/********************************************************/
+void usage(const char *iBinaryName)
+{
+ cerr << _("usage: %s dictionary") << iBinaryName << endl;
+ cerr << _(" dictionary: path to eliot dawg dictionary") << endl;
+}
+
+
+int main(int argc, char* argv[])
+{
+#if HAVE_SETLOCALE
+ // Set locale via LC_ALL
+ setlocale(LC_ALL, "");
+#endif
+
+#if ENABLE_NLS
+ // Set the message domain
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+ if (argc != 2)
+ {
+ usage(argv[0]);
+ return 0;
+ }
+
+ try
+ {
+ Dictionary dic(argv[1]);
+
+ char er[200];
+ strcpy(er, ".");
+
+ struct search_RegE_list_t regList;
+ while (strcmp(er, ""))
+ {
+ cout <<
"**************************************************************" << endl;
+ cout <<
"**************************************************************" << endl;
+ cout << _("enter a regular expression:") << endl;
+ fgets(er, sizeof(er), stdin);
+ /* strip \n */
+ er[strlen(er) - 1] = '\0';
+ if (strcmp(er, "") == 0)
+ break;
+
+ /* automaton */
+ init_letter_lists(®List);
+ list<wstring> wordList;
+ dic.searchRegExp(convertToWc(er), wordList, ®List);
+
+ cout << _("result:") << endl;
+ list<wstring>::const_iterator it;
+ for (it = wordList.begin(); it != wordList.end(); it++)
+ {
+ cerr << convertToMb(*it) << endl;
+ }
+ }
+
+ return 0;
+ }
+ catch (std::exception &e)
+ {
+ std::cerr << e.what() << endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cerr << "Unkown exception taken" << endl;
+ return 1;
+ }
+}
Index: dic/tile.cpp
===================================================================
RCS file: dic/tile.cpp
diff -N dic/tile.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/tile.cpp 8 Jan 2008 13:52:36 -0000 1.2
@@ -0,0 +1,150 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière & Antoine Fraboulet
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ * Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
+
+#include <sstream>
+#include <string>
+#include <wctype.h>
+#include "tile.h"
+#include "header.h"
+#include "encoding.h"
+#include "dic_exception.h"
+
+
+const Header * Tile::m_header = NULL;
+Tile Tile::m_TheJoker;
+
+
+Tile::Tile(wchar_t c)
+{
+ if (iswalpha(c))
+ {
+ m_joker = iswlower(c);
+ m_char = towupper(c);
+ m_code = m_header->getCodeFromChar(m_char);
+ }
+ else if (c == kTILE_JOKER)
+ {
+ m_joker = true;
+ m_char = kTILE_JOKER;
+ m_code = m_header->getCodeFromChar(m_char);
+ }
+ else if (c == kTILE_DUMMY)
+ {
+ // The char and the code are chosen to be different from any possible
+ // real tile
+ m_joker = false;
+ m_char = kTILE_DUMMY;
+ m_code = 0;
+ }
+ else
+ {
+ ostringstream ss;
+ ss << "Tile::Tile: Unknown character: " << convertToMb(c);
+ throw DicException(ss.str());
+ }
+}
+
+
+bool Tile::isVowel() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::isVowel: Invalid tile");
+ return m_header->isVowel(m_code);
+}
+
+
+bool Tile::isConsonant() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::isConsonant: Invalid tile");
+ return m_header->isConsonant(m_code);
+}
+
+
+unsigned int Tile::maxNumber() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::maxNumber: Invalid tile");
+ return m_header->getFrequency(m_code);
+}
+
+
+unsigned int Tile::getPoints() const
+{
+ if (m_code == 0)
+ throw DicException("Tile::getPoints: Invalid tile");
+ return m_header->getPoints(m_code);
+}
+
+
+wchar_t Tile::toChar() const
+{
+ if (m_joker)
+ {
+ if (iswalpha(m_char))
+ return towlower(m_char);
+ else
+ return kTILE_JOKER;
+ }
+ return m_char;
+}
+
+
+unsigned int Tile::toCode() const
+{
+ return m_code;
+}
+
+
+bool Tile::operator<(const Tile &iOther) const
+{
+ if (m_joker)
+ return false;
+ else if (iOther.m_joker)
+ return true;
+ else
+ return m_char < iOther.m_char;
+}
+
+
+bool Tile::operator==(const Tile &iOther) const
+{
+ if (m_joker || iOther.m_joker)
+ {
+ if (m_joker != iOther.m_joker)
+ return false;
+ return m_char == iOther.m_char;
+ }
+ return m_char == iOther.m_char;
+}
+
+
+bool Tile::operator!=(const Tile &iOther) const
+{
+ return !(*this == iOther);
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: dic/tile.h
===================================================================
RCS file: dic/tile.h
diff -N dic/tile.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dic/tile.h 8 Jan 2008 13:52:36 -0000 1.2
@@ -0,0 +1,96 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2005-2007 Olivier Teulière & Antoine Fraboulet
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ * Antoine Fraboulet <antoine.fraboulet @@ free.fr>
+ *
+ * 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
+ *****************************************************************************/
+
+#ifndef _TILE_H_
+#define _TILE_H_
+
+#include <list>
+#include <vector>
+
+using namespace std;
+
+class Header;
+
+
+/*************************
+ * A Tile is the internal representation
+ * used within the game library to
+ * handle letters
+ *************************/
+
+class Tile
+{
+ friend class Dictionary;
+public:
+
+ // a lowercase character is always a joker
+ // - this permits to detect joker in already played games
+ // - we need to pay attention when inserting characters taken
+ // from user input
+
+ Tile(wchar_t c = kTILE_DUMMY);
+
+ bool isEmpty() const { return m_char == kTILE_DUMMY; }
+ bool isJoker() const { return m_joker; }
+ bool isVowel() const;
+ bool isConsonant() const;
+ unsigned int maxNumber() const;
+ unsigned int getPoints() const;
+ wchar_t toChar() const;
+ unsigned int toCode() const;
+
+ static const Tile &Joker() { return m_TheJoker; }
+
+ bool operator <(const Tile &iOther) const;
+ bool operator ==(const Tile &iOther) const;
+ bool operator !=(const Tile &iOther) const;
+
+private:
+ wchar_t m_char;
+ bool m_joker;
+
+ /**
+ * Internal code, used in the dictionary to represent the letter.
+ * It is mainly used by the Cross class.
+ */
+ int m_code;
+
+ static const wchar_t kTILE_DUMMY = L'%';
+ static const wchar_t kTILE_JOKER = L'?';
+
+ // Special tiles are declared static
+ static Tile m_TheJoker;
+
+ /// Dictionary header
+ static const Header *m_header;
+
+ /// Update the dictionary header
+ static void SetHeader(const Header &iHeader) { m_header = &iHeader; }
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: game/move.cpp
===================================================================
RCS file: game/move.cpp
diff -N game/move.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ game/move.cpp 8 Jan 2008 13:52:38 -0000 1.2
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#include <algorithm>
+#include <wctype.h>
+
+#include "move.h"
+
+
+Move::Move(const Round &iRound)
+ : m_score(0), m_round(iRound)
+{
+ m_type = VALID_ROUND;
+ m_score = m_round.getPoints();
+}
+
+
+Move::Move(const wstring &iWord, const wstring &iCoord)
+ : m_word(iWord), m_coord(iCoord)
+{
+ m_type = INVALID_WORD;
+ m_score = 0;
+}
+
+
+Move::Move(const wstring &iLetters)
+ : m_score(0), m_letters(iLetters)
+{
+ // Make the letters uppercase
+ std::transform(m_letters.begin(), m_letters.end(),
+ m_letters.begin(), towupper);
+
+ if (m_letters.empty())
+ m_type = PASS;
+ else
+ m_type = CHANGE_LETTERS;
+}
+
+
+const Round & Move::getRound() const
+{
+ if (m_type != VALID_ROUND)
+ {
+ // FIXME: throw an exception object instead
+ throw 1;
+ }
+ return m_round;
+}
+
+
+const wstring & Move::getBadWord() const
+{
+ if (m_type != INVALID_WORD)
+ {
+ // FIXME: throw an exception object instead
+ throw 1;
+ }
+ return m_word;
+}
+
+
+const wstring & Move::getBadCoord() const
+{
+ if (m_type != INVALID_WORD)
+ {
+ // FIXME: throw an exception object instead
+ throw 1;
+ }
+ return m_coord;
+}
+
+
+const wstring & Move::getChangedLetters() const
+{
+ if (m_type != CHANGE_LETTERS &&
+ m_type != PASS)
+ {
+ // FIXME: throw an exception object instead
+ throw 1;
+ }
+ return m_letters;
+}
+
+
+wstring Move::toString() const
+{
+ // TODO
+ return L"";
+}
+
Index: game/move.h
===================================================================
RCS file: game/move.h
diff -N game/move.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ game/move.h 8 Jan 2008 13:52:38 -0000 1.2
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#ifndef _MOVE_H
+#define _MOVE_H
+
+#include <string>
+
+#include "round.h"
+
+using std::wstring;
+
+
+/**
+ * A Move is what a player can do during the game:
+ * - play a valid word
+ * - play an invalid or misplaced word
+ * - pass the turn (freegame only)
+ * - change letters (freegame only)
+ * - play nothing (timeout) (not supported yet)
+ *
+ * Moves are useful to record what happened, even if the board doesn't keep
+ * a trace of the move (e.g.: an invalid move which was rejected will still
+ * be remembered in the player history).
+ *
+ * Currently, moves are not used by the interfaces (they are only used
+ * internally), but this could change in the future.
+ */
+class Move
+{
+ public:
+ /**
+ * Constructor taking a (valid) round
+ */
+ explicit Move(const Round &iRound);
+
+ /**
+ * Constructor taking a word and its coordinates, corresponding
+ * to an invalid move by the player (invalid word, invalid coordinates,
+ * letters not corresponding to the rack, ...)
+ */
+ explicit Move(const wstring &iWord, const wstring &iCoord);
+
+ /**
+ * Constructor taking letters to change.
+ * An empty string means that the player simply passes without
+ * changing any letter.
+ * The given letters must have been already validated for correctness.
+ */
+ explicit Move(const wstring &iLetters);
+
+ enum Type
+ {
+ VALID_ROUND,
+ INVALID_WORD,
+ PASS,
+ CHANGE_LETTERS
+ };
+
+ /// Return the type of move
+ Type getType() const { return m_type; }
+
+ /// Get the score of this move (0 unless the round is valid)
+ int getScore() const { return m_score; };
+
+ /**
+ * Return the round associated with the move, or throw an exception
+ * if this move was not constructed from a valid round
+ */
+ const Round & getRound() const;
+
+ /**
+ * Return the word played at this move associated with the move, or
+ * throw an exception if this move was not constructed from an invalid
+ * pair (word, coord)
+ */
+ const wstring & getBadWord() const;
+
+ /**
+ * Return the coordinates of the (incorrect) word played at this move,
+ * or throw an exception if this move was not constructed from an
+ * invalid pair (cord, coord)
+ */
+ const wstring & getBadCoord() const;
+
+ /**
+ * Return the changed letters (possibly an empty string if the player
+ * simply wanted to pass the turn), or throw an exception if this move
+ * does not correspond to a passed turn
+ */
+ const wstring & getChangedLetters() const;
+
+ /// To help debugging
+ wstring toString() const;
+
+ private:
+ /// Type of move
+ Type m_type;
+
+ /// Score associated with this move
+ int m_score;
+
+ /// Round played at this turn
+ Round m_round;
+
+ /// Word played (incorrectly)
+ wstring m_word;
+
+ /// Coordinates of the word played (incorrectly)
+ wstring m_coord;
+
+ /// Changed letters (or empty string for passed turn)
+ wstring m_letters;
+};
+
+#endif
+
Index: game/settings.cpp
===================================================================
RCS file: game/settings.cpp
diff -N game/settings.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ game/settings.cpp 8 Jan 2008 13:52:39 -0000 1.2
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#include <cstdlib>
+
+#include "settings.h"
+
+
+Settings *Settings::m_instance = NULL;
+
+
+Settings & Settings::Instance()
+{
+ if (m_instance == NULL)
+ {
+ m_instance = new Settings;
+ }
+ return *m_instance;
+}
+
+
+void Settings::Destroy()
+{
+ delete m_instance;
+ m_instance = NULL;
+}
+
+
+Settings::Settings()
+{
+ // ============== General options ==============
+
+
+ // ============== Training mode options ==============
+
+
+ // ============== Duplicate mode options ==============
+
+ // Minimum number of players in a duplicate game needed to apply a "solo"
bonus
+ // (16 is the ODS value)
+ m_intHandler.addOption("duplicate-solo-players", 16);
+ // Number of points granted for a solo (10 is the ODS value)
+ m_intHandler.addOption("duplicate-solo-value", 10);
+
+ // If true, Eliot complains when the player does something illegal
+ // If false, the word is accepted (with a score of 0) and the player does
+ // not get a second chance
+ m_boolHandler.addOption("duplicate-reject-invalid", false);
+
+
+ // ============== Freegame mode options ==============
+
+ // If true, Eliot complains when the player does something illegal
+ // If false, the word is accepted (with a score of 0) and the player does
+ // not get a second chance.
+ // Trying to change letters or to pass the turn in an incorrect way will
+ // be rejected in any case.
+ m_boolHandler.addOption("freegame-reject-invalid", false);
+}
+
+
+void Settings::setBool(const string &iName, bool iValue)
+{
+ m_boolHandler.setOption(iName, iValue);
+}
+
+
+bool Settings::getBool(const string &iName) const
+{
+ return m_boolHandler.getOption(iName);
+}
+
+
+void Settings::setInt(const string &iName, int iValue)
+{
+ m_intHandler.setOption(iName, iValue);
+}
+
+
+int Settings::getInt(const string &iName) const
+{
+ return m_intHandler.getOption(iName);
+}
+
+
+template <typename T>
+void Settings::OptionsHandler<T>::addOption(const string &iName, const T
&iValue)
+{
+ m_options[iName] = iValue;
+}
+
+
+template <typename T>
+void Settings::OptionsHandler<T>::setOption(const string &iName, const T
&iValue)
+{
+ typename map<string, T>::iterator it = m_options.find(iName);
+ if (it == m_options.end())
+ {
+ // FIXME: throw an exception object instead
+ throw 1;
+ }
+ it->second = iValue;
+}
+
+
+template <typename T>
+const T& Settings::OptionsHandler<T>::getOption(const string &iName) const
+{
+ typename map<string, T>::const_iterator it = m_options.find(iName);
+ if (it == m_options.end())
+ {
+ // FIXME: throw an exception object instead
+ throw 1;
+ }
+ return it->second;
+}
+
Index: game/settings.h
===================================================================
RCS file: game/settings.h
diff -N game/settings.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ game/settings.h 8 Jan 2008 13:52:39 -0000 1.2
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2007 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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
+ *****************************************************************************/
+
+#ifndef _SETTINGS_H_
+#define _SETTINGS_H_
+
+#include <string>
+#include <map>
+
+using std::string;
+using std::map;
+
+
+/**
+ * This class centralizes the various configuration options of Eliot.
+ * It implements the Singleton pattern.
+ *
+ * Currently, there are few settings, and their initial value is hard-coded.
+ * In a later phase, this class will be able to export/import settings
+ * to/from a configuration file, and it should be possible to override
+ * configuration settings with settings given on the command-line (TODO).
+ * The boost::program_options library could be useful for this.
+ *
+ * This class will also be helpful for the "Settings" dialog box of the GUI.
+ */
+class Settings
+{
+public:
+ /// Access to the singleton
+ static Settings& Instance();
+ /// Destroy the singleton cleanly
+ static void Destroy();
+
+ void setBool(const string &iName, bool iValue);
+ bool getBool(const string &iName) const;
+
+ void setInt(const string &iName, int iValue);
+ int getInt(const string &iName) const;
+
+private:
+
+ /**
+ * This nested class is simply there to handle storage and retrieval
+ * for options of a particular type (and factorize code)
+ */
+ template <typename T>
+ class OptionsHandler
+ {
+ public:
+ /// Set the value of an option
+ /**
+ * If the option already exists, its value is replaced,
+ * otherwise the option is created
+ */
+ void addOption(const string &iName, const T &iValue);
+
+ /**
+ * Change the value of an existing option.
+ * An exception is thrown if the option doesn't exist yet
+ */
+ void setOption(const string &iName, const T &iValue);
+
+ /**
+ * Query the value of an option.
+ * An exception is thrown if the option doesn't exist
+ */
+ const T& getOption(const string &iName) const;
+
+ private:
+ map<string, T> m_options;
+ };
+
+
+ /// Singleton instance
+ static Settings *m_instance;
+ Settings();
+
+ /// The settings can be of various types
+ OptionsHandler<bool> m_boolHandler;
+ OptionsHandler<int> m_intHandler;
+ // Add types as needed...
+
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: m4/ax_boost_base.m4
===================================================================
RCS file: m4/ax_boost_base.m4
diff -N m4/ax_boost_base.m4
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ m4/ax_boost_base.m4 8 Jan 2008 13:52:40 -0000 1.2
@@ -0,0 +1,198 @@
+##### http://autoconf-archive.cryp.to/ax_boost_base.html
+#
+# SYNOPSIS
+#
+# AX_BOOST_BASE([MINIMUM-VERSION])
+#
+# DESCRIPTION
+#
+# Test for the Boost C++ libraries of a particular version (or newer)
+#
+# If no path to the installed boost library is given the macro
+# searchs under /usr, /usr/local, and /opt, and evaluates the
+# $BOOST_ROOT environment variable. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
+#
+# And sets:
+#
+# HAVE_BOOST
+#
+# LAST MODIFICATION
+#
+# 2007-03-15
+#
+# COPYLEFT
+#
+# Copyright (c) 2007 Thomas Porschberg <address@hidden>
+#
+# Copying and distribution of this file, with or without
+# modification, are permitted in any medium without royalty provided
+# the copyright notice and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_BASE],
+[
+AC_ARG_WITH([boost],
+ AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes)
- it is possible to specify the root directory for boost (optional)]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ac_boost_path=""
+ else
+ want_boost="yes"
+ ac_boost_path="$withval"
+ fi
+ ],
+ [want_boost="yes"])
+
+if test "x$want_boost" = "xyes"; then
+ boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
+ boost_lib_version_req_shorten=`expr $boost_lib_version_req :
'\([[0-9]]*\.[[0-9]]*\)'`
+ boost_lib_version_req_major=`expr $boost_lib_version_req :
'\([[0-9]]*\)'`
+ boost_lib_version_req_minor=`expr $boost_lib_version_req :
'[[0-9]]*\.\([[0-9]]*\)'`
+ boost_lib_version_req_sub_minor=`expr $boost_lib_version_req :
'[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+ if test "x$boost_lib_version_req_sub_minor" = "x" ; then
+ boost_lib_version_req_sub_minor="0"
+ fi
+ WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+
$boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
+ AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
+ succeeded=no
+
+ dnl first we check the system location for boost libraries
+ dnl this location ist chosen if boost libraries are installed with the
--layout=system option
+ dnl or if you install boost with RPM
+ if test "$ac_boost_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_path/lib"
+ BOOST_CPPFLAGS="-I$ac_boost_path/include"
+ else
+ for ac_boost_path_tmp in /usr /usr/local /opt ; do
+ if test -d "$ac_boost_path_tmp/include/boost" && test
-r "$ac_boost_path_tmp/include/boost"; then
+ BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
+ BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+ break;
+ fi
+ done
+ fi
+
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+
+
+
+ dnl if we found no boost with system layout we search for boost
libraries
+ dnl built and installed without the --layout=system option or for a
staged(not installed) version
+ if test "x$succeeded" != "xyes"; then
+ _version=0
+ if test "$ac_boost_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_path/lib"
+ if test -d "$ac_boost_path" && test -r
"$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-*
2>/dev/null`; do
+ _version_tmp=`echo $i | sed
"s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \>
$_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ fi
+ VERSION_UNDERSCORE=`echo $_version |
sed 's/\./_/'`
+
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
+ done
+ fi
+ else
+ for ac_boost_path in /usr /usr/local /opt ; do
+ if test -d "$ac_boost_path" && test -r
"$ac_boost_path"; then
+ for i in `ls -d
$ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed
"s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \>
$_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ best_path=$ac_boost_path
+ fi
+ done
+ fi
+ done
+
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
+ BOOST_LDFLAGS="-L$best_path/lib"
+
+ if test "x$BOOST_ROOT" != "x"; then
+ if test -d "$BOOST_ROOT" && test -r
"$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r
"$BOOST_ROOT/stage/lib"; then
+ version_dir=`expr //$BOOST_ROOT :
'.*/\(.*\)'`
+ stage_version=`echo $version_dir | sed
's/boost_//' | sed 's/_/./g'`
+ stage_version_shorten=`expr
$stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
+ V_CHECK=`expr $stage_version_shorten
\>\= $_version`
+ if test "$V_CHECK" = "1" ; then
+ AC_MSG_NOTICE(We will use a
staged boost library from $BOOST_ROOT)
+ BOOST_CPPFLAGS="-I$BOOST_ROOT"
+
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
+ fi
+ fi
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[
+ ])
+ AC_LANG_POP([C++])
+ fi
+
+ if test "$succeeded" != "yes" ; then
+ if test "$_version" = "0" ; then
+ AC_MSG_ERROR([[We could not detect the boost libraries
(version $boost_lib_version_req_shorten or higher). If you have a staged boost
library (still not installed) please specify \$BOOST_ROOT in your environment
and do not give a PATH to --with-boost option. If you are sure you have boost
installed, then check your version number looking in <boost/version.hpp>. See
http://randspringer.de/boost for more documentation.]])
+ else
+ AC_MSG_NOTICE([Your boost libraries seems to old
(version $_version).])
+ fi
+ else
+ AC_SUBST(BOOST_CPPFLAGS)
+ AC_SUBST(BOOST_LDFLAGS)
+ AC_DEFINE(HAVE_BOOST,,[define if the Boost library is
available])
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+fi
+
+])
Index: test/duplicate_humans_ai.input
===================================================================
RCS file: test/duplicate_humans_ai.input
diff -N test/duplicate_humans_ai.input
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/duplicate_humans_ai.input 8 Jan 2008 13:52:41 -0000 1.2
@@ -0,0 +1,20 @@
+d 2 1
+a T
+j DOSAIT H4
+j DOSAIT h5
+a S
+a T
+n 1
+j DISAIENT 11A
+a S
+j DESTINAI 11E
+a S
+a t
+j FRiPE 10K
+j sERF M11
+a S
+a t
+a g
+a p
+q
+q
Index: test/duplicate_humans_ai.ref
===================================================================
RCS file: test/duplicate_humans_ai.ref
diff -N test/duplicate_humans_ai.ref
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/duplicate_humans_ai.ref 8 Jan 2008 13:52:41 -0000 1.2
@@ -0,0 +1,78 @@
+[?] pour l'aide
+commande> d 2 1
+mode duplicate
+[?] pour l'aide
+commande> a T
+Joueur 0: ATOYDSI
+Joueur 1: ATOYDSI
+Joueur 2: ATOYDSI
+commande> j DOSAIT H4
+commande> j DOSAIT h5
+commande> a S
+Joueur 0: 18
+Joueur 1: 14
+Joueur 2: 30
+commande> a T
+Joueur 0: DIAEINS
+Joueur 1: DIAEINS
+Joueur 2: DIAEINS
+commande> n 1
+commande> j DISAIENT 11A
+commande> a S
+Joueur 0: 18
+Joueur 1: 82
+Joueur 2: 30
+commande> j DESTINAI 11E
+commande> a S
+Joueur 0: 104
+Joueur 1: 82
+Joueur 2: 116
+commande> a t
+P?RBFEG
+commande> j FRiPE 10K
+commande> j sERF M11
+commande> a S
+Joueur 0: 126
+Joueur 1: 103
+Joueur 2: 145
+commande> a t
+BGEEMTB
+commande> a g
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ A - - - - - - - - - - - F - - -
+ B - - - - - - - - - - - R - - -
+ C - - - - - - - - - - - i - - -
+ D - - - - - - - - - - - P - - -
+ E - - - - - - - - - - D E - - -
+ F - - - - - - - - - - E - - - -
+ G - - - - - - - - - - S - - - -
+ H - - - - - - - O Y A T S - - -
+ I - - - - - - - - - - I - - - -
+ J - - - - - - - - - - N - - - -
+ K - - - - - - - - - - A - - - -
+ L - - - - - - - - - - I - - - -
+ M - - - - - - - - - - - - - - -
+ N - - - - - - - - - - - - - - -
+ O - - - - - - - - - - - - - - -
+commande> a p
+Eliot 1.5
+
+Game type: Duplicate
+Player 0: Human
+Player 1: Human
+Player 2: Computer
+
+ N | RACK | SOLUTION | REF | PTS | P | BONUS
+ ===|==========|=================|=====|=====|===|======
+ 1 | ATOYDSI | OYATS | H8 | 30 | 2 |
+ 2 | DI+AEINS | DESTINAI | 11E | 86 | 0 | *
+ 3 | P?RBFEG | FRiPE | 12A | 29 | 2 |
+
+ Total: 145
+
+Rack 0: BG+EEMTB
+Rack 1: BG+EEMTB
+Rack 2: BG+EEMTB
+commande> q
+fin du mode duplicate
+commande> q
Index: test/training_7pl1.input
===================================================================
RCS file: test/training_7pl1.input
diff -N test/training_7pl1.input
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/training_7pl1.input 8 Jan 2008 13:52:41 -0000 1.2
@@ -0,0 +1,6 @@
+e
+b p maison
+b p noword
+b p zeuer
+q
+q
Index: test/training_7pl1.ref
===================================================================
RCS file: test/training_7pl1.ref
diff -N test/training_7pl1.ref
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/training_7pl1.ref 8 Jan 2008 13:52:41 -0000 1.2
@@ -0,0 +1,84 @@
+[?] pour l'aide
+commande> e
+mode entraînement
+[?] pour l'aide
+commande> b p maison
+ AIMONS
+ AMNIOS
+ MAISON
++A
+ OMANAIS
++B
+ ABIMONS
++C
+ CAMIONS
+ MANIOCS
++D
+ AMIDONS
+ DAMIONS
+ DOMINAS
+ MADISON
+ MONDAIS
++E
+ ANOMIES
+ ANOSMIE
++G
+ GOMINAS
++I
+ AIMIONS
++L
+ LAMIONS
+ OSMANLI
++M
+ NOMMAIS
++N
+ ANIMONS
+ MANIONS
+ MANNOIS
+ MANSION
+ NOMINAS
++P
+ PAMIONS
++R
+ ARMIONS
+ MANOIRS
+ MARIONS
+ MINORAS
+ NORMAIS
+ RAMIONS
+ ROMAINS
+ ROMANIS
++S
+ MAISONS
++T
+ MATIONS
+ MOISANT
+ MONTAIS
++Z
+ MAZIONS
+commande> b p noword
+commande> b p zeuer
++A
+ AZUREE
++C
+ ECUREZ
++H
+ HUEREZ
++M
+ MUEREZ
+ REMUEZ
++N
+ NUEREZ
++P
+ EPUREZ
+ PUEREZ
++R
+ RUEREZ
++S
+ SUEREZ
+ USEREZ
++T
+ TUEREZ
+commande> q
+fin du mode entraînement
+commande> q
Index: test/training_benj.input
===================================================================
RCS file: test/training_benj.input
diff -N test/training_benj.input
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/training_benj.input 8 Jan 2008 13:52:42 -0000 1.2
@@ -0,0 +1,6 @@
+e
+b b maison
+b b animal
+b b jures
+q
+q
Index: test/training_benj.ref
===================================================================
RCS file: test/training_benj.ref
diff -N test/training_benj.ref
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/training_benj.ref 8 Jan 2008 13:52:42 -0000 1.2
@@ -0,0 +1,14 @@
+[?] pour l'aide
+commande> e
+mode entraînement
+[?] pour l'aide
+commande> b b maison
+PLUmaison
+commande> b b animal
+commande> b b jures
+CONjures
+GOUjures
+PARjures
+commande> q
+fin du mode entraînement
+commande> q
Index: test/training_racc.input
===================================================================
RCS file: test/training_racc.input
diff -N test/training_racc.input
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/training_racc.input 8 Jan 2008 13:52:42 -0000 1.2
@@ -0,0 +1,6 @@
+e
+b r ave
+b r yeux
+b r ka
+q
+q
Index: test/training_racc.ref
===================================================================
RCS file: test/training_racc.ref
diff -N test/training_racc.ref
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/training_racc.ref 8 Jan 2008 13:52:42 -0000 1.2
@@ -0,0 +1,26 @@
+[?] pour l'aide
+commande> e
+mode entraînement
+[?] pour l'aide
+commande> b r ave
+Bave
+Cave
+Gave
+Have
+Lave
+Nave
+Pave
+Rave
+aveC
+aveN
+aveU
+aveZ
+commande> b r yeux
+commande> b r ka
+Oka
+Ska
+kaN
+kaS
+commande> q
+fin du mode entraînement
+commande> q
Index: dic/alist.c
===================================================================
RCS file: dic/alist.c
diff -N dic/alist.c
--- dic/alist.c 4 Aug 2007 20:01:28 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,201 +0,0 @@
-/* Eliot */
-/* Copyright (C) 2005 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file alist.c
- * \brief List type used by automaton
- * \author Antoine Fraboulet
- * \date 2005
- */
-
-#include <stdlib.h>
-#include "alist.h"
-
-#define __UNUSED__ __attribute__((unused))
-
-struct alist_elt_t {
- void* info;
- alist_elt next;
-};
-
-struct alist_t {
- int size;
- void (*delete_function)(void*);
- alist_elt start;
-};
-
-
-void*
-alist_elt_get_value(alist_elt e)
-{
- return e->info;
-}
-
-alist_elt
-alist_elt_create(void* info)
-{
- alist_elt e;
- e = (alist_elt)malloc(sizeof(struct alist_elt_t));
- e->info = info;
- e->next = NULL;
- return e;
-}
-
-/* ************************************************** */
-/* ************************************************** */
-/* ************************************************** */
-
-alist
-alist_create()
-{
- alist l;
- l = (alist)malloc(sizeof(struct alist_t));
- l->size = 0;
- l->start = NULL;
- l->delete_function = NULL;
- return l;
-}
-
-alist
-alist_clone(alist l)
-{
- alist t;
- alist_elt ptr;
- t = alist_create();
- for(ptr = alist_get_first(l); ptr ; ptr = alist_get_next(l,ptr))
- {
- alist_add(t,alist_elt_get_value(ptr));
- }
- return t;
-}
-
-void
-alist_set_delete (alist l, void (*f)(void*))
-{
- l->delete_function = f;
-}
-
-static void
-alist_delete_rec(alist_elt e, void (*delete_function)(void*))
-{
- if (e != NULL)
- {
- alist_delete_rec(e->next, delete_function);
- if (delete_function)
- delete_function(e->info);
- e->info = NULL;
- free(e);
- }
-}
-
-void
-alist_delete(alist l)
-{
- alist_delete_rec(l->start,l->delete_function);
- free(l);
-}
-
-void
-alist_add(alist l, void* value)
-{
- alist_elt e;
- e = alist_elt_create(value);
- e->next = l->start;
- l->start = e;
- l->size ++;
-}
-
-int
-alist_is_in(alist l, void* e)
-{
- alist_elt ptr;
- for(ptr = alist_get_first(l); ptr; ptr = alist_get_next(l,ptr))
- if (alist_elt_get_value(ptr) == e)
- return 1;
- return 0;
-}
-
-int
-alist_equal(alist id1, alist id2)
-{
- alist_elt e1;
-
- if (alist_get_size(id1) != alist_get_size(id2))
- return 0;
-
- for(e1 = alist_get_first(id1) ; e1 ; e1 = alist_get_next(id1,e1))
- {
- if (! alist_is_in(id2, alist_elt_get_value(e1)))
- return 0;
- }
-
- return 1;
-}
-
-void
-alist_insert(alist dst, alist src)
-{
- alist_elt ptr;
- for(ptr = alist_get_first(src); ptr ; ptr = alist_get_next(src,ptr))
- {
- void *e = alist_elt_get_value(ptr);
- if (! alist_is_in(dst,e))
- alist_add(dst,e);
- }
-}
-
-alist_elt
-alist_get_first(alist l)
-{
- return l->start;
-}
-
-alist_elt
-alist_get_next(alist __UNUSED__ l, alist_elt e)
-{
- return e->next;
-}
-
-void*
-alist_pop_first_value(alist l)
-{
- void* p = NULL;
- alist_elt e = l->start;
- if (e)
- {
- l->start = e->next;
- e->next = NULL;
- p = e->info;
- l->size --;
- alist_delete_rec(e,l->delete_function);
- }
- return p;
-}
-
-int
-alist_get_size(alist l)
-{
- return l->size;
-}
-
-int
-alist_is_empty(alist l)
-{
- return l->size == 0;
-}
Index: dic/alist.h
===================================================================
RCS file: dic/alist.h
diff -N dic/alist.h
--- dic/alist.h 1 Jan 2006 19:51:00 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,98 +0,0 @@
-/* Eliot */
-/* Copyright (C) 2005 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file alist.h
- * \brief List type used by automaton
- * \author Antoine Fraboulet
- * \date 2005
- */
-
-#ifndef _ALIST_H_
-#define _ALIST_H_
-#if defined(__cplusplus)
-extern "C"
- {
-#endif
-
- /**
- * untyped list type element
- */
- typedef struct alist_elt_t* alist_elt;
-
- /**
- * extract the value from an alist element
- * result is untyped si the user should know
- * what the value type is
- */
- void* alist_elt_get_value(alist_elt);
-
- /**
- * untyped list type
- */
- typedef struct alist_t* alist;
-
- /**
- * list creation
- * @returns list
- */
- alist alist_create ();
- alist alist_clone (alist);
-
- /**
- * funtion to use on data during list deletion.
- */
- void alist_set_delete (alist,void (*f)(void*));
-
- /**
- * delete a complete list.
- */
- void alist_delete (alist);
-
- /**
- * add a element to the list
- */
- void alist_add (alist, void*);
- void alist_insert (alist, alist);
- /**
- * get first element
- */
- int alist_is_in (alist l, void* e);
- int alist_equal (alist , alist);
-
- alist_elt alist_get_first (alist);
-
- /**
- * get next element from current
- */
- alist_elt alist_get_next (alist,alist_elt);
-
- /**
- * @returns 0 or 1
- */
- int alist_is_empty (alist);
-
- int alist_get_size (alist);
-
- void* alist_pop_first_value (alist);
-
-#if defined(__cplusplus)
- }
-#endif
-#endif /* _ALIST_H_ */
Index: dic/automaton.c
===================================================================
RCS file: dic/automaton.c
diff -N dic/automaton.c
--- dic/automaton.c 4 Aug 2007 20:01:28 -0000 1.13
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,679 +0,0 @@
-/* Eliot */
-/* Copyright (C) 2005 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file automaton.c
- * \brief (Non)Deterministic Finite Automaton for Regexp
- * \author Antoine Fraboulet
- * \date 2005
- */
-
-#include "config.h"
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#include <unistd.h>
-
-#include "dic.h"
-#include "regexp.h"
-#include "alist.h"
-#include "automaton.h"
-
-#ifdef DEBUG_AUTOMATON
-#define DMSG(a) a
-#else
-#define DMSG(a)
-#endif
-
-#define MAX_TRANSITION_LETTERS 256
-
-typedef struct automaton_state_t *astate;
-typedef struct Automaton_t *Automaton;
-
-/* ************************************************** *
- exported functions for static automata
- * ************************************************** */
-
-automaton automaton_build (int init_state, int *ptl, int *PS, struct
search_RegE_list_t *list);
-void automaton_delete (automaton a);
-int automaton_get_nstate (automaton a);
-int automaton_get_init (automaton a);
-int automaton_get_accept (automaton a, int state);
-int automaton_get_next_state (automaton a, int start, char l);
-void automaton_dump (automaton a, char* filename);
-
-
-/* ************************************************** *
- static functions for dynamic automata
- * ************************************************** */
-
-static Automaton s_automaton_create ();
-static void s_automaton_delete (Automaton a);
-
-static alist s_automaton_id_create (int id);
-static astate s_automaton_state_create (alist id);
-
-static void s_automaton_add_state (Automaton a, astate s);
-static astate s_automaton_get_state (Automaton a, alist id);
-
-static Automaton s_automaton_PS_to_NFA (int init_state, int *ptl, int
*PS);
-static Automaton s_automaton_NFA_to_DFA (Automaton a, struct
search_RegE_list_t *list);
-static automaton s_automaton_finalize (Automaton a);
-
-#ifdef DEBUG_AUTOMATON
-static char* s_automaton_id_to_str (alist id);
-static void s_automaton_dump (Automaton a, char* filename);
-#endif
-
-/* ************************************************** *
- data types
- * ************************************************** */
-
-struct automaton_state_t {
- alist id; // alist of int
- int accept;
- int id_static;
- astate next[MAX_TRANSITION_LETTERS];
-};
-
-struct Automaton_t {
- int nstates;
- astate init_state;
- alist states; // alist of alist of int
-};
-
-struct automaton_t {
- int nstates;
- int init;
- int *accept;
- int **trans;
-};
-
-/* ************************************************** *
- exported functions for static automata
- * ************************************************** */
-
-automaton automaton_build(int init_state, int *ptl, int *PS, struct
search_RegE_list_t *list)
-{
- Automaton nfa,dfa;
- automaton final;
-
- nfa = s_automaton_PS_to_NFA(init_state,ptl,PS);
- DMSG(printf("\n non deterministic automaton OK \n\n"));
- DMSG(s_automaton_dump(nfa,"auto_nfa"));
-
- dfa = s_automaton_NFA_to_DFA(nfa, list);
- DMSG(printf("\n deterministic automaton OK \n\n"));
- DMSG(s_automaton_dump(dfa,"auto_dfa"));
-
- final = s_automaton_finalize(dfa);
- DMSG(printf("\n final automaton OK \n\n"));
- DMSG(automaton_dump(final,"auto_fin"));
-
- s_automaton_delete(nfa);
- s_automaton_delete(dfa);
- return final;
-}
-
-void automaton_delete(automaton a)
-{
- int i;
- free(a->accept);
- for(i=0; i <= a->nstates; i++)
- free(a->trans[i]);
- free(a->trans);
- free(a);
-}
-
-inline int automaton_get_nstates(automaton a)
-{
- return a->nstates;
-}
-
-inline int automaton_get_init(automaton a)
-{
- return a->init;
-}
-
-inline int automaton_get_accept(automaton a, int state)
-{
- return a->accept[state];
-}
-
-inline int automaton_get_next_state(automaton a, int state, char l)
-{
- return a->trans[state][(int)l];
-}
-
-void automaton_dump(automaton a, char* filename)
-{
- int i,l;
- FILE* f;
-#ifdef HAVE_SYS_WAIT_H
- pid_t pid;
-#endif
-
- if (a == NULL)
- return ;
- f=fopen(filename,"w");
- fprintf(f,"digraph automaton {\n");
- for(i=1; i<=a->nstates; i++)
- {
- fprintf(f,"\t%d [label = \"%d\"",i,i);
- if (i == a->init)
- fprintf(f,", style = filled, color=lightgrey");
- if (a->accept[i])
- fprintf(f,", shape = doublecircle");
- fprintf(f,"];\n");
- }
- fprintf(f,"\n");
- for(i=1; i<=a->nstates; i++)
- for(l=0; l < MAX_TRANSITION_LETTERS; l++)
- if (a->trans[i][l])
- {
- fprintf(f,"\t%d -> %d [label = \"",i,a->trans[i][l]);
- regexp_print_letter(f,l);
- fprintf(f,"\"];\n");
- }
- fprintf(f,"fontsize=20;\n");
- fprintf(f,"}\n");
- fclose(f);
-
-#ifdef HAVE_SYS_WAIT_H
- pid = fork ();
- if (pid > 0) {
- wait(NULL);
- } else if (pid == 0) {
- execlp("dotty","dotty",filename,NULL);
- printf("exec dotty failed\n");
- exit(1);
- }
-#endif
-}
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
-
-void state_delete_fun(void* ps)
-{
- astate s = ps;
- alist_delete(s->id);
- free(s);
-}
-
-static Automaton s_automaton_create()
-{
- Automaton a;
- a = (Automaton)malloc(sizeof(struct Automaton_t));
- a->nstates = 0;
- a->init_state = NULL;
- a->states = alist_create();
- alist_set_delete(a->states,state_delete_fun);
- return a;
-}
-
-
-static void s_automaton_delete(Automaton a)
-{
- alist_delete(a->states);
- free(a);
-}
-
-static alist s_automaton_id_create(int id)
-{
- alist a = alist_create();
- alist_add(a,(void*)((unsigned long)id));
- return a;
-}
-
-static astate s_automaton_state_create(alist id)
-{
- astate s;
- s = (astate)malloc(sizeof(struct automaton_state_t));
- s->id = id;
- s->accept = 0;
- memset(s->next,0,sizeof(astate)*MAX_TRANSITION_LETTERS);
- DMSG(printf("** state %s creation\n",s_automaton_id_to_str(id)));
- return s;
-}
-
-static void s_automaton_add_state(Automaton a, astate s)
-{
- a->nstates ++;
- alist_add(a->states,(void*)s);
- DMSG(printf("** state %s added to
automaton\n",s_automaton_id_to_str(s->id)));
-}
-
-static astate s_automaton_get_state(Automaton a, alist id)
-{
- astate s;
- alist_elt ptr;
- for(ptr = alist_get_first(a->states) ; ptr ; ptr =
alist_get_next(a->states,ptr))
- {
- s = alist_elt_get_value(ptr);
- if (alist_equal(s->id,id))
- {
- //DMSG(printf("** get state %s ok\n",s_automaton_id_to_str(s->id)));
- return s;
- }
- }
- return NULL;
-}
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
-
-Automaton s_automaton_PS_to_NFA(int init_state_id, int *ptl, int *PS)
-{
- int p;
- int maxpos = PS[0];
- Automaton nfa = NULL;
- alist temp_id;
- alist_elt ptr;
- astate temp_state,current_state;
- alist L;
- char used_letter[MAX_TRANSITION_LETTERS];
-
- nfa = s_automaton_create();
- L = alist_create();
-
- /* 1: init_state = root->PP */
- temp_id = s_automaton_id_create(init_state_id);
- temp_state = s_automaton_state_create(temp_id);
- nfa->init_state = temp_state;
- s_automaton_add_state(nfa,temp_state);
- alist_add(L,temp_state);
- /* 2: while \exist state \in state_list */
- while (! alist_is_empty(L))
- {
- current_state = (astate)alist_pop_first_value(L);
- DMSG(printf("** current state =
%s\n",s_automaton_id_to_str(current_state->id)));
- memset(used_letter,0,sizeof(used_letter));
- /* 3: \foreach l in \sigma | l \neq # */
- for(p=1; p < maxpos; p++)
- {
- int current_letter = ptl[p];
- if (used_letter[current_letter] == 0)
- {
- /* 4: int set = \cup { PS(pos) | pos \in state \wedge pos == l }
*/
- int pos, ens = 0;
- for(pos = 1; pos <= maxpos; pos++)
- {
- if (ptl[pos] == current_letter &&
- (unsigned
long)alist_elt_get_value(alist_get_first(current_state->id)) & (1 << (pos - 1)))
- ens |= PS[pos];
- }
- /* 5: transition from current_state to temp_state */
- if (ens)
- {
- temp_id = s_automaton_id_create(ens);
- temp_state = s_automaton_get_state(nfa,temp_id);
- if (temp_state == NULL)
- {
- temp_state = s_automaton_state_create(temp_id);
- s_automaton_add_state (nfa,temp_state);
- current_state->next[current_letter] = temp_state;
- alist_add(L,temp_state);
- }
- else
- {
- alist_delete(temp_id);
- current_state->next[current_letter] = temp_state;
- }
- }
- used_letter[current_letter] = 1;
- }
- }
- }
-
- alist_delete(L);
-
- for(ptr = alist_get_first(nfa->states); ptr ; ptr =
alist_get_next(nfa->states,ptr))
- {
- astate s = (astate)alist_elt_get_value(ptr);
- if ((unsigned long)alist_elt_get_value(alist_get_first(s->id)) & (1 <<
(maxpos - 1)))
- s->accept = 1;
- }
-
- return nfa;
-}
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
-
-static alist s_automaton_successor(alist S, int letter, Automaton nfa, struct
search_RegE_list_t *list)
-{
- alist R,r;
- alist_elt ptr;
- R = alist_create(); /* R = \empty */
- /* \forall y \in S
*/
- for(ptr = alist_get_first(S); ptr ; ptr = alist_get_next(S,ptr))
- {
- int i;
- alist t, Ry; astate y,z;
-
- i = (unsigned long)alist_elt_get_value(ptr);
- t = s_automaton_id_create(i);
- assert(y = s_automaton_get_state(nfa,t));
- alist_delete(t);
-
- Ry = alist_create(); /* Ry = \empty
*/
-
- if ((z = y->next[letter]) != NULL) /* \delta (y,z) = l
*/
- {
- r = s_automaton_successor(z->id,RE_EPSILON,nfa, list);
- alist_insert(Ry,r);
- alist_delete(r);
- alist_insert(Ry,z->id); /* Ry = Ry \cup
succ(z) */
- }
-
- /* \epsilon transition from start node */
- if ((z = y->next[RE_EPSILON]) != NULL) /* \delta (y,z) =
\epsilon */
- {
- r = s_automaton_successor(z->id,letter,nfa, list);
- alist_insert(Ry,r); /* Ry = Ry \cup
succ(z) */
- alist_delete(r);
- }
-
- if (letter < RE_FINAL_TOK)
- {
- for(i = 0 ; i < DIC_SEARCH_REGE_LIST ; i++)
- if (list->valid[i])
- {
- if (list->letters[i][letter] && (z =
y->next[(int)list->symbl[i]]) != NULL)
- {
- DMSG(printf("*** letter "));
- DMSG(regexp_print_letter(stdout,letter));
- DMSG(printf("is in "));
- DMSG(regexp_print_letter(stdout,i));
-
- r = s_automaton_successor(z->id,RE_EPSILON,nfa, list);
- alist_insert(Ry,r);
- alist_delete(r);
- alist_insert(Ry,z->id);
- }
- }
- }
-
-#if 0
- if (alist_is_empty(Ry)) /* Ry = \empty
*/
- return Ry;
-#endif
-
- alist_insert(R,Ry); /* R = R \cup Ry
*/
- alist_delete(Ry);
- }
-
- return R;
-}
-
-static void s_automaton_node_set_accept(astate s, Automaton nfa)
-{
- void* idx;
- alist_elt ptr;
-
- DMSG(printf("=== setting accept for node (%s)
:",s_automaton_id_to_str(s->id)));
- for(ptr = alist_get_first(nfa->states) ; ptr ; ptr =
alist_get_next(nfa->states,ptr))
- {
- astate ns = (astate)alist_elt_get_value(ptr);
- idx = alist_elt_get_value(alist_get_first(ns->id));
- DMSG(printf("%s ",s_automaton_id_to_str(ns->id)));
- if (ns->accept && alist_is_in(s->id,idx))
- {
- DMSG(printf("(ok) "));
- s->accept = 1;
- }
- }
- DMSG(printf("\n"));
-}
-
-static Automaton s_automaton_NFA_to_DFA(Automaton nfa, struct
search_RegE_list_t *list)
-{
- Automaton dfa = NULL;
- alist temp_id;
- alist_elt ptr;
- astate temp_state, current_state;
- alist L;
- int letter;
-
- dfa = s_automaton_create();
- L = alist_create();
-
- temp_id = alist_clone(nfa->init_state->id);
- temp_state = s_automaton_state_create(temp_id);
- dfa->init_state = temp_state;
- s_automaton_add_state(dfa,temp_state);
- alist_add(L,temp_state);
- while (! alist_is_empty(L))
- {
- current_state = (astate)alist_pop_first_value(L);
- DMSG(printf("** current state =
%s\n",s_automaton_id_to_str(current_state->id)));
- for(letter = 1; letter < DIC_LETTERS; letter++)
- {
- // DMSG(printf("*** start successor of
%s\n",s_automaton_id_to_str(current_state->id)));
-
- temp_id = s_automaton_successor(current_state->id,letter,nfa,list);
-
- if (! alist_is_empty(temp_id))
- {
-
- DMSG(printf("*** successor of %s for
",s_automaton_id_to_str(current_state->id)));
- DMSG(regexp_print_letter(stdout,letter));
- DMSG(printf(" = %s\n", s_automaton_id_to_str(temp_id)));
-
- temp_state = s_automaton_get_state(dfa,temp_id);
-
- // DMSG(printf("*** automaton get state -%s-
ok\n",s_automaton_id_to_str(temp_id)));
-
- if (temp_state == NULL)
- {
- temp_state = s_automaton_state_create(temp_id);
- s_automaton_add_state(dfa,temp_state);
- current_state->next[letter] = temp_state;
- alist_add(L,temp_state);
- }
- else
- {
- alist_delete(temp_id);
- current_state->next[letter] = temp_state;
- }
- }
- else
- {
- alist_delete(temp_id);
- }
- }
- }
-
- for(ptr = alist_get_first(dfa->states) ; ptr ; ptr =
alist_get_next(dfa->states,ptr))
- {
- astate s = (astate)alist_elt_get_value(ptr);
- s_automaton_node_set_accept(s,nfa);
- }
-
- alist_delete(L);
- return dfa;
-}
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
-
-static automaton s_automaton_finalize(Automaton a)
-{
- int i,l;
- automaton fa = NULL;
- alist_elt ptr;
- astate s;
-
- if (a == NULL)
- return NULL;
-
- /* creation */
- fa = (automaton)malloc(sizeof(struct automaton_t));
- fa->nstates = a->nstates;
- fa->accept = (int*) malloc((fa->nstates + 1)*sizeof(int));
- memset(fa->accept,0,(fa->nstates + 1)*sizeof(int));
- fa->trans = (int**)malloc((fa->nstates + 1)*sizeof(int*));
- for(i=0; i <= fa->nstates; i++)
- {
- fa->trans[i] = (int*)malloc(MAX_TRANSITION_LETTERS * sizeof(int));
- memset(fa->trans[i],0,MAX_TRANSITION_LETTERS * sizeof(int));
- }
-
- /* create new id for states */
- for(i = 1 , ptr = alist_get_first(a->states); ptr ; ptr =
alist_get_next(a->states,ptr), i++)
- {
- s = (astate)alist_elt_get_value(ptr);
- s->id_static = i;
- }
-
- /* build new automaton */
- for(ptr = alist_get_first(a->states); ptr ; ptr =
alist_get_next(a->states,ptr))
- {
- s = (astate)alist_elt_get_value(ptr);
- i = s->id_static;
-
- if (s == a->init_state)
- fa->init = i;
- if (s->accept == 1)
- fa->accept[i] = 1;
-
- for(l=0; l < MAX_TRANSITION_LETTERS; l++)
- if (s->next[l])
- fa->trans[i][l] = s->next[l]->id_static;
- }
-
- return fa;
-}
-
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
-
-#ifdef DEBUG_AUTOMATON
-static char* s_automaton_id_to_str(alist id)
-{
- static char s[250];
- memset(s,0,sizeof(s));
- alist_elt ptr;
- for(ptr = alist_get_first(id); ptr ; ptr = alist_get_next(id,ptr))
- {
- char tmp[50];
- sprintf(tmp,"%d ",(int)alist_elt_get_value(ptr));
- strcat(s,tmp);
- }
- return s;
-}
-#endif // DEBUG_AUTOMATON
-
-#ifdef DEBUG_AUTOMATON
-static void s_automaton_print_nodes(FILE* f, Automaton a)
-{
- char * sid;
- astate s;
- alist_elt ptr;
- for(ptr = alist_get_first(a->states) ; ptr != NULL ; ptr =
alist_get_next(a->states,ptr))
- {
- s = alist_elt_get_value(ptr);
- sid = s_automaton_id_to_str(s->id);
- fprintf(f,"\t\"%s\" [label = \"%s\"",sid,sid);
- if (s == a->init_state)
- {
- fprintf(f,", style = filled, color=lightgrey");
- }
- if (s->accept)
- {
- fprintf(f,", shape = doublecircle");
- }
- fprintf(f,"];\n");
- }
- fprintf(f,"\n");
-}
-#endif // DEBUG_AUTOMATON
-
-#ifdef DEBUG_AUTOMATON
-static void s_automaton_print_edges(FILE* f, Automaton a)
-{
- int letter;
- char * sid;
- astate s;
- alist_elt ptr;
- for(ptr = alist_get_first(a->states) ; ptr != NULL ; ptr =
alist_get_next(a->states,ptr))
- {
- s = (astate)alist_elt_get_value(ptr);
- for(letter=0; letter < 255; letter++)
- {
- if (s->next[letter])
- {
- sid = s_automaton_id_to_str(s->id);
- fprintf(f,"\t\"%s\" -> ",sid);
- sid = s_automaton_id_to_str(s->next[letter]->id);
- fprintf(f,"\"%s\" [label = \"",sid);
- regexp_print_letter(f,letter);
- fprintf(f,"\"];\n");
- }
- }
- }
-}
-#endif // DEBUG_AUTOMATON
-
-#ifdef DEBUG_AUTOMATON
-static void s_automaton_dump(Automaton a, char* filename)
-{
- FILE* f;
-#ifdef HAVE_SYS_WAIT_H
- pid_t pid;
-#endif
- if (a == NULL)
- return;
- f=fopen(filename,"w");
- fprintf(f,"digraph automaton {\n");
- s_automaton_print_nodes(f,a);
- s_automaton_print_edges(f,a);
- fprintf(f,"fontsize=20;\n");
- fprintf(f,"}\n");
- fclose(f);
-
-#ifdef HAVE_SYS_WAIT_H
- pid = fork ();
- if (pid > 0) {
- wait(NULL);
- } else if (pid == 0) {
- execlp("dotty","dotty",filename,NULL);
- printf("exec dotty failed\n");
- exit(1);
- }
-#endif
-}
-#endif // DEBUG_AUTOMATON
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
-
Index: dic/compdic.c
===================================================================
RCS file: dic/compdic.c
diff -N dic/compdic.c
--- dic/compdic.c 4 Aug 2007 20:01:28 -0000 1.10
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,350 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file compdic.c
- * \brief Program used to compress a dictionary
- * \author Antoine Fraboulet
- * \date 1999
- */
-
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "hashtable.h"
-#include "dic_internals.h"
-#include "dic.h"
-
-//#define DEBUG_LIST
-//#define DEBUG_OUTPUT
-//#define DEBUG_OUTPUT_L2
-#define CHECK_RECURSION
-
-char*
-load_uncompressed(const char* file_name, unsigned int *dic_size)
-{
- unsigned r;
- char *uncompressed;
- FILE* file_desc;
-
- if ((file_desc = fopen (file_name, "r")) == NULL)
- return NULL;
-
- if ((uncompressed = (char*)malloc (sizeof(char)*(*dic_size))) == NULL)
- return NULL;
-
- r = fread (uncompressed, 1, *dic_size, file_desc);
- if (r < *dic_size)
- {
- /* \n is 2 chars under MS OS */
- printf("\n");
- printf("** The number of bytes read is less than the size of the file
**\n");
- printf("** this may be OK if you run a Microsoft OS but not on Unix
**\n");
- printf("** please check the results.
**\n");
- printf("\n");
- *dic_size = r;
- }
-
- fclose(file_desc);
- return uncompressed;
-}
-
-
-int
-file_length(const char* file_name)
-{
- struct stat stat_buf;
- if (stat (file_name, &stat_buf) < 0)
- return - 1;
- return (int) stat_buf.st_size;
-}
-
-
-void
-skip_init_header(FILE* outfile, Dict_header *header)
-{
- header->unused_1 = 0;
- header->unused_2 = 0;
- header->root = 0;
- header->nwords = 0;
- header->nodesused = 1;
- header->edgesused = 1;
- header->nodessaved = 0;
- header->edgessaved = 0;
-
- fwrite (header, sizeof(Dict_header), 1, outfile);
-}
-
-
-void
-fix_header(FILE* outfile, Dict_header* header)
-{
- strcpy(header->ident,_COMPIL_KEYWORD_);
- header->root = header->edgesused;
- rewind (outfile);
-#if defined(WORDS_BIGENDIAN)
- #warning "**********************************************"
- #warning "compdic does not run yet on bigendian machines"
- #warning "**********************************************"
-#else
- fwrite (header, sizeof(Dict_header), 1, outfile);
-#endif
-}
-
-
-void
-print_header_info(Dict_header *header)
-{
- printf("============================\n");
- printf("keyword length %lu bytes\n", (unsigned
long)strlen(_COMPIL_KEYWORD_));
- printf("keyword size %lu bytes\n", (unsigned
long)sizeof(_COMPIL_KEYWORD_));
- printf("header size %lu bytes\n", (unsigned long)sizeof(Dict_header));
- printf("\n");
- printf("%d words\n",header->nwords);
- printf("\n");
- printf("root : %7d (edge)\n",header->root);
- printf("root : %7lu (byte)\n",(unsigned long) header->root *
sizeof(Dawg_edge));
- printf("\n");
- printf("nodes : %d+%d\n",header->nodesused, header->nodessaved);
- printf("edges : %d+%d\n",header->edgesused, header->edgessaved);
- printf("============================\n");
-}
-
-
-void
-write_node(Dawg_edge *edges, int size, int num, FILE* outfile)
-{
-#ifdef DEBUG_OUTPUT
- int i;
- printf("writing %d edges\n",num);
- for(i=0; i<num; i++)
- {
-#ifdef DEBUG_OUTPUT_L2
- printf("ptr=%2d t=%d l=%d f=%d chr=%2d (%c)\n",
- edges[i].ptr, edges[i].term, edges[i].last,
- edges[i].fill, edges[i].chr, edges[i].chr -1 +'a');
-#endif
- fwrite (edges+i, sizeof(Dawg_edge), 1, outfile);
- }
-#else
- fwrite (edges, size, num, outfile);
-#endif
-}
-
-#define MAX_STRING_LENGTH 200
-
-
-#define MAX_EDGES 2000
-/* ods3: ?? */
-/* ods4: 1746 */
-
-/* global variables */
-FILE* global_outfile;
-Dict_header global_header;
-Hash_table global_hashtable;
-
-char global_stringbuf[MAX_STRING_LENGTH]; /* Space for current string */
-char* global_endstring; /* Marks END of current
string */
-char* global_input;
-char* global_endofinput;
-
-/*
- * Makenode takes a prefix (as position relative to stringbuf) and
- * returns an index of the start node of a dawg that recognizes all
- * words beginning with that prefix. String is a pointer (relative
- * to stringbuf) indicating how much of prefix is matched in the
- * input.
- */
-#ifdef CHECK_RECURSION
-int current_rec =0;
-int max_rec = 0;
-#endif
-
-unsigned int
-makenode(char *prefix)
-{
- int numedges;
- Dawg_edge edges[MAX_EDGES];
- Dawg_edge *edgeptr = edges;
- unsigned *saved_position;
-
-#ifdef CHECK_RECURSION
- current_rec++;
- if (current_rec > max_rec)
- max_rec = current_rec;
-#endif
-
- while (prefix == global_endstring)
- {
- /* More edges out of node */
- edgeptr->ptr = 0;
- edgeptr->term = 0;
- edgeptr->last = 0;
- edgeptr->fill = 0;
- edgeptr->chr = 0;
-
- (*(edgeptr++)).chr = (*global_endstring++ = *global_input++) &
DIC_CHAR_MASK;
- if (*global_input == '\n') /* End of a word */
- {
- global_header.nwords++;
- edgeptr[-1].term = 1; /* Mark edge as word */
- *global_endstring++ = *global_input++; /* Skip \n */
- if (global_input == global_endofinput) /* At end of input? */
- break;
-
- global_endstring = global_stringbuf;
- while(*global_endstring == *global_input)
- {
- global_endstring++;
- global_input++;
- }
- }
- /* make dawg pointed to by this edge */
- edgeptr[-1].ptr = makenode(prefix + 1);
- }
-
- numedges = edgeptr - edges;
- if (numedges == 0)
- {
-#ifdef CHECK_RECURSION
- current_rec --;
-#endif
- return 0; /* Special node zero - no edges */
- }
-
- edgeptr[-1].last = 1; /* Mark the last edge */
-
- saved_position = (unsigned int*) hash_find (global_hashtable,
- (void*)edges,
- numedges*sizeof(Dawg_edge));
- if (saved_position)
- {
- global_header.edgessaved += numedges;
- global_header.nodessaved++;
-
-#ifdef CHECK_RECURSION
- current_rec --;
-#endif
- return *saved_position;
- }
- else
- {
- unsigned int node_pos;
-
- node_pos = global_header.edgesused;
- hash_add(global_hashtable,
- (void*)edges,numedges*sizeof(Dawg_edge),
-
(void*)(&global_header.edgesused),sizeof(global_header.edgesused));
- global_header.edgesused += numedges;
- global_header.nodesused++;
- write_node (edges, sizeof(Dawg_edge), numedges, global_outfile);
-
-#ifdef CHECK_RECURSION
- current_rec --;
-#endif
- return node_pos;
- }
-}
-
-
-
-
-int
-main(int argc, char* argv[])
-{
- unsigned int dicsize;
- char *uncompressed;
- Dawg_edge rootnode = {0,0,0,0,0};
- Dawg_edge specialnode = {0,0,0,0,0};
-
- int size;
- char* outfilename;
- char outfilenamedefault[] = "dict.daw";
- clock_t starttime, endtime;
-
- if (argc < 2)
- {
- fprintf(stderr,"usage: %s uncompressed_dic [compressed_dic]\n",argv[0]);
- exit(1);
- }
-
- size = file_length (argv[1]);
- if (size < 0)
- {
- fprintf(stderr,"Cannot stat uncompressed dictionary %s\n",argv[1]);
- exit(1);
- }
-
- dicsize = size;
- outfilename = (argc == 3) ? argv[2] : outfilenamedefault;
-
- if ((global_outfile = fopen (outfilename,"wb")) == NULL)
- {
- fprintf(stderr,"Cannot open output file %s\n",outfilename);
- exit(1);
- }
-
- if ((uncompressed = load_uncompressed(argv[1], &dicsize)) == NULL)
- {
- fprintf(stderr,"Cannot load uncompressed dictionary into memory\n");
- exit(1);
- }
-
- global_input = uncompressed;
- global_endofinput = global_input + dicsize;
-
-#define SCALE 0.6
- global_hashtable = hash_init((unsigned int)(dicsize * SCALE));
-#undef SCALE
-
- skip_init_header(global_outfile,&global_header);
-
- specialnode.last = 1;
- write_node(&specialnode,sizeof(specialnode),1,global_outfile);
- /*
- * Call makenode with null (relative to stringbuf) prefix;
- * Initialize string to null; Put index of start node on output
- */
- starttime=clock();
- rootnode.ptr = makenode(global_endstring = global_stringbuf);
- endtime=clock();
- write_node(&rootnode,sizeof(rootnode),1,global_outfile);
-
- fix_header(global_outfile,&global_header);
-
- print_header_info(&global_header);
- hash_destroy(global_hashtable);
- free(uncompressed);
- fclose(global_outfile);
-
- printf(" Elapsed time is : %f s\n", 1.0*(endtime-starttime)
/ CLOCKS_PER_SEC);
-#ifdef CHECK_RECURSION
- printf(" Maximum recursion level reached : %d\n",max_rec);
-#endif
- return 0;
-}
-
-
Index: dic/dic.c
===================================================================
RCS file: dic/dic.c
diff -N dic/dic.c
--- dic/dic.c 4 Aug 2007 20:01:28 -0000 1.12
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,282 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file dic.c
- * \brief Dawg dictionary
- * \author Antoine Fraboulet
- * \date 2002
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "config.h"
-#include "dic_internals.h"
-#include "dic.h"
-
-#define __UNUSED__ __attribute__((unused))
-
-#if defined(WORDS_BIGENDIAN)
-static uint32_t swap4(uint32_t v)
-{
- uint32_t r;
- uint8_t *pv,*pr;
-
- pv = (uint8_t*)&v;
- pr = (uint8_t*)&r;
-
- pr[0] = pv[3];
- pr[1] = pv[2];
- pr[2] = pv[1];
- pr[3] = pv[0];
-
- return r;
-}
-#endif
-
-static int
-Dic_read_convert_header(Dict_header *header, FILE* file)
-{
-
- if (fread(header,sizeof(Dict_header),1,file) != 1)
- return 1;
-
-#if defined(WORDS_BIGENDIAN)
- header->root = swap4(header->root);
- header->nwords = swap4(header->nwords);
- header->nodesused = swap4(header->nodesused);
- header->edgesused = swap4(header->edgesused);
- header->nodessaved = swap4(header->nodessaved);
- header->edgessaved = swap4(header->edgessaved);
-#else
-
-#endif
- return 0;
-}
-
-int
-Dic_check_header(Dict_header *header, const char *path)
-{
- int r;
- FILE* file;
- if ((file = fopen(path,"rb")) == NULL)
- return 1;
-
- r = Dic_read_convert_header(header,file);
- fclose(file);
-
- return r || strcmp(header->ident,_COMPIL_KEYWORD_);
-}
-
-static void
-Dic_convert_data_to_arch(Dictionary __UNUSED__ dic)
-{
-#if defined(WORDS_BIGENDIAN)
- int i;
- uint32_t* p;
- p = (uint32_t*)dic->dawg;
- for(i=0; i < (dic->nedges + 1); i++)
- {
- p[i] = swap4(p[i]);
- }
-#endif
-}
-
-int
-Dic_load(Dictionary *dic, const char* path)
-{
- FILE* file;
- Dict_header header;
-
-
- *dic = NULL;
- if ((file = fopen(path,"rb")) == NULL)
- return 1;
-
- Dic_read_convert_header(&header,file);
-
- if ((*dic = (Dictionary) malloc(sizeof(struct _Dictionary))) == NULL)
- return 3;
-
- if (((*dic)->dawg = (Dawg_edge*)malloc((header.edgesused +
1)*sizeof(Dawg_edge))) == NULL)
- {
- free(*dic);
- *dic = NULL;
- return 4;
- }
-
- if (fread((*dic)->dawg,sizeof(Dawg_edge),header.edgesused + 1,file) !=
- (header.edgesused + 1))
- {
- free((*dic)->dawg);
- free(*dic);
- *dic = NULL;
- return 5;
- }
-
- (*dic)->root = header.root;
- (*dic)->nwords = header.nwords;
- (*dic)->nnodes = header.nodesused;
- (*dic)->nedges = header.edgesused;
-
- Dic_convert_data_to_arch(*dic);
-
- fclose(file);
- return 0;
-}
-
-
-int
-Dic_destroy(Dictionary dic)
-{
- if (dic != NULL)
- {
- if (dic->dawg != NULL)
- free(dic->dawg);
- else
- {
- free(dic);
- return 2;
- }
- free(dic);
- }
- else
- return 1;
-
- return 0;
-}
-
-
-dic_elt_t
-Dic_next(Dictionary d, dic_elt_t e)
-{
- if (! Dic_last(d,e))
- return e+1;
- return 0;
-}
-
-
-dic_elt_t
-Dic_succ(Dictionary d, dic_elt_t e)
-{
- return (d->dawg[e]).ptr;
-}
-
-
-dic_elt_t
-Dic_root(Dictionary d)
-{
- return d->root;
-}
-
-
-dic_code_t
-Dic_chr(Dictionary d, dic_elt_t e)
-{
- return (dic_code_t)(d->dawg[e]).chr;
-}
-
-
-int
-Dic_last(Dictionary d, dic_elt_t e)
-{
- return (d->dawg[e]).last;
-}
-
-
-int
-Dic_word(Dictionary d, dic_elt_t e)
-{
- return (d->dawg[e]).term;
-}
-
-unsigned int
-Dic_lookup(Dictionary d, dic_elt_t root, dic_code_t* s)
-{
- unsigned int p;
-begin:
- if (! *s)
- return root;
- if (! Dic_succ(d, root))
- return 0;
- p = Dic_succ(d, root);
- do
- {
- if (Dic_chr(d, p) == *s)
- {
- root = p;
- s++;
- goto begin;
- }
- else if (Dic_last(d, p))
- {
- return 0;
- }
- p = Dic_next(d, p);
- } while (1);
-
- return 0;
-}
-
-/*
**************************************************************************** */
-/*
**************************************************************************** */
-/*
**************************************************************************** */
-/*
**************************************************************************** */
-
-char
-Dic_char(Dictionary d, dic_elt_t e)
-{
- char c = (d->dawg[e]).chr;
- if (c)
- return c + 'A' - 1;
- else
- return 0;
-}
-
-unsigned int
-Dic_char_lookup(Dictionary d, dic_elt_t root, char* s)
-{
- unsigned int p;
-begin:
- if (! *s)
- return root;
- if (! Dic_succ(d, root))
- return 0;
- p = Dic_succ(d, root);
- do
- {
- if (Dic_char(d, p) == *s)
- {
- root = p;
- s++;
- goto begin;
- }
- else if (Dic_last(d, p))
- {
- return 0;
- }
- p = Dic_next(d, p);
- } while (1);
-
- return 0;
-}
Index: dic/dic_search.c
===================================================================
RCS file: dic/dic_search.c
diff -N dic/dic_search.c
--- dic/dic_search.c 4 Aug 2007 20:01:28 -0000 1.21
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,690 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file dic_search.c
- * \brief Dictionary lookup functions
- * \author Antoine Fraboulet
- * \date 2002
- */
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wchar.h>
-
-#include "dic_internals.h"
-#include "dic.h"
-#include "regexp.h"
-#include "dic_search.h"
-#include "libdic_a-ery.h" /* generated by bison */
-#include "libdic_a-erl.h" /* generated by flex */
-#include "automaton.h"
-
-/**
- * function prototype for bison generated parser
- */
-int regexpparse(yyscan_t scanner, NODE** root,
- struct search_RegE_list_t *list,
- struct regexp_error_report_t *err);
-
-/**
- * Dic_seel_edgeptr
- * walk the dictionary until the end of the word
- * @param dic : dictionnary
- * @param s : current pointer to letters
- * @param eptr : current edge in the dawg
- */
-static Dawg_edge*
-Dic_seek_edgeptr(const Dictionary dic, const char* s, Dawg_edge *eptr)
-{
- if (*s)
- {
- Dawg_edge *p = dic->dawg + eptr->ptr;
- do {
- if (p->chr == (unsigned)(*s & DIC_CHAR_MASK))
- return Dic_seek_edgeptr (dic,s + 1, p);
- } while (!(*p++).last);
- return dic->dawg;
- }
- else
- return eptr;
-}
-
-
-/**
- * Dic_search_word_inner : direct application of Dic_seek_edgeptr
- * @param dic : dictionary
- * @param word : word to lookup
- * @result 0 not a valid word, 1 ok
- */
-static int Dic_search_word_inner(const Dictionary dic, const char* word)
-{
- Dawg_edge *e;
- e = Dic_seek_edgeptr(dic, word, dic->dawg + dic->root);
- return e->term;
-}
-
-
-/**
- * Wrapper around Dic_search_word_inner, until we have multibyte support in
- * the dictionary
- */
-int Dic_search_word(const Dictionary dic, const wchar_t* word)
-{
- int res;
- char *tmp_word = malloc(wcslen(word) + 1);
- sprintf(tmp_word, "%ls", word);
-
- // Do the actual work
- res = Dic_search_word_inner(dic, tmp_word);
-
- // Release memory
- free(tmp_word);
- return res;
-}
-
-
-/**
- * global variables for Dic_search_word_by_len :
- *
- * a pointer to the structure is passed as a parameter
- * so that all the search_* variables appear to the functions
- * as global but the code remains re-entrant.
- * Should be better to change the algorithm ...
- */
-
-struct params_7plus1_t {
- Dictionary search_dic;
- int search_len;
- int search_wordlistlen;
- int search_wordlistlenmax;
- char search_wordtst[DIC_WORD_MAX];
- char search_letters[DIC_LETTERS];
- char (*search_wordlist)[RES_7PL1_MAX][DIC_WORD_MAX];
-};
-
-static void
-Dic_search_word_by_len(struct params_7plus1_t *params, int i, Dawg_edge
*edgeptr)
-{
- /* depth first search in the dictionary */
- do {
- /* we use a static array and not a real list so we have to stop if
- * the array is full */
- if (params->search_wordlistlen >= params->search_wordlistlenmax)
- break;
-
- /* the test is false only when reach the end-node */
- if (edgeptr->chr)
- {
-
- /* is the letter available in search_letters */
- if (params->search_letters[edgeptr->chr])
- {
- params->search_wordtst[i] = edgeptr->chr + 'A' - 1;
- params->search_letters[edgeptr->chr] --;
- if (i == params->search_len)
- {
- if ((edgeptr->term)
- /* && (params->search_wordlistlen <
params->search_wordlistlenmax) */)
-
strcpy((*params->search_wordlist)[params->search_wordlistlen++],params->search_wordtst);
- }
- else /* if (params->search_wordlistlen <
params->search_wordlistlenmax) */
- {
- Dic_search_word_by_len(params,i + 1, params->search_dic->dawg +
edgeptr->ptr);
- }
- params->search_letters[edgeptr->chr] ++;
- params->search_wordtst[i] = '\0';
- }
-
- /* the letter is of course available if we have a joker available */
- if (params->search_letters[0])
- {
- params->search_wordtst[i] = edgeptr->chr + 'a' - 1;
- params->search_letters[0] --;
- if (i == params->search_len)
- {
- if ((edgeptr->term)
- /* && (params->search_wordlistlen <
params->search_wordlistlenmax) */)
-
strcpy((*(params->search_wordlist))[params->search_wordlistlen++],params->search_wordtst);
- }
- else /* if (params->search_wordlistlen <
params->search_wordlistlenmax) */
- {
- Dic_search_word_by_len(params,i + 1,params->search_dic->dawg +
edgeptr->ptr);
- }
- params->search_letters[0] ++;
- params->search_wordtst[i] = '\0';
- }
- }
- } while (! (*edgeptr++).last);
-}
-
-static void
-Dic_search_7pl1_inner(const Dictionary dic, const char* rack,
- char buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
- int joker)
-{
- int i,j,wordlen;
- const char* r = rack;
- struct params_7plus1_t params;
- Dawg_edge *root_edge;
-
- for(i=0; i < DIC_LETTERS; i++)
- for(j=0; j < RES_7PL1_MAX; j++)
- buff[i][j][0] = '\0';
-
- for(i=0; i<DIC_LETTERS; i++)
- params.search_letters[i] = 0;
-
- if (dic == NULL || rack == NULL || *rack == '\0')
- return;
-
- /*
- * the letters are verified and changed to the dic internal
- * representation (*r & DIC_CHAR_MASK)
- */
- for(wordlen=0; wordlen < DIC_WORD_MAX && *r; r++)
- {
- if (isalpha(*r))
- {
- params.search_letters[(int)*r & DIC_CHAR_MASK]++;
- wordlen++;
- }
- else if (*r == '?')
- {
- if (joker)
- {
- params.search_letters[0]++;
- wordlen++;
- }
- else
- {
- strncpy(buff[0][0],"** joker **",DIC_WORD_MAX);
- return;
- }
- }
- }
-
- if (wordlen < 1)
- return;
-
- root_edge = dic->dawg + (dic->dawg[dic->root].ptr);
-
- params.search_dic = dic;
- params.search_wordlistlenmax = RES_7PL1_MAX;
-
- /* search for all the words that can be done with the letters */
- params.search_len = wordlen - 1;
- params.search_wordtst[wordlen]='\0';
- params.search_wordlist = & buff[0];
- params.search_wordlistlen = 0;
- Dic_search_word_by_len(¶ms,0,root_edge);
-
- /* search for all the words that can be done with the letters +1 */
- params.search_len = wordlen;
- params.search_wordtst[wordlen + 1]='\0';
- for(i='a'; i <= 'z'; i++)
- {
- params.search_letters[i & DIC_CHAR_MASK]++;
-
- params.search_wordlist = & buff[i & DIC_CHAR_MASK];
- params.search_wordlistlen = 0;
- Dic_search_word_by_len(¶ms,0,root_edge);
-
- params.search_letters[i & DIC_CHAR_MASK]--;
- }
-}
-
-
-/**
- * Wrapper around Dic_search_7pl1_inner, until we have multibyte support in
- * the dictionary
- */
-void
-Dic_search_7pl1(const Dictionary dic, const wchar_t* rack,
- wchar_t buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
- int joker)
-{
- int i, j, k;
- char tmp_buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
- char *tmp_rack = malloc(wcslen(rack) + 1);
- sprintf(tmp_rack, "%ls", rack);
- // Do the actual work
- Dic_search_7pl1_inner(dic, tmp_rack, tmp_buff, joker);
-
- for (i = 0; i < DIC_LETTERS; i++)
- {
- for (j = 0; j < RES_7PL1_MAX; j++)
- {
- for (k = 0; k < DIC_WORD_MAX; k++)
- {
- buff[i][j][k] = tmp_buff[i][j][k];
- }
- }
- }
- free(tmp_rack);
-}
-
-/****************************************/
-/****************************************/
-
-static void
-Dic_search_Racc_inner(const Dictionary dic, const char* word,
- char wordlist[RES_RACC_MAX][DIC_WORD_MAX])
-{
- /* search_racc will try to add a letter in front and at the end of a word */
-
- int i,wordlistlen;
- Dawg_edge *edge;
- char wordtst[DIC_WORD_MAX];
-
- for(i=0; i < RES_RACC_MAX; i++)
- wordlist[i][0] = 0;
-
- if (dic == NULL || wordlist == NULL || *wordlist == '\0')
- return;
-
- /* let's try for the front */
- wordlistlen = 0;
- strcpy(wordtst+1,word);
- for(i='a'; i <= 'z'; i++)
- {
- wordtst[0] = i;
- if (Dic_search_word_inner(dic,wordtst) && wordlistlen < RES_RACC_MAX)
- strcpy(wordlist[wordlistlen++],wordtst);
- }
-
- /* add a letter at the end */
- for(i=0; word[i]; i++)
- wordtst[i] = word[i];
-
- wordtst[i ] = '\0';
- wordtst[i+1] = '\0';
-
- edge = Dic_seek_edgeptr(dic,word,dic->dawg + dic->root);
-
- /* points to what the next letter can be */
- edge = dic->dawg + edge->ptr;
-
- if (edge != dic->dawg)
- {
- do {
- if (edge->term && wordlistlen < RES_RACC_MAX)
- {
- wordtst[i] = edge->chr + 'a' - 1;
- strcpy(wordlist[wordlistlen++],wordtst);
- }
- } while (!(*edge++).last);
- }
-}
-
-/**
- * Wrapper around Dic_search_Racc_inner, until we have multibyte support in
- * the dictionary
- */
-void
-Dic_search_Racc(const Dictionary dic, const wchar_t* word,
- wchar_t wordlist[RES_RACC_MAX][DIC_WORD_MAX])
-{
- int i, j;
- char tmp_buff[RES_RACC_MAX][DIC_WORD_MAX];
- char *tmp_word = malloc(wcslen(word) + 1);
- sprintf(tmp_word, "%ls", word);
- // Do the actual work
- Dic_search_Racc_inner(dic, tmp_word, tmp_buff);
-
- for (i = 0; i < RES_RACC_MAX; i++)
- {
- for (j = 0; j < DIC_WORD_MAX; j++)
- {
- wordlist[i][j] = tmp_buff[i][j];
- }
- }
- free(tmp_word);
-}
-
-/****************************************/
-/****************************************/
-
-
-static void
-Dic_search_Benj_inner(const Dictionary dic, const char* word,
- char wordlist[RES_BENJ_MAX][DIC_WORD_MAX])
-{
- int i,wordlistlen;
- char wordtst[DIC_WORD_MAX];
- Dawg_edge *edge0,*edge1,*edge2,*edgetst;
-
- for(i=0; i < RES_BENJ_MAX; i++)
- wordlist[i][0] = 0;
-
- if (dic == NULL || word == NULL || *word == '\0')
- return;
-
- wordlistlen = 0;
-
- strcpy(wordtst+3,word);
- edge0 = dic->dawg + (dic->dawg[dic->root].ptr);
- do {
- wordtst[0] = edge0->chr + 'a' - 1;
- edge1 = dic->dawg + edge0->ptr;
- do {
- wordtst[1] = edge1->chr + 'a' - 1;
- edge2 = dic->dawg + edge1->ptr;
- do {
- wordtst[2] = edge2->chr + 'a' - 1;
- edgetst = Dic_seek_edgeptr(dic,word,edge2);
- if (edgetst->term && wordlistlen < RES_BENJ_MAX)
- strcpy(wordlist[wordlistlen++],wordtst);
- } while (!(*edge2++).last);
- } while (!(*edge1++).last);
- } while (!(*edge0++).last);
-}
-
-/**
- * Wrapper around Dic_search_Benj_inner, until we have multibyte support in
- * the dictionary
- */
-void
-Dic_search_Benj(const Dictionary dic, const wchar_t* word,
- wchar_t wordlist[RES_BENJ_MAX][DIC_WORD_MAX])
-{
- int i, j;
- char tmp_buff[RES_BENJ_MAX][DIC_WORD_MAX];
- char *tmp_word = malloc(wcslen(word) + 1);
- sprintf(tmp_word, "%ls", word);
- // Do the actual work
- Dic_search_Benj_inner(dic, tmp_word, tmp_buff);
-
- for (i = 0; i < RES_BENJ_MAX; i++)
- {
- for (j = 0; j < DIC_WORD_MAX; j++)
- {
- wordlist[i][j] = tmp_buff[i][j];
- }
- }
- free(tmp_word);
-}
-
-
-/****************************************/
-/****************************************/
-
-struct params_cross_t {
- Dictionary dic;
- int wordlen;
- int wordlistlen;
- int wordlistlenmax;
- char mask[DIC_WORD_MAX];
-};
-
-
-void
-Dic_search_cross_rec(struct params_cross_t *params,
- char wordlist[RES_CROS_MAX][DIC_WORD_MAX],
- Dawg_edge *edgeptr)
-{
- Dawg_edge *current = params->dic->dawg + edgeptr->ptr;
-
- if (params->mask[params->wordlen] == '\0' && edgeptr->term)
- {
- if (params->wordlistlen < params->wordlistlenmax)
- strcpy(wordlist[params->wordlistlen++],params->mask);
- }
- else if (params->mask[params->wordlen] == '.')
- {
- do
- {
- params->mask[params->wordlen] = current->chr + 'a' - 1;
- params->wordlen ++;
- Dic_search_cross_rec(params,wordlist,current);
- params->wordlen --;
- params->mask[params->wordlen] = '.';
- }
- while (!(*current++).last);
- }
- else
- {
- do
- {
- if (current->chr == (unsigned int)(params->mask[params->wordlen] &
DIC_CHAR_MASK))
- {
- params->wordlen ++;
- Dic_search_cross_rec(params,wordlist,current);
- params->wordlen --;
- break;
- }
- }
- while (!(*current++).last);
- }
-}
-
-
-static void
-Dic_search_Cros_inner(const Dictionary dic, const char* mask,
- char wordlist[RES_CROS_MAX][DIC_WORD_MAX])
-{
- int i;
- struct params_cross_t params;
-
- for(i=0; i < RES_CROS_MAX; i++)
- wordlist[i][0] = 0;
-
- if (dic == NULL || mask == NULL || *mask == '\0')
- return;
-
- for(i=0; i < DIC_WORD_MAX && mask[i]; i++)
- {
- if (isalpha(mask[i]))
- params.mask[i] = (mask[i] & DIC_CHAR_MASK) + 'A' - 1;
- else
- params.mask[i] = '.';
- }
- params.mask[i] = '\0';
-
- params.dic = dic;
- params.wordlen = 0;
- params.wordlistlen = 0;
- params.wordlistlenmax = RES_CROS_MAX;
- Dic_search_cross_rec(¶ms, wordlist, dic->dawg + dic->root);
-}
-
-
-/**
- * Wrapper around Dic_search_Cros_inner, until we have multibyte support in
- * the dictionary
- */
-void
-Dic_search_Cros(const Dictionary dic, const wchar_t* mask,
- wchar_t wordlist[RES_CROS_MAX][DIC_WORD_MAX])
-{
- int i, j;
- char tmp_buff[RES_CROS_MAX][DIC_WORD_MAX];
- char *tmp_mask = malloc(wcslen(mask) + 1);
- sprintf(tmp_mask, "%ls", mask);
- // Do the actual work
- Dic_search_Cros_inner(dic, tmp_mask, tmp_buff);
-
- for (i = 0; i < RES_CROS_MAX; i++)
- {
- for (j = 0; j < DIC_WORD_MAX; j++)
- {
- wordlist[i][j] = tmp_buff[i][j];
- }
- }
- free(tmp_mask);
-}
-
-/****************************************/
-/****************************************/
-
-struct params_regexp_t {
- Dictionary dic;
- int minlength;
- int maxlength;
- automaton automaton;
- struct search_RegE_list_t *charlist;
- char word[DIC_WORD_MAX];
- int wordlen;
- int wordlistlen;
- int wordlistlenmax;
-};
-
-void
-Dic_search_regexp_rec(struct params_regexp_t *params,
- int state,
- Dawg_edge *edgeptr,
- char wordlist[RES_REGE_MAX][DIC_WORD_MAX])
-{
- int next_state;
- Dawg_edge *current;
- /* if we have a valid word we store it */
- if (automaton_get_accept(params->automaton,state) && edgeptr->term)
- {
- int l = strlen(params->word);
- if (params->wordlistlen < params->wordlistlenmax &&
- params->minlength <= l &&
- params->maxlength >= l)
- {
- strcpy(wordlist[params->wordlistlen++],params->word);
- }
- }
- /* we now drive the search by exploring the dictionary */
- current = params->dic->dawg + edgeptr->ptr;
- do {
- /* the current letter is current->chr */
- next_state =
automaton_get_next_state(params->automaton,state,current->chr);
- /* 1 : the letter appears in the automaton as is */
- if (next_state)
- {
- params->word[params->wordlen] = current->chr + 'a' - 1;
- params->wordlen ++;
- Dic_search_regexp_rec(params,next_state,current,wordlist);
- params->wordlen --;
- params->word[params->wordlen] = '\0';
- }
- } while (!(*current++).last);
-}
-
-
-void
-Dic_search_RegE_inner(const Dictionary dic, const char* re,
- char wordlist[RES_REGE_MAX][DIC_WORD_MAX],
- struct search_RegE_list_t *list)
-{
- int i,p,n,value;
- int ptl[REGEXP_MAX+1];
- int PS [REGEXP_MAX+1];
- NODE* root;
- yyscan_t scanner;
- YY_BUFFER_STATE buf;
- automaton a;
- char stringbuf[250];
- struct params_regexp_t params;
- struct regexp_error_report_t report;
-
- /* init */
- for(i=0; i < RES_REGE_MAX; i++)
- wordlist[i][0] = 0;
-
- if (dic == NULL || re == NULL || *re == '\0')
- return;
-
- /* (expr)# */
- sprintf(stringbuf,"(%s)#",re);
- for(i=0; i < REGEXP_MAX; i++)
- {
- PS[i] = 0;
- ptl[i] = 0;
- }
-
- report.pos1 = 0;
- report.pos2 = 0;
- report.msg[0] = '\0';
-
- /* parsing */
- regexplex_init( &scanner );
- buf = regexp_scan_string( stringbuf, scanner );
- root = NULL;
- value = regexpparse( scanner , &root, list, &report);
- regexp_delete_buffer(buf,scanner);
- regexplex_destroy( scanner );
-
- if (value)
- {
-#ifdef DEBUG_FLEX_IS_BROKEN
- fprintf(stderr,"parser error at pos %d - %d : %s\n",
- report.pos1, report.pos2, report.msg);
-#endif
- regexp_delete_tree(root);
- return ;
- }
-
- n = 1;
- p = 1;
- regexp_parcours(root, &p, &n, ptl);
- PS [0] = p - 1;
- ptl[0] = p - 1;
-
- regexp_possuivante(root,PS);
-
- if ((a = automaton_build(root->PP,ptl,PS,list)) != NULL)
- {
- params.dic = dic;
- params.minlength = list->minlength;
- params.maxlength = list->maxlength;
- params.automaton = a;
- params.charlist = list;
- memset(params.word,'\0',sizeof(params.word));
- params.wordlen = 0;
- params.wordlistlen = 0;
- params.wordlistlenmax = RES_REGE_MAX;
- Dic_search_regexp_rec(¶ms, automaton_get_init(a), dic->dawg +
dic->root, wordlist);
-
- automaton_delete(a);
- }
- regexp_delete_tree(root);
-}
-
-/**
- * Wrapper around Dic_search_RegE_inner, until we have multibyte support in
- * the dictionary
- */
-void
-Dic_search_RegE(const Dictionary dic, const wchar_t* re,
- wchar_t wordlist[RES_REGE_MAX][DIC_WORD_MAX],
- struct search_RegE_list_t *list)
-{
- int i;
- char tmp_buff[RES_REGE_MAX][DIC_WORD_MAX];
- char *tmp_re = malloc(wcslen(re) + 1);
- sprintf(tmp_re, "%ls", re);
- // Do the actual work
- Dic_search_RegE_inner(dic, tmp_re, tmp_buff, list);
-
- for (i = 0; i < RES_REGE_MAX; i++)
- {
- mbstowcs(wordlist[i], tmp_buff[i], DIC_WORD_MAX);
- }
- free(tmp_re);
-}
-
-/****************************************/
-/****************************************/
-
Index: dic/dic_search.h
===================================================================
RCS file: dic/dic_search.h
diff -N dic/dic_search.h
--- dic/dic_search.h 22 Jan 2006 12:23:53 -0000 1.12
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,131 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file dic_search.h
- * \brief Dictionary lookup functions
- * \author Antoine Fraboulet
- * \date 2002
- */
-
-#ifndef _DIC_SEARCH_H_
-#define _DIC_SEARCH_H_
-#if defined(__cplusplus)
-extern "C"
- {
-#endif
-
- /**
- * number of results for Rack+1 search (Dic_search_7pl1)
- */
-#define RES_7PL1_MAX 200
-
- /**
- * number of results for Extensions search (Dic_search_Racc)
- */
-#define RES_RACC_MAX 100
-
- /**
- * number of results for Benjamin search (Dic_search_Benj)
- */
-#define RES_BENJ_MAX 100
-
- /**
- * number of results for CrossWords search (Dic_search_Cros)
- */
-#define RES_CROS_MAX 200
-
- /**
- * number of results for Regular Expression search (Dic_search_RegE)
- */
-#define RES_REGE_MAX 200
-
- /**
- * Search for a word in the dictionnary
- * @param dic : dictionary
- * @param path : lookup word
- * @return 1 present, 0 error
- */
-int Dic_search_word(Dictionary dic,
- const wchar_t* path);
-
- /**
- * Search for all feasible word with "rack" plus one letter
- * @param dic : dictionary
- * @param rack : letters
- * @param wordlist : results
- */
-void Dic_search_7pl1(Dictionary dic,
- const wchar_t* rack,
- wchar_t wordlist[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
- int joker);
-
- /**
- * Search for all feasible word adding a letter in front or at the end
- * @param dic : dictionary
- * @param word : word
- * @param wordlist : results
- */
-void Dic_search_Racc(Dictionary dic,
- const wchar_t* word,
- wchar_t wordlist[RES_RACC_MAX][DIC_WORD_MAX]);
-
- /**
- * Search for benjamins
- * @param dic : dictionary
- * @param rack : letters
- * @param wordlist : results
- */
-void Dic_search_Benj(Dictionary dic,
- const wchar_t* word,
- wchar_t wordlist[RES_BENJ_MAX][DIC_WORD_MAX]);
-
- /**
- * Search for crosswords
- * @param dic : dictionary
- * @param rack : letters
- * @param wordlist : results
- */
-void Dic_search_Cros(Dictionary dic,
- const wchar_t* mask,
- wchar_t wordlist[RES_CROS_MAX][DIC_WORD_MAX]);
-
- /**
- * Search for words matching a regular expression
- * @param dic : dictionary
- * @param re : regular expression
- * @param wordlist : results
- */
-void Dic_search_RegE(Dictionary dic,
- const wchar_t* re,
- wchar_t wordlist[RES_REGE_MAX][DIC_WORD_MAX],
- struct search_RegE_list_t *list);
-
- /**
- * Internal version of Dic_search_RegE, used inside the dictionary.
- * Please use Dic_search_RegE instead from outside the dic library.
- */
-void Dic_search_RegE_inner(const Dictionary dic, const char* re,
- char wordlist[RES_REGE_MAX][DIC_WORD_MAX],
- struct search_RegE_list_t *list);
-
-#if defined(__cplusplus)
- }
-#endif
-#endif /* _DIC_SEARCH_H_ */
Index: dic/erl.l
===================================================================
RCS file: dic/erl.l
diff -N dic/erl.l
--- dic/erl.l 4 Aug 2007 19:57:46 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,58 +0,0 @@
-%{
-/* Eliot */
-/* Copyright (C) 2005 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Elit 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
*/
-
-#include "dic.h"
-#include "regexp.h"
-#include "libdic_a-ery.h"
-
-#define MASK_TO_REMOVE 0x1F
-
-%}
-%option prefix="regexp"
-%option outfile="lex.yy.c"
-%option header-file="libdic_a-erl.h"
-%option reentrant bison-bridge
-%option bison-locations
-%option noyywrap nounput
-
-/* TODO : remove lexer translation */
-alphabet [a-zA-Z]
-%%
-
-{alphabet} {yylval_param->c=(yytext[0]&MASK_TO_REMOVE); return LEX_CHAR;}
-"[" {return LEX_L_SQBRACKET;}
-"]" {return LEX_R_SQBRACKET;}
-"(" {return LEX_L_BRACKET;}
-")" {return LEX_R_BRACKET;}
-"^" {return LEX_HAT;}
-
-"." {return LEX_ALL;}
-":v:" {return LEX_VOWL;}
-":c:" {return LEX_CONS;}
-":1:" {return LEX_USER1;}
-":2:" {return LEX_USER2;}
-
-"?" {return LEX_QMARK;}
-"+" {return LEX_PLUS;}
-"*" {return LEX_STAR;}
-
-"#" {return LEX_SHARP;}
-%%
-
Index: dic/ery.y
===================================================================
RCS file: dic/ery.y
diff -N dic/ery.y
--- dic/ery.y 4 Aug 2007 19:57:45 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,294 +0,0 @@
-%{
-/* Eliot */
-/* Copyright (C) 2005 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Elit 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
*/
-
-#include <stdio.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "dic.h"
-#include "regexp.h"
-#include "libdic_a-ery.h"
-#include "libdic_a-erl.h"
-
-/* ************************************************** */
-/* ************************************************** */
-/* ************************************************** */
-
- /**
- * function prototype for parser generated by bison
- */
-int regexpparse(yyscan_t scanner, NODE** root,
- struct search_RegE_list_t *list,
- struct regexp_error_report_t *err);
-
- /**
- * function prototype for error reporting
- */
-void regexperror(YYLTYPE *llocp, yyscan_t scanner, NODE** root,
- struct search_RegE_list_t *list,
- struct regexp_error_report_t *err,
- char const *msg);
-
-/* ************************************************** */
-/* ************************************************** */
-/* ************************************************** */
-
-%}
-%union {
- char c;
- NODE *NODE_TYPE;
- char letters[DIC_LETTERS];
-};
-
-%defines
-%name-prefix="regexp"
-%pure-parser
-%locations
-%parse-param {yyscan_t yyscanner}
-%parse-param {NODE **root}
-%parse-param {struct search_RegE_list_t *list}
-%parse-param {struct regexp_error_report_t *err}
-%lex-param {yyscan_t yyscanner}
-
-%token <c> LEX_CHAR
-%token LEX_ALL
-%token LEX_VOWL
-%token LEX_CONS
-%token LEX_USER1
-%token LEX_USER2
-
-%token LEX_L_SQBRACKET LEX_R_SQBRACKET
-%token LEX_L_BRACKET LEX_R_BRACKET
-%token LEX_HAT
-
-%token LEX_QMARK
-%token LEX_PLUS
-%token LEX_STAR
-%token LEX_SHARP
-
-%type <NODE_TYPE> var
-%type <NODE_TYPE> expr
-%type <letters> vardis
-%type <letters> exprdis
-%type <NODE_TYPE> exprdisnode
-%start start
-%%
-
-start: LEX_L_BRACKET expr LEX_R_BRACKET LEX_SHARP
- {
- NODE* sharp = regexp_createNODE(NODE_VAR,RE_FINAL_TOK,NULL,NULL);
- *root = regexp_createNODE(NODE_AND,'\0',$2,sharp);
- YYACCEPT;
- }
- ;
-
-
-expr : var
- {
- $$=$1;
- }
- | expr expr
- {
- $$=regexp_createNODE(NODE_AND,'\0',$1,$2);
- }
- | var LEX_QMARK
- {
- NODE* epsilon=regexp_createNODE(NODE_VAR,RE_EPSILON,NULL,NULL);
- $$=regexp_createNODE(NODE_OR,'\0',$1,epsilon);
- }
- | var LEX_PLUS
- {
- $$=regexp_createNODE(NODE_PLUS,'\0',$1,NULL);
- }
- | var LEX_STAR
- {
- $$=regexp_createNODE(NODE_STAR,'\0',$1,NULL);
- }
-/* () */
- | LEX_L_BRACKET expr LEX_R_BRACKET
- {
- $$=$2;
- }
- | LEX_L_BRACKET expr LEX_R_BRACKET LEX_QMARK
- {
- NODE* epsilon=regexp_createNODE(NODE_VAR,RE_EPSILON,NULL,NULL);
- $$=regexp_createNODE(NODE_OR,'\0',$2,epsilon);
- }
- | LEX_L_BRACKET expr LEX_R_BRACKET LEX_PLUS
- {
- $$=regexp_createNODE(NODE_PLUS,'\0',$2,NULL);
- }
- | LEX_L_BRACKET expr LEX_R_BRACKET LEX_STAR
- {
- $$=regexp_createNODE(NODE_STAR,'\0',$2,NULL);
- }
-/* [] */
- | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET
- {
- $$=$2;
- }
- | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET LEX_QMARK
- {
- NODE* epsilon=regexp_createNODE(NODE_VAR,RE_EPSILON,NULL,NULL);
- $$=regexp_createNODE(NODE_OR,'\0',$2,epsilon);
- }
- | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET LEX_PLUS
- {
- $$=regexp_createNODE(NODE_PLUS,'\0',$2,NULL);
- }
- | LEX_L_SQBRACKET exprdisnode LEX_R_SQBRACKET LEX_STAR
- {
- $$=regexp_createNODE(NODE_STAR,'\0',$2,NULL);
- }
- ;
-
-
-
-var : LEX_CHAR
- {
-#ifdef DEBUG_RE_PARSE
- printf("var : lecture %c\n",$1 + 'a' -1);
-#endif
- $$=regexp_createNODE(NODE_VAR,$1,NULL,NULL);
- }
- | LEX_ALL
- {
- $$=regexp_createNODE(NODE_VAR,RE_ALL_MATCH,NULL,NULL);
- }
- | LEX_VOWL
- {
- $$=regexp_createNODE(NODE_VAR,RE_VOWL_MATCH,NULL,NULL);
- }
- | LEX_CONS
- {
- $$=regexp_createNODE(NODE_VAR,RE_CONS_MATCH,NULL,NULL);
- }
- | LEX_USER1
- {
- $$=regexp_createNODE(NODE_VAR,RE_USR1_MATCH,NULL,NULL);
- }
- | LEX_USER2
- {
- $$=regexp_createNODE(NODE_VAR,RE_USR2_MATCH,NULL,NULL);
- }
- ;
-
-
-exprdisnode : exprdis
- {
- int i,j;
-#ifdef DEBUG_RE_PARSE
- printf("exprdisnode : exprdis : ");
-#endif
- for(i=RE_LIST_USER_END + 1; i < DIC_SEARCH_REGE_LIST; i++)
- {
- if (list->valid[i] == 0)
- {
- list->valid[i] = 1;
- list->symbl[i] = RE_ALL_MATCH + i;
- list->letters[i][0] = 0;
- for(j=1; j < DIC_LETTERS; j++)
- list->letters[i][j] = $1[j] ? 1 : 0;
-#ifdef DEBUG_RE_PARSE
- printf("list %d symbl x%02x : ",i,list->symbl[i]);
- for(j=0; j < DIC_LETTERS; j++)
- if (list->letters[i][j])
- printf("%c",j+'a'-1);
- printf("\n");
-#endif
- break;
- }
- }
- $$=regexp_createNODE(NODE_VAR,list->symbl[i],NULL,NULL);
- }
- | LEX_HAT exprdis
- {
- int i,j;
-#ifdef DEBUG_RE_PARSE
- printf("exprdisnode : HAT exprdis : ");
-#endif
- for(i=RE_LIST_USER_END + 1; i < DIC_SEARCH_REGE_LIST; i++)
- {
- if (list->valid[i] == 0)
- {
- list->valid[i] = 1;
- list->symbl[i] = RE_ALL_MATCH + i;
- list->letters[i][0] = 0;
- for(j=1; j < DIC_LETTERS; j++)
- list->letters[i][j] = $2[j] ? 0 : 1;
-#ifdef DEBUG_RE_PARSE
- printf("list %d symbl x%02x : ",i,list->symbl[i]);
- for(j=0; j < DIC_LETTERS; j++)
- if (list->letters[i][j])
- printf("%c",j+'a'-1);
- printf("\n");
-#endif
- break;
- }
- }
- $$=regexp_createNODE(NODE_VAR,list->symbl[i],NULL,NULL);
- }
- ;
-
-
-exprdis: vardis
- {
- memcpy($$,$1,sizeof(char)*DIC_LETTERS);
- }
- | vardis exprdis
- {
- int i;
- for(i=0; i < DIC_LETTERS; i++)
- $$[i] = $1[i] | $2[i];
- }
- ;
-
-
-
-vardis: LEX_CHAR
- {
- int c = $1;
- memset($$,0,sizeof(char)*DIC_LETTERS);
-#ifdef DEBUG_RE_PARSE
- printf("vardis : lecture %c\n",c + 'a' -1);
-#endif
- $$[c] = 1;
- }
- ;
-
-
-%%
-
-#define UNUSED __attribute__((unused))
-
-void regexperror(YYLTYPE *llocp, yyscan_t UNUSED yyscanner, NODE UNUSED **root,
- struct search_RegE_list_t UNUSED *list,
- struct regexp_error_report_t *err, char const *msg)
-{
- err->pos1 = llocp->first_column;
- err->pos2 = llocp->last_column;
- strncpy(err->msg,msg,sizeof(err->msg));
-}
-
-/*
- * shut down the compiler
- */
-//int yy_init_globals (yyscan_t yyscanner);
Index: dic/hashtable.c
===================================================================
RCS file: dic/hashtable.c
diff -N dic/hashtable.c
--- dic/hashtable.c 1 Jan 2006 19:51:00 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,163 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file hashtable.c
- * \brief Simple hashtable type
- * \author Antoine Fraboulet
- * \date 1999
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "hashtable.h"
-
-typedef struct _Hash_node {
- struct _Hash_node *next;
- void* key;
- unsigned int keysize;
- void* value;
- unsigned int valuesize;
-} Hash_node;
-
-struct _Hash_table {
- unsigned int size;
- Hash_node** nodes;
-};
-
-
-Hash_table
-hash_init(unsigned int size)
-{
- Hash_table ht;
-
- ht = (Hash_table) calloc(1,sizeof(struct _Hash_table));
- ht->size = size;
- ht->nodes = (Hash_node **) calloc (size, sizeof (Hash_node*));
- return ht;
-}
-
-void
-hash_rec_free(Hash_node* node)
-{
- if (node)
- {
- if (node->next)
- hash_rec_free(node->next);
- if (node->key)
- free(node->key);
- if (node->value)
- free(node->value);
- free(node);
- }
-}
-
-int
-hash_destroy(Hash_table hashtable)
-{
- unsigned int i;
- if (hashtable)
- {
- for(i=0; i<hashtable->size; i++)
- if (hashtable->nodes[i])
- hash_rec_free(hashtable->nodes[i]);
- if (hashtable->nodes)
- free(hashtable->nodes);
- free(hashtable);
- }
- return 0;
-}
-
-
-static unsigned int
-hash_key(Hash_table hashtable, void* ptr, unsigned int size)
-{
- unsigned int i;
- unsigned int key = 0;
-
- if (size % 4 == 0)
- {
- unsigned int *v = (unsigned int*)ptr;
- for (i = 0; i < (size / 4); i++)
- key ^= (key << 3) ^ (key >> 1) ^ v[i];
- }
- else
- {
- unsigned char *v = (unsigned char*)ptr;
- for (i = 0; i < size; i++)
- key ^= (key << 3) ^ (key >> 1) ^ v[i];
- }
- key %= hashtable->size;
- return key;
-}
-
-
-void*
-hash_find(Hash_table hashtable, void* key, unsigned int keysize)
-{
- Hash_node *entry;
- unsigned int h_key;
-
- h_key = hash_key(hashtable,key,keysize);
- for (entry = hashtable->nodes[h_key]; entry; entry = entry -> next)
- {
- if ((entry -> keysize == keysize) &&
- (memcmp(entry->key,key,keysize) == 0))
- {
- return entry->value;
- }
- }
- return NULL;
-}
-
-
-static Hash_node*
-new_entry(void* key, unsigned int keysize, void* value, unsigned int
- valuesize)
-{
- Hash_node *n;
- n = (Hash_node*)calloc(1,sizeof(Hash_node));
- n->key = (void*)malloc(keysize);
- n->value = (void*)malloc(valuesize);
- n->keysize = keysize;
- n->valuesize = valuesize;
- memcpy(n->key,key,keysize);
- memcpy(n->value,value,valuesize);
- return n;
-}
-
-
-int
-hash_add(Hash_table hashtable,
- void* key, unsigned int keysize,
- void* value, unsigned int valuesize)
-{
- Hash_node *entry;
- unsigned int h_key;
-
- h_key = hash_key(hashtable,key,keysize);
- entry = new_entry(key,keysize,value,valuesize);
- entry->next = hashtable->nodes[h_key];
- hashtable->nodes[h_key] = entry;
-
- return 0;
-}
-
-
Index: dic/listdic.c
===================================================================
RCS file: dic/listdic.c
diff -N dic/listdic.c
--- dic/listdic.c 4 Aug 2007 20:01:28 -0000 1.10
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,207 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file listdic.c
- * \brief Program used to list a dictionary
- * \author Antoine Fraboulet
- * \date 1999
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include "dic_internals.h"
-#include "dic.h"
-
-
-static void
-print_dic_rec(FILE* out, Dictionary dic, char *buf, char* s, Dawg_edge i)
-{
- if (i.term) /* edge points at a complete word */
- {
- *s = '\0';
- fprintf (out,"%s\n", buf);
- }
- if (i.ptr)
- { /* Compute index: is it non-zero ? */
- Dawg_edge *p = dic->dawg + i.ptr;
- do { /* for each edge out of this node */
- *s = p->chr + 'a' - 1;
- print_dic_rec (out,dic,buf,s + 1, *p);
- }
- while (!(*p++).last);
- }
-}
-
-
-void
-dic_load(Dictionary* dic, char* filename)
-{
- int res;
- if ((res = Dic_load(dic, filename)) != 0)
- {
- switch (res) {
- case 1: printf("chargement: problème d'ouverture de %s\n",filename);
break;
- case 2: printf("chargement: mauvais en-tete de dictionnaire\n"); break;
- case 3: printf("chargement: problème 3 d'allocation mémoire\n"); break;
- case 4: printf("chargement: problème 4 d'alocation mémoire\n"); break;
- case 5: printf("chargement: problème de lecture des arcs du
dictionnaire\n"); break;
- default: printf("chargement: problème non-repertorié\n"); break;
- }
- exit(res);
- }
-}
-
-
-void
-print_dic_list(char* filename, char* out)
-{
- FILE* fout;
- Dictionary dic;
- static char buf[80];
-
- dic_load(&dic,filename);
-
- if (strcmp(out,"stdout") == 0)
- print_dic_rec(stdout,dic,buf,buf,dic->dawg[dic->root]);
- else if (strcmp(out,"stderr") == 0)
- print_dic_rec(stderr,dic,buf,buf,dic->dawg[dic->root]);
- else
- {
- if ((fout = fopen(out,"w")) == NULL)
- return;
- print_dic_rec(fout,dic,buf,buf,dic->dawg[dic->root]);
- fclose(fout);
- }
- Dic_destroy(dic);
-}
-
-
-void
-print_header(char* filename)
-{
- Dict_header header;
-
- Dic_check_header(&header,filename);
-
-#define OO(IDENT) (unsigned long)offsetof(Dict_header,IDENT)
-
- printf("Dictionary header information\n");
- printf("0x%02lx ident : %s\n", OO(ident) ,header.ident);
- printf("0x%02lx unused 1 : %6d %06x\n",OO(unused_1) ,header.unused_1
,header.unused_1);
- printf("0x%02lx unused 2 : %6d %06x\n",OO(unused_2) ,header.unused_2
,header.unused_2);
- printf("0x%02lx root : %6d %06x\n",OO(root) ,header.root
,header.root);
- printf("0x%02lx words : %6d %06x\n",OO(nwords) ,header.nwords
,header.nwords);
- printf("0x%02lx edges used : %6d %06x\n",OO(edgesused) ,header.edgesused
,header.edgesused);
- printf("0x%02lx nodes used : %6d %06x\n",OO(nodesused) ,header.nodesused
,header.nodesused);
- printf("0x%02lx nodes saved : %6d
%06x\n",OO(nodessaved),header.nodessaved,header.nodessaved);
- printf("0x%02lx edges saved : %6d
%06x\n",OO(edgessaved),header.edgessaved,header.edgessaved);
- printf("\n");
- printf("sizeof(header) = 0x%lx (%lu)\n", (unsigned long)sizeof(header),
(unsigned long)sizeof(header));
-}
-
-
-static void
-print_node_hex(Dictionary dic, int i)
-{
- union edge_t {
- Dawg_edge e;
- uint32_t s;
- } ee;
-
- ee.e = dic->dawg[i];
-
- printf("0x%04lx %08x |%4d ptr=%8d t=%d l=%d f=%d chr=%2d (%c)\n",
- (unsigned long)i*sizeof(ee), (unsigned int)(ee.s),
- i, ee.e.ptr, ee.e.term, ee.e.last, ee.e.fill, ee.e.chr, ee.e.chr +'a'
-1);
-}
-
-
-void
-print_dic_hex(char* filename)
-{
- int i;
- Dictionary dic;
- dic_load(&dic,filename);
-
- printf("offs binary structure \n");
- printf("---- -------- | ------------------\n");
- for(i=0; i < (dic->nedges + 1); i++)
- print_node_hex(dic,i);
- Dic_destroy(dic);
-}
-
-
-void
-usage(char* name)
-{
- printf("usage: %s [-a|-d|-h|-l] dictionnaire\n", name);
- printf(" -a : print all\n");
- printf(" -h : print header\n");
- printf(" -d : print dic in hex\n");
- printf(" -l : print dic word list\n");
-}
-
-
-int
-main(int argc, char *argv[])
-{
- int arg_count;
- int option_print_all = 0;
- int option_print_header = 0;
- int option_print_dic_hex = 0;
- int option_print_dic_list = 0;
-
- if (argc < 3)
- {
- usage(argv[0]);
- exit(1);
- }
-
- arg_count = 1;
- while(argv[arg_count][0] == '-')
- {
- switch (argv[arg_count][1])
- {
- case 'a': option_print_all = 1; break;
- case 'h': option_print_header = 1; break;
- case 'd': option_print_dic_hex = 1; break;
- case 'l': option_print_dic_list = 1; break;
- default: usage(argv[0]); exit(2);
- break;
- }
- arg_count++;
- }
-
- if (option_print_header || option_print_all)
- {
- print_header(argv[arg_count]);
- }
- if (option_print_dic_hex || option_print_all)
- {
- print_dic_hex(argv[arg_count]);
- }
- if (option_print_dic_list || option_print_all)
- {
- print_dic_list(argv[arg_count],"stdout");
- }
- return 0;
-}
Index: dic/regexp.c
===================================================================
RCS file: dic/regexp.c
diff -N dic/regexp.c
--- dic/regexp.c 1 Jan 2006 19:51:00 -0000 1.12
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,382 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file regexp.c
- * \brief Regular Expression functions
- * \author Antoine Fraboulet
- * \date 2005
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#include <unistd.h>
-
-#include "dic.h"
-#include "regexp.h"
-#include "automaton.h"
-
-#ifndef PDBG
-#ifdef DEBUG_RE2
-#define PDBG(x) x
-#else
-#define PDBG(x)
-#endif
-#endif
-
-NODE* regexp_createNODE(int type,char v,NODE *fg,NODE *fd)
-{
- NODE *x;
- x=(NODE *)malloc(sizeof(NODE));
- x->type = type;
- x->var = v;
- x->fd = fd;
- x->fg = fg;
- x->numero = 0;
- x->position = 0;
- x->annulable = 0;
- x->PP = 0;
- x->DP = 0;
- return x;
-}
-
-void regexp_delete_tree(NODE *root)
-{
- if (root == NULL)
- return;
- regexp_delete_tree(root->fg);
- regexp_delete_tree(root->fd);
- free(root);
-}
-
-#ifdef DEBUG_RE
-static void print_node(FILE*, NODE *n, int detail);
-#endif
-
-/**
- * computes position, annulable, PP, DP attributes
- * @param r = root
- * @param p = current leaf position
- * @param n = current node number
- * @param ptl = position to letter
- */
-
-void regexp_parcours(NODE* r, int *p, int *n, int ptl[])
-{
- if (r == NULL)
- return;
-
- regexp_parcours(r->fg,p,n,ptl);
- regexp_parcours(r->fd,p,n,ptl);
-
- switch (r->type)
- {
- case NODE_VAR:
- r->position = *p;
- ptl[*p] = r->var;
- *p = *p + 1;
- r->annulable = 0;
- r->PP = 1 << (r->position - 1);
- r->DP = 1 << (r->position - 1);
- break;
- case NODE_OR:
- r->position = 0;
- r->annulable = r->fg->annulable || r->fd->annulable;
- r->PP = r->fg->PP | r->fd->PP;
- r->DP = r->fg->DP | r->fd->DP;
- break;
- case NODE_AND:
- r->position = 0;
- r->annulable = r->fg->annulable && r->fd->annulable;
- r->PP = (r->fg->annulable) ? (r->fg->PP | r->fd->PP) : r->fg->PP;
- r->DP = (r->fd->annulable) ? (r->fg->DP | r->fd->DP) : r->fd->DP;
- break;
- case NODE_PLUS:
- r->position = 0;
- r->annulable = 0;
- r->PP = r->fg->PP;
- r->DP = r->fg->DP;
- break;
- case NODE_STAR:
- r->position = 0;
- r->annulable = 1;
- r->PP = r->fg->PP;
- r->DP = r->fg->DP;
- break;
- }
-
- r->numero = *n;
- *n = *n + 1;
-}
-
-/**
- * computes possuivante
- * @param r = root
- * @param PS = next position
- */
-
-void regexp_possuivante(NODE* r, int PS[])
-{
- int pos;
- if (r == NULL)
- return;
-
- regexp_possuivante(r->fg,PS);
- regexp_possuivante(r->fd,PS);
-
- switch (r->type)
- {
- case NODE_AND:
- /************************************/
- /* \forall p \in DP(left) */
- /* PS[p] = PS[p] \cup PP(right) */
- /************************************/
- for(pos=1; pos <= PS[0]; pos++)
- {
- if (r->fg->DP & (1 << (pos-1)))
- PS[pos] |= r->fd->PP;
- }
- break;
- case NODE_PLUS:
- /************************************/
- /* == same as START */
- /* \forall p \in DP(left) */
- /* PS[p] = PS[p] \cup PP(left) */
- /************************************/
- for(pos=1; pos <= PS[0]; pos++)
- {
- if (r->DP & (1 << (pos-1)))
- PS[pos] |= r->PP;
- }
- break;
- case NODE_STAR:
- /************************************/
- /* \forall p \in DP(left) */
- /* PS[p] = PS[p] \cup PP(left) */
- /************************************/
- for(pos=1; pos <= PS[0]; pos++)
- {
- if (r->DP & (1 << (pos-1)))
- PS[pos] |= r->PP;
- }
- break;
- }
-}
-
-/*////////////////////////////////////////////////
-// DEBUG only fonctions
-////////////////////////////////////////////////*/
-
-#ifdef DEBUG_RE
-void regexp_print_PS(int PS[])
-{
- int i;
- printf("** positions suivantes **\n");
- for(i=1; i <= PS[0]; i++)
- {
- printf("%02d: 0x%08x\n", i, PS[i]);
- }
-}
-#endif
-
-/*////////////////////////////////////////////////
-////////////////////////////////////////////////*/
-
-#ifdef DEBUG_RE
-void regexp_print_ptl(int ptl[])
-{
- int i;
- printf("** pos -> lettre: ");
- for(i=1; i <= ptl[0]; i++)
- {
- printf("%d=%c ",i,ptl[i]);
- }
- printf("\n");
-}
-#endif
-
-/*////////////////////////////////////////////////
-////////////////////////////////////////////////*/
-
-void regexp_print_letter(FILE* f, char l)
-{
- switch (l)
- {
- case RE_EPSILON: fprintf(f,"( & [%d])",l); break;
- case RE_FINAL_TOK: fprintf(f,"( # [%d])",l); break;
- case RE_ALL_MATCH: fprintf(f,"( . [%d])",l); break;
- case RE_VOWL_MATCH: fprintf(f,"(:v: [%d])",l); break;
- case RE_CONS_MATCH: fprintf(f,"(:c: [%d])",l); break;
- case RE_USR1_MATCH: fprintf(f,"(:1: [%d])",l); break;
- case RE_USR2_MATCH: fprintf(f,"(:2: [%d])",l); break;
- default:
- if (l < RE_FINAL_TOK)
- fprintf(f," (%c [%d]) ",l + 'a' - 1, l);
- else
- fprintf(f," (liste %d)",l - RE_LIST_USER_END);
- break;
- }
-}
-
-/*////////////////////////////////////////////////
-////////////////////////////////////////////////*/
-
-void regexp_print_letter2(FILE* f, char l)
-{
- switch (l)
- {
- case RE_EPSILON: fprintf(f,"&"); break;
- case RE_FINAL_TOK: fprintf(f,"#"); break;
- case RE_ALL_MATCH: fprintf(f,"."); break;
- case RE_VOWL_MATCH: fprintf(f,":v:"); break;
- case RE_CONS_MATCH: fprintf(f,":c:"); break;
- case RE_USR1_MATCH: fprintf(f,":1:"); break;
- case RE_USR2_MATCH: fprintf(f,":2:"); break;
- default:
- if (l < RE_FINAL_TOK)
- fprintf(f,"%c",l + 'a' - 1);
- else
- fprintf(f,"l%d",l - RE_LIST_USER_END);
- break;
- }
-}
-
-/*////////////////////////////////////////////////
-////////////////////////////////////////////////*/
-
-#ifdef DEBUG_RE
-static void print_node(FILE* f, NODE *n, int detail)
-{
- if (n == NULL)
- return;
-
- switch (n->type)
- {
- case NODE_VAR:
- regexp_print_letter(f,n->var);
- break;
- case NODE_OR:
- fprintf(f,"OR");
- break;
- case NODE_AND:
- fprintf(f,"AND");
- break;
- case NODE_PLUS:
- fprintf(f,"+");
- break;
- case NODE_STAR:
- fprintf(f,"*");
- break;
- }
- if (detail == 2)
- {
- fprintf(f,"\\n pos=%d\\n annul=%d\\n PP=0x%04x\\n DP=0x%04x",
- n->position,n->annulable,n->PP,n->DP);
- }
-}
-#endif
-
-/*////////////////////////////////////////////////
-////////////////////////////////////////////////*/
-
-#ifdef DEBUG_RE
-static void print_tree_nodes(FILE* f, NODE* n, int detail)
-{
- if (n == NULL)
- return;
-
- print_tree_nodes(f,n->fg,detail);
- print_tree_nodes(f,n->fd,detail);
-
- fprintf(f,"%d [ label=\"",n->numero);
- print_node(f,n,detail);
- fprintf(f,"\"];\n");
-}
-#endif
-
-/*////////////////////////////////////////////////
-////////////////////////////////////////////////*/
-
-#ifdef DEBUG_RE
-static void print_tree_edges(FILE* f, NODE* n)
-{
- if (n == NULL)
- return;
-
- print_tree_edges(f,n->fg);
- print_tree_edges(f,n->fd);
-
- switch (n->type)
- {
- case NODE_OR:
- fprintf(f,"%d -> %d;",n->numero,n->fg->numero);
- fprintf(f,"%d -> %d;",n->numero,n->fd->numero);
- break;
- case NODE_AND:
- fprintf(f,"%d -> %d;",n->numero,n->fg->numero);
- fprintf(f,"%d -> %d;",n->numero,n->fd->numero);
- break;
- case NODE_PLUS:
- case NODE_STAR:
- fprintf(f,"%d -> %d;",n->numero,n->fg->numero);
- break;
- }
-}
-#endif
-
-/*////////////////////////////////////////////////
-////////////////////////////////////////////////*/
-
-#ifdef DEBUG_RE
-void regexp_print_tree(NODE* n, char* name, int detail)
-{
- FILE* f;
- pid_t pid;
-
- f=fopen(name,"w");
- fprintf(f,"digraph %s {\n",name);
- print_tree_nodes(f,n,detail);
- print_tree_edges(f,n);
- fprintf(f,"fontsize=20;\n");
- fprintf(f,"}\n");
- fclose(f);
-
-#ifdef HAVE_SYS_WAIT_H
- pid = fork ();
- if (pid > 0) {
- wait(NULL);
- } else if (pid == 0) {
- execlp("dotty","dotty",name,NULL);
- printf("exec dotty failed\n");
- exit(1);
- }
-#endif
-}
-#endif
-
-
-/// Local Variables:
-/// mode: hs-minor
-/// c-basic-offset: 2
-/// End:
Index: dic/regexpmain.c
===================================================================
RCS file: dic/regexpmain.c
diff -N dic/regexpmain.c
--- dic/regexpmain.c 4 Aug 2007 20:01:28 -0000 1.13
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,140 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file regexpmain.c
- * \brief Program used to test regexp
- * \author Antoine Fraboulet
- * \date 2005
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "dic.h"
-#include "regexp.h"
-#include "dic_search.h"
-
-#define __UNUSED__ __attribute__((unused))
-
-/********************************************************/
-/********************************************************/
-/********************************************************/
-
-const unsigned int all_letter[DIC_LETTERS] =
- {
- /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 */
- /* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 */
- /* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
- 0,1,1,1,1, 1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1
- };
-
-const unsigned int vowels[DIC_LETTERS] =
- {
- /* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
- 0,1,0,0,0, 1,0,0,0,1,0, 0,0,0,0,1,0,0,0,0,0,1,0, 0, 0, 1, 0
- };
-
-const unsigned int consonants[DIC_LETTERS] =
- {
- /* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
- 0,0,1,1,1, 0,1,1,1,0,1, 1,1,1,1,0,1,1,1,1,1,0,1, 1, 1, 1, 1
- };
-
-void init_letter_lists(struct search_RegE_list_t *list)
-{
- int i;
- memset (list,0,sizeof(*list));
- list->minlength = 1;
- list->maxlength = 15;
- list->valid[0] = 1; // all letters
- list->symbl[0] = RE_ALL_MATCH;
- list->valid[1] = 1; // vowels
- list->symbl[1] = RE_VOWL_MATCH;
- list->valid[2] = 1; // consonants
- list->symbl[2] = RE_CONS_MATCH;
- for(i=0; i < DIC_LETTERS; i++)
- {
- list->letters[0][i] = all_letter[i];
- list->letters[1][i] = vowels[i];
- list->letters[2][i] = consonants[i];
- }
- list->valid[3] = 0; // user defined list 1
- list->symbl[3] = RE_USR1_MATCH;
- list->valid[4] = 0; // user defined list 2
- list->symbl[4] = RE_USR2_MATCH;
-}
-
-/********************************************************/
-/********************************************************/
-/********************************************************/
-void
-usage(int __UNUSED__ argc, char* argv[])
-{
- fprintf(stderr,"usage: %s dictionary\n",argv[0]);
- fprintf(stderr," dictionary : path to dawg eliot dictionary\n");
-}
-
-int main(int argc, char* argv[])
-{
- int i;
- Dictionary dic;
- char wordlist[RES_REGE_MAX][DIC_WORD_MAX];
- char er[200];
- strcpy(er,".");
- struct search_RegE_list_t list;
-
- if (argc < 2)
- {
- usage(argc,argv);
- }
-
- if (Dic_load(&dic,argv[1]))
- {
- fprintf(stdout,"impossible de lire le dictionnaire\n");
- return 1;
- }
-
- while (strcmp(er,""))
- {
-
fprintf(stdout,"**************************************************************\n");
-
fprintf(stdout,"**************************************************************\n");
- fprintf(stdout,"entrer une ER:\n");
- fgets(er,sizeof(er),stdin);
- /* strip \n */
- er[strlen(er) - 1] = '\0';
- if (strcmp(er,"") == 0)
- break;
-
- /* automaton */
- init_letter_lists(&list);
- Dic_search_RegE_inner(dic,er,wordlist,&list);
-
- fprintf(stdout,"résultat:\n");
- for(i=0; i<RES_REGE_MAX && wordlist[i][0]; i++)
- {
- fprintf(stderr,"%s\n",wordlist[i]);
- }
- }
-
- Dic_destroy(dic);
- return 0;
-}
Index: game/encoding.cpp
===================================================================
RCS file: game/encoding.cpp
diff -N game/encoding.cpp
--- game/encoding.cpp 5 Nov 2006 13:30:54 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,98 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file encoding.cpp
- * \brief Utility functions to ease manipulation of wide-character strings
- * \author Olivier Teuliere
- * \date 2005
- */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <wchar.h>
-#include <wctype.h>
-#include "encoding.h"
-
-
-int _wtoi(const wchar_t *iWStr)
-{
- return wcstol(iWStr,NULL,10);
-}
-
-
-int _swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...)
-{
- int res;
- va_list argp;
- va_start(argp, format);
-#ifdef WIN32
- // Mingw32 does not take the maxlen argument
- res = vswprintf(wcs, format, argp);
-#else
- res = vswprintf(wcs, maxlen, format, argp);
-#endif
- va_end(argp);
- return res;
-}
-
-
-wstring convertToWc(const string& iStr)
-{
- // Get the needed length (we _can't_ use string::size())
- size_t len = mbstowcs(NULL, iStr.c_str(), 0);
- if (len == (size_t)-1)
- return L"";
-
- wchar_t *tmp = new wchar_t[len + 1];
- len = mbstowcs(tmp, iStr.c_str(), len + 1);
- wstring res = tmp;
- delete[] tmp;
-
- return res;
-}
-
-
-string convertToMb(const wstring& iWStr)
-{
- // Get the needed length (we _can't_ use wstring::size())
- size_t len = wcstombs(NULL, iWStr.c_str(), 0);
- if (len == (size_t)-1)
- return "";
-
- char *tmp = new char[len + 1];
- len = wcstombs(tmp, iWStr.c_str(), len + 1);
- string res = tmp;
- delete[] tmp;
-
- return res;
-}
-
-
-string convertToMb(wchar_t iWChar)
-{
- char res[MB_CUR_MAX + 1];
- int len = wctomb(res, iWChar);
- if (len == -1)
- return "";
- res[len] = '\0';
-
- return res;
-}
-
Index: game/encoding.h
===================================================================
RCS file: game/encoding.h
diff -N game/encoding.h
--- game/encoding.h 22 Jan 2006 12:23:53 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,52 +0,0 @@
-/* Eliot */
-/* Copyright (C) 1999 Antoine Fraboulet */
-/* */
-/* This file is part of Eliot. */
-/* */
-/* Eliot 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. */
-/* */
-/* Eliot 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
*/
-
-/**
- * \file encoding.h
- * \brief Utility functions to ease manipulation of wide-character strings
- * \author Olivier Teuliere
- * \date 2005
- */
-
-#ifndef _ENCODING_H_
-#define _ENCODING_H_
-
-#include <string>
-
-using std::string;
-using std::wstring;
-
-
-/// Equivalent of atoi for wide-caracter strings
-int _wtoi(const wchar_t *iWStr);
-
-/// Equivalent of swprintf, but working also with mingw32
-int _swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...);
-
-/// Convert a multi-byte string into a wide-character string
-wstring convertToWc(const string& iStr);
-
-/// Convert a wide-character string into a multi-byte string
-string convertToMb(const wstring& iWStr);
-
-/// Convert a wide character into a multi-byte string
-string convertToMb(wchar_t iWChar);
-
-#endif
-
Index: game/tile.cpp
===================================================================
RCS file: game/tile.cpp
diff -N game/tile.cpp
--- game/tile.cpp 22 Jan 2006 12:23:53 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,233 +0,0 @@
-/*****************************************************************************
- * Copyright (C) 1999-2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
- *
- * 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
- *****************************************************************************/
-
-#include "tile.h"
-#include <wctype.h>
-
-
-/*************************
- * French tiles
- * Zero + 26 letters + joker
- * tiles ares supposed to be contiguous and joker is separated
- *************************/
-
-#define TILE_START 'A'
-#define TILE_END 'Z'
-#define TILE_JOKER '?'
-#define TILE_DUMMY '%'
-
-#define TILE_IDX_DUMMY 0
-#define TILE_IDX_START 1
-#define TILE_IDX_END 26
-#define TILE_IDX_JOKER 27
-
-#define TILES_NUMBER 28
-
-/* The jokers and the 'Y' can be considered both as vowels or consonants */
-const unsigned int Tiles_vowels[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,1,0,0,0, 1,0,0,0,1,0, 0,0,0,0,1,0,0,0,0,0,1,0, 0, 0, 1, 0,1
-};
-
-const unsigned int Tiles_consonants[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,0,1,1,1, 0,1,1,1,0,1, 1,1,1,1,0,1,1,1,1,1,0,1, 1, 1, 1, 1,1
-};
-
-const unsigned int Tiles_numbers[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,9,2,2,3,15,2,2,2,8,1, 1,5,3,6,6,2,1,6,6,6,6,2, 1, 1, 1, 1,2
-};
-
-const unsigned int Tiles_points[TILES_NUMBER] =
-{
-/* x A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ? */
- 0,1,3,3,2, 1,4,2,4,1,8,10,1,2,1,1,3,8,1,1,1,1,4,10,10,10,10,0
-};
-
-/***************************
- ***************************/
-
-const Tile Tile::m_TheJoker(TILE_JOKER);
-const Tile Tile::m_TheDummy(0);
-list<Tile> Tile::m_tilesList;
-vector<Tile> Tile::m_tilesVect(TILES_NUMBER, Tile::dummy());
-bool Tile::m_vectInitialized(false);
-
-
-Tile::Tile(wchar_t c)
-{
- if (c == TILE_JOKER)
- {
- m_joker = true;
- m_dummy = false;
- m_char = TILE_JOKER;
- m_code = 27;
- }
- else if (isalpha(c))
- {
- m_joker = islower(c);
- m_dummy = false;
- m_char = towupper(c);
- m_code = m_char - 'A' + 1;
- }
- else
- {
- m_joker = false;
- m_dummy = true;
- m_char = 0;
- m_code = 0;
- }
-}
-
-
-bool Tile::isVowel() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_vowels[TILE_IDX_JOKER];
- return Tiles_vowels[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-bool Tile::isConsonant() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_consonants[TILE_IDX_JOKER];
- return Tiles_consonants[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-unsigned int Tile::maxNumber() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_numbers[TILE_IDX_JOKER];
- return Tiles_numbers[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-unsigned int Tile::getPoints() const
-{
- if (m_dummy)
- return false;
- if (m_joker)
- return Tiles_points[TILE_IDX_JOKER];
- return Tiles_points[TILE_IDX_START + m_char - TILE_START];
-}
-
-
-const list<Tile>& Tile::getAllTiles()
-{
- if (Tile::m_tilesList.size() == 0)
- {
- // XXX: this should be filled from a "language file" instead
- for (char i = TILE_START; i <= TILE_END; i++)
- Tile::m_tilesList.push_back(Tile(i));
- m_tilesList.push_back(Tile(TILE_JOKER));
- }
- return Tile::m_tilesList;
-}
-
-
-const Tile& Tile::GetTileFromCode(unsigned int iCode)
-{
- if (!m_vectInitialized)
- {
- // XXX: this should be filled from a "language file" instead
- for (char i = TILE_IDX_START; i <= TILE_IDX_END; i++)
- Tile::m_tilesVect[i] = Tile(i + 'A' - TILE_IDX_START);
- m_tilesVect[TILE_IDX_JOKER] = Tile::Joker();
- m_vectInitialized = true;
- }
- return Tile::m_tilesVect[iCode];
-}
-
-
-wchar_t Tile::toChar() const
-{
- if (m_dummy)
- return TILE_DUMMY;
- if (m_joker)
- {
- if (iswalpha(m_char))
- return towlower(m_char);
- else
- return TILE_JOKER;
- }
- return m_char;
-}
-
-unsigned int Tile::toCode() const
-{
- return m_code;
-}
-
-bool Tile::operator <(const Tile &iOther) const
-{
- if (iOther.m_dummy)
- return false;
- else if (m_dummy)
- return true;
- else if (m_joker)
- return false;
- else if (iOther.m_joker)
- return true;
- else
- return m_char < iOther.m_char;
-}
-
-
-bool Tile::operator ==(const Tile &iOther) const
-{
- if (m_dummy || iOther.m_dummy)
- return m_dummy == iOther.m_dummy;
- if (m_joker || iOther.m_joker)
- {
- if (m_joker != iOther.m_joker)
- return false;
- return m_char == iOther.m_char;
- }
- return m_char == iOther.m_char;
-// return (m_joker && iOther.m_joker && m_char == iOther.m_char) ||
-// (m_dummy && iOther.m_dummy) ||
-// (!m_dummy && !iOther.m_dummy
-// && !m_joker && !iOther.m_joker
-// && m_char == iOther.m_char);
-}
-
-
-bool Tile::operator !=(const Tile &iOther) const
-{
- return !(*this == iOther);
-}
-
-/// Local Variables:
-/// mode: c++
-/// mode: hs-minor
-/// c-basic-offset: 4
-/// indent-tabs-mode: nil
-/// End:
Index: game/tile.h
===================================================================
RCS file: game/tile.h
diff -N game/tile.h
--- game/tile.h 22 Jan 2006 12:23:53 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,95 +0,0 @@
-/*****************************************************************************
- * Copyright (C) 2005 Eliot
- * Authors: Olivier Teuliere <address@hidden>
- *
- * 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
- *****************************************************************************/
-
-#ifndef _TILE_H_
-#define _TILE_H_
-
-#include <list>
-#include <vector>
-
-using namespace std;
-
-
-/*************************
- * A Tile is the internal representation
- * used within the game library to
- * handle letters
- *************************/
-
-class Tile
-{
-public:
-
- // a lowercase character always a joker
- // - this permits to detect joker in already played games
- // - we need to pay attention when inserting character taken
- // from user input
-
- Tile(wchar_t c = 0);
- virtual ~Tile() {}
-
- bool isEmpty() const { return m_dummy; }
- bool isJoker() const { return m_joker; }
- bool isVowel() const;
- bool isConsonant() const;
- unsigned int maxNumber() const;
- unsigned int getPoints() const;
- wchar_t toChar() const;
- unsigned int toCode() const;
-
- static const Tile &dummy() { return m_TheDummy; }
- static const Tile &Joker() { return m_TheJoker; }
- static const list<Tile>& getAllTiles();
- static const Tile &GetTileFromCode(unsigned int iCode);
-
- bool operator <(const Tile &iOther) const;
- bool operator ==(const Tile &iOther) const;
- bool operator !=(const Tile &iOther) const;
-
-private:
- wchar_t m_char;
- bool m_joker;
- bool m_dummy;
-
- /**
- * Internal code, used in the dictionary to represent the letter.
- * It is mainly used by the Cross class.
- */
- int m_code;
-
- // Special tiles are declared static
- static const Tile m_TheJoker;
- static const Tile m_TheDummy;
-
- /// List of available tiles
- static list<Tile> m_tilesList;
- /// Vector of tiles indexed by their code, for fast look-up
- static vector<Tile> m_tilesVect;
- /// True when m_tilesVect is correctly initialized
- static bool m_vectInitialized;
-};
-
-#endif
-
-/// Local Variables:
-/// mode: c++
-/// mode: hs-minor
-/// c-basic-offset: 4
-/// indent-tabs-mode: nil
-/// End:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Eliot-dev] eliot INSTALL TODO configure.in dic/.cvsignore ...,
eliot-dev <=