eliot-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Eliot-dev] eliot ./TODO ./configure.in dic/alist.c dic/ali... [multibyt


From: eliot-dev
Subject: [Eliot-dev] eliot ./TODO ./configure.in dic/alist.c dic/ali... [multibyte]
Date: Tue, 03 Jan 2006 20:42:14 +0000

CVSROOT:        /sources/eliot
Module name:    eliot
Branch:         multibyte
Changes by:     Olivier Teulière <address@hidden>      06/01/03 20:42:13

Modified files:
        .              : TODO configure.in 
        dic            : alist.c alist.h automaton.c automaton.h 
                         compdic.c dic.c dic.h dic_internals.h 
                         dic_search.c dic_search.h hashtable.c 
                         hashtable.h listdic.c regexp.c regexp.h 
                         regexpmain.c 
        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 
                         history.cpp history.h player.cpp player.h 
                         pldrack.cpp pldrack.h rack.cpp rack.h 
                         results.cpp results.h round.cpp round.h 
                         tile.cpp tile.h training.cpp training.h 
                         turn.cpp turn.h 
        po             : POTFILES.in 
        test           : driver duplicate_2_ai.ref freegame_3_ai.ref 
                         freegame_passing.ref load_game.input 
                         load_game.ref test.elt training_back.ref 
                         training_search.ref 
        utils          : eliottxt.cpp game_io.cpp ncurses.cpp 
        wxwin          : auxframes.cc auxframes.h ewx.h gfxboard.cc 
                         gfxboard.h gfxresult.cc gfxresult.h main.cc 
                         mainframe.cc mainframe.h 
Added files:
        game           : game_io.cpp 
        test           : fumee load_saved_game.input load_saved_game.ref 
                         load_test_adv.input load_test_adv.ref 
                         regexp.input regexp.ref training_cross.input 
                         training_cross.ref 

Log message:
        Merged the latest updates from HEAD and adapted them to multibyte 
support.
        All the regression tests are working correctly.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/TODO.diff?only_with_tag=multibyte&tr1=1.3&tr2=1.3.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/configure.in.diff?only_with_tag=multibyte&tr1=1.14.2.1&tr2=1.14.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/alist.c.diff?only_with_tag=multibyte&tr1=1.3&tr2=1.3.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/alist.h.diff?only_with_tag=multibyte&tr1=1.3&tr2=1.3.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/automaton.c.diff?only_with_tag=multibyte&tr1=1.11&tr2=1.11.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/automaton.h.diff?only_with_tag=multibyte&tr1=1.10&tr2=1.10.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/compdic.c.diff?only_with_tag=multibyte&tr1=1.6.2.1&tr2=1.6.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/dic.c.diff?only_with_tag=multibyte&tr1=1.9&tr2=1.9.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/dic.h.diff?only_with_tag=multibyte&tr1=1.11&tr2=1.11.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/dic_internals.h.diff?only_with_tag=multibyte&tr1=1.5&tr2=1.5.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/dic_search.c.diff?only_with_tag=multibyte&tr1=1.14.2.2&tr2=1.14.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/dic_search.h.diff?only_with_tag=multibyte&tr1=1.10.2.2&tr2=1.10.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/hashtable.c.diff?only_with_tag=multibyte&tr1=1.4&tr2=1.4.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/hashtable.h.diff?only_with_tag=multibyte&tr1=1.5&tr2=1.5.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/listdic.c.diff?only_with_tag=multibyte&tr1=1.6.2.1&tr2=1.6.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/regexp.c.diff?only_with_tag=multibyte&tr1=1.11&tr2=1.11.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/regexp.h.diff?only_with_tag=multibyte&tr1=1.11&tr2=1.11.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/regexpmain.c.diff?only_with_tag=multibyte&tr1=1.10.2.1&tr2=1.10.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/Makefile.am.diff?only_with_tag=multibyte&tr1=1.11.2.1&tr2=1.11.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/ai_percent.cpp.diff?only_with_tag=multibyte&tr1=1.4&tr2=1.4.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/ai_percent.h.diff?only_with_tag=multibyte&tr1=1.5&tr2=1.5.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/ai_player.h.diff?only_with_tag=multibyte&tr1=1.6&tr2=1.6.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/bag.cpp.diff?only_with_tag=multibyte&tr1=1.5.2.1&tr2=1.5.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/bag.h.diff?only_with_tag=multibyte&tr1=1.7&tr2=1.7.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/board.cpp.diff?only_with_tag=multibyte&tr1=1.11.2.1&tr2=1.11.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/board.h.diff?only_with_tag=multibyte&tr1=1.10.2.1&tr2=1.10.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/board_cross.cpp.diff?only_with_tag=multibyte&tr1=1.5&tr2=1.5.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/board_search.cpp.diff?only_with_tag=multibyte&tr1=1.9&tr2=1.9.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/coord.cpp.diff?only_with_tag=multibyte&tr1=1.7.2.2&tr2=1.7.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/coord.h.diff?only_with_tag=multibyte&tr1=1.5.2.1&tr2=1.5.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/cross.cpp.diff?only_with_tag=multibyte&tr1=1.4&tr2=1.4.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/cross.h.diff?only_with_tag=multibyte&tr1=1.5&tr2=1.5.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/debug.h.diff?only_with_tag=multibyte&tr1=1.10&tr2=1.10.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/duplicate.cpp.diff?only_with_tag=multibyte&tr1=1.14.2.1&tr2=1.14.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/duplicate.h.diff?only_with_tag=multibyte&tr1=1.10.2.1&tr2=1.10.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/freegame.cpp.diff?only_with_tag=multibyte&tr1=1.16.2.1&tr2=1.16.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/freegame.h.diff?only_with_tag=multibyte&tr1=1.9.2.1&tr2=1.9.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game.cpp.diff?only_with_tag=multibyte&tr1=1.27.2.1&tr2=1.27.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game.h.diff?only_with_tag=multibyte&tr1=1.26.2.1&tr2=1.26.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game_factory.cpp.diff?only_with_tag=multibyte&tr1=1.6&tr2=1.6.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game_factory.h.diff?only_with_tag=multibyte&tr1=1.6&tr2=1.6.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game_io.cpp?only_with_tag=multibyte&rev=1.2.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/history.cpp.diff?only_with_tag=multibyte&tr1=1.8.2.2&tr2=1.8.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/history.h.diff?only_with_tag=multibyte&tr1=1.8.2.1&tr2=1.8.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/player.cpp.diff?only_with_tag=multibyte&tr1=1.12.2.2&tr2=1.12.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/player.h.diff?only_with_tag=multibyte&tr1=1.16.2.1&tr2=1.16.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/pldrack.cpp.diff?only_with_tag=multibyte&tr1=1.7.2.1&tr2=1.7.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/pldrack.h.diff?only_with_tag=multibyte&tr1=1.10.2.1&tr2=1.10.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/rack.cpp.diff?only_with_tag=multibyte&tr1=1.5&tr2=1.5.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/rack.h.diff?only_with_tag=multibyte&tr1=1.7&tr2=1.7.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/results.cpp.diff?only_with_tag=multibyte&tr1=1.9&tr2=1.9.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/results.h.diff?only_with_tag=multibyte&tr1=1.7&tr2=1.7.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/round.cpp.diff?only_with_tag=multibyte&tr1=1.8.2.2&tr2=1.8.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/round.h.diff?only_with_tag=multibyte&tr1=1.10.2.1&tr2=1.10.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/tile.cpp.diff?only_with_tag=multibyte&tr1=1.5.2.1&tr2=1.5.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/tile.h.diff?only_with_tag=multibyte&tr1=1.6.2.1&tr2=1.6.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/training.cpp.diff?only_with_tag=multibyte&tr1=1.14.2.1&tr2=1.14.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/training.h.diff?only_with_tag=multibyte&tr1=1.13.2.1&tr2=1.13.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/turn.cpp.diff?only_with_tag=multibyte&tr1=1.9.2.1&tr2=1.9.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/turn.h.diff?only_with_tag=multibyte&tr1=1.7.2.1&tr2=1.7.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/po/POTFILES.in.diff?only_with_tag=multibyte&tr1=1.2&tr2=1.2.4.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/driver.diff?only_with_tag=multibyte&tr1=1.3&tr2=1.3.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/duplicate_2_ai.ref.diff?only_with_tag=multibyte&tr1=1.2&tr2=1.2.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/freegame_3_ai.ref.diff?only_with_tag=multibyte&tr1=1.2&tr2=1.2.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/freegame_passing.ref.diff?only_with_tag=multibyte&tr1=1.2&tr2=1.2.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/fumee?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/load_game.input.diff?only_with_tag=multibyte&tr1=1.1&tr2=1.1.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/load_game.ref.diff?only_with_tag=multibyte&tr1=1.1&tr2=1.1.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/load_saved_game.input?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/load_saved_game.ref?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/load_test_adv.input?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/load_test_adv.ref?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/regexp.input?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/regexp.ref?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/test.elt.diff?only_with_tag=multibyte&tr1=1.1&tr2=1.1.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/training_back.ref.diff?only_with_tag=multibyte&tr1=1.1&tr2=1.1.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/training_cross.input?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/training_cross.ref?only_with_tag=multibyte&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/test/training_search.ref.diff?only_with_tag=multibyte&tr1=1.2&tr2=1.2.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/utils/eliottxt.cpp.diff?only_with_tag=multibyte&tr1=1.12.2.2&tr2=1.12.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/utils/game_io.cpp.diff?only_with_tag=multibyte&tr1=1.7.2.1&tr2=1.7.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/utils/ncurses.cpp.diff?only_with_tag=multibyte&tr1=1.19.2.1&tr2=1.19.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/auxframes.cc.diff?only_with_tag=multibyte&tr1=1.19.2.3&tr2=1.19.2.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/auxframes.h.diff?only_with_tag=multibyte&tr1=1.5.2.1&tr2=1.5.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/ewx.h.diff?only_with_tag=multibyte&tr1=1.9&tr2=1.9.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/gfxboard.cc.diff?only_with_tag=multibyte&tr1=1.8&tr2=1.8.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/gfxboard.h.diff?only_with_tag=multibyte&tr1=1.6&tr2=1.6.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/gfxresult.cc.diff?only_with_tag=multibyte&tr1=1.3.2.1&tr2=1.3.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/gfxresult.h.diff?only_with_tag=multibyte&tr1=1.2.2.1&tr2=1.2.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/main.cc.diff?only_with_tag=multibyte&tr1=1.8&tr2=1.8.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/mainframe.cc.diff?only_with_tag=multibyte&tr1=1.17.2.1&tr2=1.17.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/mainframe.h.diff?only_with_tag=multibyte&tr1=1.6&tr2=1.6.2.1&r1=text&r2=text

Patches:
Index: eliot/TODO
diff -u /dev/null eliot/TODO:1.3.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/TODO  Tue Jan  3 20:42:13 2006
@@ -0,0 +1,53 @@
+
+* ====================
+* TODO Current version
+* ====================
+
+ - The dictionary must use codes for performance reasons, 
+   the board must also be made to use codes instead of tiles. 
+   Using class Tiles during search results in a HUGE 
+   performance penalty. Class cross is a performance killer. 
+   Will return back to using code bitmaps in board for cross 
+   search. Files cross.h and cross.cpp are to be removed or
+   replaced by a 64 bits code bitmap.
+
+ - 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
+   - 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
+ - detection of blocked positions?
+ - getopt support for all the interfaces (only ncurses is done)
+
+* =============
+* Not so urgent
+* =============
+
+ - network support
+ - add timers
+
+
+%%% Local Variables:
+%%% mode: outline
+%%% End:
+
Index: eliot/configure.in
diff -u eliot/configure.in:1.14.2.1 eliot/configure.in:1.14.2.2
--- eliot/configure.in:1.14.2.1 Wed Dec 28 20:45:32 2005
+++ eliot/configure.in  Tue Jan  3 20:42:13 2006
@@ -33,17 +33,22 @@
 fi
 
 dnl Debug mode
-AC_ARG_ENABLE(debug,
-[  --enable-debug          debug mode (default enabled)])
-if test "${enable_debug}" != "no"; then
-    CPPFLAGS="${CPPFLAGS} -DDEBUG"
-    dnl CFLAGS="${CFLAGS} -O0"
-    dnl CXXFLAGS="${CXXFLAGS} -O0"
+AC_ARG_ENABLE([debug],AC_HELP_STRING([--enable-debug],[debug mode (default 
disabled)]))
+if test "${enable_debug}" = "yes"; then
+    CFLAGS="${CFLAGS} -g -DDEBUG"
+    CPPFLAGS="${CPPFLAGS} -g -DDEBUG"
 fi
 
-dnl Regexp build
-AC_ARG_ENABLE(dictools,
-[  --enable-dictools         build independant dictionary tools (default 
enabled)])
+dnl Profile mode
+AC_ARG_ENABLE([profile],AC_HELP_STRING([--enable-profile],[profile mode 
(default disabled)]))
+if test "${enable_profile}" = "yes"; then
+    CFLAGS="${CFLAGS} -pg -DPROFILE"
+    CPPFLAGS="${CPPFLAGS} -pg -DPROFILE"
+    LDFLAGS="${LDFLAGS} -pg"
+fi
+
+dnl Regexp / Listdic / Compdic build enable
+AC_ARG_ENABLE([dictools],AC_HELP_STRING([--enable-dictools],[build independant 
dictionary tools (default enabled)]))
 AM_PROG_LEX
 AC_PROG_YACC
 AM_CONDITIONAL([BUILD_DICTOOLS], [test "${enable_dictools}" != "no"])
@@ -78,32 +83,30 @@
 dnl --------------------------------------------------------------
 
 dnl Check for wxWidgets
-AC_ARG_ENABLE(wxwidgets,
-[  --enable-wxwidgets      wxWidgets interface support (default disabled)])
+AC_ARG_ENABLE([wxwidgets],AC_HELP_STRING([--enable-wxwidgets],[wxWidgets 
interface support (default disabled)]))
 if test "${enable_wxwidgets}" = "yes"
 then
-  AM_PATH_WXCONFIG([2.4.0], [wxwin=1], [wxwin=0], [], [--unicode])
-  if test "${wxwin}" != 1; then
-  AC_MSG_ERROR([
-    wxWidgets (unicode build) must be installed on your system
-    but wx-config script couldn't be found.
-
-    Please check that wx-config is in path, the directory
-    where wxWidgets libraries are installed (returned by
-    'wx-config --libs' command) is in LD_LIBRARY_PATH or
-    equivalent variable and wxWindows version is 2.4.0 or above.
-  ])
+  AM_PATH_WXCONFIG(2.6.0, [wxWin=1], [wxWin=0], [], [--unicode])
+  if test "${wxWin}" != 1; then
+        AC_MSG_ERROR([
+                wxWidgets (unicode build) must be installed on your system
+                but wx-config script couldn't be found.
+
+                Please check that wx-config is in path, the directory
+                where wxWidgets libraries are installed (returned by
+                'wx-config --libs' command) is in LD_LIBRARY_PATH or
+                equivalent variable and wxWidgets version is 2.6.0 or above.
+        ])
   fi
   AM_CPPFLAGS="$AM_CPPFLAGS $WX_CPPFLAGS"
   AM_CXXFLAGS="$AM_CXXFLAGS $WX_CXXFLAGS_ONLY"
   AM_CFLAGS="$AM_CFLAGS $WX_CFLAGS_ONLY"
   AM_LDFLAGS="$AM_LDFLAGS $WX_LIBS"
 fi
-AM_CONDITIONAL([BUILD_WXWIDGETS], [test "${wxwin}" = "1"])
+AM_CONDITIONAL([BUILD_WXWIDGETS], [test "${wxWin}" = "1"])
 
 dnl Check for ncurses
-AC_ARG_ENABLE(ncurses,
-[  --enable-ncurses        ncurses interface support (default disabled)])
+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,
@@ -112,8 +115,7 @@
 AM_CONDITIONAL([BUILD_NCURSES], [test "${want_ncurses}" = "1"])
 
 dnl Enable/disable text version
-AC_ARG_ENABLE(text,
-[  --enable-text           text interface support (default enabled)])
+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,
Index: eliot/dic/alist.c
diff -u /dev/null eliot/dic/alist.c:1.3.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/alist.c   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,200 @@
+/* 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"
+
+
+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 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: eliot/dic/alist.h
diff -u /dev/null eliot/dic/alist.h:1.3.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/alist.h   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,98 @@
+/* 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: eliot/dic/automaton.c
diff -u /dev/null eliot/dic/automaton.c:1.11.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/automaton.c       Tue Jan  3 20:42:13 2006
@@ -0,0 +1,693 @@
+/* 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 char*     s_automaton_id_to_str      (alist 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 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*)id);
+  return a;
+}
+
+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;
+}
+
+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 &&
+                     
(int)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 ((int)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 = (int)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;
+}
+
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
+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");
+}
+
+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");
+           }
+       }
+    }
+}
+
+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
+}
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
Index: eliot/dic/automaton.h
diff -u /dev/null eliot/dic/automaton.h:1.10.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/automaton.h       Tue Jan  3 20:42:13 2006
@@ -0,0 +1,76 @@
+/* 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.h
+ *  \brief  (Non)Deterministic Finite Automaton for Regexp
+ *  \author Antoine Fraboulet
+ *  \date   2005
+ */
+
+#ifndef _DIC_AUTOMATON_H_
+#define _DIC_AUTOMATON_H_
+#if defined(__cplusplus)
+extern "C"
+  {
+#endif
+
+typedef struct automaton_t       *automaton;
+
+    /**
+     * 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 delete function
+     */
+void      automaton_delete         (automaton a);
+
+    /**
+     * get the number of states in the automaton
+     * @returns number of states
+     */
+int       automaton_get_nstate     (automaton a);
+
+    /**
+     * query the id of the init state
+     * @returns init state id
+     */
+int       automaton_get_init       (automaton a);
+
+    /**
+     * ask for the acceptor flag for the state
+     * @returns boolean flag 0 or 1
+     */
+int       automaton_get_accept     (automaton a, int state);
+
+    /**
+     * returns 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);
+
+void      automaton_dump           (automaton a, char* filename);
+
+#if defined(__cplusplus)
+  }
+#endif
+#endif /* _DIC_AUTOMATON_H_ */
Index: eliot/dic/compdic.c
diff -u eliot/dic/compdic.c:1.6.2.1 eliot/dic/compdic.c:1.6.2.2
--- eliot/dic/compdic.c:1.6.2.1 Wed Dec 28 16:47:35 2005
+++ eliot/dic/compdic.c Tue Jan  3 20:42:13 2006
@@ -8,7 +8,7 @@
 /* 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,                   */
+/* 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.                              */
@@ -17,6 +17,13 @@
 /* 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>
Index: eliot/dic/dic.c
diff -u /dev/null eliot/dic/dic.c:1.9.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/dic.c     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,216 @@
+/* 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 "dic_internals.h"
+#include "dic.h"
+
+
+static int
+check_header(FILE* file, Dict_header *header)
+{
+  if (fread(header,sizeof(Dict_header),1,file) != 1)
+    return 1;
+  return strcmp(header->ident,_COMPIL_KEYWORD_);
+}
+
+
+int
+Dic_load(Dictionary *dic, const char* path)
+{
+  FILE* file;
+  Dict_header header;
+
+  *dic = NULL;
+  if ((file = fopen(path,"rb")) == NULL)
+    return 1;
+  if (check_header(file,&header))
+    return 2;
+  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;
+
+  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: eliot/dic/dic.h
diff -u /dev/null eliot/dic/dic.h:1.11.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/dic.h     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,146 @@
+/* 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.h
+ *  \brief  Dawg dictionary
+ *  \author Antoine Fraboulet
+ *  \date   2002
+ */
+
+#ifndef _DIC_H_
+#define _DIC_H_
+#if defined(__cplusplus)
+extern "C"
+  {
+#endif
+
+/**
+ * different letters in the dictionary
+ */
+#define DIC_LETTERS  27
+
+/**
+ * max length of words (including last \0)
+ */
+#define DIC_WORD_MAX 16
+
+typedef struct _Dictionary* Dictionary;
+typedef unsigned int dic_elt_t;
+typedef unsigned char dic_code_t;
+
+    /**
+     * Dictionary creation and loading from a file
+     * @param dic : pointer to a dictionary
+     * @param path : compressed dictionary path
+     * @return 0 ok, 1 error
+     */
+int    Dic_load   (Dictionary* dic,const char* path);
+
+    /**
+     * Destroy a dictionary
+     */
+int    Dic_destroy(Dictionary dic);
+
+    /**
+     * Dic_chr 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);
+
+    /**
+     * 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);
+
+    /**
+     * Returns a boolean to show if we are at the end of a word
+     * (see Dic_next)
+     * @returns 0 or 1 (true)
+     */
+int    Dic_word(Dictionary dic, dic_elt_t elt);
+
+    /**
+     * Returns the root of the dictionary
+     * @returns root element
+     */
+dic_elt_t Dic_root(Dictionary dic);
+
+    /**
+     * Returns the next available neighbor (see Dic_last)
+     * @returns next dictionary element at the same depth
+     */
+dic_elt_t Dic_next(Dictionary dic, dic_elt_t elt);
+
+    /**
+     * 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);
+
+    /**
+     * 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
+     * @returns 0 if the string cannot be matched otherwise returns the
+     * 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);
+
+    /**
+     * 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
+     * @returns 0 if the string cannot be matched otherwise returns the
+     * element that results from walking the dictionary according to the
+     * pattern
+     */
+unsigned int Dic_char_lookup(Dictionary dic, dic_elt_t root, char* pattern);
+
+#if defined(__cplusplus)
+  }
+#endif
+#endif /* _DIC_H_ */
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/dic/dic_internals.h
diff -u /dev/null eliot/dic/dic_internals.h:1.5.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/dic_internals.h   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,93 @@
+/* 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_internals.h
+ *  \brief  Internal dictionary structures
+ *  \author Antoine Fraboulet
+ *  \date   2002
+ */
+
+#ifndef _DIC_INTERNALS_H_
+#define _DIC_INTERNALS_H_
+#if defined(__cplusplus)
+extern "C"
+  {
+#endif
+
+/**
+ * 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
+ *  header              \n
+ *  ----------------    \n
+ *  specialnode (0)     \n
+ *  +                   \n
+ *  + nodes             \n
+ *  +                   \n
+ *  firstnode (= root)  \n
+ *  ----------------
+ */
+
+typedef struct _Dawg_edge {
+   unsigned int ptr  : 24;
+   unsigned int term : 1;
+   unsigned int last : 1;
+   unsigned int fill : 1;
+   unsigned int chr  : 5;
+} Dawg_edge;
+
+typedef struct _Dict_header {
+  char ident[sizeof(_COMPIL_KEYWORD_)];
+  char unused_1;
+  char unused_2;
+  int root;
+  int nwords;
+  unsigned int edgesused;
+  unsigned int nodesused;
+  unsigned int nodessaved;
+  unsigned int edgessaved;
+} Dict_header;
+
+struct _Dictionary
+{
+  Dawg_edge *dawg;
+  unsigned int root;
+  int nwords;
+  int nnodes;
+  int nedges;
+};
+
+#if defined(__cplusplus)
+  }
+#endif
+#endif /* _DIC_INTERNALS_H */
+
Index: eliot/dic/dic_search.c
diff -u eliot/dic/dic_search.c:1.14.2.2 eliot/dic/dic_search.c:1.14.2.3
--- eliot/dic/dic_search.c:1.14.2.2     Wed Dec 28 20:02:52 2005
+++ eliot/dic/dic_search.c      Tue Jan  3 20:42:13 2006
@@ -8,7 +8,7 @@
 /* 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,                   */
+/* 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.                              */
Index: eliot/dic/dic_search.h
diff -u eliot/dic/dic_search.h:1.10.2.2 eliot/dic/dic_search.h:1.10.2.3
--- eliot/dic/dic_search.h:1.10.2.2     Wed Dec 28 20:02:52 2005
+++ eliot/dic/dic_search.h      Tue Jan  3 20:42:13 2006
@@ -8,7 +8,7 @@
 /* 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,                   */
+/* 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.                              */
@@ -18,7 +18,7 @@
 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
*/
 
 /**
- *  \file dic_search.h
+ *  \file   dic_search.h
  *  \brief  Dictionary lookup functions
  *  \author Antoine Fraboulet
  *  \date   2002
Index: eliot/dic/hashtable.c
diff -u /dev/null eliot/dic/hashtable.c:1.4.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/hashtable.c       Tue Jan  3 20:42:13 2006
@@ -0,0 +1,163 @@
+/* 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: eliot/dic/hashtable.h
diff -u /dev/null eliot/dic/hashtable.h:1.5.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/hashtable.h       Tue Jan  3 20:42:13 2006
@@ -0,0 +1,46 @@
+/* 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.h
+ *  \brief  Simple hashtable type
+ *  \author Antoine Fraboulet
+ *  \date   1999
+ */
+
+#ifndef _HASHTABLE_H
+#define _HASHTABLE_H
+#if defined(__cplusplus)
+extern "C"
+  {
+#endif
+
+typedef struct _Hash_table* Hash_table;
+
+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: eliot/dic/listdic.c
diff -u eliot/dic/listdic.c:1.6.2.1 eliot/dic/listdic.c:1.6.2.2
--- eliot/dic/listdic.c:1.6.2.1 Wed Dec 28 16:47:35 2005
+++ eliot/dic/listdic.c Tue Jan  3 20:42:13 2006
@@ -8,7 +8,7 @@
 /* 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,                   */
+/* 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.                              */
@@ -17,6 +17,13 @@
 /* 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>
Index: eliot/dic/regexp.c
diff -u /dev/null eliot/dic/regexp.c:1.11.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/regexp.c  Tue Jan  3 20:42:13 2006
@@ -0,0 +1,382 @@
+/* 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: eliot/dic/regexp.h
diff -u /dev/null eliot/dic/regexp.h:1.11.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/dic/regexp.h  Tue Jan  3 20:42:13 2006
@@ -0,0 +1,160 @@
+/* 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.h
+ *  \brief  Regular Expression functions
+ *  \author Antoine Fraboulet
+ *  \date   2005
+ */
+
+#ifndef _TREE_H_
+#define _TREE_H_
+#if defined(__cplusplus)
+extern "C"
+  {
+#endif
+
+#define NODE_TOP    0
+#define NODE_VAR    1
+#define NODE_OR     2
+#define NODE_AND    3
+#define NODE_STAR   4
+#define NODE_PLUS   5
+
+typedef struct node {
+  int              type;
+  char             var;
+  struct node      *fg;
+  struct node      *fd;
+  int numero;
+  int position;
+  int annulable;
+  int PP;
+  int DP;
+} NODE;
+
+    /**
+     * maximum number of accepted terminals in regular expressions
+     */
+#define REGEXP_MAX 32
+
+    /**
+     * special terminals that should not appear in the dictionary
+     */
+#define RE_EPSILON     (DIC_LETTERS + 0)
+#define RE_FINAL_TOK   (DIC_LETTERS + 1)
+#define RE_ALL_MATCH   (DIC_LETTERS + 2)
+#define RE_VOWL_MATCH  (DIC_LETTERS + 3)
+#define RE_CONS_MATCH  (DIC_LETTERS + 4)
+#define RE_USR1_MATCH  (DIC_LETTERS + 5)
+#define RE_USR2_MATCH  (DIC_LETTERS + 6)
+
+    /**
+     * number of lists for regexp letter match \n
+     * 0 : all tiles                           \n
+     * 1 : vowels                              \n
+     * 2 : consonants                          \n
+     * 3 : user defined 1                      \n
+     * 4 : user defined 2                      \n
+     * x : lists used during parsing           \n
+     */
+#define DIC_SEARCH_REGE_LIST (REGEXP_MAX)
+
+    /**
+     * Structure used for Dic_search_RegE \n
+     * this structure is used to explicit letters list that will be matched
+     * against special tokens in the regular expression search
+     */
+struct search_RegE_list_t {
+  /** maximum length for results */
+  int minlength;
+  /** maximum length for results */
+  int maxlength;
+  /** special symbol associated with the list */
+  char symbl[DIC_SEARCH_REGE_LIST];
+  /** 0 or 1 if list is valid */
+  int  valid[DIC_SEARCH_REGE_LIST];
+  /** 0 or 1 if letter is present in the list */
+  char letters[DIC_SEARCH_REGE_LIST][DIC_LETTERS];
+};
+
+#define RE_LIST_ALL_MATCH  0
+#define RE_LIST_VOYL_MATCH 1
+#define RE_LIST_CONS_MATCH 2
+#define RE_LIST_USER_BEGIN 3
+#define RE_LIST_USER_END   4
+
+    /**
+     * Create a node for the syntactic tree used for
+     * parsing regular expressions                    \n
+     * The fonction is called by bison grammar rules
+     */
+NODE* regexp_createNODE(int type,char v,NODE *fg,NODE *fd);
+
+    /**
+     * delete regexp syntactic tree
+     */
+void  regexp_delete_tree(NODE * root);
+
+    /**
+     * Computes positions, first positions (PP), last position (DP)
+     * and translation table 'position to letter' (ptl)
+     * @param p : max position found in the tree (must be initialized to 1)
+     * @param n : number of nodes in the tree (must be initialized to 1)
+     * @param ptl : position to letter translation table
+     */
+void  regexp_parcours(NODE* r, int *p, int *n, int ptl[]);
+
+    /**
+     * Computes 'next position' table used for building the
+     * automaton
+     * @param r : root node of the syntactic tree
+     * @param PS : next position table, PS[0] must contain the
+     * number of terminals contained in the regular expression
+     */
+void  regexp_possuivante(NODE* r, int PS[]);
+
+#define MAX_REGEXP_ERROR_LENGTH 500
+
+struct regexp_error_report_t {
+  int pos1;
+  int pos2;
+  char msg[MAX_REGEXP_ERROR_LENGTH];
+};
+
+#include <stdio.h>
+
+void  regexp_print_letter(FILE* f, char l);
+void  regexp_print_letter2(FILE* f, char l);
+void  regexp_print_PS(int PS[]);
+void  regexp_print_ptl(int ptl[]);
+void  regexp_print_tree(NODE* n, char* name, int detail);
+
+#if defined(__cplusplus)
+  }
+#endif
+#endif /* _TREE_H_ */
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/dic/regexpmain.c
diff -u eliot/dic/regexpmain.c:1.10.2.1 eliot/dic/regexpmain.c:1.10.2.2
--- eliot/dic/regexpmain.c:1.10.2.1     Wed Dec 28 20:02:52 2005
+++ eliot/dic/regexpmain.c      Tue Jan  3 20:42:13 2006
@@ -8,7 +8,7 @@
 /* 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,                   */
+/* 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.                              */
Index: eliot/game/Makefile.am
diff -u eliot/game/Makefile.am:1.11.2.1 eliot/game/Makefile.am:1.11.2.2
--- eliot/game/Makefile.am:1.11.2.1     Wed Dec 28 16:47:35 2005
+++ eliot/game/Makefile.am      Tue Jan  3 20:42:13 2006
@@ -35,6 +35,7 @@
        freegame.cpp freegame.h         \
        game.cpp game.h                 \
        game_factory.cpp game_factory.h \
+       game_io.cpp                     \
        player.cpp player.h             \
        pldrack.cpp pldrack.h           \
        rack.cpp rack.h                 \
Index: eliot/game/ai_percent.cpp
diff -u /dev/null eliot/game/ai_percent.cpp:1.4.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/game/ai_percent.cpp   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * 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
+ *****************************************************************************/
+
+#include "tile.h"
+#include "rack.h"
+#include "pldrack.h"
+#include "round.h"
+#include "results.h"
+#include "board.h"
+#include "ai_percent.h"
+
+
+AIPercent::AIPercent(int iId, float iPercent)
+    : AIPlayer(iId), m_percent(iPercent)
+{
+    // Ensure the decimal value of the percentage is between 0 and 1
+    if (m_percent < 0)
+        m_percent = 0;
+    if (m_percent > 1)
+        m_percent = 1;
+}
+
+
+void AIPercent::compute(const Dictionary &iDic, Board &iBoard, int turn)
+{
+    m_results.clear();
+
+    Rack rack;
+    getCurrentRack().getRack(rack);
+    m_results.search(iDic, iBoard, rack, turn);
+}
+
+
+bool AIPercent::changesLetters() 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>();
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/ai_percent.h
diff -u /dev/null eliot/game/ai_percent.h:1.5.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/game/ai_percent.h     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * 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 _AI_PERCENT_H_
+#define _AI_PERCENT_H_
+
+#include "ai_player.h"
+#include "results.h"
+
+/**
+ * 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.
+ * This kind of AI will never change letters (unless it cannot play anything,
+ * in which case it just passes without changing letters).
+ */
+class AIPercent: public AIPlayer
+{
+public:
+    /// Constructor, taking the percentage (0.0 <= iPercent <= 1.0)
+    AIPercent(int iId, float iPercent);
+    virtual ~AIPercent() {}
+
+    /**
+     * 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;
+
+private:
+    /// Percentage used for this player
+    float m_percent;
+    /// Container for all the found solutions
+    Results m_results;
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/ai_player.h
diff -u /dev/null eliot/game/ai_player.h:1.6.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/game/ai_player.h      Tue Jan  3 20:42:13 2006
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ * 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 _AI_PLAYER_H_
+#define _AI_PLAYER_H_
+
+#include "player.h"
+
+class Round;
+class Board;
+class Tile;
+typedef struct _Dictionary * Dictionary;
+
+/**
+ * This class is a pure interface, that must be implemented by all the AI
+ * (Artificial Intelligence) players
+ *
+ * Note: we could implement various strategies (some of which are already
+ * implemented):
+ *   - best: play the word with the best score (current default implementation)
+ *   - second: play the word with the second best score (strictly lower than
+ *        the best one)
+ *   - random: randomly choose one of the possible words
+ *   - handicap(p): in the array of the n possible words (sorted by
+ *        decreasing scores), play the word number i, where i/n is nearest
+ *        from a predefined percentage p.
+ *        So 'handicap(0)' should be equivalent to 'best'.
+ *        This strategy should make an interesting opponent, because you can
+ *        adapt it to your level, with a careful choice of the p value.
+ *
+ * In fact, instead of working on the score of the words, these strategies
+ * could work on any other value. In particular, some heuristics could
+ * modulate the score with a value indicating the openings offered by the
+ * word (if a word makes accessible a "word counts triple" square, it is
+ * less interesting than another word with the same score or even with a
+ * slightly lower score, but which does not offer such a square).
+ *
+ * More evolved heuristics could even take into account the remaining
+ * letters in the bag to guess the 'statistical rack' of the opponent, and
+ * play a word both maximizing the score and minimizing the opponent's
+ * score...
+ * Hmmm... i don't think this one will be implemented in a near future :)
+ **************************/
+class AIPlayer: public Player
+{
+public:
+    virtual ~AIPlayer() {}
+
+    /// No human here. Trespassers will be shot!
+    virtual bool isHuman() const { return false; }
+
+    /**
+     * 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;
+
+protected:
+    /// This class is a pure interface, forbid any direct instanciation
+    AIPlayer(int iId): Player(iId) {}
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/bag.cpp
diff -u eliot/game/bag.cpp:1.5.2.1 eliot/game/bag.cpp:1.5.2.2
--- eliot/game/bag.cpp:1.5.2.1  Wed Dec 28 16:47:35 2005
+++ eliot/game/bag.cpp  Tue Jan  3 20:42:13 2006
@@ -136,3 +136,10 @@
     }
     fprintf(stderr, "\n");
 }
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/bag.h
diff -u /dev/null eliot/game/bag.h:1.7.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/game/bag.h    Tue Jan  3 20:42:13 2006
@@ -0,0 +1,82 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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 _BAG_H_
+#define _BAG_H_
+
+#include "tile.h"
+#include <map>
+
+using std::map;
+
+
+/**
+ * A bag stores the set of free tiles for the game.
+ */
+class Bag
+{
+public:
+    Bag();
+    virtual ~Bag() {}
+    void init();
+
+    /// Take a tile in the bag
+    void takeTile(const Tile &iTile);
+    /// Replace a tile into the bag
+    void replaceTile(const Tile &iTile);
+
+    /// Return how many tiles identical to iTile are available in the bag
+    unsigned int in(const Tile &iTile) const;
+
+    /**
+     * Return how many tiles/vowels/consonants are available
+     * Warning: nVowels(b) + nConsonants(b) != nTiles(b),
+     * because of the jokers and the 'Y'.
+     */
+    unsigned int nTiles() const  { return m_ntiles; }
+    unsigned int nVowels() const;
+    unsigned int nConsonants() const;
+
+    /**
+     * Return a random available tile
+     * The tile is not taken out of the bag.
+     */
+    Tile selectRandom();
+
+    void operator=(const Bag &iOther);
+
+    /// Print on stderr all the letters of the bag (for debugging purposes)
+    void dumpAll() const;
+
+private:
+    /// 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;
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/board.cpp
diff -u eliot/game/board.cpp:1.11.2.1 eliot/game/board.cpp:1.11.2.2
--- eliot/game/board.cpp:1.11.2.1       Wed Dec 28 16:47:35 2005
+++ eliot/game/board.cpp        Tue Jan  3 20:42:13 2006
@@ -474,3 +474,9 @@
 }
 #endif
 
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/board.h
diff -u eliot/game/board.h:1.10.2.1 eliot/game/board.h:1.10.2.2
--- eliot/game/board.h:1.10.2.1 Wed Dec 28 16:47:35 2005
+++ eliot/game/board.h  Tue Jan  3 20:42:13 2006
@@ -90,31 +90,27 @@
     void removeRound(const Dictionary &iDic, const Round &iRound);
     int checkRound(Round &iRound, bool iFirstTurn);
 
-    /*************************
+    /**
      *
-     *
-     *************************/
+     */
     void testRound(const Round &iRound);
     void removeTestRound();
     char getTestChar(int iRow, int iCol) const;
 
-    /*************************
-     *
+    /**
      * board_search.c
-     *************************/
+     */
     void search(const Dictionary &iDic, const Rack &iRack, Results &oResults);
     void searchFirst(const Dictionary &iDic, const Rack &iRack, Results 
&oResults);
 
-    /*************************
-     *
+    /**
      * board_cross.c
-     *************************/
+     */
     void buildCross(const Dictionary &iDic);
 
-    /*************************
+    /**
      *
-     *
-     *************************/
+     */
     int getWordMultiplier(int iRow, int iCol) const;
     int getLetterMultiplier(int iRow, int iCol) const;
 
@@ -150,3 +146,10 @@
 };
 
 #endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/board_cross.cpp
diff -u /dev/null eliot/game/board_cross.cpp:1.5.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/game/board_cross.cpp  Tue Jan  3 20:42:13 2006
@@ -0,0 +1,141 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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
+ *****************************************************************************/
+
+/**
+ *  \file   board_cross.cpp
+ *  \brief  Build cross information used to speed up search
+ *  \author Antoine Fraboulet & Olivier Teulière
+ *  \date   2005
+ */
+
+#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,
+                                Cross &oCross,
+                                int& oPoints,
+                                int index)
+{
+    unsigned int node, succ;
+    int j;
+
+    oPoints = 0;
+
+    /* Points on the left part */
+    int i = index;
+    while (!iTiles[i - 1].isEmpty())
+    {
+        i--;
+        if (!iJoker[i])
+            oPoints += iTiles[i].getPoints();
+    }
+
+    /* Tiles that can be played */
+    // FIXME: create a temporary string until the dictionary uses Tile objects
+    char leftTiles[BOARD_DIM + 1];
+    for (j = i; j < index; j++)
+        leftTiles[j - i] = toupper(iTiles[j].toChar());
+    leftTiles[index - i] = 0;
+    node = Dic_char_lookup(iDic, Dic_root(iDic), leftTiles);
+    if (node == 0)
+    {
+        oCross.clear();
+        return;
+    }
+
+    // FIXME: same thing for the right part
+    char rightTiles[BOARD_DIM + 1];
+    for (j = index + 1; !iTiles[j].isEmpty(); j++)
+        rightTiles[j - index - 1] = toupper(iTiles[j].toChar());
+    rightTiles[j - index - 1] = 0;
+    for (succ = Dic_succ(iDic, node); succ; succ = Dic_next(iDic, succ))
+    {
+        if (Dic_word(iDic, Dic_char_lookup(iDic, succ, rightTiles)))
+            oCross.insert(Tile(Dic_char(iDic, succ)));
+        if (Dic_last(iDic, succ))
+            break;
+    }
+
+    /* Points on the right part */
+    /* yes, it is REALLY [index+1] */
+    while (!iTiles[index+1].isEmpty())
+    {
+       index++;
+       if (!iJoker[index])
+           oPoints += iTiles[index].getPoints();
+    }
+}
+
+
+static void Board_check(const Dictionary &iDic,
+                        Matrix<Tile> &iTilesMx,
+                        Matrix<bool> &iJokerMx,
+                        Matrix<Cross> &iCrossMx,
+                        Matrix<int> &iPointMx)
+{
+    for (int i = 1; i <= BOARD_DIM; i++)
+    {
+        for (int j = 1; j <= BOARD_DIM; j++)
+        {
+            iPointMx[j][i] = -1;
+            if (!iTilesMx[i][j].isEmpty())
+            {
+                iCrossMx[j][i].clear();
+           }
+            else if (!iTilesMx[i][j - 1].isEmpty() ||
+                     !iTilesMx[i][j + 1].isEmpty())
+            {
+                iCrossMx[j][i].clear();
+                Board_checkout_tile(iDic,
+                                    iTilesMx[i],
+                                    iJokerMx[i],
+                                    iCrossMx[j][i],
+                                    iPointMx[j][i],
+                                    j);
+            }
+            else
+            {
+                iCrossMx[j][i].setAny();
+           }
+        }
+    }
+}
+
+
+void Board::buildCross(const Dictionary &iDic)
+{
+    Board_check(iDic, m_tilesRow, m_jokerRow, m_crossCol, m_pointCol);
+    Board_check(iDic, m_tilesCol, m_jokerCol, m_crossRow, m_pointRow);
+}
+
+
+/****************************************************************/
+/****************************************************************/
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/board_search.cpp
diff -u /dev/null eliot/game/board_search.cpp:1.9.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/game/board_search.cpp Tue Jan  3 20:42:13 2006
@@ -0,0 +1,299 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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 <dic.h>
+#include "tile.h"
+#include "rack.h"
+#include "round.h"
+#include "results.h"
+#include "board.h"
+
+#include "debug.h"
+
+/*
+ * computes the score of a word, coordinates may be changed to reflect
+ * the real direction of the word
+ */
+static void BoardSearchEvalMove(const Board &iBoard,
+                                Matrix<Tile> &iTilesMx,
+                                Matrix<int> &iPointsMx,
+                                Matrix<bool> &iJokerMx,
+                                Results &iResults, Round &iWord)
+{
+    int i, pts, ptscross;
+    int l, t, fromrack;
+    int len, row, col, wordmul;
+
+    fromrack = 0;
+    pts      = 0;
+    ptscross = 0;
+    wordmul  = 1;
+
+    len = iWord.getWordLen();
+
+    row = iWord.getCoord().getRow();
+    col = iWord.getCoord().getCol();
+
+    for (i = 0; i < len; i++)
+    {
+        if (!iTilesMx[row][col+i].isEmpty())
+        {
+            if (!iJokerMx[row][col+i])
+                pts += iWord.getTile(i).getPoints();
+        }
+        else
+        {
+            if (!iWord.isJoker(i))
+                l = iWord.getTile(i).getPoints() *
+                    iBoard.getLetterMultiplier(row, col + i);
+            else
+                l = 0;
+            pts += l;
+            wordmul *= iBoard.getWordMultiplier(row, col + i);
+
+            t = iPointsMx[row][col+i];
+            if (t >= 0)
+                ptscross += (t + l) * iBoard.getWordMultiplier(row, col + i);
+            fromrack++;
+        }
+    }
+    pts = ptscross + pts * wordmul + 50 * (fromrack == 7);
+    iWord.setBonus(fromrack == 7);
+    iWord.setPoints(pts);
+
+    // XXX: ugly!
+    if (iWord.getCoord().getDir() == Coord::VERTICAL)
+    {
+        // Exchange the coordinates temporarily
+        iWord.accessCoord().swap();
+    }
+    iResults.add(iWord);
+    if (iWord.getCoord().getDir() == Coord::VERTICAL)
+    {
+        // Restore the coordinates
+        iWord.accessCoord().swap();
+    }
+}
+
+
+static void ExtendRight(const Board &iBoard,
+                        const Dictionary &iDic,
+                        Matrix<Tile> &iTilesMx,
+                        Matrix<Cross> &iCrossMx,
+                        Matrix<int> &iPointsMx,
+                        Matrix<bool> &iJokerMx,
+                        Rack &iRack, Round &ioPartialWord,
+                        Results &iResults, unsigned int iNode,
+                        int iRow, int iCol, int iAnchor)
+{
+    Tile l;
+    unsigned int succ;
+
+    if (iTilesMx[iRow][iCol].isEmpty())
+    {
+        if (Dic_word(iDic, iNode) && iCol > iAnchor)
+            BoardSearchEvalMove(iBoard, iTilesMx, iPointsMx, iJokerMx,
+                                iResults, ioPartialWord);
+
+        for (succ = Dic_succ(iDic, iNode); succ; succ = Dic_next(iDic, succ))
+        {
+            l = Tile(Dic_char(iDic, succ));
+            if (iCrossMx[iRow][iCol].check(l))
+            {
+                if (iRack.in(l))
+                {
+                    iRack.remove(l);
+                    ioPartialWord.addRightFromRack(l, 0);
+                    ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
+                                iJokerMx, iRack, ioPartialWord, iResults,
+                                succ, iRow, iCol + 1, iAnchor);
+                    ioPartialWord.removeRightToRack(l, 0);
+                    iRack.add(l);
+                }
+                if (iRack.in(Tile::Joker()))
+                {
+                    iRack.remove(Tile::Joker());
+                    ioPartialWord.addRightFromRack(l, 1);
+                    ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
+                                iJokerMx, iRack, ioPartialWord, iResults,
+                                succ, iRow, iCol + 1, iAnchor);
+                    ioPartialWord.removeRightToRack(l, 1);
+                    iRack.add(Tile::Joker());
+                }
+            }
+        }
+    }
+    else
+    {
+        l = iTilesMx[iRow][iCol];
+        for (succ = Dic_succ(iDic, iNode); succ ; succ = Dic_next(iDic, succ))
+        {
+            if (Tile(Dic_char(iDic, succ)) == l)
+            {
+                ioPartialWord.addRightFromBoard(l);
+                ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
+                            iJokerMx, iRack, ioPartialWord,
+                            iResults, succ, iRow, iCol + 1, iAnchor);
+                ioPartialWord.removeRightToBoard(l);
+            }
+        }
+    }
+}
+
+
+static void LeftPart(const Board &iBoard,
+                     const Dictionary &iDic,
+                     Matrix<Tile> &iTilesMx,
+                     Matrix<Cross> &iCrossMx,
+                     Matrix<int> &iPointsMx,
+                     Matrix<bool> &iJokerMx,
+                     Rack &iRack, Round &ioPartialWord,
+                     Results &iResults, int n, int iRow,
+                     int iAnchor, int iLimit)
+{
+    Tile l;
+    int succ;
+
+    ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx, iJokerMx, iRack,
+                ioPartialWord, iResults, n, iRow, iAnchor, iAnchor);
+
+    if (iLimit > 0)
+    {
+        for (succ = Dic_succ(iDic, n); succ; succ = Dic_next(iDic, succ))
+        {
+            l = Tile(Dic_char(iDic, succ));
+            if (iRack.in(l))
+            {
+                iRack.remove(l);
+                ioPartialWord.addRightFromRack(l, 0);
+                
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);
+                iRack.add(l);
+            }
+            if (iRack.in(Tile::Joker()))
+            {
+                iRack.remove(Tile::Joker());
+                ioPartialWord.addRightFromRack(l, 1);
+                
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);
+                iRack.add(Tile::Joker());
+            }
+        }
+    }
+}
+
+
+static void BoardSearchAux(const Board &iBoard,
+                           const Dictionary &iDic,
+                           Matrix<Tile> &iTilesMx,
+                           Matrix<Cross> &iCrossMx,
+                           Matrix<int> &iPointsMx,
+                           Matrix<bool> &iJokerMx,
+                           Rack &iRack, Results &iResults,
+                           Coord::Direction iDir)
+{
+    int row, col, lastanchor;
+    Round partialword;
+    for (row = 1; row <= BOARD_DIM; row++)
+    {
+        partialword.init();
+        partialword.accessCoord().setDir(iDir);
+        partialword.accessCoord().setRow(row);
+        lastanchor = 0;
+        for (col = 1; col <= BOARD_DIM; col++)
+        {
+            if (iTilesMx[row][col].isEmpty() &&
+                (!iTilesMx[row][col - 1].isEmpty() ||
+                 !iTilesMx[row][col + 1].isEmpty() ||
+                 !iTilesMx[row - 1][col].isEmpty() ||
+                 !iTilesMx[row + 1][col].isEmpty()))
+            {
+                if (!iTilesMx[row][col - 1].isEmpty())
+                {
+                    partialword.accessCoord().setCol(lastanchor + 1);
+                    ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
+                                iJokerMx, iRack, partialword, iResults,
+                                Dic_root(iDic), 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 -
+                             lastanchor - 1);
+                }
+                lastanchor = col;
+            }
+        }
+    }
+}
+
+
+void Board::search(const Dictionary &iDic,
+                   const Rack &iRack,
+                   Results &oResults)
+{
+    // Create a copy of the rack to avoid modifying the given one
+    Rack copyRack = iRack;
+
+    BoardSearchAux(*this, iDic, m_tilesRow, m_crossRow,
+                   m_pointRow, m_jokerRow,
+                   copyRack, oResults, Coord::HORIZONTAL);
+
+    BoardSearchAux(*this, iDic, m_tilesCol, m_crossCol,
+                   m_pointCol, m_jokerCol,
+                   copyRack, oResults, Coord::VERTICAL);
+}
+
+
+void Board::searchFirst(const Dictionary &iDic,
+                        const Rack &iRack,
+                        Results &oResults)
+{
+    int row = 8, col = 8;
+
+    // Create a copy of the rack to avoid modifying the given one
+    Rack copyRack = iRack;
+
+    Round partialword;
+    partialword.accessCoord().setRow(row);
+    partialword.accessCoord().setCol(col);
+    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);
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/coord.cpp
diff -u eliot/game/coord.cpp:1.7.2.2 eliot/game/coord.cpp:1.7.2.3
--- eliot/game/coord.cpp:1.7.2.2        Wed Dec 28 18:07:53 2005
+++ eliot/game/coord.cpp        Tue Jan  3 20:42:13 2006
@@ -19,7 +19,7 @@
 
 /**
  *  \file   coord.cpp
- *  \brief  Eliot coordinate system
+ *  \brief  Board coordinate system
  *  \author Antoine Fraboulet
  *  \date   2005
  */
@@ -92,30 +92,40 @@
     setRow(row);
 }
 
-wstring Coord::toString() const
+wstring Coord::toString(coord_mode_t mode) const
 {
     ASSERT(isValid(), "Invalid coordinates");
 
-    wstring res;
-    wchar_t s[5];
-#ifdef WIN32
-    swprintf(s, L"%d", m_col);
-#else
-    swprintf(s, 4, L"%d", m_col);
-#endif
-    if (getDir() == HORIZONTAL)
-    {
-        res = wstring(1, m_row + 'A' - 1) + s;
-    }
-    else
+    wchar_t res[7];
+    wchar_t srow[3];
+    wchar_t scol[3];
+
+    swprintf(scol, 3, L"%d", m_col);
+    swprintf(srow, 3, L"%c", m_row + 'A' - 1);
+
+    switch (mode)
     {
-        res = s + wstring(1, m_row + 'A' - 1);
+    case COORD_MODE_COMPACT:
+        if (getDir() == HORIZONTAL)
+            swprintf(res, 7, L"%ls%ls", srow, scol);
+        else
+            swprintf(res, 7, L"%ls%ls", scol, srow);
+        break;
+    case COORD_MODE_LONG:
+        if (getDir() == HORIZONTAL)
+            swprintf(res, 7, L"%2ls %2ls", srow, scol);
+        else
+            swprintf(res, 7, L"%2ls %2ls", scol, srow);
+        break;
     }
+
+
     return res;
 }
 
-
 /// Local Variables:
+/// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/coord.h
diff -u eliot/game/coord.h:1.5.2.1 eliot/game/coord.h:1.5.2.2
--- eliot/game/coord.h:1.5.2.1  Wed Dec 28 16:47:35 2005
+++ eliot/game/coord.h  Tue Jan  3 20:42:13 2006
@@ -19,7 +19,7 @@
 
 /**
  *  \file   coord.h
- *  \brief  Game coordinates system
+ *  \brief  Board coordinates system
  *  \author Antoine Fraboulet
  *  \date   2005
  */
@@ -55,8 +55,14 @@
     // Swap the coordinates (without changing the direction)
     void swap();
 
+
+    enum coord_mode_t
+    {
+        COORD_MODE_COMPACT,
+        COORD_MODE_LONG
+    };
     void setFromString(const wstring &iStr);
-    wstring toString() const;
+    wstring toString(coord_mode_t mode = COORD_MODE_COMPACT) const;
 
 private:
     Direction m_dir;
@@ -66,8 +72,9 @@
 
 #endif
 
-
 /// Local Variables:
+/// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/cross.cpp
diff -u /dev/null eliot/game/cross.cpp:1.4.2.1
--- /dev/null   Tue Jan  3 20:42:13 2006
+++ eliot/game/cross.cpp        Tue Jan  3 20:42:13 2006
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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
+ *****************************************************************************/
+
+#include "cross.h"
+
+
+Cross::Cross()
+{
+    // the default behaviour is to match everything
+    m_any = true;
+}
+
+
+void Cross::clear()
+{
+    m_tilesSet.clear();
+    m_any = false;
+}
+
+
+bool Cross::check(const Tile& iTile) const
+{
+    if (m_any || (iTile.isJoker() && !m_tilesSet.empty()))
+        return true;
+    set<Tile>::const_iterator it = m_tilesSet.find(iTile);
+    return it != m_tilesSet.end();
+}
+
+
+bool Cross::operator==(const Cross &iOther) const
+{
+    if (isAny() && iOther.isAny())
+        return true;
+    // Two sets are equal if they have the same size and one of them contains
+    // the other one
+    if (m_tilesSet.size() == iOther.m_tilesSet.size())
+    {
+        set<Tile>::const_iterator it;
+        for (it = m_tilesSet.begin(); it != m_tilesSet.end(); it++)
+        {
+            if (!iOther.check(*it))
+                return false;
+        }
+        return true;
+    }
+    else
+        return false;
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/cross.h
diff -u /dev/null eliot/game/cross.h:1.5.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/cross.h  Tue Jan  3 20:42:13 2006
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * 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 _CROSS_H_
+#define _CROSS_H_
+
+#include "tile.h"
+#include <set>
+
+using namespace std;
+
+
+/*************************
+ *
+ *************************/
+
+class Cross
+{
+public:
+    Cross();
+    virtual ~Cross() {}
+
+    void setAny()                   { m_any = true; }
+    bool isAny() const              { return m_any; }
+    bool check(const Tile& iTile) const;
+
+    bool operator==(const Cross &iOther) const;
+    bool operator!=(const Cross &iOther) const { return !(*this == iOther); }
+
+    // Standard set methods (almost)
+    unsigned int size() const       { return m_tilesSet.size(); }
+    void insert(const Tile& iTile)  { m_tilesSet.insert(iTile); }
+    void clear();
+
+private:
+    // Set of the tiles accepted for the cross check
+    set<Tile> m_tilesSet;
+
+    // When this value is true, any letter matches the cross check
+    bool m_any;
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/debug.h
diff -u /dev/null eliot/game/debug.h:1.10.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/debug.h  Tue Jan  3 20:42:13 2006
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <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 _CONST_H_
+#define _CONST_H_
+
+/**********
+ * General
+ **********/
+
+#ifdef DEBUG
+#   include <iostream>
+// Assertion macro: if the condition is not verified, print a message on stderr
+// and stops execution, otherwise do nothing.
+#   define ASSERT(cond, msg) \
+    { \
+        if (!(cond)) \
+        { \
+            cerr << "ASSERTION FAILED: " << (msg) << " (at " \
+                 << __FILE__ << "#" << __LINE__ << ")\n"; \
+            abort(); \
+        } \
+    }
+#else
+#   define ASSERT(cond, msg)
+#endif
+
+#ifdef DEBUG
+#  define debug(x...) { fprintf(stderr,x); }
+#else
+#  define debug(x...)
+#endif
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/duplicate.cpp
diff -u eliot/game/duplicate.cpp:1.14.2.1 eliot/game/duplicate.cpp:1.14.2.2
--- eliot/game/duplicate.cpp:1.14.2.1   Wed Dec 28 16:47:35 2005
+++ eliot/game/duplicate.cpp    Tue Jan  3 20:42:13 2006
@@ -284,3 +284,9 @@
              m_hasPlayed[m_currPlayer]);
 }
 
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/duplicate.h
diff -u eliot/game/duplicate.h:1.10.2.1 eliot/game/duplicate.h:1.10.2.2
--- eliot/game/duplicate.h:1.10.2.1     Wed Dec 28 16:47:35 2005
+++ eliot/game/duplicate.h      Tue Jan  3 20:42:13 2006
@@ -83,3 +83,10 @@
 };
 
 #endif /* _DUPLICATE_H_ */
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/freegame.cpp
diff -u eliot/game/freegame.cpp:1.16.2.1 eliot/game/freegame.cpp:1.16.2.2
--- eliot/game/freegame.cpp:1.16.2.1    Wed Dec 28 16:47:35 2005
+++ eliot/game/freegame.cpp     Tue Jan  3 20:42:13 2006
@@ -255,3 +255,9 @@
     return 0;
 }
 
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/freegame.h
diff -u eliot/game/freegame.h:1.9.2.1 eliot/game/freegame.h:1.9.2.2
--- eliot/game/freegame.h:1.9.2.1       Wed Dec 28 16:47:35 2005
+++ eliot/game/freegame.h       Tue Jan  3 20:42:13 2006
@@ -65,3 +65,10 @@
 };
 
 #endif /* _FREEGAME_H_ */
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/game.cpp
diff -u eliot/game/game.cpp:1.27.2.1 eliot/game/game.cpp:1.27.2.2
--- eliot/game/game.cpp:1.27.2.1        Wed Dec 28 16:47:35 2005
+++ eliot/game/game.cpp Tue Jan  3 20:42:13 2006
@@ -64,271 +64,6 @@
 }
 
 
-Game * Game::load(FILE *fin, const Dictionary &iDic)
-{
-    char buff[4096];
-    char delim[] = " \t\n|";
-    char *token;
-
-    // Check characteristic string
-    if (fgets(buff, sizeof(buff), fin) == NULL)
-        return NULL;
-    if ((token = strtok(buff, delim)) == NULL)
-        return NULL;
-    if (string(token) != IDENT_STRING)
-        return NULL;
-
-    int num;
-    char rack[20];
-    char word[20];
-    char ref[4];
-    int pts;
-    int player;
-    char *pos;
-    Tile tile;
-    Game *pGame = NULL;
-
-    while (fgets(buff, sizeof(buff), fin))
-    {
-        // Indication of game type
-        pos = strstr(buff, "Game type: ");
-        if (pos != NULL)
-        {
-            // No Game object should have been created yet
-            if (pGame != NULL)
-            {
-                delete pGame;
-                return NULL;
-            }
-            // Create the correct Game object
-            if (strstr(buff, "Training"))
-                pGame = GameFactory::Instance()->createTraining(iDic);
-            else if (strstr(buff, "Free game"))
-                pGame = GameFactory::Instance()->createFreeGame(iDic);
-            else if (strstr(buff, "Duplicate"))
-                pGame = GameFactory::Instance()->createDuplicate(iDic);
-            else
-                return NULL;
-            // Read next line
-            continue;
-        }
-
-        // Players type
-        pos = strstr(buff, "Player ");
-        if (pos != NULL && pGame != NULL)
-        {
-            int nb = 0;
-            char type[20];
-            if (sscanf(pos, "Player %d: %19s", &nb, type) > 1)
-            {
-                if (string(type) == "Human")
-                    pGame->addHumanPlayer();
-                else if (string(type) == "Computer")
-                    pGame->addAIPlayer();
-                else
-                    ;
-            }
-            // Read next line
-            continue;
-        }
-
-        // Last racks
-        pos = strstr(buff, "Rack ");
-        if (pos != NULL && pGame != NULL)
-        {
-            int nb = 0;
-            char letters[20];
-            if (sscanf(pos, "Rack %d: %19s", &nb, letters) > 1)
-            {
-                // Create the played rack
-                PlayedRack pldrack;
-                char *r = letters;
-                if (strchr(r, '+'))
-                {
-                    while (*r != '+')
-                    {
-                        pldrack.addOld(Tile(*r));
-                        r++;
-                    }
-                    r++;
-                }
-                while (*r)
-                {
-                    pldrack.addNew(Tile(*r));
-                    r++;
-                }
-
-                // Give the rack to the player
-                pGame->m_players[nb]->setCurrentRack(pldrack);
-            }
-            // Read next line
-            continue;
-        }
-
-        // Skip columns title
-        if (strstr(buff, "==") != NULL ||
-            strstr(buff, "| PTS | P |") != NULL)
-        {
-            continue;
-        }
-
-        if (string(buff) != "\n" && pGame != NULL)
-        {
-            char bonus = 0;
-            int res = sscanf(buff, "   %2d | %8s | %s | %3s | %3d | %1d | %c",
-                             &num, rack, word, ref, &pts, &player, &bonus);
-            if (res < 6)
-                continue;
-
-            // Integrity checks
-            // TODO: add more checks
-            if (pts < 0)
-                continue;
-            if (player < 0 || player > pGame->getNPlayers())
-                continue;
-            if (bonus && bonus != '*')
-                continue;
-
-            // Build a rack for the correct player
-            PlayedRack pldrack;
-            char *r = rack;
-            if (strchr(r, '+'))
-            {
-                while (*r != '+')
-                {
-                    pldrack.addOld(Tile(*r));
-                    r++;
-                }
-                r++;
-            }
-
-            while (*r)
-            {
-                pldrack.addNew(Tile(*r));
-                r++;
-            }
-
-            // Build a round
-            Round round;
-            // TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
-//             round.accessCoord().setFromString(ref);
-            if (!round.getCoord().isValid())
-                continue;
-
-            round.setPoints(pts);
-            if (bonus == '*')
-                round.setBonus(1);
-
-            for (unsigned int i = 0; i < strlen(word); i++)
-            {
-                tile = Tile(word[i]);
-
-                if (round.getCoord().getDir() == Coord::HORIZONTAL)
-                {
-                    if (!pGame->m_board.getTile(round.getCoord().getRow(),
-                                                round.getCoord().getCol() + 
i).isEmpty())
-                    {
-                        round.addRightFromBoard(tile);
-                    }
-                    else
-                    {
-                        round.addRightFromRack(tile, islower(word[i]));
-                        pGame->m_bag.takeTile((islower(word[i])) ? 
Tile::Joker() : tile);
-                    }
-                }
-                else
-                {
-                    if (!pGame->m_board.getTile(round.getCoord().getRow() + i,
-                                                
round.getCoord().getCol()).isEmpty())
-                    {
-                        round.addRightFromBoard(tile);
-                    }
-                    else
-                    {
-                        round.addRightFromRack(tile, islower(word[i]));
-                        pGame->m_bag.takeTile((islower(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);
-            // Add the points
-            pGame->m_players[player]->addPoints(pts);
-            // Play the round
-            pGame->helperPlayRound(round);
-        }
-    }
-
-    // Finalize the game
-    if (pGame)
-    {
-        // 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++)
-        {
-            if (pGame->getPlayer(i).isHuman())
-            {
-                pGame->m_currPlayer = i;
-                break;
-            }
-        }
-    }
-    return pGame;
-}
-
-
-void Game::save(ostream &out) const
-{
-    const string decal = "   ";
-    // "Header" of the game
-    out << IDENT_STRING << endl << endl;
-    out << "Game type: " << getModeAsString() << endl;
-    for (int i = 0; i < getNPlayers(); i++)
-    {
-        out << "Player " << i << ": ";
-        if (getPlayer(i).isHuman())
-            out << "Human" << endl;
-        else
-            out << "Computer" << endl;
-    }
-    out << endl;
-
-    // Title of the columns
-    char line[100];
-    out << decal << " N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS" 
<< endl;
-    out << decal << "===|==========|=================|=====|=====|===|======" 
<< endl;
-
-    // Print the game itself
-    for (int i = 0; i < m_history.getSize(); i++)
-    {
-        const Turn& t = m_history.getTurn(i);
-        wstring word = t.getRound().getWord();
-        wstring coord = t.getRound().getCoord().toString();
-        sprintf(line, "%2d | %8s | %s%s | %3s | %3d | %1d | %c",
-                i + 1, convertToMb(t.getPlayedRack().toString()).c_str(),
-                convertToMb(word).c_str(),
-                string(15 - word.size(), ' ').c_str(),
-                convertToMb(coord).c_str(), t.getRound().getPoints(),
-                t.getPlayer(), t.getRound().getBonus() ? '*' : ' ');
-
-        out << decal << line << endl;
-    }
-    out << endl << decal << "Total: " << m_points << endl;
-
-    // Print current rack for all the players
-    out << endl;
-    for (int i = 0; i < getNPlayers(); i++)
-    {
-        wstring rack = getPlayer(i).getCurrentRack().toString();
-        out << "Rack " << i << ": " << convertToMb(rack) << endl;
-    }
-}
-
-
 /* This function plays a round on the board */
 int Game::helperPlayRound(const Round &iRound)
 {
@@ -422,10 +157,10 @@
 
     if (n < 0)
     {
-//         debug("Game::back negative argument\n");
-        n = -n;
+       debug("Game::back negative argument\n");
+       n = -n;
     }
-//     debug("Game::back %d\n",n);
+    debug("Game::back %d\n",n);
     for (i = 0; i < n; i++)
     {
         if (m_history.getSize() > 0)
@@ -433,7 +168,7 @@
             prevPlayer();
             player = m_players[m_currPlayer];
             const Round &lastround = m_history.getPreviousTurn().getRound();
-//             debug("Game::back last round 
%s\n",lastround.toString().c_str());
+           debug("Game::back last round %s\n",lastround.toString().c_str());
             /* Remove the word from the board, and put its letters back
              * into the bag */
             m_board.removeRound(*m_dic, lastround);
@@ -450,8 +185,8 @@
             /* Remove the points of this round */
             player->addPoints(- lastround.getPoints());
             m_points -= lastround.getPoints();
-            /* Remove the turns */
-            player->removeLastTurn();
+           /* Remove the turns */
+           player->removeLastTurn();
             m_history.removeLastTurn();
         }
         else
@@ -462,10 +197,11 @@
     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;
@@ -476,7 +212,7 @@
     /* The real content of the bag depends on the game mode */
     if (getMode() == kFREEGAME)
     {
-        /* In freegame mode, replace the letters from all the racks */
+        /* In freegame mode, take the letters from all the racks */
         for (int i = 0; i < getNPlayers(); i++)
         {
             getPlayer(i).getCurrentRack().getAllTiles(tiles);
@@ -488,7 +224,7 @@
     }
     else
     {
-        /* In training or duplicate mode, replace the rack of the current
+        /* In training or duplicate mode, take the rack of the current
          * player only */
         getPlayer(m_currPlayer).getCurrentRack().getAllTiles(tiles);
         for (unsigned int j = 0; j < tiles.size(); j++)
@@ -499,38 +235,26 @@
 }
 
 
-bool Game::rackInBag(const Rack &iRack, const Bag &iBag) const
-{
-    const list<Tile>& allTiles = Tile::getAllTiles();
-    list<Tile>::const_iterator it;
-    for (it = allTiles.begin(); it != allTiles.end(); it++)
-    {
-        if (iRack.in(*it) > iBag.in(*it))
-            return false;
-    }
-    return true;
-}
-
-
 int Game::helperSetRackRandom(int p, bool iCheck, set_rack_mode mode)
 {
     ASSERT(0 <= p && p < getNPlayers(), "Wrong player number");
 
     int nold, min;
 
-    // Make a copy of the player's rack
+    // Make a copy of the current player's rack
     PlayedRack pld = getPlayer(p).getCurrentRack();
     nold = pld.nOld();
 
     // Create a copy of the bag in which we can do everything we want,
-    // and remove from it the tiles of the racks
+    // and take from it the tiles of the players rack so that "bag"
+    // contains the right number of tiles.
     Bag bag;
     realBag(bag);
 
-    // We may have removed too many letters from the bag (i.e. the 'new'
-    // letters of the player)
     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++)
@@ -539,13 +263,24 @@
         }
         pld.resetNew();
     }
-    else
+    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::helperSetRackRandom not a random mode\n");
+    }
 
     // Nothing in the rack, nothing in the bag --> end of the game
     if (bag.nTiles() == 0 && pld.nTiles() == 0)
@@ -643,7 +378,7 @@
         }
     }
 
-    if (iCheck && !pld.checkRack(min))
+    if (iCheck && !pld.checkRack(min,min))
         return 2;
 
     m_players[p]->setCurrentRack(pld);
@@ -652,40 +387,41 @@
 }
 
 
+/**
+ * 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;
+    for (it = allTiles.begin(); it != allTiles.end(); it++)
+    {
+        if (iRack.in(*it) > iBag.in(*it))
+            return false;
+    }
+    return true;
+}
+
+/**
+ * Set the rack of the player p manually.
+ */
 int Game::helperSetRackManual(int p, bool iCheck, const wstring &iLetters)
 {
-    unsigned int i;
-    int min;
+    int min, ret;
 
     PlayedRack pld = getPlayer(p).getCurrentRack();
     pld.reset();
 
-    if (iLetters.size() == 0)
-    {
-        return 0;
-    }
-
-    for (i = 0; i < iLetters.size() && iLetters[i] != '+'; i++)
+    if ((ret = pld.setManual(iLetters)) > 0)
     {
-        Tile tile(iLetters[i]);
-        if (tile.isEmpty())
-        {
-            return 1;
-        }
-        pld.addOld(tile);
-    }
-
-    if (i < iLetters.size() && iLetters[i] == '+')
-    {
-        for (i++; i < iLetters.size(); i++)
-        {
-            Tile tile(iLetters[i]);
-            if (tile.isEmpty())
-            {
-                return 1;
-            }
-            pld.addNew(tile);
-        }
+        return 1; /* add new tests */
     }
 
     Rack rack;
@@ -703,7 +439,7 @@
             min = 2;
         else
             min = 1;
-        if (!pld.checkRack(min))
+        if (!pld.checkRack(min,min))
             return 2;
     }
 
@@ -852,4 +588,5 @@
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/game.h
diff -u eliot/game/game.h:1.26.2.1 eliot/game/game.h:1.26.2.2
--- eliot/game/game.h:1.26.2.1  Wed Dec 28 16:47:35 2005
+++ eliot/game/game.h   Tue Jan  3 20:42:13 2006
@@ -93,6 +93,14 @@
     const Player& getCurrentPlayer() const { return getPlayer(currPlayer()); };
 
     /**
+     * Eliot file formats
+     */
+    typedef enum {
+      FILE_FORMAT_STANDARD,
+      FILE_FORMAT_ADVANCED
+    } game_file_format;
+
+    /**
      * Saved games handling.
      *
      * load() returns the loaded game, or NULL if there was a problem
@@ -100,7 +108,16 @@
      * handle "hand written" files
      */
     static Game * load(FILE *fin, const Dictionary &iDic);
-    void save(ostream &out) const;
+
+    /**
+     * 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
@@ -128,7 +145,10 @@
     enum set_rack_mode {RACK_ALL, RACK_NEW, RACK_MANUAL};
     int setRack(int player, set_rack_mode mode, bool check, const wstring& 
str);
 
-    /** Getter for the history of the game  */
+    /**
+     * Methods to access already played words.
+     * The int parameter should be 0 <= int < getNTurns()
+     */
     const History& getHistory() const { return m_history; }
 
     /**
@@ -194,6 +214,36 @@
     void realBag(Bag &iBag) const;
     int  checkPlayedWord(const wstring &iCoord,
                          const wstring &iWord, Round &oRound);
+
+    /**
+     * load games from File using the first format.
+     * This format is used for Training games
+     */
+    static Game* gameLoadFormat_14(FILE *fin, const Dictionary& iDic);
+
+    /**
+     * load games from File using advanced format (since Eliot 1.5)
+     * This format is used for Duplicate, Freegame, ...
+     */
+    static Game* gameLoadFormat_15(FILE *fin, const Dictionary& iDic);
+
+    /**
+     * Training games ares saved using the initial Eliot format
+     */
+    void Game::gameSaveFormat_14(ostream &out) const;
+
+    /**
+     * Advanced game file format output
+     */
+    void Game::gameSaveFormat_15(ostream &out) const;
+
 };
 
 #endif /* _GAME_H_ */
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/game_factory.cpp
diff -u /dev/null eliot/game/game_factory.cpp:1.6.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/game_factory.cpp Tue Jan  3 20:42:13 2006
@@ -0,0 +1,223 @@
+/*****************************************************************************
+ * 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
+ *****************************************************************************/
+
+#include <getopt.h>
+
+#include "config.h"
+#include "dic.h"
+#include "game_factory.h"
+
+
+GameFactory *GameFactory::m_factory = NULL;
+
+
+GameFactory::GameFactory(): m_dic(NULL), m_human(0), m_ai(0), m_joker(false)
+{
+}
+
+
+GameFactory::~GameFactory()
+{
+    if (m_dic)
+        Dic_destroy(m_dic);
+}
+
+
+GameFactory *GameFactory::Instance()
+{
+    if (m_factory == NULL)
+        m_factory = new GameFactory;
+    return m_factory;
+}
+
+
+void GameFactory::Destroy()
+{
+    if (m_factory)
+        delete m_factory;
+    m_factory = NULL;
+}
+
+
+Training *GameFactory::createTraining(const Dictionary &iDic)
+{
+    Training *game = new Training(iDic);
+    return game;
+}
+
+
+FreeGame *GameFactory::createFreeGame(const Dictionary &iDic)
+{
+    FreeGame *game = new FreeGame(iDic);
+    return game;
+}
+
+
+Duplicate *GameFactory::createDuplicate(const Dictionary &iDic)
+{
+    Duplicate *game = new Duplicate(iDic);
+    return game;
+}
+
+
+Game *GameFactory::createFromCmdLine(int argc, char **argv)
+{
+    // 1) Parse command-line and store everything in member variables
+    static struct option long_options[] =
+    {
+        {"help", no_argument, NULL, 'h'},
+        {"version", no_argument, NULL, 'v'},
+        {"dictionary", required_argument, NULL, 'd'},
+        {"dict", required_argument, NULL, 'd'},
+        {"mode", required_argument, NULL, 'm'},
+        {"human", no_argument, NULL, 300},
+        {"ai", no_argument, NULL, 400},
+        {"joker", no_argument, NULL, 500},
+        {0, 0, 0, 0}
+    };
+    static char short_options[] = "hvd:m:";
+
+    int option_index = 1;
+    int res;
+    bool found_d = false;
+    bool found_m = false;
+    while ((res = getopt_long(argc, argv, short_options,
+                              long_options, &option_index)) != -1)
+    {
+        switch (res)
+        {
+        case 'h':
+            // Help requested, display it and exit
+            printUsage(argv[0]);
+            return NULL;
+        case 'v':
+            // Version requested, display it and exit
+            printVersion();
+            return NULL;
+        case 'd':
+            m_dicStr = optarg;
+            found_d = true;
+            break;
+        case 'm':
+            m_modeStr = optarg;
+            found_m = true;
+            break;
+        case 300:
+            m_human++;
+            break;
+        case 400:
+            m_ai++;
+            break;
+        case 500:
+            m_joker = true;
+            break;
+        }
+    }
+
+    // 2) Make sure the mandatory options are present
+    if (!found_d || !found_m)
+    {
+        cerr << "Mandatory option missing: ";
+        if (!found_d)
+            cerr << "dict";
+        else if (!found_m)
+            cerr << "mode";
+        cerr << "\n";
+
+        printUsage(argv[0]);
+        return NULL;
+    }
+
+    // 3) Try to load the dictionary
+    if (Dic_load(&m_dic, m_dicStr.c_str()))
+    {
+        cerr << "Could not load dictionary '" << m_dicStr << "'\n";
+        return NULL;
+    }
+
+    // 4) Try to create a game object
+    Game *game = NULL;
+    if (m_modeStr == "training" || m_modeStr == "t")
+    {
+        game = createTraining(m_dic);
+    }
+    else if (m_modeStr == "freegame" || m_modeStr == "f")
+    {
+        game = createFreeGame(m_dic);
+    }
+    else if (m_modeStr == "duplicate" || m_modeStr == "d")
+    {
+        game = createDuplicate(m_dic);
+    }
+    else
+    {
+        cerr << "Invalid game mode '" << m_modeStr << "'\n";
+        return NULL;
+    }
+
+    // 5) Add the players
+    for (int i = 0; i < m_human; i++)
+        game->addHumanPlayer();
+    for (int i = 0; i < m_ai; i++)
+        game->addAIPlayer();
+
+    // 6) Set the variant
+    if (m_joker)
+        game->setVariant(Game::kJOKER);
+
+    return game;
+}
+
+
+void GameFactory::releaseGame(Game &iGame)
+{
+    delete &iGame;
+}
+
+
+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";
+}
+
+
+void GameFactory::printVersion() const
+{
+    cout << PACKAGE_STRING << "\n"
+         << "This program comes with NO WARRANTY, to the extent permitted by "
+         << "law.\nYou may redistribute it under the terms of the GNU General "
+         << "Public License;\nsee the file named COPYING for details.\n";
+}
+
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/game_factory.h
diff -u /dev/null eliot/game/game_factory.h:1.6.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/game_factory.h   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,102 @@
+/*****************************************************************************
+ * 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 _GAME_FACTORY_H_
+#define _GAME_FACTORY_H_
+
+#include "game.h"
+#include "training.h"
+#include "freegame.h"
+#include "duplicate.h"
+
+
+/**
+ * This class is the entry point to create Game objects, either directly or
+ * using command-line parameters. It also offers a method to destroy Game
+ * objects.
+ * This class implements the Singleton pattern.
+ */
+class GameFactory
+{
+public:
+    static GameFactory *Instance();
+    static void Destroy();
+
+    /*************************
+     * Functions to create and destroy a game
+     * The dictionary does not belong to the
+     * game (ie: it won't be destroyed by ~Game)
+     *************************/
+    Training *createTraining(const Dictionary &iDic);
+    FreeGame *createFreeGame(const Dictionary &iDic);
+    Duplicate *createDuplicate(const Dictionary &iDic);
+    //Game *loadGame(FILE *fin, const Dictionary &iDic);
+
+    Game *createFromCmdLine(int argc, char **argv);
+
+    /// Destroy a Game object, created by any of the createXXX methods above
+    void releaseGame(Game &iGame);
+
+private:
+
+    GameFactory();
+    virtual ~GameFactory();
+
+    /// The unique instance of the class
+    static GameFactory *m_factory;
+
+    /// Initial dictionary (it could be changed later)
+    Dictionary m_dic;
+
+    /** Parameters specified on the command-line */
+    //@{
+
+    /// Dictionary
+    string m_dicStr;
+
+    /// Game mode
+    string m_modeStr;
+
+    /// Number of human players
+    int m_human;
+
+    /// Number of AI players
+    int m_ai;
+
+    /// Variant of the game
+    bool m_joker;
+
+    //@}
+
+    /// Print command-line usage
+    void printUsage(const string &iBinaryName) const;
+
+    /// Print version
+    void printVersion() const;
+
+};
+
+#endif // _GAME_FACTORY_H_
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/game_io.cpp
diff -u /dev/null eliot/game/game_io.cpp:1.2.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/game_io.cpp      Tue Jan  3 20:42:13 2006
@@ -0,0 +1,582 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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
+ *****************************************************************************/
+
+/**
+ *  \file   game_io.cpp
+ *  \brief  Eliot game class file load/save handling
+ *  \author Antoine Fraboulet & Olivier Teuliere
+ *  \date   2002 - 2005
+ */
+
+#include "pldrack.h"
+#include "round.h"
+#include "turn.h"
+#include "player.h"
+#include "game.h"
+#include "game_factory.h"
+#include "encoding.h"
+#include "debug.h"
+
+using namespace std;
+
+/*************************
+ * Ident string used to identify saved Eliot games
+ *************************/
+#define IDENT_STRING "Eliot"
+#define IDENT_FORMAT_14 ""
+#define IDENT_FORMAT_15 "1.5"
+
+
+/********************************************************
+ *
+ * Loading games
+ *
+ ********************************************************/
+
+Game * Game::load(FILE *fin, const Dictionary& iDic)
+{
+    char buff[4096];
+    // 10d is \012
+    // 13d is \015
+    char delim[] = " \t\n\012\015|";
+    char *token;
+
+    // Check characteristic string
+    if (fgets(buff, sizeof(buff), fin) == NULL)
+    {
+        debug("Game::load cannot load first line\n");
+        return NULL;
+    }
+
+    if ((token = strtok(buff, delim)) == NULL)
+    {
+        debug("Game::load first line is empty\n");
+        return NULL;
+    }
+
+    /* checks for IDENT_STRING and file format */
+    if (string(token) != IDENT_STRING)
+    {
+        debug("Game::load IDENT_STRING %s unknown\n",token);
+        return NULL;
+    }
+
+    if ((token = strtok(NULL, delim)) == NULL)
+    {
+        debug("Game_io::loading file format 1.4\n");
+        return Game::gameLoadFormat_14(fin,iDic);
+    }
+
+    if (string(token) == string(IDENT_FORMAT_15))
+    {
+        debug("Game_io::loading file format 1.5\n");
+        return Game::gameLoadFormat_15(fin,iDic);
+    }
+
+    debug("Game::load unknown format %s\n",token);
+    return NULL;
+}
+
+
+Game* Game::gameLoadFormat_14(FILE *fin, const Dictionary& iDic)
+{
+     Tile tile;
+     char buff[4096];
+     char rack[20];
+     char word[20];
+     char pos [5];
+     char delim[]=" \t\n\012\015";
+     char *token;
+     Game *pGame = NULL;
+
+     debug("Game::gameLoadFormat_14\n");
+
+     pGame = GameFactory::Instance()->createTraining(iDic);
+     pGame->start();
+
+     /*    rack        word          ?bonus    pts  coord    */
+     /*    EUOFMIE     FUMEE          *        26   H  4     */
+
+     /* read all turns until total */
+     while (fgets(buff, sizeof(buff), fin))
+     {
+         token = strtok(buff, delim);
+         if (token != NULL)
+         {
+             if (strcmp(token, "total") == 0)
+             {
+                 break;
+             }
+
+             /* rack */
+             strncpy(rack, token, sizeof(rack));
+             static_cast<Training*>(pGame)->setRack(RACK_MANUAL, false,
+                                                    convertToWc(rack));
+             debug("%s ", rack);
+
+             /* word */
+             token = strtok(NULL, delim);
+             if (!token || strcmp(token, "total") == 0)
+             {
+                 break;
+             }
+
+             strncpy(word, token, sizeof(word));
+             debug("\t%s ", word);
+
+             /* bonus */
+             if ((token = strtok(NULL, delim)) == NULL)
+                 break;
+
+             /* points */
+             if (token[0] == '*')
+             {
+                 debug("%s\t", token);
+                 if ((token = strtok(NULL, delim)) == NULL)
+                     break;
+             }
+
+             /* pos 1 */
+             if ((token = strtok(NULL, delim)) == NULL)
+                 break;
+
+             debug("(%s ", token);
+             strncpy(pos, token, sizeof(pos));
+
+             /* pos 2 */
+             if ((token = strtok(NULL, delim)) == NULL)
+                 break;
+
+             debug("%s)", token);
+             strncat(pos, token, sizeof(pos));
+             debug("%s\n", pos);
+
+             debug("   play %s %s\n", pos, word);
+             pGame->play(convertToWc(pos), convertToWc(word));
+         }
+     }
+     return pGame;
+}
+
+
+Game* Game::gameLoadFormat_15(FILE *fin, const Dictionary& iDic)
+{
+    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 */
+    /*************/
+
+    while (fgets(buff, sizeof(buff), fin))
+    {
+        // Indication of game type
+        pos = strstr(buff, "Game type: ");
+        if (pos != NULL)
+        {
+            // No Game object should have been created yet
+            if (pGame != NULL)
+            {
+                delete pGame;
+                return NULL;
+            }
+            // Create the correct Game object
+            if (strstr(buff, "Training"))
+            {
+                debug("Game::gameLoadFormat_15 new Training\n");
+                pGame = GameFactory::Instance()->createTraining(iDic);
+                break;
+            }
+            else if (strstr(buff, "Free game"))
+            {
+                debug("Game::gameLoadFormat_15 new Freegame\n");
+                pGame = GameFactory::Instance()->createFreeGame(iDic);
+                break;
+            }
+            else if (strstr(buff, "Duplicate"))
+            {
+                debug("Game::gameLoadFormat_15 new Duplicate\n");
+                pGame = GameFactory::Instance()->createDuplicate(iDic);
+                break;
+            }
+            else
+            {
+                debug("Game::gameLoadFormat_15 unknown Game type\n");
+                return NULL;
+            }
+        }
+    }
+
+    debug("   Game type is ok, switching to player list\n");
+
+    /***************/
+    /* Player List */
+    /***************/
+
+    while (fgets(buff, sizeof(buff), fin))
+    {
+        // Players type
+        pos = strstr(buff, "Player ");
+        if (pos != NULL)
+        {
+            int nb = 0;
+            char type[20];
+            if (sscanf(pos, "Player %d: %19s", &nb, type) > 1)
+            {
+                if (string(type) == "Human")
+                {
+                    debug("   add Human player\n");
+                    pGame->addHumanPlayer();
+                }
+                else if (string(type) == "Computer")
+                {
+                    if (pGame->getMode() == kTRAINING)
+                    {
+                        debug("   mode == TRAINING, skip player list since we 
have a computer player\n");
+                        break;
+                    }
+                    else
+                    {
+                        debug("   add Computer player\n");
+                        pGame->addAIPlayer();
+                    }
+                }
+                else
+                {
+                    debug("   unknown player, bailing out\n");
+                    delete pGame;
+                    return NULL;
+                }
+            }
+        }
+        else if (strstr(buff," N |   RACK   "))
+        {
+            debug("   ok for player list, going turn list\n");
+            break;
+        }
+    }
+
+    debug("   Player list ok, switching to turn list \n");
+
+    /*************/
+    /* Turn list */
+    /*************/
+
+    while (fgets(buff, sizeof(buff), fin))
+    {
+        // Skip columns title
+        if (strstr(buff,"| PTS | P |") != NULL)
+        {
+            debug("   ** PTS line, skiping\n");
+            continue;
+        }
+
+        // Skip columns title
+        if (strstr(buff, "==") != NULL)
+        {
+            debug("   ** == line, skiping\n");
+            continue;
+        }
+
+        if (string(buff) == "\n")
+        {
+            debug("   ** empty line\n");
+            continue;
+        }
+
+
+        char bonus = 0;
+        int res = sscanf(buff, "   %2d | %8s | %s | %3s | %3d | %1d | %c",
+                         &num, rack, word, ref, &pts, &player, &bonus);
+
+        debug("   -- line %s",buff);
+
+        if (res < 6)
+            {
+                debug("   Game::load15 invalid line -%s-\n",buff);
+                continue;
+            }
+
+        debug("              %2d | %8s | %s | %3s | %3d | %1d | %c \n",
+              num, rack, word, ref, pts, player, bonus);
+
+        // Integrity checks
+        // TODO: add more checks
+        if (pts < 0)
+            {
+                debug("   Game::load15 line -%s- points < 0  ?\n",buff);
+                continue;
+            }
+        if (player < 0 || player > pGame->getNPlayers())
+            {
+                debug("   Game::load15 line -%s- too much player 
(%d>%d)",buff,player,pGame->getNPlayers());
+                continue;
+            }
+        if (bonus && bonus != '*')
+            {
+                debug("   Game::load15 line -%s- wring bonus sign\n",buff);
+                continue;
+            }
+
+        // Build a rack for the correct player
+        PlayedRack pldrack;
+        if ((res = pldrack.setManual(convertToWc(rack))) > 0)
+        {
+            debug("   Game::load15 set rack manual returned with error 
%d\n",res);
+        }
+        debug("    history rack %s\n",pldrack.toString().c_str());
+
+        // Build a round
+        Round round;
+        round.setPoints(pts);
+        if (bonus == '*')
+            round.setBonus(1);
+
+        if (isalpha(ref[0]))
+            {
+                // Horizontal word
+                round.accessCoord().setDir(Coord::HORIZONTAL);
+                round.accessCoord().setRow(ref[0] - 'A' + 1);
+                round.accessCoord().setCol(atoi(ref + 1));
+
+                for (unsigned int i = 0; i < strlen(word); i++)
+                    {
+                        tile = Tile(word[i]);
+
+                        if (!pGame->m_board.getTile(round.getCoord().getRow(), 
round.getCoord().getCol() + i).isEmpty())
+                            {
+                                round.addRightFromBoard(tile);
+                            }
+                        else
+                            {
+                                round.addRightFromRack(tile, islower(word[i]));
+                                pGame->m_bag.takeTile((islower(word[i])) ? 
Tile::Joker() : tile);
+                            }
+                    }
+            }
+        else
+            {
+                // Vertical word
+                round.accessCoord().setDir(Coord::VERTICAL);
+                round.accessCoord().setRow(ref[strlen(ref) - 1] - 'A' + 1);
+                round.accessCoord().setCol(atoi(ref));
+
+                for (unsigned int i = 0; i < strlen(word); i++)
+                    {
+                        tile = Tile(word[i]);
+
+                        if (!pGame->m_board.getTile(round.getCoord().getRow() 
+ i, round.getCoord().getCol()).isEmpty())
+                            {
+                                round.addRightFromBoard(tile);
+                            }
+                        else
+                            {
+                                round.addRightFromRack(tile, islower(word[i]));
+                                pGame->m_bag.takeTile((islower(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);
+
+        // Play the round
+        pGame->helperPlayRound(round);
+    }
+
+    /**************************************/
+    /* End of turn list, switching to ... */
+    /**************************************/
+
+    // Last racks
+    pos = strstr(buff, "Rack ");
+    if (pos != NULL && pGame != NULL)
+    {
+        int nb = 0;
+        char letters[20];
+        if (sscanf(pos, "Rack %d: %19s", &nb, letters) > 1)
+        {
+            // Create the played rack
+            PlayedRack pldrack;
+            pldrack.setManual(convertToWc(letters));
+            // Give the rack to the player
+            pGame->m_players[nb]->setCurrentRack(pldrack);
+        }
+        // Read next line
+        //            continue;
+    }
+
+
+    // Finalize the game
+    if (pGame)
+    {
+        // 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++)
+        {
+            if (pGame->m_players[i]->isHuman())
+            {
+                pGame->m_currPlayer = i;
+                break;
+            }
+        }
+    }
+
+    return pGame;
+}
+
+/********************************************************
+ *
+ * Loading games
+ *
+ ********************************************************/
+
+void Game::save(ostream &out, game_file_format format) const
+{
+    if (getMode() == kTRAINING && format == FILE_FORMAT_STANDARD)
+    {
+        gameSaveFormat_14(out);
+    }
+    else
+    {
+        gameSaveFormat_15(out);
+    }
+}
+
+
+void Game::gameSaveFormat_14(ostream &out) const
+{
+    int i;
+    char line[100];
+    const char decal[]="   ";
+    out << IDENT_STRING << endl << endl;
+
+    for(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));
+
+        // 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(),
+                coord.c_str()
+               );
+
+        out << decal << line << endl;
+    }
+
+    out << endl;
+    out << decal << "total" << string(24,' ');
+    sprintf(line,"%4d", getCurrentPlayer().getPoints());
+    out << line << endl;
+}
+
+
+void Game::gameSaveFormat_15(ostream &out) const
+{
+    const string decal = "   ";
+    // "Header" of the game
+    out << IDENT_STRING << " " << IDENT_FORMAT_15 << endl << endl;
+    // Game type
+    out << "Game type: " << getModeAsString() << endl;
+    // Player list
+    for (int i = 0; i < getNPlayers(); i++)
+    {
+        out << "Player " << i << ": ";
+        if (m_players[i]->isHuman())
+            out << "Human" << endl;
+        else
+            out << "Computer" << endl;
+    }
+    out << endl;
+
+    // Title of the columns
+    char line[100];
+    out << decal << " N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS" 
<< endl;
+    out << decal << "===|==========|=================|=====|=====|===|======" 
<< endl;
+
+    // Print the game itself
+    for (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",
+                i + 1,
+                rack.c_str(),                               /* pldrack     */
+                word.c_str(),                               /* word        */
+                string(15 - word.size(), ' ').c_str(),      /* fill spaces */
+                coord.c_str(),                              /* coord       */
+                turn.getRound().getPoints(),
+                turn.getPlayer(),
+                turn.getRound().getBonus() ? '*' : ' ');
+
+        out << decal << line << endl;
+    }
+
+    switch (getMode())
+    {
+    case kDUPLICATE:
+        // TODO : we should note the score individualy
+        out << endl << decal << "Total: " << m_points << endl;
+        break;
+    case kFREEGAME:
+        out << endl << decal << "Total: " << m_points << endl;
+        break;
+    case kTRAINING:
+        out << endl << decal << "Total: " << m_points << endl;
+        break;
+    }
+
+    // Print current rack for all the players
+    out << endl;
+    for (int i = 0; i < getNPlayers(); i++)
+    {
+        wstring rack = m_players[i]->getCurrentRack().toString();
+        out << "Rack " << i << ": " << convertToMb(rack) << endl;
+    }
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/history.cpp
diff -u eliot/game/history.cpp:1.8.2.2 eliot/game/history.cpp:1.8.2.3
--- eliot/game/history.cpp:1.8.2.2      Wed Dec 28 18:07:53 2005
+++ eliot/game/history.cpp      Tue Jan  3 20:42:13 2006
@@ -39,7 +39,7 @@
 
 History::History()
 {
-    Turn* t = new Turn();
+    Turn* t = new Turn ();
     m_history.clear();
     m_history.push_back(t);
 }
@@ -143,7 +143,7 @@
         delete t;
     }
 
-    // Now we have the previous played round in back()
+    // now we have the previous played round in back()
     Turn* t = m_history.back();
     t->setNum(0);
     t->setPlayer(0);
@@ -180,6 +180,8 @@
 
 
 /// Local Variables:
+/// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/history.h
diff -u eliot/game/history.h:1.8.2.1 eliot/game/history.h:1.8.2.2
--- eliot/game/history.h:1.8.2.1        Wed Dec 28 16:47:35 2005
+++ eliot/game/history.h        Tue Jan  3 20:42:13 2006
@@ -37,7 +37,6 @@
 class Turn;
 class PlayedRack;
 
-
 /**
  * History stores all the turns that have been played
  * This class is used many times in the game
@@ -56,12 +55,13 @@
  * setCurrentRack must be called whenever the current played rack is
  * modified.
  *
- * History owns the turns that it stores. Do not delete a turn referenced by 
History
+ * History owns the turns that it stores. Do not delete a turn referenced
+ * by History
  */
 
 class History
 {
-public:
+ public:
     History();
     virtual ~History();
 
@@ -90,15 +90,15 @@
     /// String handling
     wstring toString() const;
 
-private:
+ private:
     vector<Turn*> m_history;
 };
 
 #endif
 
-
 /// Local Variables:
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/player.cpp
diff -u eliot/game/player.cpp:1.12.2.2 eliot/game/player.cpp:1.12.2.3
--- eliot/game/player.cpp:1.12.2.2      Wed Dec 28 18:07:53 2005
+++ eliot/game/player.cpp       Tue Jan  3 20:42:13 2006
@@ -104,4 +104,5 @@
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/player.h
diff -u eliot/game/player.h:1.16.2.1 eliot/game/player.h:1.16.2.2
--- eliot/game/player.h:1.16.2.1        Wed Dec 28 16:47:35 2005
+++ eliot/game/player.h Tue Jan  3 20:42:13 2006
@@ -89,6 +89,8 @@
 class HumanPlayer: public Player
 {
 public:
+    string name;
+
     HumanPlayer(int iId): Player(iId) {}
     virtual ~HumanPlayer() {}
 
@@ -98,3 +100,9 @@
 
 #endif
 
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/pldrack.cpp
diff -u eliot/game/pldrack.cpp:1.7.2.1 eliot/game/pldrack.cpp:1.7.2.2
--- eliot/game/pldrack.cpp:1.7.2.1      Wed Dec 28 16:47:35 2005
+++ eliot/game/pldrack.cpp      Tue Jan  3 20:42:13 2006
@@ -18,12 +18,24 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *****************************************************************************/
 
+/**
+ *  \file   pldrack.cpp
+ *  \brief  Improved Rack class with old and new tiles
+ *  \author Antoine Fraboulet & Olivier Teuliere
+ *  \date   2002 - 2005
+ */
+
 #include "rack.h"
 #include "pldrack.h"
 
 #include "debug.h"
 
 
+PlayedRack::PlayedRack()
+{
+  reject = false;
+}
+
 void PlayedRack::addOld(const Tile &t)
 {
     m_oldTiles.push_back(t);
@@ -135,8 +147,43 @@
     }
 }
 
+int PlayedRack::setManual(const wstring& iLetters)
+{
+    unsigned int i;
+    reset();
+
+    if (iLetters.size() == 0)
+    {
+        return 0; /* empty is ok */
+    }
+
+    for (i = 0; i < iLetters.size() && iLetters[i] != L'+'; i++)
+    {
+        Tile tile(iLetters[i]);
+        if (tile.isEmpty())
+        {
+            return 1; /* */
+        }
+        addOld(tile);
+    }
+
+    if (i < iLetters.size() && iLetters[i] == L'+')
+    {
+        for (i++; i < iLetters.size(); i++)
+        {
+            Tile tile(iLetters[i]);
+            if (tile.isEmpty())
+            {
+                return 1; /* */
+            }
+            addNew(tile);
+        }
+    }
+
+    return 0;
+}
 
-bool PlayedRack::checkRack(int iMin) const
+bool PlayedRack::checkRack(int cMin, int vMin) const
 {
     vector<Tile>::const_iterator it;
     int v = 0;
@@ -152,7 +199,7 @@
         if (it->isVowel()) v++;
         if (it->isConsonant()) c++;
     }
-    return (v >= iMin) && (c >= iMin);
+    return (v >= vMin) && (c >= cMin);
 }
 
 
@@ -163,19 +210,41 @@
 }
 
 
-wstring PlayedRack::toString(bool iShowExtraSigns) const
+wstring PlayedRack::toString(display_mode mode) const
 {
-    vector<Tile>::const_iterator it;
     wstring s;
+    vector<Tile>::const_iterator it;
 
-    for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
-        s += it->toChar();
+    if (nOld() > 0)
+    {
+        for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
+            s += it->toChar();
+    }
 
-    if (iShowExtraSigns && nOld() > 0 && nNew() > 0)
+    if (mode > RACK_SIMPLE && nOld() > 0 && nNew() > 0)
+    {
         s += L"+";
+    }
 
-    for (it = m_newTiles.begin(); it != m_newTiles.end(); it++)
-        s += it->toChar();
+    if (mode > RACK_EXTRA  && reject)
+    {
+        s += L"-";
+        // new rack: reject
+        // not after a scrabble
+    }
+
+    if (nNew() > 0)
+    {
+        for (it = m_newTiles.begin(); it != m_newTiles.end(); it++)
+            s += it->toChar();
+    }
 
     return s;
 }
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/pldrack.h
diff -u eliot/game/pldrack.h:1.10.2.1 eliot/game/pldrack.h:1.10.2.2
--- eliot/game/pldrack.h:1.10.2.1       Wed Dec 28 16:47:35 2005
+++ eliot/game/pldrack.h        Tue Jan  3 20:42:13 2006
@@ -18,6 +18,13 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *****************************************************************************/
 
+/**
+ *  \file   pldrack.h
+ *  \brief  Improved Rack class with old and new tiles
+ *  \author Antoine Fraboulet & Olivier Teuliere
+ *  \date   2002 - 2005
+ */
+
 #ifndef _PLAYEDRACK_H_
 #define _PLAYEDRACK_H_
 
@@ -39,7 +46,7 @@
 class PlayedRack
 {
 public:
-    PlayedRack() {}
+    PlayedRack();
     virtual ~PlayedRack() {}
 
     void reset();
@@ -51,6 +58,7 @@
 
     void setOld(const Rack &iRack);
     void setNew(const Rack &iRack);
+    int  setManual(const wstring& iLetters);
 
     int nTiles() const  { return nNew() + nOld(); }
     int nNew() const    { return m_newTiles.size(); }
@@ -62,14 +70,29 @@
     void getOldTiles(vector<Tile> &oTiles) const;
     void getAllTiles(vector<Tile> &oTiles) const;
 
-    bool checkRack(int iMin) const;
+    bool checkRack(int cMin, int vMin) const;
 
     void operator=(const PlayedRack &iOther);
-    wstring toString(bool iShowExtraSigns = true) const;
+
+    enum display_mode
+    {
+        RACK_SIMPLE,
+        RACK_EXTRA,
+        RACK_DEBUG
+    };
+    wstring toString(display_mode iShowExtraSigns = RACK_EXTRA) const;
 
 private:
+    bool reject;
     vector<Tile> m_oldTiles;
     vector<Tile> m_newTiles;
 };
 
 #endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/rack.cpp
diff -u /dev/null eliot/game/rack.cpp:1.5.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/rack.cpp Tue Jan  3 20:42:13 2006
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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
+ *****************************************************************************/
+
+/**
+ *  \file   rack.cpp
+ *  \brief  Rack class : multiset of tiles
+ *  \author Antoine Fraboulet & Olivier Teuliere
+ *  \date   2002 - 2005
+ */
+
+#include "rack.h"
+
+
+void Rack::remove(const Tile &t)
+{
+    multiset<Tile>::const_iterator it = m_tiles.find(t);
+    if (it != m_tiles.end())
+        m_tiles.erase(it);
+}
+
+
+void Rack::getTiles(list<Tile> &oTiles) const
+{
+    multiset<Tile>::const_iterator it;
+    for (it = m_tiles.begin(); it != m_tiles.end(); it++)
+    {
+        oTiles.push_back(*it);
+    }
+}
+
+
+string Rack::toString()
+{
+  string rs("");
+  multiset<Tile>::const_iterator it;
+  for (it = m_tiles.begin(); it != m_tiles.end(); it++)
+    {
+      rs += it->toChar();
+    }
+  return rs;
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/rack.h
diff -u /dev/null eliot/game/rack.h:1.7.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/rack.h   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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
+ *****************************************************************************/
+
+/**
+ *  \file   rack.h
+ *  \brief  Rack class : multiset of tiles
+ *  \author Antoine Fraboulet & Olivier Teuliere
+ *  \date   2002 - 2005
+ */
+
+#ifndef _RACK_H_
+#define _RACK_H_
+
+#include "tile.h"
+#include <set>
+#include <list>
+#include <string>
+
+using namespace std;
+
+
+/**
+ * A rack is a set of tiles, no more.
+ * Tiles have to be in the bag for the rack to be valid.
+ */
+class Rack
+{
+public:
+    Rack() {}
+    virtual ~Rack() {}
+
+    int nTiles() const          { return m_tiles.size(); }
+    bool isEmpty() const        { return nTiles() == 0; }
+
+    unsigned int in(const Tile &t) const { return m_tiles.count(t); }
+    void add(const Tile &t)     { m_tiles.insert(t); }
+    void remove(const Tile &t);
+    void clear()                { m_tiles.clear(); }
+    void getTiles(list<Tile> &oTiles) const;
+
+    string toString();
+
+private:
+    multiset<Tile> m_tiles;
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/results.cpp
diff -u /dev/null eliot/game/results.cpp:1.9.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/results.cpp      Tue Jan  3 20:42:13 2006
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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
+ *****************************************************************************/
+
+/**
+ *  \file   results.cc
+ *  \brief  Search result storage class
+ *  \author Olivier Teulière & Antoine Fraboulet
+ *  \date   2005
+ */
+
+#include <algorithm>
+#include <functional>
+
+#include "tile.h"
+#include "round.h"
+#include "board.h"
+#include "results.h"
+#include "debug.h"
+
+
+struct less_points : public binary_function<const Round&,
+                     const Round&, bool>
+{
+    bool operator()(const Round &r1, const Round &r2)
+    {
+        // We want higher scores first, so we use '>' instead of '<'
+        return r1.getPoints() > r2.getPoints();
+    }
+};
+
+
+const Round & Results::get(int i) const
+{
+    ASSERT(0 <= i && i < size(), "Results index out of bounds");
+    return m_rounds[i];
+}
+
+
+void Results::search(const Dictionary &iDic, Board &iBoard,
+                     const Rack &iRack, int iTurn)
+{
+    clear();
+
+    if (iTurn == 0)
+    {
+        iBoard.searchFirst(iDic, iRack, *this);
+    }
+    else
+    {
+        iBoard.search(iDic, iRack, *this);
+    }
+
+    sort_by_points();
+}
+
+
+void Results::sort_by_points()
+{
+    less_points lp;
+    std::sort(m_rounds.begin(), m_rounds.end(), lp);
+}
+
+/****************************************************************/
+/****************************************************************/
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/results.h
diff -u /dev/null eliot/game/results.h:1.7.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/game/results.h        Tue Jan  3 20:42:13 2006
@@ -0,0 +1,80 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          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
+ *****************************************************************************/
+
+/**
+ *  \file   results.h
+ *  \brief  Search result storage class
+ *  \author Olivier Teulière & Antoine Fraboulet
+ *  \date   2005
+ */
+
+#ifndef _RESULTS_H_
+#define _RESULTS_H_
+
+#include <vector>
+#include "round.h"
+
+using namespace std;
+
+class Board;
+class Rack;
+typedef struct _Dictionary * Dictionary;
+
+
+/**
+ * This class allows to perform a search on the board for a given rack,
+ * and it offers accessors to the resulting rounds.
+ * The rounds are sorted by decreasing number of points (but there is no
+ * other ordering between 2 rounds with the same number of points).
+ */
+class Results
+{
+public:
+    Results() {}
+    virtual ~Results() {}
+
+    int size() const    { return m_rounds.size(); }
+    void clear()        { m_rounds.clear(); }
+    const Round & get(int) const;
+
+    // Perform a search on the board
+    void search(const Dictionary &iDic, Board &iBoard,
+                const Rack &iRack, int iTurn);
+
+    // FIXME: These methods are used to fill the container with the rounds,
+    // but they 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;
+};
+
+#endif
+
+/****************************************************************/
+/****************************************************************/
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/round.cpp
diff -u eliot/game/round.cpp:1.8.2.2 eliot/game/round.cpp:1.8.2.3
--- eliot/game/round.cpp:1.8.2.2        Wed Dec 28 18:07:53 2005
+++ eliot/game/round.cpp        Tue Jan  3 20:42:13 2006
@@ -181,6 +181,8 @@
 }
 
 /// Local Variables:
+/// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/round.h
diff -u eliot/game/round.h:1.10.2.1 eliot/game/round.h:1.10.2.2
--- eliot/game/round.h:1.10.2.1 Wed Dec 28 16:47:35 2005
+++ eliot/game/round.h  Tue Jan  3 20:42:13 2006
@@ -82,6 +82,7 @@
     const Coord& getCoord() const { return m_coord; }
     Coord& accessCoord()          { return m_coord; }
 
+
     wstring toString() const;
 
 private:
@@ -93,3 +94,10 @@
 };
 
 #endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/tile.cpp
diff -u eliot/game/tile.cpp:1.5.2.1 eliot/game/tile.cpp:1.5.2.2
--- eliot/game/tile.cpp:1.5.2.1 Wed Dec 28 16:47:35 2005
+++ eliot/game/tile.cpp Tue Jan  3 20:42:13 2006
@@ -210,3 +210,9 @@
     return !(*this == iOther);
 }
 
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/tile.h
diff -u eliot/game/tile.h:1.6.2.1 eliot/game/tile.h:1.6.2.2
--- eliot/game/tile.h:1.6.2.1   Wed Dec 28 16:47:35 2005
+++ eliot/game/tile.h   Tue Jan  3 20:42:13 2006
@@ -73,3 +73,10 @@
 };
 
 #endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/training.cpp
diff -u eliot/game/training.cpp:1.14.2.1 eliot/game/training.cpp:1.14.2.2
--- eliot/game/training.cpp:1.14.2.1    Wed Dec 28 16:47:35 2005
+++ eliot/game/training.cpp     Tue Jan  3 20:42:13 2006
@@ -38,14 +38,20 @@
 {
 }
 
-int Training::setRackRandom(int p, bool iCheck, set_rack_mode mode)
+
+int Training::setRackRandom(bool iCheck, set_rack_mode mode)
 {
+#define MAX_RANDOM_TRY 5
+
     int res;
+    int try_number = 0;
+    int p = m_currPlayer;
     m_results.clear();
     do
     {
         res = helperSetRackRandom(p, iCheck, mode);
-    } while (res == 2);
+        try_number ++;
+    } while (res == 2 && try_number < MAX_RANDOM_TRY);
     // 0 : ok
     // 1 : not enough tiles
     // 2 : check failed (number of voyels before round 15)
@@ -83,10 +89,10 @@
             res = setRackManual(iCheck, iLetters);
             break;
         case RACK_ALL:
-            res = setRackRandom(m_currPlayer, iCheck, iMode);
+            res = setRackRandom(iCheck, iMode);
             break;
         case RACK_NEW:
-            res = setRackRandom(m_currPlayer, iCheck, iMode);
+            res = setRackRandom(iCheck, iMode);
             break;
     }
     return res;
@@ -128,6 +134,7 @@
     return 0;
 }
 
+
 int Training::endTurn()
 {
     // Nothing to do?
@@ -140,7 +147,7 @@
     // Search for the current player
     Rack r;
     m_players[m_currPlayer]->getCurrentRack().getRack(r);
-//     debug("Training::search for %s\n",r.toString().c_str());
+    debug("Training::search for %s\n",r.toString().c_str());
     m_results.search(*m_dic, m_board, r, m_history.getSize());
 }
 
@@ -209,4 +216,5 @@
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/training.h
diff -u eliot/game/training.h:1.13.2.1 eliot/game/training.h:1.13.2.2
--- eliot/game/training.h:1.13.2.1      Wed Dec 28 16:47:35 2005
+++ eliot/game/training.h       Tue Jan  3 20:42:13 2006
@@ -53,7 +53,7 @@
     void search();
     int playResult(int);
 
-    virtual int setRackRandom(int, bool, set_rack_mode);
+    int setRackRandom(bool, set_rack_mode);
     int setRackManual(bool iCheck, const wstring &iLetters);
     int setRack(set_rack_mode iMode, bool iCheck, const wstring &iLetters);
 
@@ -88,3 +88,10 @@
 };
 
 #endif /* _TRAINING_H_ */
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/game/turn.cpp
diff -u eliot/game/turn.cpp:1.9.2.1 eliot/game/turn.cpp:1.9.2.2
--- eliot/game/turn.cpp:1.9.2.1 Wed Dec 28 16:47:35 2005
+++ eliot/game/turn.cpp Tue Jan  3 20:42:13 2006
@@ -47,9 +47,10 @@
 #if 0
 void Turn::operator=(const Turn &iOther)
 {
-    m_num     = iOther.m_num;
-    m_pldrack = iOther.m_pldrack;
-    m_round   = iOther.m_round;
+    m_num      = iOther.m_num;
+    m_playerId = iOther.m_playerId;
+    m_pldrack  = iOther.m_pldrack;
+    m_round    = iOther.m_round;
 }
 #endif
 
@@ -64,8 +65,9 @@
     return rs;
 }
 
-
 /// Local Variables:
+/// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/game/turn.h
diff -u eliot/game/turn.h:1.7.2.1 eliot/game/turn.h:1.7.2.2
--- eliot/game/turn.h:1.7.2.1   Wed Dec 28 16:47:35 2005
+++ eliot/game/turn.h   Tue Jan  3 20:42:13 2006
@@ -60,8 +60,9 @@
 
 #endif
 
-
 /// Local Variables:
+/// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/po/POTFILES.in
diff -u /dev/null eliot/po/POTFILES.in:1.2.4.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/po/POTFILES.in        Tue Jan  3 20:42:13 2006
@@ -0,0 +1,71 @@
+./dic/automaton.c
+./dic/automaton.h
+./dic/compdic.c
+./dic/dic.c
+./dic/dic.h
+./dic/dic_internals.h
+./dic/dic_search.c
+./dic/dic_search.h
+./dic/hashtable.c
+./dic/hashtable.h
+./dic/listdic.c
+./dic/regexp.c
+./dic/regexp.h
+./game/bag.cpp
+./game/bag.h
+./game/board.cpp
+./game/board.h
+./game/board_cross.cpp
+./game/board_search.cpp
+./game/cross.cpp
+./game/cross.h
+./game/debug.h
+./game/duplicate.cpp
+./game/duplicate.h
+./game/freegame.cpp
+./game/freegame.h
+./game/game.cpp
+./game/game.h
+./game/game_io.cpp
+./game/history.cpp
+./game/history.h
+./game/player.cpp
+./game/player.h
+./game/pldrack.cpp
+./game/pldrack.h
+./game/rack.cpp
+./game/rack.h
+./game/results.cpp
+./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/game_io.h
+./utils/game_io.cpp
+./utils/ncurses.cpp
+./utils/ncurses.h
+./wxwin/auxframes.h
+./wxwin/auxframes.cc
+./wxwin/confdimdlg.h
+./wxwin/confdimdlg.cc
+./wxwin/configdb.h
+./wxwin/configdb.cc
+./wxwin/confsearch.h
+./wxwin/confsearch.cc
+./wxwin/ewx.h
+./wxwin/gfxboard.h
+./wxwin/gfxboard.cc
+./wxwin/gfxresult.h
+./wxwin/gfxresult.cc
+./wxwin/main.cc
+./wxwin/mainframe.h
+./wxwin/mainframe.cc
+./wxwin/printout.h
+./wxwin/printout.cc
+./wxwin/searchpanel.h
+./wxwin/searchpanel.cc
+./config.h
Index: eliot/test/driver
diff -u /dev/null eliot/test/driver:1.3.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/driver   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,66 @@
+# Each regression scenario must be on one line, with the following syntax:
+# scenario_name   rand_seed
+#
+# The rand seed is a number, used to initialize the random numbers generator.
+# To each scenario 'scenario' correspond an input file 'scenario.input' and a
+# reference file 'scenario.ref'. The regression gives the input file to the
+# text interface (along with the rand seed), which generates a 'scenario.run'
+# file. This file is then compared to the reference file, and if there is no
+# difference the scenario is considered successful.
+#
+# Everything after a # is ignored.
+
+################
+# Training mode
+################
+
+# Check various words in the dictionary
+training_dict       0  # randseed unused
+# Display the tiles remaining in the bag
+training_bag        0  # randseed unused
+# Enter a rack, then display all the possibilities
+training_search     0  # randseed unused
+# Several ways of getting a rack and playing a word
+training_play       4
+# Training rack+search+play+back 
+training_back       5
+# Board cross off by one score problem
+training_cross      0
+
+#################
+# Duplicate mode
+#################
+
+# 2 AI players
+duplicate_2_ai      5
+
+#################
+# Free game mode
+#################
+
+# The human player always passes, letting the AI player do what it wants
+freegame_passing    1
+# 2 human players, changing letters a lot
+freegame_change     3
+# Three AI players
+freegame_3_ai       2
+
+##############
+# Load / Save 
+##############
+
+# load a standard training game (fumee)
+load_game           0
+# save and reload a training game, standard format
+load_saved_game     5
+# load a training game with advanced format (test.elt)
+# load_test_adv       0 # We need to specifie a much more complete file format
+                        # before we can handle load/save on duplicate and
+                       # freegame games
+
+#####################
+# Regular Expression
+#####################
+
+# test some patterns
+regexp              0
Index: eliot/test/duplicate_2_ai.ref
diff -u /dev/null eliot/test/duplicate_2_ai.ref:1.2.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/duplicate_2_ai.ref       Tue Jan  3 20:42:13 2006
@@ -0,0 +1,49 @@
+[?] pour l'aide
+commande> d 0 2
+mode duplicate
+[?] pour l'aide
+commande> a S
+Joueur 0:  866
+Joueur 1:  866
+commande> a T
+Joueur 0: RTTUW
+Joueur 1: RTTUW
+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
+commande> a p
+Eliot 1.5
+
+Game type: Duplicate
+Player 0: Computer
+Player 1: Computer
+
+    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 |  
+
+   Total: 866
+
+Rack 0: RTTUW
+Rack 1: RTTUW
+commande> q
+fin du mode duplicate
+commande> q
Index: eliot/test/freegame_3_ai.ref
diff -u /dev/null eliot/test/freegame_3_ai.ref:1.2.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/freegame_3_ai.ref        Tue Jan  3 20:42:13 2006
@@ -0,0 +1,50 @@
+[?] pour l'aide
+commande> l 0 3
+mode partie libre
+[?] pour l'aide
+commande> a T
+Joueur 0: 
+Joueur 1: DEPKAS
+Joueur 2: DILMQ
+commande> a S
+Joueur 0:  398
+Joueur 1:  266
+Joueur 2:  205
+commande> a p
+Eliot 1.5
+
+Game type: Free game
+Player 0: Computer
+Player 1: Computer
+Player 2: Computer
+
+    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 | *
+
+   Total: 869
+
+Rack 0: 
+Rack 1: DEP+KAS
+Rack 2: DILMQ
+commande> q
+fin du mode partie libre
+commande> q
Index: eliot/test/freegame_passing.ref
diff -u /dev/null eliot/test/freegame_passing.ref:1.2.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/freegame_passing.ref     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,63 @@
+[?] pour l'aide
+commande> l 1 1
+mode partie libre
+[?] pour l'aide
+commande> a S
+Joueur 0:    0
+Joueur 1:    0
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> p
+commande> a p
+Eliot 1.5
+
+Game type: Free game
+Player 0: Human
+Player 1: Computer
+
+    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 |  
+
+   Total: 850
+
+Rack 0: EGISSTU
+Rack 1: INT+ESDO
+commande> q
+fin du mode partie libre
+commande> q
Index: eliot/test/fumee
diff -u /dev/null eliot/test/fumee:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/fumee    Tue Jan  3 20:42:13 2006
@@ -0,0 +1,27 @@
+Eliot
+
+   EUOFMIE     FUMEE              26  H  4
+   IO+EOKAN    KIMONO             38  6  F
+   AE+EWTIS    WESTIE             49  L  4
+   A+EAVSLS    LAVASSE         *  86 10  H
+   BTUOMEQ     LOQUET             63  H 10
+   BM+UNOSI    OMNIBUS         *  94  O  4
+   IOZXEGP     EXPIEZ             52  N 10
+   GO+AETPI    TOPAZE             60 15  J
+   GI+AVNCO    VAINCU             28 13  C
+   GO+ESRAS    ESSORAGE        *  80  8  A
+   JEUDIDR     JOUR               44  K  5
+   DDEI+ALY    DIALYSE            56  C  3
+   D+IHUEEB    HEU                32 10  B
+   BDEI+CIL    CIEL               25  D  1
+   BDI+RRA?    BRADeRIE        *  86  A  1
+   EUGTDEA     DUT                29  M  3
+   AEEG+LR?    CERcLAGE        *  80  1  D
+   TFLATNN     JOURNAL            30  K  5
+   AFNTT+HM    MATH               24  D 12
+   AFNT+NRE    FANON              23  I  3
+   ERT         ET                 18  I 13
+   R
+
+   total                        1023
+
Index: eliot/test/load_game.input
diff -u /dev/null eliot/test/load_game.input:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/load_game.input  Tue Jan  3 20:42:13 2006
@@ -0,0 +1,6 @@
+c fumee
+a g
+a l
+a p
+q
+q
Index: eliot/test/load_game.ref
diff -u /dev/null eliot/test/load_game.ref:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/load_game.ref    Tue Jan  3 20:42:13 2006
@@ -0,0 +1,60 @@
+[?] pour l'aide
+commande> c fumee
+mode entraînement
+[?] pour l'aide
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  M  A  T  H
+ E   E  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   R  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   c  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   L  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   A  -  F  A  N  O  N  -  -  A  -  -  E  T  -
+ J   G  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   E  -  -  -  J  O  U  R  N  A  L  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  D  U  T  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+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 0 0 0 0 0 0 0 0 0
+commande> a p
+Eliot 1.5
+
+Game type: Training
+Player 0: Human
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+    1 |  EUOFMIE | FUMEE           |  H4 |  26 | 0 |  
+    2 | IO+EOKAN | KIMONO          |  6F |  38 | 0 |  
+    3 | AE+EWTIS | WESTIE          |  L4 |  49 | 0 |  
+    4 | A+EAVSLS | LAVASSE         | 10H |  86 | 0 | *
+    5 |  BTUOMEQ | LOQUET          | H10 |  63 | 0 |  
+    6 | BM+UNOSI | OMNIBUS         |  O4 |  94 | 0 | *
+    7 |  IOZXEGP | EXPIEZ          | N10 |  52 | 0 |  
+    8 | GO+AETPI | TOPAZE          | 15J |  60 | 0 |  
+    9 | GI+AVNCO | VAINCU          | 13C |  28 | 0 |  
+   10 | GO+ESRAS | ESSORAGE        |  8A |  80 | 0 | *
+   11 |  JEUDIDR | JOUR            |  K5 |  44 | 0 |  
+   12 | DDEI+ALY | DIALYSE         |  C3 |  56 | 0 |  
+   13 | D+IHUEEB | HEU             | 10B |  32 | 0 |  
+   14 | BDEI+CIL | CIEL            |  D1 |  25 | 0 |  
+   15 | BDI+RRA? | BRADeRIE        |  A1 |  86 | 0 | *
+   16 |  EUGTDEA | DUT             |  M3 |  29 | 0 |  
+   17 | AEEG+LR? | CERcLAGE        |  1D |  80 | 0 | *
+   18 |  TFLATNN | JOURNAL         |  K5 |  30 | 0 |  
+   19 | AFNTT+HM | MATH            | D12 |  24 | 0 |  
+   20 | AFNT+NRE | FANON           |  I3 |  23 | 0 |  
+   21 |      ERT | ET              | I13 |  18 | 0 |  
+
+   Total: 1023
+
+Rack 0: R
+commande> q
+fin du mode entraînement
+commande> q
Index: eliot/test/load_saved_game.input
diff -u /dev/null eliot/test/load_saved_game.input:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/load_saved_game.input    Tue Jan  3 20:42:13 2006
@@ -0,0 +1,44 @@
+e
+*
+a t
+r
+n 1
++
+a t
+r
+a r
+n 2
+a g
+
+n -1
+
+r
+n 1
+
++
+a t
+r
+a r
+n 1
+a g
+
++
+a t
+r
+a r
+n 3
+
+a g
+a p
+a l
+
+s load_saved_game.elt
+q
+c load_saved_game.elt
+
+a g
+a p
+a l
+
+q
+q
Index: eliot/test/load_saved_game.ref
diff -u /dev/null eliot/test/load_saved_game.ref:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/load_saved_game.ref      Tue Jan  3 20:42:13 2006
@@ -0,0 +1,183 @@
+[?] pour l'aide
+commande> e
+mode entraînement
+[?] pour l'aide
+commande> *
+commande> a t
+EA?AEBF
+commande> r
+commande> n 1
+commande> +
+commande> a t
+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
+  6: BAYE               35 6H
+  7: BEY                34 6H
+  8: LAYEE              34 10D
+  9: YUE                32 10F
+ 10: AMYLE              30 5H
+commande> n 2
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  A  B  A  c  E  E  -  -  -  -  -
+ I   -  -  -  -  -  A  -  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  Y  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  L  -  -  -  -  -  -  -  -  -
+ L   -  -  -  -  -  E  -  -  -  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> 
+commande> n -1
+commande> 
+commande> r
+commande> n 1
+commande> 
+commande> +
+commande> a t
+AMUJEIG
+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
+commande> n 1
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  Y  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  E  -  -  M  -  -  -  -  -  -
+ H   -  -  -  F  A  B  A  c  E  E  -  -  -  -  -
+ I   -  -  -  -  -  L  -  -  J  -  -  -  -  -  -
+ J   -  -  -  -  -  E  -  -  U  -  -  -  -  -  -
+ K   -  -  -  -  -  -  -  -  G  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  E  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  A  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  I  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> 
+commande> +
+commande> a t
+LEHNMGA
+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
+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  -  -  -  -  -  -
+ H   -  -  -  F  A  B  A  c  E  E  -  -  -  -  -
+ I   -  -  -  -  -  L  -  -  J  -  -  -  -  -  -
+ J   -  -  -  -  -  E  -  -  U  -  -  -  -  -  -
+ K   -  -  -  -  -  -  -  -  G  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  E  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  A  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  I  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a p
+Eliot 1.5
+
+Game type: Training
+Player 0: Human
+
+    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 |  
+
+   Total: 226
+
+Rack 0: HL
+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
+commande> 
+commande> s load_saved_game.elt
+commande> q
+fin du mode entraînement
+commande> c load_saved_game.elt
+mode entraînement
+[?] pour l'aide
+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  -  -  -  -  -  -
+ H   -  -  -  F  A  B  A  c  E  E  -  -  -  -  -
+ I   -  -  -  -  -  L  -  -  J  -  -  -  -  -  -
+ J   -  -  -  -  -  E  -  -  U  -  -  -  -  -  -
+ K   -  -  -  -  -  -  -  -  G  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  E  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  A  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  I  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a p
+Eliot 1.5
+
+Game type: Training
+Player 0: Human
+
+    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 |  
+
+   Total: 226
+
+Rack 0: HL
+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
+commande> 
+commande> q
+fin du mode entraînement
+commande> q
Index: eliot/test/load_test_adv.input
diff -u /dev/null eliot/test/load_test_adv.input:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/load_test_adv.input      Tue Jan  3 20:42:13 2006
@@ -0,0 +1,7 @@
+c test.elt
+a p
+a g
+a l
+q
+q
+
Index: eliot/test/load_test_adv.ref
diff -u /dev/null eliot/test/load_test_adv.ref:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/load_test_adv.ref        Tue Jan  3 20:42:13 2006
@@ -0,0 +1,2 @@
+[?] pour l'aide
+commande> c test.elt
Index: eliot/test/regexp.input
diff -u /dev/null eliot/test/regexp.input:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/regexp.input     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,16 @@
+x a.* 50
+x a.* 200
+x .*a.*e.*i.*o.*u.* 50 10
+x .*a.*e.*i.*o.*u.* 50 13
+x .*a.*e.*i.*o.*u.* 50 13 13
+x .*hop.* 50
+x a.*b 50
+x [abc].*b 
+x [abc]*b
+x [abc]*.b
+x .*(cba)*b
+x .*(cba)+b
+x .*(nn)+.*
+x .*(nn)+.*x 200
+q
+
Index: eliot/test/regexp.ref
diff -u /dev/null eliot/test/regexp.ref:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/regexp.ref       Tue Jan  3 20:42:13 2006
@@ -0,0 +1,539 @@
+[?] pour l'aide
+commande> x a.* 50
+search for a.* (50,1,15)
+aa
+aas
+abaca
+abacas
+abacost
+abacosts
+abacule
+abacules
+abaissa
+abaissable
+abaissables
+abaissai
+abaissaient
+abaissais
+abaissait
+abaissames
+abaissant
+abaissante
+abaissantes
+abaissants
+abaissas
+abaissasse
+abaissassent
+abaissasses
+abaissassiez
+abaissassions
+abaissat
+abaissates
+abaisse
+abaissee
+abaissees
+abaissement
+abaissements
+abaissent
+abaisser
+abaissera
+abaisserai
+abaisseraient
+abaisserais
+abaisserait
+abaisseras
+abaisserent
+abaisserez
+abaisseriez
+abaisserions
+abaisserons
+abaisseront
+abaisses
+abaisseur
+abaisseurs
+50 printed results
+commande> x a.* 200
+search for a.* (200,1,15)
+aa
+aas
+abaca
+abacas
+abacost
+abacosts
+abacule
+abacules
+abaissa
+abaissable
+abaissables
+abaissai
+abaissaient
+abaissais
+abaissait
+abaissames
+abaissant
+abaissante
+abaissantes
+abaissants
+abaissas
+abaissasse
+abaissassent
+abaissasses
+abaissassiez
+abaissassions
+abaissat
+abaissates
+abaisse
+abaissee
+abaissees
+abaissement
+abaissements
+abaissent
+abaisser
+abaissera
+abaisserai
+abaisseraient
+abaisserais
+abaisserait
+abaisseras
+abaisserent
+abaisserez
+abaisseriez
+abaisserions
+abaisserons
+abaisseront
+abaisses
+abaisseur
+abaisseurs
+abaisseuse
+abaisseuses
+abaissez
+abaissiez
+abaissions
+abaissons
+abajoue
+abajoues
+abalone
+abalones
+abandon
+abandonna
+abandonnai
+abandonnaient
+abandonnais
+abandonnait
+abandonnames
+abandonnant
+abandonnas
+abandonnasse
+abandonnassent
+abandonnasses
+abandonnassiez
+abandonnassions
+abandonnat
+abandonnataire
+abandonnataires
+abandonnates
+abandonnateur
+abandonnateurs
+abandonnatrice
+abandonnatrices
+abandonne
+abandonnee
+abandonnees
+abandonnement
+abandonnements
+abandonnent
+abandonner
+abandonnera
+abandonnerai
+abandonneraient
+abandonnerais
+abandonnerait
+abandonneras
+abandonnerent
+abandonnerez
+abandonneriez
+abandonnerions
+abandonnerons
+abandonneront
+abandonnes
+abandonnez
+abandonniez
+abandonnions
+abandonnique
+abandonniques
+abandonnons
+abandons
+abaque
+abaques
+abasie
+abasies
+abasourdi
+abasourdie
+abasourdies
+abasourdimes
+abasourdir
+abasourdira
+abasourdirai
+abasourdiraient
+abasourdirais
+abasourdirait
+abasourdiras
+abasourdirent
+abasourdirez
+abasourdiriez
+abasourdirions
+abasourdirons
+abasourdiront
+abasourdis
+abasourdissais
+abasourdissait
+abasourdissant
+abasourdissante
+abasourdissants
+abasourdisse
+abasourdissent
+abasourdisses
+abasourdissez
+abasourdissiez
+abasourdissions
+abasourdissons
+abasourdit
+abasourdites
+abat
+abatage
+abatages
+abatant
+abatants
+abatardi
+abatardie
+abatardies
+abatardimes
+abatardir
+abatardira
+abatardirai
+abatardiraient
+abatardirais
+abatardirait
+abatardiras
+abatardirent
+abatardirez
+abatardiriez
+abatardirions
+abatardirons
+abatardiront
+abatardis
+abatardissaient
+abatardissais
+abatardissait
+abatardissant
+abatardisse
+abatardissement
+abatardissent
+abatardisses
+abatardissez
+abatardissiez
+abatardissions
+abatardissons
+abatardit
+abatardites
+abatee
+abatees
+abatis
+abats
+abattable
+abattables
+abattage
+abattages
+abattaient
+abattais
+abattait
+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)
+ameliorateur
+ameliorateurs
+aperiodique
+aperiodiques
+archiepiscopaux
+arseniosulfure
+arseniosulfures
+arteriosclereux
+bacteriologique
+caleidoscopique
+kaleidoscopique
+11 printed results
+commande> x .*a.*e.*i.*o.*u.* 50 13
+search for .*a.*e.*i.*o.*u.* (50,13,15)
+ameliorateurs
+archiepiscopaux
+arseniosulfure
+arseniosulfures
+arteriosclereux
+bacteriologique
+caleidoscopique
+kaleidoscopique
+8 printed results
+commande> x .*a.*e.*i.*o.*u.* 50 13 13
+search for .*a.*e.*i.*o.*u.* (50,13,13)
+ameliorateurs
+1 printed results
+commande> x .*hop.* 50
+search for .*hop.* (50,1,15)
+achoppa
+achoppai
+achoppaient
+achoppais
+achoppait
+achoppames
+achoppant
+achoppas
+achoppasse
+achoppassent
+achoppasses
+achoppassiez
+achoppassions
+achoppat
+achoppates
+achoppe
+achoppee
+achoppees
+achoppement
+achoppements
+achoppent
+achopper
+achoppera
+achopperai
+achopperaient
+achopperais
+achopperait
+achopperas
+achopperent
+achopperez
+achopperiez
+achopperions
+achopperons
+achopperont
+achoppes
+achoppez
+achoppiez
+achoppions
+achoppons
+anthophage
+anthophages
+bishop
+bishops
+cenesthopathie
+cenesthopathies
+chop
+chopa
+chopai
+chopaient
+chopais
+50 printed results
+commande> x a.*b 50
+search for a.*b (50,1,15)
+acheb
+aeroclub
+aplomb
+3 printed results
+commande> x [abc].*b 
+search for [abc].*b (50,1,15)
+acheb
+aeroclub
+aplomb
+baobab
+bob
+bulb
+cab
+cineclub
+club
+cob
+coulomb
+crib
+cuproplomb
+13 printed results
+commande> x [abc]*b
+search for [abc]*b (50,1,15)
+cab
+1 printed results
+commande> x [abc]*.b
+search for [abc]*.b (50,1,15)
+bob
+cab
+cob
+3 printed results
+commande> x .*(cba)*b
+search for .*(cba)*b (50,1,15)
+acheb
+aeroclub
+aplomb
+baobab
+bob
+bulb
+cab
+cineclub
+club
+cob
+coulomb
+crib
+cuproplomb
+dab
+deb
+fob
+guib
+hidjab
+hub
+jab
+job
+kebab
+kob
+lob
+mahaleb
+mihrab
+mob
+nabab
+nib
+plomb
+pub
+rab
+rabab
+radoub
+rebab
+rhumb
+rob
+rumb
+sahib
+scrub
+serdab
+snob
+stilb
+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)
+abandonna
+abandonnai
+abandonnaient
+abandonnais
+abandonnait
+abandonnames
+abandonnant
+abandonnas
+abandonnasse
+abandonnassent
+abandonnasses
+abandonnassiez
+abandonnassions
+abandonnat
+abandonnataire
+abandonnataires
+abandonnates
+abandonnateur
+abandonnateurs
+abandonnatrice
+abandonnatrices
+abandonne
+abandonnee
+abandonnees
+abandonnement
+abandonnements
+abandonnent
+abandonner
+abandonnera
+abandonnerai
+abandonneraient
+abandonnerais
+abandonnerait
+abandonneras
+abandonnerent
+abandonnerez
+abandonneriez
+abandonnerions
+abandonnerons
+abandonneront
+abandonnes
+abandonnez
+abandonniez
+abandonnions
+abandonnique
+abandonniques
+abandonnons
+abbevillienne
+abbevilliennes
+abelienne
+50 printed results
+commande> x .*(nn)+.*x 200
+search for .*(nn)+.*x (200,1,15)
+annaux
+anneaux
+baronniaux
+biennaux
+bonneteaux
+boutonneux
+buissonneux
+cartonneux
+centennaux
+chaponneaux
+charbonneux
+confessionnaux
+conneaux
+cotonneux
+couenneux
+coulonneux
+decennaux
+dindonneaux
+enneagonaux
+ennuyeux
+faisanneaux
+fauconneaux
+floconneux
+gazonneux
+goudronneux
+haillonneux
+heronneaux
+jambonneaux
+jargonneux
+mangonneaux
+molletonneux
+moutonneux
+panneaux
+paonneaux
+pigeonneaux
+poissonneux
+precautionneux
+processionnaux
+quadriennaux
+quinquennaux
+ramponneaux
+ronchonneaux
+sablonneux
+savonneux
+septennaux
+sexennaux
+soupconneux
+stanneux
+tonneaux
+tricennaux
+triennaux
+tyranneaux
+vallonneux
+vanneaux
+vicennaux
+55 printed results
+commande> q
Index: eliot/test/test.elt
diff -u /dev/null eliot/test/test.elt:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/test.elt Tue Jan  3 20:42:13 2006
@@ -0,0 +1,17 @@
+Eliot 1.5
+
+Game type: Training
+Player 0: Computer
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+    1 |  TSL?ENU | LUTiNES         |  H7 |  64 | 0 | *
+    2 |  EURTEAA | LAUREATE        |  7H |  60 | 0 | *
+    3 |  SAFNEQT | FANEES          |  O4 |  39 | 0 |  
+    4 | QT+SAPIO | PORTAIS         |  K5 |  36 | 0 |  
+    5 | Q+I?JEEG | JuGEES          | 13C |  28 | 0 |  
+    6 | IQ+ZRFEH | QUIZ            | D12 |  58 | 0 |  
+
+   Total: 285
+
+Rack 0: EFHR
Index: eliot/test/training_back.ref
diff -u /dev/null eliot/test/training_back.ref:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/training_back.ref        Tue Jan  3 20:42:13 2006
@@ -0,0 +1,129 @@
+[?] pour l'aide
+commande> e
+mode entraînement
+[?] pour l'aide
+commande> *
+commande> a t
+EA?AEBF
+commande> r
+commande> n 1
+commande> +
+commande> a t
+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
+  6: BAYE               35 6H
+  7: BEY                34 6H
+  8: LAYEE              34 10D
+  9: YUE                32 10F
+ 10: AMYLE              30 5H
+commande> n 2
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  A  B  A  c  E  E  -  -  -  -  -
+ I   -  -  -  -  -  A  -  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  Y  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  L  -  -  -  -  -  -  -  -  -
+ L   -  -  -  -  -  E  -  -  -  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> n -1
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  A  B  A  c  E  E  -  -  -  -  -
+ I   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a p
+Eliot 1.5
+
+Game type: Training
+Player 0: Human
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+    1 |  EA?AEBF | FABAcEE         |  H4 |  80 | 0 | *
+
+   Total: 80
+
+Rack 0: LMUAEYE
+commande> n -1
+commande> a p
+Eliot 1.5
+
+Game type: Training
+Player 0: Human
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+
+   Total: 0
+
+Rack 0: EA?AEBF
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ H   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ I   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+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 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> *
+commande> r
+commande> n 1
+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
+commande> a p
+Eliot 1.5
+
+Game type: Training
+Player 0: Human
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+    1 |  IEIEIEF | FIEE            |  H8 |  14 | 0 |  
+
+   Total: 14
+
+Rack 0: EII
+commande> q
+fin du mode entraînement
+commande> q
Index: eliot/test/training_cross.input
diff -u /dev/null eliot/test/training_cross.input:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/training_cross.input     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,174 @@
+e
+
+t EUOFMIE
+r
+a r
+n 1
+a g
+a t
+a s
+a l
+
+t IO+EOKAN
+r
+a r
+n 1
+a g
+a s
+a l
+
+t AE+EWTIS
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t A+EAVSLS
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t BTUOMEQ
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t BM+UNOSI
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t IOZXEGP
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t GO+AETPI
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t GI+AVNCO
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t GO+ESRAS
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t JEUDIDR
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t DDEI+ALY
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t D+IHUEEB
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t BDEI+CIL
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t BDI+RRA?
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t EUGTDEA
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t AEEG+LR?
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t TFLATNN
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t AFNTT+HM
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t AFNT+NRE
+r
+a r
+n 1 
+a g
+a s
+a l
+
+t ERT
+r
+a r
+n 1 
+a g
+a s
+a l
+
+q
+q
+
Index: eliot/test/training_cross.ref
diff -u /dev/null eliot/test/training_cross.ref:1.1.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/training_cross.ref       Tue Jan  3 20:42:13 2006
@@ -0,0 +1,787 @@
+[?] pour l'aide
+commande> e
+mode entraînement
+[?] pour l'aide
+commande> 
+commande> t EUOFMIE
+commande> r
+commande> a r
+  1: FUMEE              26 H4
+  2: FOUIE              24 H4
+  3: FOUEE              24 H4
+  4: MEFIE              22 H4
+  5: FUMEE              20 H8
+  6: MEFIE              20 H8
+  7: FOUIE              18 H8
+  8: FOUEE              18 H8
+  9: FUMEE              18 H6
+ 10: FUMEE              18 H7
+commande> n 1
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  -  -  -  -  -  -
+ I   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a t
+IO
+commande> a s
+26
+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 8 1 1 5 2 6 6 2 1 6 6 6 5 2 1 1 1 1 2
+commande> 
+commande> t IO+EOKAN
+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
+  8: KINE               33 I3
+  9: KAN                29 I3
+ 10: OKA                27 I2
+commande> n 1
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  -  -  -  -  -  -
+ I   -  -  -  -  -  O  -  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  O  -  -  -  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a s
+64
+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 0 5 2 5 4 2 1 6 6 6 5 2 1 1 1 1 2
+commande> 
+commande> t AE+EWTIS
+commande> r
+commande> a r
+  1: WESTIE             49 L4
+  2: EWES               43 L3
+  3: SWEAT              34 9H
+  4: SWEAT              32 L6
+  5: ETAIES             31 L1
+  6: AISEE              29 L4
+  7: ETAIS              27 L2
+  8: TAISE              27 L3
+  9: TAIES              27 L2
+ 10: WESTIE             27 9F
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  -  -  -  -  -  -
+ I   -  -  -  -  -  O  -  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  O  -  -  -  -  -  -  -  -  -
+ L   -  -  -  W  E  S  T  I  E  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a s
+113
+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 11 1 2 2 6 1 0 5 2 5 4 2 1 6 5 5 5 2 0 1 1 1 2
+commande> 
+commande> t A+EAVSLS
+commande> r
+commande> a r
+  1: LAVASSE         *  86 10H
+  2: VASSALE         *  80 10I
+  3: LAVASSE         *  78 10G
+  4: VASSALE         *  75 K9
+  5: LAVASSE         *  73 9C
+  6: LAVASSE         *  72 9D
+  7: LAVASSE         *  72 K9
+  8: VASSALE         *  67 G8
+  9: LAVASSE         *  64 G8
+ 10: EVASAS             35 10I
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  L  -  -  -  -  -
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  -
+ K   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  E  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a s
+199
+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 ?
+ 7 2 2 3 10 1 2 2 6 1 0 4 2 5 4 2 1 6 3 5 5 1 0 1 1 1 2
+commande> 
+commande> t BTUOMEQ
+commande> r
+commande> a r
+  1: LOQUET             63 H10
+  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
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  -
+ K   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  E  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> a s
+262
+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 ?
+ 7 2 2 3 9 1 2 2 6 1 0 4 2 5 3 2 0 6 3 4 4 1 0 1 1 1 2
+commande> 
+commande> t BM+UNOSI
+commande> r
+commande> a r
+  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
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  -
+ K   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  E  -  -  -  -  -
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  -
+commande> a s
+356
+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 ?
+ 7 1 2 3 9 1 2 2 5 1 0 4 1 4 2 2 0 6 2 4 3 1 0 1 1 1 2
+commande> 
+commande> t IOZXEGP
+commande> r
+commande> a r
+  1: EXPIEZ             52 N10
+  2: EXIGEZ             50 N10
+  3: AXIEZ              46 K10
+  4: AXEZ               44 K10
+  5: IXEE               33 14E
+  6: EXPIEZ             32 14D
+  7: ZEE                32 14F
+  8: ZOE                32 14F
+  9: EXPIEZ             32 14H
+ 10: EXPIE              32 N10
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  -
+ K   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  -
+commande> a s
+408
+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 ?
+ 7 1 2 3 8 1 2 2 4 1 0 4 1 4 2 1 0 6 2 4 3 1 0 0 1 0 2
+commande> 
+commande> t GO+AETPI
+commande> r
+commande> a r
+  1: TOPAZE             60 15J
+  2: GAIZE              48 15K
+  3: GAZE               48 15L
+  4: PAGEOTE            24 14B
+  5: EPITOGE            24 14B
+  6: EPIAIT             22 G2
+  7: GOPAK              21 F2
+  8: TAPAGE             20 K9
+  9: PETA               20 7C
+ 10: PIGEA              20 7B
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  -  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  -  O  -  -  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+468
+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 ?
+ 6 1 2 3 7 1 2 2 4 1 0 4 1 4 1 0 0 6 2 3 3 1 0 0 1 0 2
+commande> 
+commande> t GI+AVNCO
+commande> r
+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
+  8: VINA               22 7C
+  9: CAVA               22 K9
+ 10: CANE               21 7E
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  V  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  A  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  -  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  -  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  -  O  -  -  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+496
+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 1 3 7 1 2 2 3 1 0 4 1 3 1 0 0 6 2 3 3 0 0 0 1 0 2
+commande> 
+commande> t GO+ESRAS
+commande> r
+commande> a r
+  1: ESSORAGE        *  80 8A
+  2: GOSSA              23 11G
+  3: ROSES              21 11G
+  4: ROSSA              21 11G
+  5: ROSAS              21 11G
+  6: AGRESSA            20 D7
+  7: OSES               19 11H
+  8: OSAS               19 11H
+  9: ESSORA             18 7A
+ 10: GERA               18 7C
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  S  -  -  -  -  V  -  -
+ D   -  -  -  -  -  -  -  O  -  -  -  -  A  -  -
+ E   -  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  -  O  -  -  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+576
+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 ?
+ 4 1 1 3 6 1 1 2 3 1 0 4 1 3 0 0 0 5 0 3 3 0 0 0 1 0 2
+commande> 
+commande> t JEUDIDR
+commande> r
+commande> a r
+  1: JOUR               44 K5
+  2: JARDE              35 K9
+  3: JADE               33 K9
+  4: JARD               33 K9
+  5: JEU                31 M2
+  6: JEUDIS             30 C3
+  7: JUDD               29 N1
+  8: JAR                29 K9
+  9: JUPE               28 12L
+ 10: JARD               28 D12
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  S  -  -  -  -  V  -  -
+ D   -  -  -  -  -  -  -  O  -  -  -  -  A  -  -
+ E   -  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  J  O  U  R  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+620
+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 ?
+ 4 1 1 3 6 1 1 2 3 0 0 4 1 3 0 0 0 4 0 3 2 0 0 0 1 0 2
+commande> 
+commande> t DDEI+ALY
+commande> r
+commande> a r
+  1: DIALYSE            56 C3
+  2: AY                 49 11J
+  3: LADY               48 D12
+  4: DEY                42 14B
+  5: DYADES             36 C3
+  6: DYADE              34 D11
+  7: LAYES              34 B4
+  8: DELAYA             34 D10
+  9: YAWL               34 4J
+ 10: DRAYE              30 E7
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  -  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  -  -  -  V  -  -
+ D   -  -  -  -  -  -  -  O  -  -  -  -  A  -  -
+ E   -  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  J  O  U  R  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+676
+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 ?
+ 3 1 1 2 5 1 1 2 2 0 0 3 1 3 0 0 0 4 0 3 2 0 0 0 0 0 2
+commande> 
+commande> t D+IHUEEB
+commande> r
+commande> a r
+  1: HEU                32 10B
+  2: BEDE               31 10B
+  3: HE                 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
+ 10: HIE                26 10A
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   -  -  -  -  -  -  -  O  -  U  -  -  A  -  -
+ E   -  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  J  O  U  R  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+708
+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 ?
+ 3 1 1 2 4 1 1 1 2 0 0 3 1 3 0 0 0 4 0 3 1 0 0 0 0 0 2
+commande> 
+commande> t BDEI+CIL
+commande> r
+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
+ 10: CIBLE              18 4B
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  -  A  -  -
+ E   -  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  J  O  U  R  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+733
+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 ?
+ 3 1 0 2 3 1 1 1 1 0 0 2 1 3 0 0 0 4 0 3 1 0 0 0 0 0 2
+commande> 
+commande> t BDI+RRA?
+commande> r
+commande> a r
+  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
+  9: CIBARe             27 1D
+ 10: DuRCIRA            27 1A
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  -  A  -  -
+ E   -  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  J  O  U  R  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  -  -  -  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+819
+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 ?
+ 2 0 0 1 3 1 1 1 0 0 0 2 1 3 0 0 0 2 0 3 1 0 0 0 0 0 1
+commande> 
+commande> t EUGTDEA
+commande> r
+commande> a r
+  1: DUT                29 M3
+  2: EUT                27 M3
+  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
+ 10: CAGET              24 1D
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  -  A  -  -
+ E   -  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   -  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   -  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   -  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   -  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   -  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   -  -  -  -  J  O  U  R  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  D  U  T  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+848
+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 ?
+ 2 0 0 0 3 1 1 1 0 0 0 2 1 3 0 0 0 2 0 2 0 0 0 0 0 0 1
+commande> 
+commande> t AEEG+LR?
+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
+ 10: GREnELAT        *  74 15A
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  -  A  -  -
+ E   E  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   R  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   c  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   L  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   A  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   G  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   E  -  -  -  J  O  U  R  -  A  -  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  D  U  T  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+928
+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 ?
+ 1 0 0 0 1 1 0 1 0 0 0 1 1 3 0 0 0 1 0 2 0 0 0 0 0 0 0
+commande> 
+commande> t TFLATNN
+commande> r
+commande> a r
+  1: JOURNAL            30 K5
+  2: FLA                26 12D
+  3: FLA                24 M13
+  4: FANON              23 I3
+  5: FA                 22 12D
+  6: FLAN               21 14A
+  7: FAN                19 14B
+  8: FANON              18 11E
+  9: FLA                17 14A
+ 10: NAKFA              17 F4
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  -  A  -  -
+ E   E  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   R  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   c  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   L  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   A  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   G  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   E  -  -  -  J  O  U  R  N  A  L  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  D  U  T  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+958
+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 ?
+ 1 0 0 0 1 1 0 1 0 0 0 0 1 2 0 0 0 1 0 2 0 0 0 0 0 0 0
+commande> 
+commande> t AFNTT+HM
+commande> r
+commande> a r
+  1: MATH               24 D12
+  2: HATIF              22 13K
+  3: HA                 22 12D
+  4: FA                 22 12D
+  5: KHANAT             20 F6
+  6: MATON              19 I3
+  7: FAN                19 14B
+  8: HAN                19 14B
+  9: AH                 19 12D
+ 10: MANIF              18 13K
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  M  A  T  H
+ E   E  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   R  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   c  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   L  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   A  -  -  -  -  O  -  -  -  A  -  -  -  -  -
+ J   G  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   E  -  -  -  J  O  U  R  N  A  L  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  D  U  T  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+982
+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 ?
+ 1 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 1 0 1 0 0 0 0 0 0 0
+commande> 
+commande> t AFNT+NRE
+commande> r
+commande> a r
+  1: FANON              23 I3
+  2: KRAFT              19 F6
+  3: FRET               19 14A
+  4: REAI               18 E10
+  5: FANON              18 11E
+  6: FREON              18 11E
+  7: REFAIT             18 13J
+  8: FERAIT             18 13J
+  9: FRETIN             18 13J
+ 10: EN                 18 I13
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  M  A  T  H
+ E   E  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   R  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   c  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   L  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   A  -  F  A  N  O  N  -  -  A  -  -  -  -  -
+ J   G  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   E  -  -  -  J  O  U  R  N  A  L  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  D  U  T  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+1005
+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 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0
+commande> 
+commande> t ERT
+commande> r
+commande> a r
+  1: ET                 18 I13
+  2: RELAVASSES         15 10F
+  3: VAINCUE            13 13C
+  4: EX                 13 11M
+  5: SE                 13 M10
+  6: TREK               13 F3
+  7: TEK                12 F4
+  8: TES                11 M8
+  9: RE                 11 E10
+ 10: TET                11 14B
+commande> n 1 
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   B  R  A  D  e  R  I  E  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  S  -  H  -  -  -  -  -
+ C   -  -  D  I  A  L  Y  S  E  E  -  -  V  -  -
+ D   C  I  E  L  -  -  -  O  -  U  -  M  A  T  H
+ E   E  -  -  -  -  -  -  R  -  -  -  -  I  -  -
+ F   R  -  -  -  -  K  -  A  -  -  -  -  N  -  -
+ G   c  -  -  -  -  I  -  G  -  -  -  -  C  -  -
+ H   L  -  -  F  U  M  E  E  -  L  O  Q  U  E  T
+ I   A  -  F  A  N  O  N  -  -  A  -  -  E  T  -
+ J   G  -  -  -  -  N  -  -  -  V  -  -  -  -  T
+ K   E  -  -  -  J  O  U  R  N  A  L  -  -  -  O
+ L   -  -  -  W  E  S  T  I  E  S  -  -  -  -  P
+ M   -  -  D  U  T  -  -  -  -  S  -  -  -  -  A
+ N   -  -  -  -  -  -  -  -  -  E  X  P  I  E  Z
+ O   -  -  -  O  M  N  I  B  U  S  -  -  -  -  E
+commande> a s
+1023
+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 0 0 0 0 0 0 0 0 0
+commande> 
+commande> q
+fin du mode entraînement
+commande> q
Index: eliot/test/training_search.ref
diff -u /dev/null eliot/test/training_search.ref:1.2.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/test/training_search.ref      Tue Jan  3 20:42:13 2006
@@ -0,0 +1,852 @@
+[?] pour l'aide
+commande> e
+mode entraînement
+[?] pour l'aide
+commande> t QpiNZ?s
+commande> a t
+QPINZ?S
+commande> r
+commande> a r 1000
+  1: SPItZ              50 H8
+  2: ZINcS              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
+ 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
+ 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
+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
+483: NItS                6 H7
+484: SeIN                6 H6
+485: yINS                6 H8
+486: SaIN                6 H5
+487: NuIS                6 H7
+488: SaIN                6 H6
+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
+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: aIE                 2 8G
+ 17: fIE                 2 8G
+ 18: IxE                 2 8H
+ 19: IvE                 2 8H
+ 20: IrE                 2 8H
+ 21: IpE                 2 8H
+ 22: IlE                 2 8H
+ 23: IdE                 2 8H
+ 24: lEI                 2 8F
+ 25: EpI                 2 8F
+ 26: hIE                 2 8G
+ 27: lIE                 2 8G
+ 28: mIE                 2 8G
+ 29: nIE                 2 8G
+ 30: oIE                 2 8G
+ 31: pIE                 2 8G
+ 32: vIE                 2 8G
+ 33: rIE                 2 8G
+ 34: hI                  1 8G
+ 35: lI                  1 8G
+ 36: xI                  1 8G
+ 37: aI                  1 8G
+ 38: mI                  1 8G
+ 39: bI                  1 8G
+ 40: cI                  1 8G
+ 41: fI                  1 8G
+ 42: sI                  1 8G
+ 43: nI                  1 8G
+ 44: rI                  1 8G
+ 45: pI                  1 8G
+ 46: In                  1 8H
+ 47: If                  1 8H
+ 48: Il                  1 8H
+commande> q
+fin du mode entraînement
+commande> q
Index: eliot/utils/eliottxt.cpp
diff -u eliot/utils/eliottxt.cpp:1.12.2.2 eliot/utils/eliottxt.cpp:1.12.2.3
--- eliot/utils/eliottxt.cpp:1.12.2.2   Wed Dec 28 20:02:52 2005
+++ eliot/utils/eliottxt.cpp    Tue Jan  3 20:42:13 2006
@@ -31,6 +31,7 @@
 
 #include "dic.h"
 #include "dic_search.h"
+#include "regexp.h"
 #include "game_io.h"
 #include "game_factory.h"
 #include "training.h"
@@ -189,6 +190,7 @@
     printf("            gn -- grille + valeur des cases (variante)\n");
     printf("            l -- lettres non jouées\n");
     printf("            p -- partie\n");
+    printf("            P -- partie (format standard)\n");
     printf("            r -- recherche\n");
     printf("            s -- score\n");
     printf("            S -- score de tous les joueurs\n");
@@ -216,6 +218,7 @@
     printf("            j -- joueur courant\n");
     printf("            l -- lettres non jouées\n");
     printf("            p -- partie\n");
+    printf("            P -- partie (format standard)\n");
     printf("            s -- score\n");
     printf("            S -- score de tous les joueurs\n");
     printf("            t -- tirage\n");
@@ -240,6 +243,7 @@
     printf("            j -- joueur courant\n");
     printf("            l -- lettres non jouées\n");
     printf("            p -- partie\n");
+    printf("            P -- partie (format standard)\n");
     printf("            s -- score\n");
     printf("            S -- score de tous les joueurs\n");
     printf("            t -- tirage\n");
@@ -262,6 +266,11 @@
     printf("                [] joueurs humains et {} joueurs IA\n");
     printf("  D       : raccourci pour d 1 1\n");
     printf("  L       : raccourci pour l 1 1\n");
+    printf("  x [] {1} {2} {3} : expressions rationnelles\n");
+    printf("          [] expression à rechercher\n");
+    printf("          {1} nombre de résultats à afficher\n");
+    printf("          {2} longueur minimum d'un mot\n");
+    printf("          {3} longueur maximum d'un mot\n");
     printf("  q       : quitter\n");
 }
 
@@ -305,7 +314,10 @@
             GameIO::printNonPlayed(cout, iGame);
             break;
         case L'p':
-            iGame.save(cout);
+            iGame.save(cout,Game::FILE_FORMAT_ADVANCED);
+            break;
+        case L'P':
+            iGame.save(cout,Game::FILE_FORMAT_STANDARD);
             break;
         case L'r':
             token = next_token_digit(NULL, delim, state);
@@ -435,10 +447,10 @@
                         eliottxt_get_cross(iGame.getDic(), token);
                     break;
                 case L'*':
-                    iGame.setRackRandom(0, false, Game::RACK_ALL);
+                    iGame.setRackRandom(false, Game::RACK_ALL);
                     break;
                 case L'+':
-                    iGame.setRackRandom(0, false, Game::RACK_NEW);
+                    iGame.setRackRandom(false, Game::RACK_NEW);
                     break;
                 case L's':
                     token = next_token_filename(NULL, delim, &state);
@@ -675,6 +687,112 @@
 }
 
 
+void eliot_regexp_build_default_llist(struct search_RegE_list_t &llist)
+{
+    memset(&llist, 0, sizeof(llist));
+
+    llist.minlength = 1;
+    llist.maxlength = 15;
+
+    llist.symbl[0] = RE_ALL_MATCH;
+    llist.symbl[1] = RE_VOWL_MATCH;
+    llist.symbl[2] = RE_CONS_MATCH;
+    llist.symbl[3] = RE_USR1_MATCH;
+    llist.symbl[5] = RE_USR2_MATCH;
+
+    llist.valid[0] = 1; // all letters
+    llist.valid[1] = 1; // vowels
+    llist.valid[2] = 1; // consonants
+    llist.valid[3] = 0; // user defined list 1
+    llist.valid[4] = 0; // user defined list 2
+
+    for (int i = 0; i < DIC_SEARCH_REGE_LIST; i++)
+    {
+        memset(llist.letters[i], 0, sizeof(llist.letters[i]));
+    }
+
+    const list<Tile>& allTiles = Tile::getAllTiles();
+    list<Tile>::const_iterator it;
+    for (it = allTiles.begin(); it != allTiles.end(); it++)
+    {
+        if (! it->isJoker() && ! it->isEmpty())
+        {
+            // all tiles
+            llist.letters[0][it->toCode()] = 1;
+            // vowels
+            if (it->isVowel())
+            {
+                llist.letters[1][it->toCode()] = 1;
+            }
+            // consonants
+            if (it->isConsonant())
+            {
+                llist.letters[2][it->toCode()] = 1;
+            }
+        }
+    }
+}
+
+void eliot_regexp(const Dictionary& iDic, wchar_t *cmd,
+                  const wchar_t *delim, wchar_t **state)
+{
+    /*
+    printf("  x [] {1} {2} {3} : expressions rationnelles\n");
+    printf("          [] expression à rechercher\n");
+    printf("          {1} nombre de résultats à afficher\n");
+    printf("          {2} longueur minimum d'un mot\n");
+    printf("          {3} longueur maximum d'un mot\n");
+    */
+
+#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;
+
+    exp   = wcstok(NULL, delim, state);
+    cnres = wcstok(NULL, delim, state);
+    clmin = wcstok(NULL, delim, state);
+    clmax = wcstok(NULL, delim, state);
+
+    if (exp == NULL)
+    {
+        return;
+    }
+    int nres = cnres ? _wtoi(cnres) : 50;
+    int lmin = clmin ? _wtoi(clmin) : 1;
+    int lmax = clmax ? _wtoi(clmax) : DIC_WORD_MAX - 1;
+
+    if (lmax <= (DIC_WORD_MAX - 1) && lmin >= 1 && lmin <= lmax)
+    {
+        llist.minlength = lmin;
+        llist.maxlength = lmax;
+    }
+    else
+    {
+        printf("bad length -%s,%s-\n", (const char*)clmin, (const char*)clmax);
+        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(),
+           nres, lmin, lmax);
+    Dic_search_RegE(iDic, re, buff, &llist);
+
+    int nresult = 0;
+    for (int i = 0; i < RES_REGE_MAX && i < nres && buff[i][0]; i++)
+    {
+        printf("%s\n", convertToMb(buff[i]).c_str());
+        nresult++;
+    }
+    printf("%d printed results\n", nresult);
+}
+
+
 void main_loop(const Dictionary &iDic)
 {
     wchar_t *token;
@@ -702,8 +820,6 @@
                     else
                     {
                         string filename = convertToMb(token);
-                        fprintf(stderr, "chargement de -%s-\n",
-                                filename.c_str());
                         FILE* fin;
                         if ((fin = fopen(filename.c_str(), "r")) == NULL)
                         {
@@ -715,7 +831,7 @@
                         fclose(fin);
                         if (game == NULL)
                         {
-                            fprintf(stderr, "erreur pendant le chargement\n");
+                            printf("erreur pendant le chargement\n");
                         }
                         else
                         {
@@ -811,6 +927,10 @@
                     GameFactory::Instance()->releaseGame(*game);
                     break;
                 }
+                case L'x':
+                    // Regular expression tests
+                    eliot_regexp(iDic, NULL, delim, &state);
+                    break;
                 case L'q':
                     quit = 1;
                     break;
@@ -889,3 +1009,10 @@
 
     return 0;
 }
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/utils/game_io.cpp
diff -u eliot/utils/game_io.cpp:1.7.2.1 eliot/utils/game_io.cpp:1.7.2.2
--- eliot/utils/game_io.cpp:1.7.2.1     Wed Dec 28 16:47:35 2005
+++ eliot/utils/game_io.cpp     Tue Jan  3 20:42:13 2006
@@ -166,7 +166,7 @@
 
 void GameIO::printPlayedRack(ostream &out, const Game &iGame, int n)
 {
-    out << 
convertToMb(iGame.getCurrentPlayer().getCurrentRack().toString(false)) << endl;
+    out << 
convertToMb(iGame.getCurrentPlayer().getCurrentRack().toString(PlayedRack::RACK_SIMPLE))
 << endl;
 }
 
 
@@ -175,7 +175,7 @@
     for (int j = 0; j < iGame.getNPlayers(); j++)
     {
         out << "Joueur " << j << ": ";
-        out << 
convertToMb(iGame.getPlayer(j).getCurrentRack().toString(false)) << endl;
+        out << 
convertToMb(iGame.getPlayer(j).getCurrentRack().toString(PlayedRack::RACK_SIMPLE))
 << endl;
     }
 }
 
Index: eliot/utils/ncurses.cpp
diff -u eliot/utils/ncurses.cpp:1.19.2.1 eliot/utils/ncurses.cpp:1.19.2.2
--- eliot/utils/ncurses.cpp:1.19.2.1    Wed Dec 28 16:47:35 2005
+++ eliot/utils/ncurses.cpp     Tue Jan  3 20:42:13 2006
@@ -202,7 +202,7 @@
     {
         if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
             attron(A_BOLD);
-        string rack = 
convertToMb(m_game->getPlayer(i).getCurrentRack().toString(false));
+        string rack = 
convertToMb(m_game->getPlayer(i).getCurrentRack().toString(PlayedRack::RACK_SIMPLE));
         mvwprintw(win, y + yOff + i + 1, x + 2,
                   _("Player %d: %s"), i, rack.c_str());
         if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
@@ -567,11 +567,11 @@
     switch (iKey)
     {
         case '*':
-            iGame.setRackRandom(0, false, Game::RACK_ALL);
+            iGame.setRackRandom(false, Game::RACK_ALL);
             return 1;
 
         case '+':
-            iGame.setRackRandom(0, false, Game::RACK_NEW);
+            iGame.setRackRandom(false, Game::RACK_NEW);
             return 1;
 
         case 't':
Index: eliot/wxwin/auxframes.cc
diff -u eliot/wxwin/auxframes.cc:1.19.2.3 eliot/wxwin/auxframes.cc:1.19.2.4
--- eliot/wxwin/auxframes.cc:1.19.2.3   Thu Dec 29 19:40:24 2005
+++ eliot/wxwin/auxframes.cc    Tue Jan  3 20:42:13 2006
@@ -608,4 +608,5 @@
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/wxwin/auxframes.h
diff -u eliot/wxwin/auxframes.h:1.5.2.1 eliot/wxwin/auxframes.h:1.5.2.2
--- eliot/wxwin/auxframes.h:1.5.2.1     Wed Dec 28 20:10:56 2005
+++ eliot/wxwin/auxframes.h     Tue Jan  3 20:42:13 2006
@@ -254,4 +254,5 @@
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/wxwin/ewx.h
diff -u /dev/null eliot/wxwin/ewx.h:1.9.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/wxwin/ewx.h   Tue Jan  3 20:42:13 2006
@@ -0,0 +1,82 @@
+/* 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   ewx.h
+ *  \brief  Eliot wxwidgets switch and defines
+ *  \author Antoine Fraboulet
+ *  \date   2002
+ */
+
+#ifndef __EWX__
+#define __EWX__
+
+#ifdef DEBUG
+#  define debug(x...) { fprintf(stderr,x); }
+#else
+#  define debug(x...)
+#endif
+
+#if defined(TRACE_TODO)
+#  define TODO(x...) {                                                   \
+       fprintf(stderr,"** TODO ** %s:%d: ", __FILE__, __LINE__); \
+       fprintf(stderr,x);                                                \
+       }
+#else
+#  define TODO(x...)
+#endif
+
+#if defined(__WIN32__) || defined(__WIN95__) || defined(__WXMSW__)
+#  define ENABLE_LC_NO_HEADER
+#  define ENABLE_RESLIST_IN_MAIN
+#  define MSW_RESIZE_BUG
+#  define INCOMPLETE
+#else
+#  define ENABLE_SAVE_POSTSCRIPT
+#  define ENABLE_LOCALE
+#  define ENABLE_RESLIST_IN_MAIN
+#  define INCOMPLETE { std::cerr << "incomplete " << __FILE__ << " " << 
__LINE__ << "\n"; }
+#endif
+
+#include "config.h"
+#define APPNAME "Eliot"
+
+// wxU is used to convert ansi/utf8 strings to unicode strings (wchar_t)
+#if defined( ENABLE_NLS ) && defined( ENABLE_UTF8 )
+#   if wxUSE_UNICODE
+#       define wxU(utf8) wxString(utf8, wxConvUTF8)
+#   else
+#       define wxU(utf8) wxString(wxConvUTF8.cMB2WC(utf8), *wxConvCurrent)
+#   endif
+#else // ENABLE_NLS && ENABLE_UTF8
+#   if wxUSE_UNICODE
+#       define wxU(ansi) wxString(ansi, *wxConvCurrent)
+#   else
+#       define wxU(ansi) ansi
+#   endif
+#endif // ENABLE_NLS && ENABLE_UTF8
+
+#endif // __EWX__
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/wxwin/gfxboard.cc
diff -u /dev/null eliot/wxwin/gfxboard.cc:1.8.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/wxwin/gfxboard.cc     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,459 @@
+/* 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   gfxboard.cc
+ *  \brief  Game board graphical view
+ *  \author Antoine Fraboulet
+ *  \date   2002
+ */
+
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+
+#include "wx/dcmemory.h"
+
+#include "ewx.h"
+#include "dic.h"
+#include "game.h"
+#include "configdb.h"
+#include "gfxboard.h"
+
+#ifdef DEBUG_
+#   define GFXDEBUG(x) x
+#else
+#   define GFXDEBUG(x)
+#endif
+
+BEGIN_EVENT_TABLE(GfxBoard, wxWindow)
+    EVT_PAINT(GfxBoard::OnPaint)
+    EVT_SIZE(GfxBoard::OnSize)
+END_EVENT_TABLE()
+
+#define LINE_WIDTH 1
+#define BOARD_SIZE (BOARD_DIM + 2)
+
+    /* ************************************************** */
+    /* ************************************************** */
+
+GfxBoard::GfxBoard(wxFrame *parent, Game &iGame) :
+       wxWindow(parent, wxWindowID(-1), wxDefaultPosition, wxDefaultSize,
+                wxNO_BORDER | wxFULL_REPAINT_ON_RESIZE, wxT("gfxboard")),
+       m_game(iGame)
+{
+    bmp          = NULL;
+    board_size   = 0;
+    tile_size    = 0;
+#if defined(MSW_RESIZE_BUG)
+    just_resized = false;
+#endif
+    for(int i=0; i<BOARD_DIM; i++)
+       {
+           for(int j=0; j < BOARD_DIM; j++)
+               {
+                   paintedboard_char[i][j] = wxT(' ');
+                   paintedboard_attr[i][j] = 0;
+               }
+       }
+}
+
+    /* ************************************************** */
+    /* ************************************************** */
+
+GfxBoard::~GfxBoard(void)
+{
+    if (bmp)
+       {
+           delete bmp;
+           bmp = NULL;
+       }
+}
+
+/**
+ * Make new dimensions available for the next OnPaint
+ * event. The BMP is deleted if it exists.
+ */
+
+void
+GfxBoard::OnSize(wxSizeEvent& e)
+{
+    GFXDEBUG(std::cerr << "On size : ");
+
+    wxSize cs = GetClientSize();
+    board_size = cs.GetWidth() < cs.GetHeight() ? cs.GetWidth() : 
cs.GetHeight();
+    tile_size  = (int)((float)board_size / (float)(BOARD_SIZE)) - LINE_WIDTH;
+
+    GFXDEBUG(std::cerr << "(" << cs.GetWidth() << "," << cs.GetHeight() << 
")");
+    GFXDEBUG(std::cerr << " tile size " << tile_size << endl);
+
+    TopLeft  = wxPoint((cs.GetWidth()  - (board_size - tile_size/2)) / 2,
+                      (cs.GetHeight() - (board_size - tile_size/2)) / 2);
+
+#if defined(MSW_RESIZE_BUG)
+    just_resized = true;
+#endif
+
+    if (bmp)
+       {
+           delete bmp;
+           bmp = NULL;
+       }
+}
+
+/**
+ * Creates a BMP in memory and draws the board inside
+ */
+
+void
+GfxBoard::CreateBMP()
+{
+    GFXDEBUG(std::cerr << "Create BMP ");
+    if (!bmp)
+       {
+           wxSize bs = GetClientSize();
+           bmp=new wxBitmap(bs.x,bs.y);
+           GFXDEBUG(std::cerr << " new bmp (" << bs.x << "," << bs.y << ")");
+           if (bmp)
+               {
+                   wxMemoryDC memDC;
+                   memDC.SelectObject(* bmp);
+                   DrawBoard(&memDC);
+                   memDC.SelectObject(wxNullBitmap);
+               }
+       }
+    GFXDEBUG(std::cerr << endl);
+}
+
+
+/**
+ * Update the full BMP and copy only the requested area
+ * to the ClientDC
+ */
+
+void
+GfxBoard::RefreshSquare(wxRect &r)
+{
+    wxClientDC dc(this);
+
+    if (bmp)
+       {
+           int vX,vY,vW,vH;
+           wxMemoryDC memDC;
+           memDC.SelectObject(* bmp);
+           DrawBoard(&memDC);
+           vX = r.x;
+           vY = r.y;
+           vW = r.width;
+           vH = r.height;
+           GFXDEBUG(std::cerr << " refresh (" << vX << "," << vY << "," << vW 
<< "," << vH << ") ");
+           dc.Blit(vX,vY,vW,vH,&memDC,vX,vY,wxCOPY);
+           memDC.SelectObject(wxNullBitmap);
+       }
+    else
+       {
+           DrawBoard(&dc);
+       }
+}
+
+/**
+ * Force a full refresh of the board
+ */
+
+void
+GfxBoard::Refresh(board_refresh_t WXUNUSED(force))
+{
+    wxSize cs = GetClientSize();
+    board_size = cs.GetWidth() < cs.GetHeight() ? cs.GetWidth() : 
cs.GetHeight();
+    tile_size  = (int)((float)board_size / (float)(BOARD_SIZE)) - LINE_WIDTH;
+    wxRect r (0,0,cs.GetWidth(),cs.GetHeight());
+    RefreshSquare(r);
+}
+
+/**
+ * Window manager OnPaint event handler.
+ */
+
+void
+GfxBoard::OnPaint(wxPaintEvent&)
+{
+    wxPaintDC dc(this);
+
+    CreateBMP();
+
+    GFXDEBUG(std::cerr << "OnPaint : ");
+
+    if (bmp)
+       {
+#if defined(MSW_RESIZE_BUG)
+           Refresh(BOARD_FORCE_REFRESH);
+           if (just_resized == true)
+               {
+                   just_resized = false;
+               }
+#else
+           // we keep that code for wxgtk
+           // it does not work under wxmsw, don't know why
+           // all the onsize/repaint should be checked ... later
+           int vX,vY,vW,vH;
+           wxMemoryDC memDC;
+           memDC.SelectObject(* bmp);
+           wxRegionIterator upd(GetUpdateRegion());
+           while (upd)
+               {
+                   vX = upd.GetX();
+                   vY = upd.GetY();
+                   vW = upd.GetW();
+                   vH = upd.GetH();
+                   GFXDEBUG(std::cerr << "+(" << vX << "," << vY << "," << vW 
<< "," << vH << ")");
+                   dc.Blit(vX,vY,vW,vH,&memDC,vX,vY,wxCOPY);
+                   upd ++ ;
+               }
+           memDC.SelectObject(wxNullBitmap);
+#endif
+       }
+    else
+       {
+           GFXDEBUG(std::cerr << " call to DrawBoard ");
+           DrawBoard(&dc);
+       }
+
+    GFXDEBUG(std::cerr << "End of OnPaint" << endl);
+}
+
+
+void
+GfxBoard::DrawTileBack(wxDC* dc, int top, int left, int size, bool testtile)
+{
+    //    void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, 
wxCoord height, double radius = 20)
+    wxBrush oldbrush = dc->GetBrush();
+    wxColour colBackground;
+
+    if (testtile)
+       {
+           colBackground = config.getColour(wxString(BTSTTILEBACKGROUND));
+       }
+    else
+       {
+           colBackground = config.getColour(wxString(BTILEBACKGROUND));
+       }
+
+    wxBrush *BackgroundBrush = 
wxTheBrushList->FindOrCreateBrush(colBackground, wxSOLID);
+    dc->SetBrush(* BackgroundBrush);
+    dc->DrawRoundedRectangle(left,top,size,size,std::max(2,size/6));
+    dc->SetBrush(oldbrush);
+}
+
+/**
+ * Draw a tile to the wxDC object.
+ */
+
+#define TILE_LEFT(col) (col*(tile_size+LINE_WIDTH) + TopLeft.x)
+#define TILE_TOP(row) (row*(tile_size+LINE_WIDTH) + TopLeft.y)
+
+/*
+   TODO
+   - ajuster avec une LINE_SIZE differente
+   - calculer la taille de la police
+*/
+
+/*    TILE_LEFT
+      |
+      |  TILE_LEFT + LINE_WIDTH
+      |  |
+      +++++++++-- TILE_TOP
+      +++++++++
+      +++++++++
+      +++   +++-------------- TILE_TOP + LINE_WIDTH
+      +++   +++ | = tile_size
+      +++   +++--
+      +++++++++--
+      +++++++++ | = LINE_WIDTH
+      +++++++++--
+      | |
+      |_|
+       |
+       LINE_WIDTH
+*/
+
+void
+GfxBoard::DrawTile(wxDC *dc, wxString& wxs, int row, int column, bool 
testtile, bool drawtileback)
+{
+    wxColour colour;
+    wxCoord width, height;
+    wxCoord posx, posy;
+    wxCoord left,top;
+    // redraw borders
+    left = TILE_LEFT(column);
+    top  = TILE_TOP(row);
+
+    if (wxs.length() > 0 && *wxs.GetData())
+       {
+           // we got a letter (or 2 chars for coordinates > 9)
+           // draw plastic tile
+           if (drawtileback)
+               {
+                   DrawTileBack(dc,
+                                top  + LINE_WIDTH,
+                                left + LINE_WIDTH,
+                                tile_size, testtile);
+               }
+           // draw letter
+           if (testtile)
+               {
+                   colour = config.getColour(wxString(BCOLOURTSTLETTERS));
+               }
+           else
+               {
+                   colour = config.getColour(wxString(BCOLOURLETTERS));
+               }
+
+           dc->SetTextForeground(colour);
+           dc->GetTextExtent(wxs,&width,&height);
+           posx = left + LINE_WIDTH + (tile_size - width) / 2;
+           posy = top  + LINE_WIDTH + (tile_size - height) / 2;
+           dc->DrawText(wxs,posx,posy);
+       }
+}
+
+/**
+ * Draw the complete board in the wxDC.
+ */
+
+void
+GfxBoard::DrawBoard(wxDC *dc)
+{
+    Board board;
+
+    wxString wxs;
+    int row,column;
+
+    wxFont   font            = config.getFont(BOARDFONT);
+    wxColour colForeground   = config.getColour(wxString(BCOLOURLINES));
+    wxColour colBackground   = config.getColour(wxString(BCOLOURBACKGROUND));
+
+    wxBrush *BackgroundBrush = 
wxTheBrushList->FindOrCreateBrush(colBackground, wxSOLID);
+    wxPen   *LinesPen        = wxThePenList->FindOrCreatePen(colForeground, 
LINE_WIDTH, wxSOLID);
+
+    dc->SetFont (font);
+    dc->SetPen  (* LinesPen);
+    dc->SetBrush(* BackgroundBrush);
+
+    // background rectangle (entire frame)
+    wxSize bs = GetClientSize();
+    dc->DrawRectangle(0,0,bs.x,bs.y);
+
+    // lines
+    for(row=BOARD_MIN; row < BOARD_MAX; row++)
+       {
+           // vertical
+           dc->DrawLine(TILE_LEFT(row+1),
+                        TILE_TOP(1),
+                        TILE_LEFT(row+1),
+                        TILE_TOP(BOARD_MAX));
+           // horizontal row <-> line
+           dc->DrawLine(TILE_LEFT(1),
+                        TILE_TOP(row+1),
+                        TILE_LEFT(BOARD_MAX),
+                        TILE_TOP(row+1));
+       }
+
+    // 1 2 3 4 5 ...
+    // A B C D ...
+    for(row=BOARD_MIN; row <= BOARD_MAX; row++)
+       {
+           wxs.Printf(wxT("%d"), row);
+           DrawTile(dc, wxs, 0, row);
+           wxs.Printf(wxT("%c"), row + 'A' - 1);
+           DrawTile(dc, wxs, row, 0);
+       }
+
+    // Board Background
+    wxColour colWx3         = config.getColour(wxString(BCOLOURWX3));
+    wxColour colWx2         = config.getColour(wxString(BCOLOURWX2));
+    wxColour colLx3         = config.getColour(wxString(BCOLOURLX3));
+    wxColour colLx2         = config.getColour(wxString(BCOLOURLX2));
+
+    wxBrush *Wx3Brush = wxTheBrushList->FindOrCreateBrush(colWx3, wxSOLID);
+    wxBrush *Wx2Brush = wxTheBrushList->FindOrCreateBrush(colWx2, wxSOLID);
+    wxBrush *Lx3Brush = wxTheBrushList->FindOrCreateBrush(colLx3, wxSOLID);
+    wxBrush *Lx2Brush = wxTheBrushList->FindOrCreateBrush(colLx2, wxSOLID);
+
+    board = m_game.getBoard();
+    for(row=BOARD_MIN; row <= BOARD_MAX; row++)
+       {
+           for (column = BOARD_MIN; column <= BOARD_MAX; column++)
+               {
+                   if (board.getLetterMultiplier(row, column) == 2)
+                       {
+                           dc->SetBrush(*Lx2Brush);
+                       }
+                   else if (board.getLetterMultiplier(row, column) == 3)
+                       {
+                           dc->SetBrush(*Lx3Brush);
+                       }
+                   else if (board.getWordMultiplier(row, column) == 2)
+                       {
+                           dc->SetBrush(*Wx2Brush);
+                       }
+                   else if (board.getWordMultiplier(row, column) == 3)
+                       {
+                           dc->SetBrush(*Wx3Brush);
+                       }
+                   else
+                       {
+                           dc->SetBrush(*BackgroundBrush);
+                       }
+
+                   if (row && column)
+                       {
+                           dc->DrawRectangle(TILE_LEFT(column), TILE_TOP(row),
+                                             tile_size + 2*LINE_WIDTH,
+                                             tile_size + 2*LINE_WIDTH);
+                       }
+               }
+       }
+
+    // Tiles
+    LinesPen->SetWidth(1);
+    dc->SetPen  (* LinesPen);
+    bool drawtiles = config.getDrawTile();
+    for(row=BOARD_MIN; row <= BOARD_MAX; row++)
+       {
+           for (column = BOARD_MIN; column <= BOARD_MAX; column++)
+               {
+                   int attr = board.getCharAttr(row, column);
+                   wxs  = wxString((wxChar)board.getChar(row, column));
+
+                   paintedboard_char[row - BOARD_MIN][column - BOARD_MIN] = 
*wxs.GetData();
+                   paintedboard_attr[row - BOARD_MIN][column - BOARD_MIN] = 
attr;
+
+                   DrawTile(dc,wxs,row,column,attr & ATTR_TEST,drawtiles);
+               }
+       }
+
+    dc->SetFont(wxNullFont);
+}
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/wxwin/gfxboard.h
diff -u /dev/null eliot/wxwin/gfxboard.h:1.6.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/wxwin/gfxboard.h      Tue Jan  3 20:42:13 2006
@@ -0,0 +1,116 @@
+/* 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   gfxboard.h
+ *  \brief  Game board graphical view
+ *  \author Antoine Fraboulet
+ *  \date   2002
+ */
+
+#ifndef _GFXBOARD_H
+#define _GFXBOARD_H
+
+/**
+ * gfxboard is a wxWindow widget that draws a Scrabble board
+ */
+
+class GfxBoard : public wxWindow
+{
+ private:
+    /**
+     * reference on the played game
+     */
+    Game &m_game;
+
+    /**
+     * paintedboard_char is the matrix of played tiles
+     */
+    wxChar paintedboard_char[BOARD_DIM][BOARD_DIM];
+
+    /**
+     * paintedboard_attr is the matrix of special attributes for tiles, for
+     * instance it can store if a tile is a test tile (placed but not played).
+     */
+    char   paintedboard_attr[BOARD_DIM][BOARD_DIM];
+
+    /**
+     * size in pixels for the board.
+     * board_size = min(width,height)
+     */
+    int board_size;
+
+    /**
+     * tile_size = size in pixels of a tile
+     */
+    int tile_size;
+
+    /**
+     * there is a bug when doing an OnSize under windows : the window
+     * has to be fully refreshed (UpdateRegion does not seem to work).
+     */
+#if defined(MSW_RESIZE_BUG)
+    bool just_resized;
+#endif
+
+    /**
+     * top left point used to draw the lines, used to keep the board
+     * centered horizontally and vertically
+     */
+    wxPoint  TopLeft;
+
+    /**
+     * Board bitmap, created by CreateBMP
+     */
+    wxBitmap *bmp;
+
+    void CreateBMP();
+    void DrawTileBack(wxDC*,int,int,int, bool testtile);
+    void DrawTile(wxDC*,wxString&,int,int,bool testtile = false, bool 
drawtileback = false);
+    void DrawBoard(wxDC*);
+    void RefreshSquare(wxRect&);
+
+    ConfigDB config;
+
+ public:
+
+    GfxBoard(wxFrame* parent, Game& game);
+    ~GfxBoard(void);
+
+    void OnPaint (wxPaintEvent& event);
+    void OnSize  (wxSizeEvent&  event);
+
+    typedef enum {
+       BOARD_REFRESH,
+       BOARD_FORCE_REFRESH
+    } board_refresh_t;
+
+    void Refresh (board_refresh_t force = BOARD_REFRESH);
+
+    DECLARE_EVENT_TABLE()
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/wxwin/gfxresult.cc
diff -u eliot/wxwin/gfxresult.cc:1.3.2.1 eliot/wxwin/gfxresult.cc:1.3.2.2
--- eliot/wxwin/gfxresult.cc:1.3.2.1    Wed Dec 28 20:10:56 2005
+++ eliot/wxwin/gfxresult.cc    Tue Jan  3 20:42:13 2006
@@ -229,6 +229,8 @@
 /* ************************************************** */
 
 /// Local Variables:
+/// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/wxwin/gfxresult.h
diff -u eliot/wxwin/gfxresult.h:1.2.2.1 eliot/wxwin/gfxresult.h:1.2.2.2
--- eliot/wxwin/gfxresult.h:1.2.2.1     Wed Dec 28 20:10:56 2005
+++ eliot/wxwin/gfxresult.h     Tue Jan  3 20:42:13 2006
@@ -65,4 +65,5 @@
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/wxwin/main.cc
diff -u /dev/null eliot/wxwin/main.cc:1.8.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/wxwin/main.cc Tue Jan  3 20:42:13 2006
@@ -0,0 +1,97 @@
+/* Eliot                                                                     */
+/* Copyright (C) 1999  Antoine Fraboulet                                     */
+/* 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 
*/
+
+/**
+ *  \file   main.cc
+ *  \brief  Eliot main entry point
+ *  \author Antoine Fraboulet
+ *  \date   2005
+ */
+
+#ifdef WIN32 // mingw32 hack
+#   undef Yield
+#   undef CreateDialog
+#endif
+
+#include <stdlib.h>
+#include <time.h>
+#include <wx/wxprec.h>
+#include <wx/wx.h>
+#include <wx/app.h>
+#include <wx/intl.h>
+
+#include "ewx.h"
+#include "configdb.h"
+#include "mainframe.h"
+#include "game_factory.h"
+
+#include "eliot.xpm"
+
+class EliotApp : public wxApp
+{
+private:
+protected:
+#ifdef ENABLE_LOCALE
+  wxLocale locale;
+#endif
+public:
+  virtual bool OnInit();
+  virtual int  OnExit();
+};
+
+IMPLEMENT_APP(EliotApp)
+
+bool
+EliotApp::OnInit()
+{
+    srand(time(NULL));
+    SetVendorName(wxT("Afrab"));
+    SetAppName(wxString(wxT("eliot")) + wxT("-") + wxT(VERSION));
+    SetClassName(wxT("eliot"));
+
+    wxConfigBase* config = wxConfigBase::Get();
+    config = NULL;
+#ifdef ENABLE_LOCALE
+    locale.Init(wxLocale::GetSystemLanguage(),
+                wxLOCALE_LOAD_DEFAULT | wxLOCALE_CONV_ENCODING);
+#endif
+    ConfigDB configdb;
+    configdb.setFirstDefault();
+    MainFrame *mainframe = new MainFrame(configdb.getFramePos(wxT(APPNAME)),
+                                         configdb.getFrameSize(wxT(APPNAME)));
+    mainframe->SetIcon(wxICON(eliot));
+    mainframe->Show(TRUE);
+    SetTopWindow(mainframe);
+    return TRUE;
+}
+
+int
+EliotApp::OnExit()
+{
+    GameFactory::Destroy();
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+    return 0;
+}
+
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// indent-tabs-mode: nil
+/// End:
Index: eliot/wxwin/mainframe.cc
diff -u eliot/wxwin/mainframe.cc:1.17.2.1 eliot/wxwin/mainframe.cc:1.17.2.2
--- eliot/wxwin/mainframe.cc:1.17.2.1   Wed Dec 28 20:10:56 2005
+++ eliot/wxwin/mainframe.cc    Tue Jan  3 20:42:13 2006
@@ -142,10 +142,11 @@
     EVT_BUTTON(Button_Search,   MainFrame::OnSearch)
     EVT_BUTTON(Button_PlayBack, MainFrame::OnPlay)
     //
-    EVT_TEXT_ENTER(Rack_ID, MainFrame::OnSearch)
+    EVT_TEXT_ENTER(Rack_ID,    MainFrame::OnTextEnter)
     //
     EVT_CLOSE(MainFrame::OnCloseWindow)
     //
+    //EVT_MENU(Menu_Help,              MainFrame::OnMenuHelp)
 END_EVENT_TABLE()
 
 // ******************************
@@ -413,7 +414,7 @@
 
     FILE* fin;
 
-    if ((fin = fopen(dialog.GetPath().mb_str(), "r")) == NULL)
+    if ((fin = fopen(dialog.GetPath().mb_str(), "rb")) == NULL)
         {
             txt << wxT("Impossible d'ouvrir") << dialog.GetPath();
             wxMessageDialog msg(this, txt, wxT("Ouverture d'une partie"));
@@ -433,8 +434,6 @@
             return;
         }
 
-#if 0
-    // FIXME
     if (m_game->getHistory().getSize() == 0)
        {
             wxMessageDialog msg(this,
@@ -443,16 +442,13 @@
             msg.ShowModal();
             return;
        }
-#endif
 
-    std::string r = "";
-#if 0
-    // FIXME
+    std::wstring r;
+
     if (m_game->getHistory().getSize() >= 0)
-       {
-           r = m_game->getCurrentPlayer().getCurrentRack().toString();
-       }
-#endif
+    {
+        r = m_game->getCurrentPlayer().getCurrentRack().toString();
+    }
 
     rack->SetValue(wxU(r.c_str()));
     // update gfxboard and all frames
@@ -750,7 +746,7 @@
 {
     wxString msg;
     // XXX:    msg << wxT("Eliot\n© Antoine Fraboulet 1999-2004\n\n");
-    msg << wxT("Eliot\nCopyright 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");
@@ -774,7 +770,7 @@
 MainFrame::OnSetRack(wxCommandEvent& event)
 {
     int id;
-    // TODO Game::set_rack_mode -> PlayedRack::set_rack_mode
+
     Game::set_rack_mode mode = Game::RACK_NEW;
     debug("OnSetRack ");
     switch ((id = event.GetId()))
@@ -800,6 +796,7 @@
 void
 MainFrame::OnSearch(wxCommandEvent& WXUNUSED(event))
 {
+    debug("MainFrame::OnSearch\n");
     Search();
 }
 
@@ -968,6 +965,7 @@
     wxString msg;
     bool check = config.getRackChecking();
 
+    static_cast<Training*>(m_game)->removeTestPlay();
     std::wstring str = srack.c_str();
     res = static_cast<Training*>(m_game)->setRack(mode, check, str);
 
@@ -1062,4 +1060,5 @@
 /// mode: c++
 /// mode: hs-minor
 /// c-basic-offset: 4
+/// indent-tabs-mode: nil
 /// End:
Index: eliot/wxwin/mainframe.h
diff -u /dev/null eliot/wxwin/mainframe.h:1.6.2.1
--- /dev/null   Tue Jan  3 20:42:14 2006
+++ eliot/wxwin/mainframe.h     Tue Jan  3 20:42:13 2006
@@ -0,0 +1,119 @@
+/* Eliot                                                                     */
+/* Copyright (C) 1999  Antoine Fraboulet                                     */
+/* 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 
*/
+
+/**
+ *  \file   mainframe.h
+ *  \brief  Main frame for the Eliot GUI
+ *  \author Antoine Fraboulet
+ *  \date   2005
+ */
+
+#ifndef _MAINFRAME_H_
+#define _MAINFRAME_H_
+
+#include "dic.h"
+#include "game.h"
+#include "auxframes.h"
+
+class MainFrame: public wxFrame
+{
+private:
+
+    Dictionary  m_dic;
+    Game        *m_game;
+    ConfigDB    config;
+    AuxFrame    *auxframes_ptr[MAX_FRAME_ID];
+
+    wxTextCtrl  *rack;
+#ifdef ENABLE_RESLIST_IN_MAIN
+    GfxResult   *reslist;
+#endif
+
+    wxButton    *b_play;
+    wxButton    *b_rackrandomset;
+    wxButton    *b_rackrandomnew;
+    wxButton    *b_search;
+    wxButton    *b_back;
+
+    wxStatusBar *statusbar;
+
+    void InitFrames();
+    void InitMenu();
+    void UpdateStatusBar();
+
+public:
+    MainFrame(wxPoint,wxSize);
+    virtual ~MainFrame();
+    
+    // *******
+    // Actions
+    // *******
+    void SetRack(Game::set_rack_mode, wxString = wxT(""));
+    void Search();
+    void Play(int);
+    void TestPlay(int);
+
+    void UpdateFrames(AuxFrame::refresh_t force = AuxFrame::REFRESH);
+    
+    // *****
+    // Menus
+    // *****
+    void OnMenuGameNew          (wxCommandEvent& event);
+    void OnMenuGameOpen         (wxCommandEvent& event);
+    void OnMenuGameSave         (wxCommandEvent& event);
+    void OnMenuGamePrint        (wxCommandEvent& event);
+    void OnMenuGamePrintPreview (wxCommandEvent& event);
+    void OnMenuGamePrintPS      (wxCommandEvent& event);
+
+    void OnMenuConfGameDic      (wxCommandEvent& event);
+    void OnMenuConfGameSearch   (wxCommandEvent& event);
+
+    void OnMenuConfPrint        (wxCommandEvent& event);
+
+    void OnMenuConfAspectFont        (wxCommandEvent& event);
+    void OnMenuConfAspectBoardColour (wxCommandEvent& event);
+
+    void OnMenuShowFrame        (wxCommandEvent& event);
+
+    void OnMenuQuitApropos      (wxCommandEvent& event);
+    void OnMenuQuitConfirm      (wxCommandEvent& event);
+
+    // *******
+    // Buttons
+    // *******
+    void OnPlay     (wxCommandEvent& event);
+    void OnSetRack  (wxCommandEvent& event);
+    void OnSearch   (wxCommandEvent& event);
+    void OnPlayBack (wxCommandEvent& event);
+    void OnTextEnter(wxCommandEvent& event);
+
+    // *******
+    // Objects
+    // *******
+    void OnCloseWindow       (wxCloseEvent& event);
+
+    DECLARE_EVENT_TABLE()
+};
+
+#endif
+
+/// Local Variables:
+/// mode: c++
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// End:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]