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/.cvsignore dic/...


From: eliot-dev
Subject: [Eliot-dev] eliot ./TODO ./configure.in dic/.cvsignore dic/...
Date: Sun, 22 Jan 2006 12:23:53 +0000

CVSROOT:        /cvsroot/eliot
Module name:    eliot
Branch:         
Changes by:     Olivier Teulière <address@hidden>      06/01/22 12:23:53

Modified files:
        .              : TODO configure.in 
        dic            : .cvsignore compdic.c dic_search.c dic_search.h 
                         listdic.c regexpmain.c 
        game           : Makefile.am bag.cpp board.cpp board.h 
                         board_search.cpp coord.cpp coord.h cross.cpp 
                         cross.h duplicate.cpp duplicate.h freegame.cpp 
                         freegame.h game.cpp game.h game_io.cpp 
                         history.cpp history.h player.cpp player.h 
                         pldrack.cpp pldrack.h rack.cpp rack.h round.cpp 
                         round.h tile.cpp tile.h training.cpp training.h 
                         turn.cpp turn.h 
        utils          : eliottxt.cpp game_io.cpp ncurses.cpp 
        wxwin          : auxframes.cc auxframes.h gfxresult.cc 
                         gfxresult.h mainframe.cc searchpanel.cc 
Added files:
        game           : encoding.cpp encoding.h 

Log message:
        Backport of the 'multibyte' branch on HEAD.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/TODO.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/configure.in.diff?tr1=1.16&tr2=1.17&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/.cvsignore.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/compdic.c.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/dic_search.c.diff?tr1=1.15&tr2=1.16&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/dic_search.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/listdic.c.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/dic/regexpmain.c.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/Makefile.am.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/bag.cpp.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/board.cpp.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/board.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/board_search.cpp.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/coord.cpp.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/coord.h.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/cross.cpp.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/cross.h.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/duplicate.cpp.diff?tr1=1.15&tr2=1.16&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/duplicate.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/encoding.cpp.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/encoding.h.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/freegame.cpp.diff?tr1=1.17&tr2=1.18&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/freegame.h.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game.cpp.diff?tr1=1.28&tr2=1.29&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game.h.diff?tr1=1.27&tr2=1.28&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/game_io.cpp.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/history.cpp.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/history.h.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/player.cpp.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/player.h.diff?tr1=1.17&tr2=1.18&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/pldrack.cpp.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/pldrack.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/rack.cpp.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/rack.h.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/round.cpp.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/round.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/tile.cpp.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/tile.h.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/training.cpp.diff?tr1=1.15&tr2=1.16&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/training.h.diff?tr1=1.14&tr2=1.15&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/turn.cpp.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/game/turn.h.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/utils/eliottxt.cpp.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/utils/game_io.cpp.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/utils/ncurses.cpp.diff?tr1=1.20&tr2=1.21&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/auxframes.cc.diff?tr1=1.20&tr2=1.21&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/auxframes.h.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/gfxresult.cc.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/gfxresult.h.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/mainframe.cc.diff?tr1=1.18&tr2=1.19&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/eliot/eliot/wxwin/searchpanel.cc.diff?tr1=1.14&tr2=1.15&r1=text&r2=text

Patches:
Index: eliot/TODO
diff -u eliot/TODO:1.5 eliot/TODO:1.6
--- eliot/TODO:1.5      Sun Jan  1 23:09:27 2006
+++ eliot/TODO  Sun Jan 22 12:23:52 2006
@@ -3,15 +3,7 @@
 * 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 
+ - 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.
@@ -19,14 +11,14 @@
  - Add "joker" type games in wxwin version of Eliot, Freegame
    and Duplicate will follow
 
- - full French i18n interface and error messages for wxwin. 
+ - full French i18n interface and error messages for wxwin.
 
 
 * ==================
 * Next Eliot version
 * ==================
 
- - new dictionnary format that includes tiles 
+ - new dictionnary format that includes tiles
    - number
    - points
    - printable equivalent
@@ -45,6 +37,8 @@
 
  - network support
  - add timers
+ - implement the dictionary as a GADDAG:
+   
http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol24/issue2/spe880.pdf
 
 
 %%% Local Variables:
Index: eliot/configure.in
diff -u eliot/configure.in:1.16 eliot/configure.in:1.17
--- eliot/configure.in:1.16     Sun Jan  1 22:16:42 2006
+++ eliot/configure.in  Sun Jan 22 12:23:53 2006
@@ -86,10 +86,10 @@
 AC_ARG_ENABLE([wxwidgets],AC_HELP_STRING([--enable-wxwidgets],[wxWidgets 
interface support (default disabled)]))
 if test "${enable_wxwidgets}" = "yes"
 then
-  AM_PATH_WXCONFIG(2.6.0, wxWin=1)
+  AM_PATH_WXCONFIG(2.6.0, [wxWin=1], [wxWin=0], [], [--unicode])
   if test "${wxWin}" != 1; then
         AC_MSG_ERROR([
-                wxWidgets must be installed on your system
+                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
Index: eliot/dic/.cvsignore
diff -u eliot/dic/.cvsignore:1.1 eliot/dic/.cvsignore:1.2
--- eliot/dic/.cvsignore:1.1    Thu Jul  8 18:17:32 2004
+++ eliot/dic/.cvsignore        Sun Jan 22 12:23:53 2006
@@ -1,5 +1,10 @@
 .deps
 Makefile
 Makefile.in
+scanner.h
+er.c
+libdic_a-er.c
+libdic_a-er.h
 compdic
 listdic
+regexp
Index: eliot/dic/compdic.c
diff -u eliot/dic/compdic.c:1.7 eliot/dic/compdic.c:1.8
--- eliot/dic/compdic.c:1.7     Sun Jan  1 19:51:00 2006
+++ eliot/dic/compdic.c Sun Jan 22 12:23:53 2006
@@ -111,14 +111,14 @@
 print_header_info(Dict_header *header)
 {
   printf("============================\n");
-  printf("keyword length %d bytes\n",(int)strlen(_COMPIL_KEYWORD_));
-  printf("keyword size   %d bytes\n",sizeof(_COMPIL_KEYWORD_));
-  printf("header size    %d bytes\n",sizeof(Dict_header));
+  printf("keyword length %lu bytes\n", strlen(_COMPIL_KEYWORD_));
+  printf("keyword size   %lu bytes\n", sizeof(_COMPIL_KEYWORD_));
+  printf("header size    %lu bytes\n", sizeof(Dict_header));
   printf("\n");
   printf("%d words\n",header->nwords);
   printf("\n");
   printf("root : %7d (edge)\n",header->root);
-  printf("root : %7d (byte)\n",header->root * sizeof(Dawg_edge));
+  printf("root : %7lu (byte)\n",header->root * sizeof(Dawg_edge));
   printf("\n");
   printf("nodes : %d+%d\n",header->nodesused, header->nodessaved);
   printf("edges : %d+%d\n",header->edgesused, header->edgessaved);
Index: eliot/dic/dic_search.c
diff -u eliot/dic/dic_search.c:1.15 eliot/dic/dic_search.c:1.16
--- eliot/dic/dic_search.c:1.15 Sun Jan  1 19:51:00 2006
+++ eliot/dic/dic_search.c      Sun Jan 22 12:23:53 2006
@@ -27,6 +27,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wchar.h>
 
 #include "dic_internals.h"
 #include "dic.h"
@@ -70,18 +71,35 @@
 
 
 /**
- * Dic_search_word : direct application of Dic_seek_edgeptr
+ * Dic_search_word_inner : direct application of Dic_seek_edgeptr
  * @param dic : dictionary
  * @param word : word to lookup
  * @result 0 not a valid word, 1 ok
  */
+static int Dic_search_word_inner(const Dictionary dic, const char* word)
+{
+    Dawg_edge *e;
+    e = Dic_seek_edgeptr(dic, word, dic->dawg + dic->root);
+    return e->term;
+}
 
-int
-Dic_search_word(const Dictionary dic, const char* word)
+
+/**
+ * Wrapper around Dic_search_word_inner, until we have multibyte support in
+ * the dictionary
+ */
+int Dic_search_word(const Dictionary dic, const wchar_t* word)
 {
-  Dawg_edge *e;
-  e = Dic_seek_edgeptr(dic,word,dic->dawg + dic->root);
-  return e->term;
+    int res;
+    char *tmp_word = malloc(wcslen(word) + 1);
+    sprintf(tmp_word, "%ls", word);
+
+    // Do the actual work
+    res = Dic_search_word_inner(dic, tmp_word);
+
+    // Release memory
+    free(tmp_word);
+    return res;
 }
 
 
@@ -159,10 +177,10 @@
   } while (! (*edgeptr++).last);
 }
 
-void
-Dic_search_7pl1(const Dictionary dic, const char* rack,
-                char buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
-                int joker)
+static void
+Dic_search_7pl1_inner(const Dictionary dic, const char* rack,
+                      char buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
+                      int joker)
 {
   int i,j,wordlen;
   const char* r = rack;
@@ -235,12 +253,41 @@
     }
 }
 
+
+/**
+ * Wrapper around Dic_search_7pl1_inner, until we have multibyte support in
+ * the dictionary
+ */
+void
+Dic_search_7pl1(const Dictionary dic, const wchar_t* rack,
+                wchar_t buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
+                int joker)
+{
+    int i, j, k;
+    char tmp_buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
+    char *tmp_rack = malloc(wcslen(rack) + 1);
+    sprintf(tmp_rack, "%ls", rack);
+    // Do the actual work
+    Dic_search_7pl1_inner(dic, tmp_rack, tmp_buff, joker);
+
+    for (i = 0; i < DIC_LETTERS; i++)
+    {
+        for (j = 0; j < RES_7PL1_MAX; j++)
+        {
+            for (k = 0; k < DIC_WORD_MAX; k++)
+            {
+                buff[i][j][k] = tmp_buff[i][j][k];
+            }
+        }
+    }
+}
+
 /****************************************/
 /****************************************/
 
-void
-Dic_search_Racc(const Dictionary dic, const char* word,
-                char wordlist[RES_RACC_MAX][DIC_WORD_MAX])
+static void
+Dic_search_Racc_inner(const Dictionary dic, const char* word,
+                      char wordlist[RES_RACC_MAX][DIC_WORD_MAX])
 {
   /* search_racc will try to add a letter in front and at the end of a word */
 
@@ -260,7 +307,7 @@
   for(i='a'; i <= 'z'; i++)
     {
       wordtst[0] = i;
-      if (Dic_search_word(dic,wordtst) && wordlistlen < RES_RACC_MAX)
+      if (Dic_search_word_inner(dic,wordtst) && wordlistlen < RES_RACC_MAX)
        strcpy(wordlist[wordlistlen++],wordtst);
     }
 
@@ -288,13 +335,37 @@
     }
 }
 
+/**
+ * Wrapper around Dic_search_Racc_inner, until we have multibyte support in
+ * the dictionary
+ */
+void
+Dic_search_Racc(const Dictionary dic, const wchar_t* word,
+                wchar_t wordlist[RES_RACC_MAX][DIC_WORD_MAX])
+{
+    int i, j;
+    char tmp_buff[RES_RACC_MAX][DIC_WORD_MAX];
+    char *tmp_word = malloc(wcslen(word) + 1);
+    sprintf(tmp_word, "%ls", word);
+    // Do the actual work
+    Dic_search_Racc_inner(dic, tmp_word, tmp_buff);
+
+    for (i = 0; i < RES_RACC_MAX; i++)
+    {
+        for (j = 0; j < DIC_WORD_MAX; j++)
+        {
+            wordlist[i][j] = tmp_buff[i][j];
+        }
+    }
+}
+
 /****************************************/
 /****************************************/
 
 
-void
-Dic_search_Benj(const Dictionary dic, const char* word,
-                char wordlist[RES_BENJ_MAX][DIC_WORD_MAX])
+static void
+Dic_search_Benj_inner(const Dictionary dic, const char* word,
+                      char wordlist[RES_BENJ_MAX][DIC_WORD_MAX])
 {
   int i,wordlistlen;
   char wordtst[DIC_WORD_MAX];
@@ -326,6 +397,30 @@
   } while (!(*edge0++).last);
 }
 
+/**
+ * Wrapper around Dic_search_Benj_inner, until we have multibyte support in
+ * the dictionary
+ */
+void
+Dic_search_Benj(const Dictionary dic, const wchar_t* word,
+                wchar_t wordlist[RES_BENJ_MAX][DIC_WORD_MAX])
+{
+    int i, j;
+    char tmp_buff[RES_BENJ_MAX][DIC_WORD_MAX];
+    char *tmp_word = malloc(wcslen(word) + 1);
+    sprintf(tmp_word, "%ls", word);
+    // Do the actual work
+    Dic_search_Benj_inner(dic, tmp_word, tmp_buff);
+
+    for (i = 0; i < RES_BENJ_MAX; i++)
+    {
+        for (j = 0; j < DIC_WORD_MAX; j++)
+        {
+            wordlist[i][j] = tmp_buff[i][j];
+        }
+    }
+}
+
 
 /****************************************/
 /****************************************/
@@ -341,8 +436,8 @@
 
 void
 Dic_search_cross_rec(struct params_cross_t *params,
-                    char wordlist[RES_CROS_MAX][DIC_WORD_MAX],
-                    Dawg_edge *edgeptr)
+                     char wordlist[RES_CROS_MAX][DIC_WORD_MAX],
+                     Dawg_edge *edgeptr)
 {
   Dawg_edge *current = params->dic->dawg + edgeptr->ptr;
 
@@ -380,10 +475,9 @@
 }
 
 
-
-void
-Dic_search_Cros(const Dictionary dic, const char* mask,
-                char wordlist[RES_CROS_MAX][DIC_WORD_MAX])
+static void
+Dic_search_Cros_inner(const Dictionary dic, const char* mask,
+                      char wordlist[RES_CROS_MAX][DIC_WORD_MAX])
 {
   int  i;
   struct params_cross_t params;
@@ -410,6 +504,31 @@
   Dic_search_cross_rec(&params, wordlist, dic->dawg + dic->root);
 }
 
+
+/**
+ * Wrapper around Dic_search_Cros_inner, until we have multibyte support in
+ * the dictionary
+ */
+void
+Dic_search_Cros(const Dictionary dic, const wchar_t* mask,
+                wchar_t wordlist[RES_CROS_MAX][DIC_WORD_MAX])
+{
+    int i, j;
+    char tmp_buff[RES_CROS_MAX][DIC_WORD_MAX];
+    char *tmp_mask = malloc(wcslen(mask) + 1);
+    sprintf(tmp_mask, "%ls", mask);
+    // Do the actual work
+    Dic_search_Cros_inner(dic, tmp_mask, tmp_buff);
+
+    for (i = 0; i < RES_CROS_MAX; i++)
+    {
+        for (j = 0; j < DIC_WORD_MAX; j++)
+        {
+            wordlist[i][j] = tmp_buff[i][j];
+        }
+    }
+}
+
 /****************************************/
 /****************************************/
 
@@ -466,13 +585,13 @@
      * function prototype for parser generated by bison
      */
 int  regexpparse(yyscan_t scanner, NODE** root,
-                struct search_RegE_list_t *list,
-                struct regexp_error_report_t *err);
+                 struct search_RegE_list_t *list,
+                 struct regexp_error_report_t *err);
 
 void
-Dic_search_RegE(const Dictionary dic, const char* re,
-                char wordlist[RES_REGE_MAX][DIC_WORD_MAX],
-               struct search_RegE_list_t *list)
+Dic_search_RegE_inner(const Dictionary dic, const char* re,
+                      char wordlist[RES_REGE_MAX][DIC_WORD_MAX],
+                      struct search_RegE_list_t *list)
 {
   int i,p,n,value;
   int ptl[REGEXP_MAX+1];
@@ -548,6 +667,31 @@
   regexp_delete_tree(root);
 }
 
+/**
+ * Wrapper around Dic_search_RegE_inner, until we have multibyte support in
+ * the dictionary
+ */
+void
+Dic_search_RegE(const Dictionary dic, const wchar_t* re,
+                wchar_t wordlist[RES_REGE_MAX][DIC_WORD_MAX],
+                struct search_RegE_list_t *list)
+{
+    int i, j;
+    char tmp_buff[RES_REGE_MAX][DIC_WORD_MAX];
+    char *tmp_re = malloc(wcslen(re) + 1);
+    sprintf(tmp_re, "%ls", re);
+    // Do the actual work
+    Dic_search_RegE_inner(dic, tmp_re, tmp_buff, list);
+
+    for (i = 0; i < RES_REGE_MAX; i++)
+    {
+        for (j = 0; j < DIC_WORD_MAX; j++)
+        {
+            wordlist[i][j] = tmp_buff[i][j];
+        }
+    }
+}
+
 /****************************************/
 /****************************************/
 
Index: eliot/dic/dic_search.h
diff -u eliot/dic/dic_search.h:1.11 eliot/dic/dic_search.h:1.12
--- eliot/dic/dic_search.h:1.11 Sun Jan  1 19:51:00 2006
+++ eliot/dic/dic_search.h      Sun Jan 22 12:23:53 2006
@@ -62,7 +62,8 @@
      * @param path : lookup word
      * @return 1 present, 0 error
      */
-int  Dic_search_word(Dictionary dic, const char* path);
+int  Dic_search_word(Dictionary dic,
+                     const wchar_t* path);
 
     /**
      * Search for all feasible word with "rack" plus one letter
@@ -70,7 +71,10 @@
      * @param rack : letters
      * @param wordlist : results
      */
-void Dic_search_7pl1(Dictionary dic, const char* rack, char 
wordlist[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX], int joker);
+void Dic_search_7pl1(Dictionary dic,
+                     const wchar_t* rack,
+                     wchar_t wordlist[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
+                     int joker);
 
     /**
      * Search for all feasible word adding a letter in front or at the end
@@ -78,7 +82,9 @@
      * @param word : word
      * @param wordlist : results
      */
-void Dic_search_Racc(Dictionary dic, const char* word, char 
wordlist[RES_RACC_MAX][DIC_WORD_MAX]);
+void Dic_search_Racc(Dictionary dic,
+                     const wchar_t* word,
+                     wchar_t wordlist[RES_RACC_MAX][DIC_WORD_MAX]);
 
     /**
      * Search for benjamins
@@ -86,7 +92,9 @@
      * @param rack : letters
      * @param wordlist : results
      */
-void Dic_search_Benj(Dictionary dic, const char* word, char 
wordlist[RES_BENJ_MAX][DIC_WORD_MAX]);
+void Dic_search_Benj(Dictionary dic,
+                     const wchar_t* word,
+                     wchar_t wordlist[RES_BENJ_MAX][DIC_WORD_MAX]);
 
     /**
      * Search for crosswords
@@ -94,7 +102,9 @@
      * @param rack : letters
      * @param wordlist : results
      */
-void Dic_search_Cros(Dictionary dic, const char* mask, char 
wordlist[RES_CROS_MAX][DIC_WORD_MAX]);
+void Dic_search_Cros(Dictionary dic,
+                     const wchar_t* mask,
+                     wchar_t wordlist[RES_CROS_MAX][DIC_WORD_MAX]);
 
     /**
      * Search for words matching a regular expression
@@ -102,7 +112,18 @@
      * @param re : regular expression
      * @param wordlist : results
      */
-void Dic_search_RegE(Dictionary dic, const char* re, char 
wordlist[RES_REGE_MAX][DIC_WORD_MAX], struct search_RegE_list_t *list);
+void Dic_search_RegE(Dictionary dic,
+                     const wchar_t* re,
+                     wchar_t wordlist[RES_REGE_MAX][DIC_WORD_MAX],
+                     struct search_RegE_list_t *list);
+
+    /**
+     * Internal version of Dic_search_RegE, used inside the dictionary.
+     * Please use Dic_search_RegE instead from outside the dic library.
+     */
+void Dic_search_RegE_inner(const Dictionary dic, const char* re,
+                           char wordlist[RES_REGE_MAX][DIC_WORD_MAX],
+                           struct search_RegE_list_t *list);
 
 #if defined(__cplusplus)
   }
Index: eliot/dic/listdic.c
diff -u eliot/dic/listdic.c:1.7 eliot/dic/listdic.c:1.8
--- eliot/dic/listdic.c:1.7     Sun Jan  1 19:51:00 2006
+++ eliot/dic/listdic.c Sun Jan 22 12:23:53 2006
@@ -156,7 +156,7 @@
   printf("0x%s nodes saved : %6d 
%s\n",offset(&header,&header.nodessaved),header.nodessaved,hexl(header.nodessaved));
   printf("0x%s edges saved : %6d 
%s\n",offset(&header,&header.edgessaved),header.edgessaved,hexl(header.edgessaved));
   printf("\n");
-  printf("sizeof(header) = 0x%s (%d)\n",hexb(sizeof(header)),sizeof(header));
+  printf("sizeof(header) = 0x%s (%lu)\n", hexb(sizeof(header)), 
sizeof(header));
 }
 
 void
Index: eliot/dic/regexpmain.c
diff -u eliot/dic/regexpmain.c:1.11 eliot/dic/regexpmain.c:1.12
--- eliot/dic/regexpmain.c:1.11 Sun Jan  1 19:51:00 2006
+++ eliot/dic/regexpmain.c      Sun Jan 22 12:23:53 2006
@@ -124,7 +124,7 @@
 
       /* automaton */
       init_letter_lists(&list);
-      Dic_search_RegE(dic,er,wordlist,&list);
+      Dic_search_RegE_inner(dic,er,wordlist,&list);
 
       fprintf(stdout,"résultat:\n");
       for(i=0; i<RES_REGE_MAX && wordlist[i][0]; i++)
Index: eliot/game/Makefile.am
diff -u eliot/game/Makefile.am:1.12 eliot/game/Makefile.am:1.13
--- eliot/game/Makefile.am:1.12 Sun Jan  1 19:36:16 2006
+++ eliot/game/Makefile.am      Sun Jan 22 12:23:53 2006
@@ -31,6 +31,7 @@
        board_cross.cpp                 \
        board_search.cpp                \
        duplicate.cpp duplicate.h       \
+       encoding.cpp encoding.h         \
        freegame.cpp freegame.h         \
        game.cpp game.h                 \
        game_factory.cpp game_factory.h \
Index: eliot/game/bag.cpp
diff -u eliot/game/bag.cpp:1.6 eliot/game/bag.cpp:1.7
--- eliot/game/bag.cpp:1.6      Sun Jan  1 19:49:35 2006
+++ eliot/game/bag.cpp  Sun Jan 22 12:23:53 2006
@@ -84,7 +84,7 @@
 void Bag::takeTile(const Tile &iTile)
 {
     ASSERT(in(iTile),
-           string("The bag does not contain the letter ") + iTile.toChar());
+           (wstring(L"The bag does not contain the letter ") + 
iTile.toChar()).c_str());
 
     m_tilesMap[iTile]--;
     m_ntiles--;
@@ -94,7 +94,7 @@
 void Bag::replaceTile(const Tile &iTile)
 {
     ASSERT(in(iTile) < iTile.maxNumber(),
-           string("Cannot replace tile: ") + iTile.toChar());
+           (wstring(L"Cannot replace tile: ") + iTile.toChar()).c_str());
 
     m_tilesMap[iTile]++;
     m_ntiles++;
Index: eliot/game/board.cpp
diff -u eliot/game/board.cpp:1.12 eliot/game/board.cpp:1.13
--- eliot/game/board.cpp:1.12   Sun Jan  1 19:49:35 2006
+++ eliot/game/board.cpp        Sun Jan 22 12:23:53 2006
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *****************************************************************************/
 
+#include <wctype.h>
 #include "dic.h"
 #include "tile.h"
 #include "round.h"
@@ -104,15 +105,15 @@
 }
 
 
-char Board::getChar(int iRow, int iCol) const
+wchar_t Board::getChar(int iRow, int iCol) const
 {
-    char letter = 0;
+    wchar_t letter = 0;
     Tile tile = getTile(iRow, iCol);
     if (!tile.isEmpty())
     {
         letter = tile.toChar();
         if (isJoker(iRow, iCol))
-            letter = tolower(letter);
+            letter = towlower(letter);
     }
     return letter;
 }
Index: eliot/game/board.h
diff -u eliot/game/board.h:1.11 eliot/game/board.h:1.12
--- eliot/game/board.h:1.11     Sun Jan  1 19:49:35 2006
+++ eliot/game/board.h  Sun Jan 22 12:23:53 2006
@@ -79,8 +79,8 @@
 #define ATTR_JOKER  1
 #define ATTR_TEST   2
 
-    char getChar    (int iRow, int iCol) const;
-    int  getCharAttr(int iRow, int iCol) const;
+    wchar_t getChar    (int iRow, int iCol) const;
+    int     getCharAttr(int iRow, int iCol) const;
 
     Tile getTile(int iRow, int iCol) const;
     bool isJoker(int iRow, int iCol) const;
Index: eliot/game/board_search.cpp
diff -u eliot/game/board_search.cpp:1.10 eliot/game/board_search.cpp:1.11
--- eliot/game/board_search.cpp:1.10    Sun Jan  1 19:37:57 2006
+++ eliot/game/board_search.cpp Sun Jan 22 12:23:53 2006
@@ -219,6 +219,12 @@
 {
     int row, col, lastanchor;
     Round partialword;
+
+    list<Tile> rackTiles;
+    iRack.getTiles(rackTiles);
+    list<Tile>::const_iterator it;
+    bool match;
+
     for (row = 1; row <= BOARD_DIM; row++)
     {
         partialword.init();
@@ -233,20 +239,35 @@
                  !iTilesMx[row - 1][col].isEmpty() ||
                  !iTilesMx[row + 1][col].isEmpty()))
             {
-                if (!iTilesMx[row][col - 1].isEmpty())
+                // Optimization compared to the original Appel & Jacobson
+                // algorithm: skip Leftpart if none of the tiles of the rack
+                // matches the cross mask for the current anchor
+                match = false;
+                for (it = rackTiles.begin();
+                     !match && it != rackTiles.end(); it++)
                 {
-                    partialword.accessCoord().setCol(lastanchor + 1);
-                    ExtendRight(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
-                                iJokerMx, iRack, partialword, iResults,
-                                Dic_root(iDic), row, lastanchor + 1, col);
+                    if (iCrossMx[row][col].check(*it))
+                    {
+                        match = true;
+                    }
                 }
-                else
+                if (match)
                 {
-                    partialword.accessCoord().setCol(col);
-                    LeftPart(iBoard, iDic, iTilesMx, iCrossMx, iPointsMx,
-                             iJokerMx, iRack, partialword, iResults,
-                             Dic_root(iDic), row, col, col -
-                             lastanchor - 1);
+                    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;
             }
Index: eliot/game/coord.cpp
diff -u eliot/game/coord.cpp:1.8 eliot/game/coord.cpp:1.9
--- eliot/game/coord.cpp:1.8    Sun Jan  1 19:49:35 2006
+++ eliot/game/coord.cpp        Sun Jan 22 12:23:53 2006
@@ -25,9 +25,11 @@
  */
 
 #include <string>
+#include <wchar.h>
 #include "coord.h"
 #include "board.h" // for BOARD_MIN and BOARD_MAX (TODO: remove this include)
 #include "debug.h"
+#include "encoding.h"
 
 
 Coord::Coord(int iRow, int iCol, Direction iDir)
@@ -37,7 +39,7 @@
     m_dir = iDir;
 }
 
-Coord::Coord(const string &iStr)
+Coord::Coord(const wstring &iStr)
 {
     setFromString(iStr);
 }
@@ -62,8 +64,13 @@
     m_row = tmp;
 }
 
-void Coord::setFromString(const string &iStr)
+
+void Coord::setFromString(const wstring &iWStr)
 {
+    // TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
+    // Temporary implementation: convert the wchar_t* string into a char* one
+    string iStr = convertToMb(iWStr);
+
     char l[4];
     int col;
 
@@ -85,34 +92,35 @@
     setRow(row);
 }
 
-string Coord::toString(coord_mode_t mode) const
+wstring Coord::toString(coord_mode_t mode) const
 {
     ASSERT(isValid(), "Invalid coordinates");
 
-    char res[7];
-    char srow[3];
-    char scol[3];
+    wchar_t res[7];
+    wchar_t srow[3];
+    wchar_t scol[3];
 
-    sprintf(scol, "%d", m_col);
-    sprintf(srow, "%c", m_row + 'A' - 1);
+    _swprintf(scol, 3, L"%d", m_col);
+    _swprintf(srow, 3, L"%c", m_row + 'A' - 1);
 
     switch (mode)
     {
     case COORD_MODE_COMPACT:
-       if (getDir() == HORIZONTAL)
-           sprintf(res,"%s%s",srow,scol);
-       else
-           sprintf(res,"%s%s",scol,srow);
-       break;
+        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)
-           sprintf(res,"%2s %2s",srow,scol);
-       else
-           sprintf(res,"%2s %2s",scol,srow);
-       break;
+        if (getDir() == HORIZONTAL)
+            _swprintf(res, 7, L"%2ls %2ls", srow, scol);
+        else
+            _swprintf(res, 7, L"%2ls %2ls", scol, srow);
+        break;
     }
 
-    return string(res);
+
+    return res;
 }
 
 /// Local Variables:
Index: eliot/game/coord.h
diff -u eliot/game/coord.h:1.6 eliot/game/coord.h:1.7
--- eliot/game/coord.h:1.6      Sun Jan  1 19:49:35 2006
+++ eliot/game/coord.h  Sun Jan 22 12:23:53 2006
@@ -28,6 +28,7 @@
 #define _COORD_H
 
 using std::string;
+using std::wstring;
 
 class Coord
 {
@@ -37,7 +38,7 @@
 
     // Construction, destruction
     Coord(int iRow = -1, int iCol = -1, Direction iDir = HORIZONTAL);
-    Coord(const string &iStr);
+    Coord(const wstring &iStr);
     virtual ~Coord() {}
 
     // Accessors
@@ -54,13 +55,14 @@
     // Swap the coordinates (without changing the direction)
     void swap();
 
-    void setFromString(const string &iStr);
 
-    typedef enum {
-       COORD_MODE_COMPACT,
-       COORD_MODE_LONG
-    } coord_mode_t;
-    string toString(coord_mode_t mode = COORD_MODE_COMPACT) const;
+    enum coord_mode_t
+    {
+        COORD_MODE_COMPACT,
+        COORD_MODE_LONG
+    };
+    void setFromString(const wstring &iStr);
+    wstring toString(coord_mode_t mode = COORD_MODE_COMPACT) const;
 
 private:
     Direction m_dir;
Index: eliot/game/cross.cpp
diff -u eliot/game/cross.cpp:1.5 eliot/game/cross.cpp:1.6
--- eliot/game/cross.cpp:1.5    Sun Jan  1 19:49:35 2006
+++ eliot/game/cross.cpp        Sun Jan 22 12:23:53 2006
@@ -22,45 +22,33 @@
 
 Cross::Cross()
 {
-    // the default behaviour is to match everything
+    // The default behaviour is to match everything
     m_any = true;
+    m_mask = 0xFFFFFFFF;
 }
 
 
 void Cross::clear()
 {
-    m_tilesSet.clear();
     m_any = false;
+    m_mask = 0;
 }
 
 
 bool Cross::check(const Tile& iTile) const
 {
-    if (m_any || (iTile.isJoker() && !m_tilesSet.empty()))
+    if (m_any || (iTile.isJoker() && m_mask != 0))
         return true;
-    set<Tile>::const_iterator it = m_tilesSet.find(iTile);
-    return it != m_tilesSet.end();
+    return m_mask & (1 << iTile.toCode());
 }
 
 
 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;
+    if (isAny() || iOther.isAny())
+        return isAny() && iOther.isAny();
+
+    return m_mask == iOther.m_mask;
 }
 
 /// Local Variables:
Index: eliot/game/cross.h
diff -u eliot/game/cross.h:1.6 eliot/game/cross.h:1.7
--- eliot/game/cross.h:1.6      Sun Jan  1 19:49:35 2006
+++ eliot/game/cross.h  Sun Jan 22 12:23:53 2006
@@ -20,8 +20,8 @@
 #ifndef _CROSS_H_
 #define _CROSS_H_
 
-#include "tile.h"
 #include <set>
+#include "tile.h"
 
 using namespace std;
 
@@ -44,15 +44,14 @@
     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 insert(const Tile& iTile)  { m_mask |= (1 << iTile.toCode()); }
     void clear();
 
 private:
-    // Set of the tiles accepted for the cross check
-    set<Tile> m_tilesSet;
+    /// Mask indicating which tiles are accepted for the cross check
+    unsigned int m_mask;
 
-    // When this value is true, any letter matches the cross check
+    /// When this value is true, any letter matches the cross check
     bool m_any;
 };
 
Index: eliot/game/duplicate.cpp
diff -u eliot/game/duplicate.cpp:1.15 eliot/game/duplicate.cpp:1.16
--- eliot/game/duplicate.cpp:1.15       Sun Jan  1 19:49:35 2006
+++ eliot/game/duplicate.cpp    Sun Jan 22 12:23:53 2006
@@ -50,7 +50,7 @@
 }
 
 
-int Duplicate::play(const string &iCoord, const string &iWord)
+int Duplicate::play(const wstring &iCoord, const wstring &iWord)
 {
     /* Perform all the validity checks, and fill a round */
     Round round;
Index: eliot/game/duplicate.h
diff -u eliot/game/duplicate.h:1.11 eliot/game/duplicate.h:1.12
--- eliot/game/duplicate.h:1.11 Sun Jan  1 19:49:35 2006
+++ eliot/game/duplicate.h      Sun Jan 22 12:23:53 2006
@@ -23,6 +23,7 @@
 #include "game.h"
 
 using std::string;
+using std::wstring;
 
 
 /**
@@ -58,7 +59,7 @@
      *************************/
     virtual int start();
     virtual int setRackRandom(int, bool, set_rack_mode);
-    virtual int play(const string &iCoord, const string &iWord);
+    virtual int play(const wstring &iCoord, const wstring &iWord);
     virtual int endTurn();
 
     int setPlayer(int);
Index: eliot/game/freegame.cpp
diff -u eliot/game/freegame.cpp:1.17 eliot/game/freegame.cpp:1.18
--- eliot/game/freegame.cpp:1.17        Sun Jan  1 19:49:35 2006
+++ eliot/game/freegame.cpp     Sun Jan 22 12:23:53 2006
@@ -18,6 +18,7 @@
  *****************************************************************************/
 
 #include <iomanip>
+#include <wctype.h>
 #include "dic.h"
 #include "tile.h"
 #include "rack.h"
@@ -52,7 +53,7 @@
 }
 
 
-int FreeGame::play(const string &iCoord, const string &iWord)
+int FreeGame::play(const wstring &iCoord, const wstring &iWord)
 {
     /* Perform all the validity checks, and fill a round */
     Round round;
@@ -188,7 +189,7 @@
 }
 
 
-int FreeGame::pass(const string &iToChange, int n)
+int FreeGame::pass(const wstring &iToChange, int n)
 {
     if (m_finished)
         return 3;
@@ -204,7 +205,7 @@
     vector<Tile> tilesVect;
     for (unsigned int i = 0; i < iToChange.size(); i++)
     {
-        Tile tile(toupper(iToChange[i]));
+        Tile tile(towupper(iToChange[i]));
         tilesVect.push_back(tile);
     }
 
Index: eliot/game/freegame.h
diff -u eliot/game/freegame.h:1.10 eliot/game/freegame.h:1.11
--- eliot/game/freegame.h:1.10  Sun Jan  1 19:49:35 2006
+++ eliot/game/freegame.h       Sun Jan 22 12:23:53 2006
@@ -24,6 +24,7 @@
 #include "tile.h"
 
 using std::string;
+using std::wstring;
 using std::vector;
 
 
@@ -49,9 +50,9 @@
      *************************/
     virtual int start();
     virtual int setRackRandom(int, bool, set_rack_mode);
-    virtual int play(const string &iCoord, const string &iWord);
+    virtual int play(const wstring &iCoord, const wstring &iWord);
     virtual int endTurn();
-    int pass(const string &iToChange, int n);
+    int pass(const wstring &iToChange, int n);
 
 private:
     // Private constructor and destructor to force using the GameFactory class
Index: eliot/game/game.cpp
diff -u eliot/game/game.cpp:1.28 eliot/game/game.cpp:1.29
--- eliot/game/game.cpp:1.28    Sun Jan  1 19:48:36 2006
+++ eliot/game/game.cpp Sun Jan 22 12:23:53 2006
@@ -30,6 +30,7 @@
 #include "game.h"
 #include "game_factory.h"
 #include "turn.h"
+#include "encoding.h"
 
 #include "debug.h"
 
@@ -156,8 +157,8 @@
 
     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);
     for (i = 0; i < n; i++)
@@ -167,7 +168,8 @@
             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",
+                  convertToMb(lastround.toString()).c_str());
             /* Remove the word from the board, and put its letters back
              * into the bag */
             m_board.removeRound(*m_dic, lastround);
@@ -184,8 +186,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
@@ -411,7 +413,7 @@
 /**
  * Set the rack of the player p manually.
  */
-int Game::helperSetRackManual(int p, bool iCheck, const string &iLetters)
+int Game::helperSetRackManual(int p, bool iCheck, const wstring &iLetters)
 {
     int min, ret;
 
@@ -513,8 +515,8 @@
  * 10: first word not horizontal
  * 11: first word not covering the H8 square
  */
-int Game::checkPlayedWord(const string &iCoord,
-                          const string &iWord, Round &oRound)
+int Game::checkPlayedWord(const wstring &iCoord,
+                          const wstring &iWord, Round &oRound)
 {
     ASSERT(getNPlayers() != 0, "Expected at least one player");
 
Index: eliot/game/game.h
diff -u eliot/game/game.h:1.27 eliot/game/game.h:1.28
--- eliot/game/game.h:1.27      Sun Jan  1 19:48:36 2006
+++ eliot/game/game.h   Sun Jan 22 12:23:53 2006
@@ -143,7 +143,7 @@
      *************************/
     static const int RACK_SIZE;
     enum set_rack_mode {RACK_ALL, RACK_NEW, RACK_MANUAL};
-    int setRack(int player, set_rack_mode mode, bool check, const string& str);
+    int setRack(int player, set_rack_mode mode, bool check, const wstring& 
str);
 
     /**
      * Methods to access already played words.
@@ -166,7 +166,7 @@
      * Game handling
      */
     virtual int start() = 0;
-    virtual int play(const string &iCoord, const string &iWord) = 0;
+    virtual int play(const wstring &iCoord, const wstring &iWord) = 0;
     virtual int endTurn() = 0;
 
 protected:
@@ -206,14 +206,14 @@
 
     int helperPlayRound(const Round &iRound);
     int helperSetRackRandom(int p, bool iCheck, set_rack_mode mode);
-    int helperSetRackManual(int p, bool iCheck, const string &iLetters);
+    int helperSetRackManual(int p, bool iCheck, const wstring &iLetters);
 
     void prevPlayer();
     void nextPlayer();
     bool rackInBag(const Rack &iRack, const Bag &iBag) const;
     void realBag(Bag &iBag) const;
-    int  checkPlayedWord(const string &iCoord,
-                         const string &iWord, Round &oRound);
+    int  checkPlayedWord(const wstring &iCoord,
+                         const wstring &iWord, Round &oRound);
 
     /**
      * load games from File using the first format.
Index: eliot/game/game_io.cpp
diff -u eliot/game/game_io.cpp:1.2 eliot/game/game_io.cpp:1.3
--- eliot/game/game_io.cpp:1.2  Sun Jan  1 19:36:16 2006
+++ eliot/game/game_io.cpp      Sun Jan 22 12:23:53 2006
@@ -31,6 +31,7 @@
 #include "player.h"
 #include "game.h"
 #include "game_factory.h"
+#include "encoding.h"
 #include "debug.h"
 
 using namespace std;
@@ -78,16 +79,16 @@
     }
 
     if ((token = strtok(NULL, delim)) == NULL)
-      {
-       debug("Game_io::loading file format 1.4\n");
-       return Game::gameLoadFormat_14(fin,iDic);
-      }
+    {
+        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_io::loading file format 1.5\n");
+        return Game::gameLoadFormat_15(fin,iDic);
+    }
 
     debug("Game::load unknown format %s\n",token);
     return NULL;
@@ -109,65 +110,66 @@
 
      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))
+     while (fgets(buff, sizeof(buff), fin))
      {
-         token = strtok(buff,delim);
+         token = strtok(buff, delim);
          if (token != NULL)
          {
-             if (strcmp(token,"total")==0)
+             if (strcmp(token, "total") == 0)
              {
                  break;
              }
 
              /* rack */
-             strncpy(rack,token,sizeof(rack));
-             ((Training*)pGame)->setRack(RACK_MANUAL,false,string(rack));
-             debug("%s ",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)
+             token = strtok(NULL, delim);
+             if (!token || strcmp(token, "total") == 0)
              {
                  break;
              }
 
-             strncpy(word,token,sizeof(word));
-             debug("\t%s ",word);
+             strncpy(word, token, sizeof(word));
+             debug("\t%s ", word);
 
              /* bonus */
-             if ((token = strtok(NULL,delim)) == NULL)
+             if ((token = strtok(NULL, delim)) == NULL)
                  break;
 
              /* points */
-             if (token[0]=='*')
+             if (token[0] == '*')
              {
-                 debug("%s\t",token);
-                 if ((token = strtok(NULL,delim)) == NULL)
+                 debug("%s\t", token);
+                 if ((token = strtok(NULL, delim)) == NULL)
                      break;
              }
 
              /* pos 1 */
-             if ((token = strtok(NULL,delim)) == NULL)
+             if ((token = strtok(NULL, delim)) == NULL)
                  break;
 
-             debug("(%s ",token);
-             strncpy(pos,token,sizeof(pos));
+             debug("(%s ", token);
+             strncpy(pos, token, sizeof(pos));
 
              /* pos 2 */
-             if ((token = strtok(NULL,delim)) == NULL)
+             if ((token = strtok(NULL, delim)) == NULL)
                  break;
 
-             debug("%s)",token);
-             strncat(pos,token,sizeof(pos));
-             debug("%s\n",pos);
+             debug("%s)", token);
+             strncat(pos, token, sizeof(pos));
+             debug("%s\n", pos);
 
-             debug("   play %s %s\n",pos, word);
-            pGame->play(string(pos),string(word));
+             debug("   play %s %s\n", pos, word);
+             pGame->play(convertToWc(pos), convertToWc(word));
          }
      }
      return pGame;
@@ -263,7 +265,7 @@
                     {
                         debug("   add Computer player\n");
                         pGame->addAIPlayer();
-                    }    
+                    }
                 }
                 else
                 {
@@ -312,101 +314,101 @@
         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("   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;
-            }
+        {
+            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;
-            }
+        {
+            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;
-            }
-        
+        {
+            debug("   Game::load15 line -%s- wring bonus sign\n",buff);
+            continue;
+        }
+
         // Build a rack for the correct player
         PlayedRack pldrack;
-        if ((res = pldrack.setManual(string(rack))) > 0)
+        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());
+        debug("    history rack %s\n", 
convertToMb(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++)
             {
-                // 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);
-                            }
-                    }
+                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++)
             {
-                // 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);
-                            }
-                    }
+                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);
     }
@@ -425,15 +427,15 @@
         {
             // Create the played rack
             PlayedRack pldrack;
-            pldrack.setManual(string(letters));
+            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)
     {
@@ -461,13 +463,13 @@
 void Game::save(ostream &out, game_file_format format) const
 {
     if (getMode() == kTRAINING && format == FILE_FORMAT_STANDARD)
-       {
-           gameSaveFormat_14(out);
-       }
+    {
+        gameSaveFormat_14(out);
+    }
     else
-       {
-           gameSaveFormat_15(out);
-       }
+    {
+        gameSaveFormat_15(out);
+    }
 }
 
 
@@ -479,25 +481,25 @@
     out << IDENT_STRING << endl << endl;
 
     for(i = 0; i < m_history.getSize(); i++)
-       {
-           const Turn& turn = m_history.getTurn(i);
-            string rack = 
turn.getPlayedRack().toString(PlayedRack::RACK_EXTRA);
-            string word = turn.getRound().getWord();
-            string coord = 
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()
-                    );
+    {
+        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 << decal << line << endl;
+    }
 
     out << endl;
     out << decal << "total" << string(24,' ');
@@ -532,18 +534,19 @@
     // Print the game itself
     for (int i = 0; i < m_history.getSize(); i++)
     {
-       const Turn& turn = m_history.getTurn(i);
-        string word = turn.getRound().getWord();
-        string coord = turn.getRound().getCoord().toString();
+        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,
-               turn.getPlayedRack().toString().c_str(),    /* pldrack     */
-               word.c_str(),                               /* word        */
+                rack.c_str(),                               /* pldrack     */
+                word.c_str(),                               /* word        */
                 string(15 - word.size(), ' ').c_str(),      /* fill spaces */
                 coord.c_str(),                              /* coord       */
-               turn.getRound().getPoints(),
+                turn.getRound().getPoints(),
                 turn.getPlayer(),
-               turn.getRound().getBonus() ? '*' : ' ');
+                turn.getRound().getBonus() ? '*' : ' ');
 
         out << decal << line << endl;
     }
@@ -566,8 +569,8 @@
     out << endl;
     for (int i = 0; i < getNPlayers(); i++)
     {
-        string rack = m_players[i]->getCurrentRack().toString();
-        out << "Rack " << i << ": " << rack << endl;
+        wstring rack = m_players[i]->getCurrentRack().toString();
+        out << "Rack " << i << ": " << convertToMb(rack) << endl;
     }
 }
 
Index: eliot/game/history.cpp
diff -u eliot/game/history.cpp:1.9 eliot/game/history.cpp:1.10
--- eliot/game/history.cpp:1.9  Sun Jan  1 19:49:35 2006
+++ eliot/game/history.cpp      Sun Jan 22 12:23:53 2006
@@ -29,8 +29,10 @@
 #include "pldrack.h"
 #include "round.h"
 #include "turn.h"
-#include "debug.h"
 #include "history.h"
+#include "encoding.h"
+#include "debug.h"
+
 
 /* ******************************************************** */
 /* ******************************************************** */
@@ -154,19 +156,18 @@
 }
 
 
-string History::toString() const
+wstring History::toString() const
 {
-    unsigned int i;
-    string rs = "";
+    wstring rs;
 #ifdef DEBUG
-    char buff[20];
-    sprintf(buff,"%d",m_history.size());
-    rs = "history size = " + string(buff) + "\n\n";
+    wchar_t buff[5];
+    _swprintf(buff, 4, L"%ld", m_history.size());
+    rs = L"history size = " + wstring(buff) + L"\n\n";
 #endif
-    for (i = 0; i < m_history.size(); i++)
+    for (unsigned int i = 0; i < m_history.size(); i++)
     {
         Turn *t = m_history[i];
-        rs += t->toString() + string("\n");
+        rs += t->toString() + L"\n";
     }
     return rs;
 }
Index: eliot/game/history.h
diff -u eliot/game/history.h:1.10 eliot/game/history.h:1.11
--- eliot/game/history.h:1.10   Mon Jan  2 19:05:37 2006
+++ eliot/game/history.h        Sun Jan 22 12:23:53 2006
@@ -30,14 +30,13 @@
 #include <string>
 #include <vector>
 
-using std::string;
+using std::wstring;
 using std::vector;
 
 class Round;
 class Turn;
 class PlayedRack;
 
-
 /**
  * History stores all the turns that have been played
  * This class is used many times in the game
@@ -89,7 +88,7 @@
     void removeLastTurn();
 
     /// String handling
-    string toString() const;
+    wstring toString() const;
 
  private:
     vector<Turn*> m_history;
Index: eliot/game/player.cpp
diff -u eliot/game/player.cpp:1.13 eliot/game/player.cpp:1.14
--- eliot/game/player.cpp:1.13  Sun Jan  1 19:49:35 2006
+++ eliot/game/player.cpp       Sun Jan 22 12:23:53 2006
@@ -26,6 +26,7 @@
 #include "player.h"
 #include "turn.h"
 #include "history.h"
+#include "encoding.h"
 
 #include "debug.h"
 
@@ -76,17 +77,16 @@
     m_history.removeLastTurn();
 }
 
-const string Player::toString() const
+wstring Player::toString() const
 {
-    char buff[20];
-    string res;
+    wstring res;
 
-    sprintf(buff,"Player %d\n",m_id);
-    res = string(buff);
-    res += m_history.toString();
-    res += "\n";
-    sprintf(buff,"score %d\n",m_score);
-    res += string(buff);
+    wchar_t buff[6];
+    _swprintf(buff, 5, L"Player %d\n", m_id);
+    res = wstring(buff);
+    res += m_history.toString() + L"\n";
+    _swprintf(buff, 5, L"score %d\n", m_score);
+    res += wstring(buff);
     return res;
 }
 
Index: eliot/game/player.h
diff -u eliot/game/player.h:1.17 eliot/game/player.h:1.18
--- eliot/game/player.h:1.17    Sun Jan  1 19:49:35 2006
+++ eliot/game/player.h Sun Jan 22 12:23:53 2006
@@ -69,7 +69,7 @@
     // A new rack is created with the remaining letters
     void endTurn(const Round &iRound, int iTurn);
 
-    const string toString() const;
+    wstring toString() const;
 
 private:
     /// ID of the player
Index: eliot/game/pldrack.cpp
diff -u eliot/game/pldrack.cpp:1.8 eliot/game/pldrack.cpp:1.9
--- eliot/game/pldrack.cpp:1.8  Sun Jan  1 19:47:26 2006
+++ eliot/game/pldrack.cpp      Sun Jan 22 12:23:53 2006
@@ -147,7 +147,7 @@
     }
 }
 
-int PlayedRack::setManual(const string& iLetters)
+int PlayedRack::setManual(const wstring& iLetters)
 {
     unsigned int i;
     reset();
@@ -157,17 +157,17 @@
         return 0; /* empty is ok */
     }
 
-    for (i = 0; i < iLetters.size() && iLetters[i] != '+'; i++)
+    for (i = 0; i < iLetters.size() && iLetters[i] != L'+'; i++)
     {
         Tile tile(iLetters[i]);
         if (tile.isEmpty())
         {
-            return 1; /* */ 
+            return 1; /* */
         }
         addOld(tile);
     }
 
-    if (i < iLetters.size() && iLetters[i] == '+')
+    if (i < iLetters.size() && iLetters[i] == L'+')
     {
         for (i++; i < iLetters.size(); i++)
         {
@@ -210,33 +210,33 @@
 }
 
 
-string PlayedRack::toString(display_mode mode) const
+wstring PlayedRack::toString(display_mode mode) const
 {
-    string s("");
+    wstring s;
     vector<Tile>::const_iterator it;
-  
+
     if (nOld() > 0)
     {
-       for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
-           s += it->toChar();
+        for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
+            s += it->toChar();
     }
 
     if (mode > RACK_SIMPLE && nOld() > 0 && nNew() > 0)
     {
-       s += "+";
+        s += L"+";
     }
 
     if (mode > RACK_EXTRA  && reject)
     {
-       s += "-";
-       // nouveau tirage : rejet
-       // pas après un scrabble
+        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();
+        for (it = m_newTiles.begin(); it != m_newTiles.end(); it++)
+            s += it->toChar();
     }
 
     return s;
Index: eliot/game/pldrack.h
diff -u eliot/game/pldrack.h:1.11 eliot/game/pldrack.h:1.12
--- eliot/game/pldrack.h:1.11   Sun Jan  1 19:47:26 2006
+++ eliot/game/pldrack.h        Sun Jan 22 12:23:53 2006
@@ -58,7 +58,7 @@
 
     void setOld(const Rack &iRack);
     void setNew(const Rack &iRack);
-    int  setManual(const string& iLetters);
+    int  setManual(const wstring& iLetters);
 
     int nTiles() const  { return nNew() + nOld(); }
     int nNew() const    { return m_newTiles.size(); }
@@ -74,12 +74,13 @@
 
     void operator=(const PlayedRack &iOther);
 
-    typedef enum {
-      RACK_SIMPLE,
-      RACK_EXTRA,
-      RACK_DEBUG
-    } display_mode;
-    string toString(display_mode iShowExtraSigns = RACK_EXTRA) const;
+    enum display_mode
+    {
+        RACK_SIMPLE,
+        RACK_EXTRA,
+        RACK_DEBUG
+    };
+    wstring toString(display_mode iShowExtraSigns = RACK_EXTRA) const;
 
 private:
     bool reject;
Index: eliot/game/rack.cpp
diff -u eliot/game/rack.cpp:1.6 eliot/game/rack.cpp:1.7
--- eliot/game/rack.cpp:1.6     Sun Jan  1 19:47:03 2006
+++ eliot/game/rack.cpp Sun Jan 22 12:23:53 2006
@@ -26,35 +26,61 @@
  */
 
 #include "rack.h"
+#include "encoding.h"
+#include "debug.h"
 
+// FIXME: should not be here (duplicated from tile.cpp)
+#define TILES_NUMBER 28
+#define MIN_CODE 1
+
+
+Rack::Rack()
+    : m_tiles(TILES_NUMBER, 0), m_ntiles(0)
+{
+}
 
 void Rack::remove(const Tile &t)
 {
-    multiset<Tile>::const_iterator it = m_tiles.find(t);
-    if (it != m_tiles.end())
-        m_tiles.erase(it);
+    ASSERT(in(t),
+           "The rack does not contain the letter " + convertToMb(t.toChar()));
+    m_tiles[t.toCode()]--;
+    m_ntiles--;
+}
+
+
+void Rack::clear()
+{
+    for (unsigned int i = 0; i < m_tiles.size(); i++)
+    {
+        m_tiles[i] = 0;
+    }
+    m_ntiles = 0;
 }
 
 
 void Rack::getTiles(list<Tile> &oTiles) const
 {
-    multiset<Tile>::const_iterator it;
-    for (it = m_tiles.begin(); it != m_tiles.end(); it++)
+    for (unsigned int i = MIN_CODE; i < m_tiles.size(); i++)
     {
-        oTiles.push_back(*it);
+        for (unsigned int j = 0; j < m_tiles[i]; j++)
+        {
+            oTiles.push_back(Tile::GetTileFromCode(i));
+        }
     }
 }
 
 
-string Rack::toString()
+wstring Rack::toString()
 {
-  string rs("");
-  multiset<Tile>::const_iterator it;
-  for (it = m_tiles.begin(); it != m_tiles.end(); it++)
+    wstring rs;
+    for (unsigned int i = MIN_CODE; i < m_tiles.size(); i++)
     {
-      rs += it->toChar();
+        for (unsigned int j = 0; j < m_tiles[i]; j++)
+        {
+            rs += Tile::GetTileFromCode(i).toChar();
+        }
     }
-  return rs;
+    return rs;
 }
 
 /// Local Variables:
Index: eliot/game/rack.h
diff -u eliot/game/rack.h:1.8 eliot/game/rack.h:1.9
--- eliot/game/rack.h:1.8       Sun Jan  1 19:47:03 2006
+++ eliot/game/rack.h   Sun Jan 22 12:23:53 2006
@@ -43,22 +43,24 @@
 class Rack
 {
 public:
-    Rack() {}
+    Rack();
     virtual ~Rack() {}
 
-    int nTiles() const          { return m_tiles.size(); }
+    int nTiles() const          { return m_ntiles; }
     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); }
+    unsigned int in(const Tile &t) const { return m_tiles[t.toCode()]; }
+    void add(const Tile &t)     { m_tiles[t.toCode()]++; m_ntiles++; }
     void remove(const Tile &t);
-    void clear()                { m_tiles.clear(); }
+    void clear();
     void getTiles(list<Tile> &oTiles) const;
 
-    string toString();
+    wstring toString();
 
 private:
-    multiset<Tile> m_tiles;
+    /// Vector indexed by tile codes, containing the number of tiles
+    vector<unsigned int> m_tiles;
+    int m_ntiles;
 };
 
 #endif
Index: eliot/game/round.cpp
diff -u eliot/game/round.cpp:1.9 eliot/game/round.cpp:1.10
--- eliot/game/round.cpp:1.9    Sun Jan  1 19:49:35 2006
+++ eliot/game/round.cpp        Sun Jan 22 12:23:53 2006
@@ -19,8 +19,10 @@
  *****************************************************************************/
 
 #include <string>
+#include <wctype.h>
 #include "tile.h"
 #include "round.h"
+#include "encoding.h"
 
 
 #define FROMBOARD 0x1
@@ -141,34 +143,34 @@
     m_tileOrigin.pop_back();
 }
 
-string Round::getWord() const
+wstring Round::getWord() const
 {
-  char c;
-  string s;
+    wchar_t c;
+    wstring s;
 
-  for (int i = 0; i < getWordLen(); i++)
+    for (int i = 0; i < getWordLen(); i++)
     {
-      c = getTile(i).toChar();
-      if (isJoker(i))
-        c = tolower(c);
-      s += c;
+        c = getTile(i).toChar();
+        if (isJoker(i))
+            c = towlower(c);
+        s += c;
     }
-  return s;
+    return s;
 }
 
-string Round::toString() const
+wstring Round::toString() const
 {
-    char buff[5];
-    string rs(" ");
+    wstring rs = L" ";
 
     if (getWord().size() > 0)
     {
         rs  = getWord();
-        rs += string(16 - getWord().size(), ' ');
-        rs += getBonus() ? '*' : ' ';
-        sprintf(buff,"%4d",getPoints());
+        rs += wstring(16 - getWord().size(), ' ');
+        rs += getBonus() ? L'*' : L' ';
+        wchar_t buff[5];
+        _swprintf(buff, 4, L"%d", getPoints());
         rs += buff;
-        rs += " " + getCoord().toString();
+        rs += L" " + getCoord().toString();
     }
 
     return rs;
Index: eliot/game/round.h
diff -u eliot/game/round.h:1.11 eliot/game/round.h:1.12
--- eliot/game/round.h:1.11     Sun Jan  1 19:49:35 2006
+++ eliot/game/round.h  Sun Jan 22 12:23:53 2006
@@ -70,19 +70,20 @@
     bool isJoker         (int iIndex) const;
     bool isPlayedFromRack(int iIndex) const;
     const Tile& getTile  (int iIndex) const;
-    
-    string getWord() const;
-    int getWordLen() const;
-    int getPoints()  const        { return m_points; }
-    int getBonus()   const        { return m_bonus; }
+
+    wstring getWord() const;
+    int getWordLen()  const;
+    int getPoints()   const       { return m_points; }
+    int getBonus()    const       { return m_bonus; }
 
     /*************************
      * Coordinates
      *************************/
     const Coord& getCoord() const { return m_coord; }
     Coord& accessCoord()          { return m_coord; }
-    
-    string toString() const;
+
+
+    wstring toString() const;
 
 private:
     vector<Tile> m_word;
Index: eliot/game/tile.cpp
diff -u eliot/game/tile.cpp:1.6 eliot/game/tile.cpp:1.7
--- eliot/game/tile.cpp:1.6     Sun Jan  1 19:49:35 2006
+++ eliot/game/tile.cpp Sun Jan 22 12:23:53 2006
@@ -18,7 +18,8 @@
  *****************************************************************************/
 
 #include "tile.h"
-#include <ctype.h>
+#include <wctype.h>
+
 
 /*************************
  * French tiles
@@ -66,30 +67,35 @@
 /***************************
  ***************************/
 
-list<Tile> Tile::m_tilesList;
 const Tile Tile::m_TheJoker(TILE_JOKER);
 const Tile Tile::m_TheDummy(0);
+list<Tile> Tile::m_tilesList;
+vector<Tile> Tile::m_tilesVect(TILES_NUMBER, Tile::dummy());
+bool Tile::m_vectInitialized(false);
 
 
-Tile::Tile(char c)
+Tile::Tile(wchar_t c)
 {
     if (c == TILE_JOKER)
     {
         m_joker = true;
         m_dummy = false;
         m_char = TILE_JOKER;
+        m_code = 27;
     }
     else if (isalpha(c))
     {
         m_joker = islower(c);
         m_dummy = false;
-        m_char = toupper(c);
+        m_char = towupper(c);
+        m_code = m_char - 'A' + 1;
     }
     else
     {
         m_joker = false;
         m_dummy = true;
         m_char = 0;
+        m_code = 0;
     }
 }
 
@@ -147,27 +153,37 @@
 }
 
 
-char Tile::toChar() const
+const Tile& Tile::GetTileFromCode(unsigned int iCode)
+{
+    if (!m_vectInitialized)
+    {
+        // XXX: this should be filled from a "language file" instead
+        for (char i = TILE_IDX_START; i <= TILE_IDX_END; i++)
+            Tile::m_tilesVect[i] = Tile(i + 'A' - TILE_IDX_START);
+        m_tilesVect[TILE_IDX_JOKER] = Tile::Joker();
+        m_vectInitialized = true;
+    }
+    return Tile::m_tilesVect[iCode];
+}
+
+
+wchar_t Tile::toChar() const
 {
     if (m_dummy)
         return TILE_DUMMY;
     if (m_joker)
     {
-        if (isalpha(m_char))
-            return tolower(m_char);
+        if (iswalpha(m_char))
+            return towlower(m_char);
         else
             return TILE_JOKER;
     }
     return m_char;
 }
 
-int Tile::toCode() const
+unsigned int Tile::toCode() const
 {
-    if (m_dummy)
-        return TILE_IDX_DUMMY;
-    if (m_joker)
-        return TILE_IDX_DUMMY;
-    return (TILE_IDX_START + m_char - TILE_START);
+    return m_code;
 }
 
 bool Tile::operator <(const Tile &iOther) const
Index: eliot/game/tile.h
diff -u eliot/game/tile.h:1.7 eliot/game/tile.h:1.8
--- eliot/game/tile.h:1.7       Sun Jan  1 19:49:35 2006
+++ eliot/game/tile.h   Sun Jan 22 12:23:53 2006
@@ -21,9 +21,11 @@
 #define _TILE_H_
 
 #include <list>
+#include <vector>
 
 using namespace std;
 
+
 /*************************
  * A Tile is the internal representation
  * used within the game library to
@@ -39,7 +41,7 @@
   // - we need to pay attention when inserting character taken
   //   from user input
 
-    Tile(char c = 0);
+    Tile(wchar_t c = 0);
     virtual ~Tile() {}
 
     bool isEmpty() const        { return m_dummy; }
@@ -48,28 +50,39 @@
     bool isConsonant() const;
     unsigned int maxNumber() const;
     unsigned int getPoints() const;
-    char toChar() const;
-    int toCode() const;
+    wchar_t toChar() const;
+    unsigned int toCode() const;
 
     static const Tile &dummy()  { return m_TheDummy; }
     static const Tile &Joker()  { return m_TheJoker; }
     static const list<Tile>& getAllTiles();
+    static const Tile &GetTileFromCode(unsigned int iCode);
 
     bool operator <(const Tile &iOther) const;
     bool operator ==(const Tile &iOther) const;
     bool operator !=(const Tile &iOther) const;
 
 private:
-    char m_char;
+    wchar_t m_char;
     bool m_joker;
     bool m_dummy;
 
+    /**
+     * Internal code, used in the dictionary to represent the letter.
+     * It is mainly used by the Cross class.
+     */
+    int m_code;
+
     // Special tiles are declared static
     static const Tile m_TheJoker;
     static const Tile m_TheDummy;
 
-    // List of available tiles
+    /// List of available tiles
     static list<Tile> m_tilesList;
+    /// Vector of tiles indexed by their code, for fast look-up
+    static vector<Tile> m_tilesVect;
+    /// True when m_tilesVect is correctly initialized
+    static bool m_vectInitialized;
 };
 
 #endif
Index: eliot/game/training.cpp
diff -u eliot/game/training.cpp:1.15 eliot/game/training.cpp:1.16
--- eliot/game/training.cpp:1.15        Sun Jan  1 19:49:35 2006
+++ eliot/game/training.cpp     Sun Jan 22 12:23:53 2006
@@ -25,6 +25,7 @@
 #include "pldrack.h"
 #include "player.h"
 #include "training.h"
+#include "encoding.h"
 
 #include "debug.h"
 
@@ -58,21 +59,21 @@
     return res;
 }
 
-int Training::setRackManual(bool iCheck, const string &iLetters)
+int Training::setRackManual(bool iCheck, const wstring &iLetters)
 {
     int res;
     int p = m_currPlayer;
-    string::iterator it;
-    string uLetters; // uppercase letters
+    wstring::iterator it;
+    wstring uLetters; // uppercase letters
     // letters can be lowercase or uppercase as they are
     // coming from user input. We do not consider a lowercase
     // letter to be a joker which has been assigned to a letter.
     m_results.clear();
     uLetters = iLetters;
-    for(it = uLetters.begin(); it != uLetters.end(); it ++)
-      {
-       *it = toupper(*it);
-      }
+    for (it = uLetters.begin(); it != uLetters.end(); it ++)
+    {
+        *it = towupper(*it);
+    }
     res = helperSetRackManual(p, iCheck, uLetters);
     // 0 : ok
     // 1 : not enough tiles
@@ -80,25 +81,25 @@
     return res;
 }
 
-int Training::setRack(set_rack_mode iMode, bool iCheck, const string &iLetters)
+int Training::setRack(set_rack_mode iMode, bool iCheck, const wstring 
&iLetters)
 {
     int res = 0;
     switch(iMode)
-       {
-       case RACK_MANUAL:
-           res = setRackManual(iCheck, iLetters);
-           break;
-       case RACK_ALL:
-           res = setRackRandom(iCheck, iMode);
-           break;
-       case RACK_NEW:
-           res = setRackRandom(iCheck, iMode);
-           break;
-       }
+    {
+        case RACK_MANUAL:
+            res = setRackManual(iCheck, iLetters);
+            break;
+        case RACK_ALL:
+            res = setRackRandom(iCheck, iMode);
+            break;
+        case RACK_NEW:
+            res = setRackRandom(iCheck, iMode);
+            break;
+    }
     return res;
 }
 
-int Training::play(const string &iCoord, const string &iWord)
+int Training::play(const wstring &iCoord, const wstring &iWord)
 {
     /* Perform all the validity checks, and fill a round */
     Round round;
@@ -147,7 +148,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", convertToMb(r.toString()).c_str());
     m_results.search(*m_dic, m_board, r, m_history.getSize());
 }
 
@@ -204,7 +205,7 @@
     m_testRound = Round();
 }
 
-std::string Training::getTestPlayWord() const
+wstring Training::getTestPlayWord() const
 {
     return m_testRound.getWord();
 }
Index: eliot/game/training.h
diff -u eliot/game/training.h:1.14 eliot/game/training.h:1.15
--- eliot/game/training.h:1.14  Sun Jan  1 19:49:35 2006
+++ eliot/game/training.h       Sun Jan 22 12:23:53 2006
@@ -27,6 +27,7 @@
 #include "results.h"
 
 using std::string;
+using std::wstring;
 
 
 /**
@@ -47,14 +48,14 @@
      * Game handling
      *************************/
     virtual int start();
-    virtual int play(const string &iCoord, const string &iWord);
+    virtual int play(const wstring &iCoord, const wstring &iWord);
     virtual int endTurn();
     void search();
     int playResult(int);
 
     int setRackRandom(bool, set_rack_mode);
-    int setRackManual(bool iCheck, const string &iLetters);
-    int setRack(set_rack_mode iMode, bool iCheck, const string &iLetters);
+    int setRackManual(bool iCheck, const wstring &iLetters);
+    int setRack(set_rack_mode iMode, bool iCheck, const wstring &iLetters);
 
     /*************************
      * Override the default behaviour of these methods, because in training
@@ -74,7 +75,7 @@
     /// Remove the temporary word(s)
     void removeTestPlay();
     /// Get the temporary word
-    string getTestPlayWord() const;
+    wstring getTestPlayWord() const;
 
 private:
     // Private constructor and destructor to force using the GameFactory class
Index: eliot/game/turn.cpp
diff -u eliot/game/turn.cpp:1.10 eliot/game/turn.cpp:1.11
--- eliot/game/turn.cpp:1.10    Sun Jan  1 19:49:35 2006
+++ eliot/game/turn.cpp Sun Jan 22 12:23:53 2006
@@ -54,14 +54,14 @@
 }
 #endif
 
-string Turn::toString(bool iShowExtraSigns) const
+wstring Turn::toString(bool iShowExtraSigns) const
 {
-    string rs = "";
+    wstring rs = L"";
     if (iShowExtraSigns)
     {
-        rs = ""; // TODO
+        // TODO
     }
-    rs = rs + m_pldrack.toString() + " " + m_round.toString();
+    rs = rs + m_pldrack.toString() + L" " + m_round.toString();
     return rs;
 }
 
Index: eliot/game/turn.h
diff -u eliot/game/turn.h:1.8 eliot/game/turn.h:1.9
--- eliot/game/turn.h:1.8       Sun Jan  1 19:49:35 2006
+++ eliot/game/turn.h   Sun Jan 22 12:23:53 2006
@@ -48,7 +48,7 @@
 #if 0
     void operator=(const Turn &iOther);
 #endif
-    string toString(bool iShowExtraSigns = false) const;
+    wstring toString(bool iShowExtraSigns = false) const;
 
 private:
     int        m_num;
Index: eliot/utils/eliottxt.cpp
diff -u eliot/utils/eliottxt.cpp:1.13 eliot/utils/eliottxt.cpp:1.14
--- eliot/utils/eliottxt.cpp:1.13       Sun Jan  1 19:32:44 2006
+++ eliot/utils/eliottxt.cpp    Sun Jan 22 12:23:53 2006
@@ -22,7 +22,9 @@
 #include <stdio.h>
 #include <time.h>
 #include <string.h>
-#include <ctype.h>
+#include <locale.h>
+#include <wctype.h>
+#include <wchar.h>
 #include <fstream>
 #include <readline/readline.h>
 #include <readline/history.h>
@@ -35,16 +37,19 @@
 #include "training.h"
 #include "duplicate.h"
 #include "freegame.h"
+#include "encoding.h"
 
 
 /* A static variable for holding the line. */
 static char *line_read = NULL;
+/* Wide version of the line */
+static wchar_t *wline_read = NULL;
 
 /**
  * Read a string, and return a pointer to it.
  * Returns NULL on EOF.
  */
-char *rl_gets()
+wchar_t *rl_gets()
 {
     // If the buffer has already been allocated, return the memory to the free
     // pool
@@ -53,6 +58,11 @@
         free(line_read);
         line_read = NULL;
     }
+    if (wline_read)
+    {
+        free(wline_read);
+        wline_read = NULL;
+    }
 
     // Get a line from the user
     line_read = readline("commande> ");
@@ -61,117 +71,116 @@
     if (line_read && *line_read)
         add_history(line_read);
 
-    return line_read;
+    // Convert the line into wide characters
+    // Get the needed length (we _can't_ use string::size())
+    size_t len = mbstowcs(NULL, line_read, 0);
+    if (len == (size_t)-1)
+        return NULL;
+
+    wline_read = new wchar_t[len + 1];
+    len = mbstowcs(wline_read, line_read, len + 1);
+
+    return wline_read;
 }
 
 
-char *
-next_token_alpha(char *cmd, const char *delim)
+wchar_t * next_token_alpha(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
 {
-    int i;
-    char *token = strtok(cmd, delim);
+    wchar_t *token = wcstok(cmd, delim, state);
     if (token == NULL)
         return NULL;
-    for (i = 0; token[i] && isalpha(token[i]); i++)
+    int i;
+    for (i = 0; token[i] && iswalpha(token[i]); i++)
         ;
-    token[i] = '\0';
+    token[i] = L'\0';
     return token;
 }
 
 
-char *
-next_token_alphanum(char *cmd, const char *delim)
+wchar_t * next_token_alphanum(wchar_t *cmd, const wchar_t *delim, wchar_t 
**state)
 {
-    int i;
-    char *token = strtok(cmd, delim);
+    wchar_t *token = wcstok(cmd, delim, state);
     if (token == NULL)
         return NULL;
-    for (i = 0; token[i] && isalnum(token[i]); i++)
+    int i;
+    for (i = 0; token[i] && iswalnum(token[i]); i++)
         ;
-    token[i] = '\0';
+    token[i] = L'\0';
     return token;
 }
 
 
-char *
-next_token_alphaplusjoker(char *cmd, const char *delim)
+wchar_t * next_token_alphaplusjoker(wchar_t *cmd, const wchar_t *delim, 
wchar_t **state)
 {
-    int i;
-    char *token = strtok(cmd, delim);
+    wchar_t *token = wcstok(cmd, delim, state);
     if (token == NULL)
         return NULL;
-    for (i = 0; token[i] && (isalpha(token[i]) ||
-                             token[i] == '?'   ||
-                             token[i] == '+');
+    int i;
+    for (i = 0; token[i] && (iswalpha(token[i]) ||
+                             token[i] == L'?'   ||
+                             token[i] == L'+');
          i++)
         ;
-    token[i] = '\0';
+    token[i] = L'\0';
     return token;
 }
 
 
-char *
-next_token_digit(char *cmd, const char *delim)
+wchar_t * next_token_digit(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
 {
-    int i;
-    char *token = strtok(cmd, delim);
+    wchar_t *token = wcstok(cmd, delim, state);
     if (token == NULL)
         return NULL;
-    for (i = 0; token[i] && (isdigit(token[i]) || token[i] == '-'); i++)
+    int i;
+    for (i = 0; token[i] && (iswdigit(token[i]) || token[i] == L'-'); i++)
         ;
-    token[i] = '\0';
+    token[i] = L'\0';
     return token;
 }
 
 
-char *
-next_token_cross(char *cmd, const char *delim)
+wchar_t * next_token_cross(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
 {
-    int i;
-    char *token = strtok(cmd, delim);
+    wchar_t *token = wcstok(cmd, delim, state);
     if (token == NULL)
         return NULL;
+    int i;
     for (i = 0; token[i] &&
-         (isalpha(token[i]) || token[i] == '.');
+         (iswalpha(token[i]) || token[i] == L'.');
          i++)
         ;
-    token[i] = '\0';
+    token[i] = L'\0';
     return token;
 }
 
 
-char *
-next_token_filename(char *cmd, const char *delim)
+wchar_t * next_token_filename(wchar_t *cmd, const wchar_t *delim, wchar_t 
**state)
 {
-    int i;
-    char *token = strtok(cmd, delim);
+    wchar_t *token = wcstok(cmd, delim, state);
     if (token == NULL)
         return NULL;
-    for (i = 0; token[i] && (isalnum(token[i]) ||
-                             token[i] == '.' ||
-                             token[i] == '_'); i++)
+    int i;
+    for (i = 0; token[i] && (iswalnum(token[i]) ||
+                             token[i] == L'.' ||
+                             token[i] == L'_'); i++)
         ;
-    token[i] = '\0';
+    token[i] = L'\0';
     return token;
 }
 
 
-void
-eliottxt_get_cross(const Dictionary &iDic, char* cros)
+void eliottxt_get_cross(const Dictionary &iDic, wchar_t *cros)
 {
-    int i;
-    //  (Dictionary dic, char* regx, char wordlist[RES_REGX_MAX][DIC_WORD_MAX])
-    char wordlist[RES_CROS_MAX][DIC_WORD_MAX];
+    wchar_t wordlist[RES_CROS_MAX][DIC_WORD_MAX];
     Dic_search_Cros(iDic, cros, wordlist);
-    for (i = 0; i<RES_CROS_MAX && wordlist[i][0]; i++)
+    for (int i = 0; i < RES_CROS_MAX && wordlist[i][0]; i++)
     {
-        printf("  %s\n", wordlist[i]);
+        printf("  %s\n", convertToMb(wordlist[i]).c_str());
     }
 }
 
 
-void
-help_training()
+void help_training()
 {
     printf("  ?    : aide -- cette page\n");
     printf("  a [g|l|p|r|t] : afficher :\n");
@@ -198,8 +207,7 @@
 }
 
 
-void
-help_freegame()
+void help_freegame()
 {
     printf("  ?    : aide -- cette page\n");
     printf("  a [g|l|p|s|t] : afficher :\n");
@@ -224,8 +232,7 @@
 }
 
 
-void
-help_duplicate()
+void help_duplicate()
 {
     printf("  ?    : aide -- cette page\n");
     printf("  a [g|l|p|s|t] : afficher :\n");
@@ -249,8 +256,7 @@
 }
 
 
-void
-help()
+void help()
 {
     printf("  ?       : aide -- cette page\n");
     printf("  e       : démarrer le mode entraînement\n");
@@ -269,12 +275,11 @@
 }
 
 
-void
-display_data(const Game &iGame, const char *delim)
+void display_data(const Game &iGame, const wchar_t *delim, wchar_t **state)
 {
-    char *token;
+    wchar_t *token;
 
-    token = next_token_alpha(NULL, delim);
+    token = next_token_alpha(NULL, delim, state);
     if (token == NULL)
     {
         cout << "commande incomplète\n";
@@ -282,19 +287,19 @@
     }
     switch (token[0])
     {
-        case 'g':
+        case L'g':
             switch (token[1])
             {
-                case '\0':
+                case L'\0':
                     GameIO::printBoard(cout, iGame);
                     break;
-                case 'j':
+                case L'j':
                     GameIO::printBoardJoker(cout, iGame);
                     break;
-                case 'm':
+                case L'm':
                     GameIO::printBoardMultipliers(cout, iGame);
                     break;
-                case 'n':
+                case L'n':
                     GameIO::printBoardMultipliers2(cout, iGame);
                     break;
                 default:
@@ -302,20 +307,20 @@
                     break;
             }
             break;
-        case 'j':
+        case L'j':
             cout << "Joueur " << iGame.currPlayer() << endl;
             break;
-        case 'l':
+        case L'l':
             GameIO::printNonPlayed(cout, iGame);
             break;
-        case 'p':
+        case L'p':
             iGame.save(cout,Game::FILE_FORMAT_ADVANCED);
             break;
-        case 'P':
+        case L'P':
             iGame.save(cout,Game::FILE_FORMAT_STANDARD);
             break;
-        case 'r':
-            token = next_token_digit(NULL, delim);
+        case L'r':
+            token = next_token_digit(NULL, delim, state);
             if (token == NULL)
                 GameIO::printSearchResults(cout,
                                            static_cast<const Training&>(iGame),
@@ -323,18 +328,18 @@
             else
                 GameIO::printSearchResults(cout,
                                            static_cast<const Training&>(iGame),
-                                           atoi(token));
+                                           _wtoi(token));
             break;
-        case 's':
+        case L's':
             GameIO::printPoints(cout, iGame);
             break;
-        case 'S':
+        case L'S':
             GameIO::printAllPoints(cout, iGame);
             break;
-        case 't':
+        case L't':
             GameIO::printPlayedRack(cout, iGame, iGame.getHistory().getSize());
             break;
-        case 'T':
+        case L'T':
             GameIO::printAllRacks(cout, iGame);
             break;
         default:
@@ -344,12 +349,12 @@
 }
 
 
-void
-loop_training(Training &iGame)
+void loop_training(Training &iGame)
 {
-    char *token;
-    char *commande = NULL;
-    char delim[] = " \t";
+    wchar_t *token;
+    wchar_t *state;
+    wchar_t *commande = NULL;
+    wchar_t delim[] = L" \t";
     int quit = 0;
 
     cout << "mode entraînement\n";
@@ -357,37 +362,43 @@
     while (quit == 0)
     {
         commande = rl_gets();
-        token = strtok(commande, delim);
+        token = wcstok(commande, delim, &state);
         if (token)
         {
             switch (token[0])
             {
-                case '?':
+                case L'?':
                     help_training();
                     break;
-                case 'a':
-                    display_data(iGame, delim);
+                case L'a':
+                    display_data(iGame, delim, &state);
                     break;
-                case 'd':
-                    token = next_token_alpha(NULL, delim);
+                case L'd':
+                    token = next_token_alpha(NULL, delim, &state);
                     if (token == NULL)
                         help_training();
                     else
                     {
                         if (Dic_search_word(iGame.getDic(), token))
-                            printf("le mot -%s- existe\n", token);
+                        {
+                            printf("le mot -%s- existe\n",
+                                   convertToMb(token).c_str());
+                        }
                         else
-                            printf("le mot -%s- n'existe pas\n", token);
+                        {
+                            printf("le mot -%s- n'existe pas\n",
+                                   convertToMb(token).c_str());
+                        }
                     }
                     break;
-               case 'j':
-                    token = next_token_alpha(NULL, delim);
+               case L'j':
+                    token = next_token_alpha(NULL, delim, &state);
                     if (token == NULL)
                         help_training();
                     else
                     {
                         int res;
-                        char *coord = next_token_alphanum(NULL, delim);
+                        wchar_t *coord = next_token_alphanum(NULL, delim, 
&state);
                         if (coord == NULL)
                         {
                             help_training();
@@ -401,13 +412,13 @@
                         }
                     }
                     break;
-                case 'n':
-                    token = next_token_digit(NULL, delim);
+                case L'n':
+                    token = next_token_digit(NULL, delim, &state);
                     if (token == NULL)
                         help_training();
                     else
                     {
-                        int n = atoi(token);
+                        int n = _wtoi(token);
                         if (n <= 0)
                             iGame.back(n == 0 ? 1 : -n);
                         else
@@ -417,45 +428,47 @@
                         }
                     }
                     break;
-                case 'r':
+                case L'r':
                     iGame.search();
                     break;
-                case 't':
-                    token = next_token_alphaplusjoker(NULL, delim);
+                case L't':
+                    token = next_token_alphaplusjoker(NULL, delim, &state);
                     if (token == NULL)
                         help_training();
                     else
                         if (iGame.setRackManual(0, token))
                             printf("le sac ne contient pas assez de 
lettres\n");
                     break;
-                case 'x':
-                    token = next_token_cross(NULL, delim);
+                case L'x':
+                    token = next_token_cross(NULL, delim, &state);
                     if (token == NULL)
                         help_training();
                     else
                         eliottxt_get_cross(iGame.getDic(), token);
                     break;
-                case '*':
+                case L'*':
                     iGame.setRackRandom(false, Game::RACK_ALL);
                     break;
-                case '+':
+                case L'+':
                     iGame.setRackRandom(false, Game::RACK_NEW);
                     break;
-                case 's':
-                    token = next_token_filename(NULL, delim);
+                case L's':
+                    token = next_token_filename(NULL, delim, &state);
                     if (token != NULL)
                     {
-                        ofstream fout(token);
+                        string filename = convertToMb(token);
+                        ofstream fout(filename.c_str());
                         if (fout.rdstate() == ios::failbit)
                         {
-                            printf("impossible d'ouvrir %s\n", token);
+                            printf("impossible d'ouvrir %s\n",
+                                   filename.c_str());
                             break;
                         }
                         iGame.save(fout);
                         fout.close();
                     }
                     break;
-                case 'q':
+                case L'q':
                     quit = 1;
                     break;
                 default:
@@ -468,12 +481,12 @@
 }
 
 
-void
-loop_freegame(FreeGame &iGame)
+void loop_freegame(FreeGame &iGame)
 {
-    char *token;
-    char *commande = NULL;
-    char delim[] = " \t";
+    wchar_t *token;
+    wchar_t *state;
+    wchar_t *commande = NULL;
+    wchar_t delim[] = L" \t";
     int quit = 0;
 
     printf("mode partie libre\n");
@@ -481,37 +494,43 @@
     while (quit == 0)
     {
         commande = rl_gets();
-        token = strtok(commande, delim);
+        token = wcstok(commande, delim, &state);
         if (token)
         {
             switch (token[0])
             {
-                case '?':
+                case L'?':
                     help_freegame();
                     break;
-                case 'a':
-                    display_data(iGame, delim);
+                case L'a':
+                    display_data(iGame, delim, &state);
                     break;
-                case 'd':
-                    token = next_token_alpha(NULL, delim);
+                case L'd':
+                    token = next_token_alpha(NULL, delim, &state);
                     if (token == NULL)
                         help_freegame();
                     else
                     {
                         if (Dic_search_word(iGame.getDic(), token))
-                            printf("le mot -%s- existe\n", token);
+                        {
+                            printf("le mot -%s- existe\n",
+                                   convertToMb(token).c_str());
+                        }
                         else
-                            printf("le mot -%s- n'existe pas\n", token);
+                        {
+                            printf("le mot -%s- n'existe pas\n",
+                                   convertToMb(token).c_str());
+                        }
                     }
                     break;
-               case 'j':
-                    token = next_token_alpha(NULL, delim);
+               case L'j':
+                    token = next_token_alpha(NULL, delim, &state);
                     if (token == NULL)
                         help_freegame();
                     else
                     {
                         int res;
-                        char *coord = next_token_alphanum(NULL, delim);
+                        wchar_t *coord = next_token_alphanum(NULL, delim, 
&state);
                         if (coord == NULL)
                         {
                             help_freegame();
@@ -525,30 +544,32 @@
                         }
                     }
                     break;
-               case 'p':
-                    token = next_token_alpha(NULL, delim);
+               case L'p':
+                    token = next_token_alpha(NULL, delim, &state);
                     /* You can pass your turn without changing any letter */
                     if (token == NULL)
-                        token = "";
+                        token = L"";
 
                     if (iGame.pass(token, iGame.currPlayer()) != 0)
                         break;
                     break;
-                case 's':
-                    token = next_token_filename(NULL, delim);
+                case L's':
+                    token = next_token_filename(NULL, delim, &state);
                     if (token != NULL)
                     {
-                        ofstream fout(token);
+                        string filename = convertToMb(token);
+                        ofstream fout(filename.c_str());
                         if (fout.rdstate() == ios::failbit)
                         {
-                            printf("impossible d'ouvrir %s\n", token);
+                            printf("impossible d'ouvrir %s\n",
+                                   filename.c_str());
                             break;
                         }
                         iGame.save(fout);
                         fout.close();
                     }
                     break;
-                case 'q':
+                case L'q':
                     quit = 1;
                     break;
                 default:
@@ -561,12 +582,12 @@
 }
 
 
-void
-loop_duplicate(Duplicate &iGame)
+void loop_duplicate(Duplicate &iGame)
 {
-    char *token;
-    char *commande = NULL;
-    char delim[] = " \t";
+    wchar_t *token;
+    wchar_t *state;
+    wchar_t *commande = NULL;
+    wchar_t delim[] = L" \t";
     int quit = 0;
 
     printf("mode duplicate\n");
@@ -574,37 +595,43 @@
     while (quit == 0)
     {
         commande = rl_gets();
-        token = strtok(commande, delim);
+        token = wcstok(commande, delim, &state);
         if (token)
         {
             switch (token[0])
             {
-                case '?':
+                case L'?':
                     help_duplicate();
                     break;
-                case 'a':
-                    display_data(iGame, delim);
+                case L'a':
+                    display_data(iGame, delim, &state);
                     break;
-                case 'd':
-                    token = next_token_alpha(NULL, delim);
+                case L'd':
+                    token = next_token_alpha(NULL, delim, &state);
                     if (token == NULL)
                         help_duplicate();
                     else
                     {
                         if (Dic_search_word(iGame.getDic(), token))
-                            printf("le mot -%s- existe\n", token);
+                        {
+                            printf("le mot -%s- existe\n",
+                                   convertToMb(token).c_str());
+                        }
                         else
-                            printf("le mot -%s- n'existe pas\n", token);
+                        {
+                            printf("le mot -%s- n'existe pas\n",
+                                   convertToMb(token).c_str());
+                        }
                     }
                     break;
-                case 'j':
-                    token = next_token_alpha(NULL, delim);
+                case L'j':
+                    token = next_token_alpha(NULL, delim, &state);
                     if (token == NULL)
                         help_duplicate();
                     else
                     {
                         int res;
-                        char *coord = next_token_alphanum(NULL, delim);
+                        wchar_t *coord = next_token_alphanum(NULL, delim, 
&state);
                         if (coord == NULL)
                         {
                             help_duplicate();
@@ -618,34 +645,36 @@
                         }
                     }
                     break;
-                case 'n':
-                    token = next_token_digit(NULL, delim);
+                case L'n':
+                    token = next_token_digit(NULL, delim, &state);
                     if (token == NULL)
                         help_duplicate();
                     else
                     {
-                        int res = iGame.setPlayer(atoi(token));
+                        int res = iGame.setPlayer(_wtoi(token));
                         if (res == 1)
                             fprintf(stderr, "Numéro de joueur invalide\n");
                         else if (res == 2)
                             fprintf(stderr, "Impossible de choisir un joueur 
non humain\n");
                     }
                     break;
-                case 's':
-                    token = next_token_filename(NULL, delim);
+                case L's':
+                    token = next_token_filename(NULL, delim, &state);
                     if (token != NULL)
                     {
-                        ofstream fout(token);
+                        string filename = convertToMb(token);
+                        ofstream fout(filename.c_str());
                         if (fout.rdstate() == ios::failbit)
                         {
-                            printf("impossible d'ouvrir %s\n", token);
+                            printf("impossible d'ouvrir %s\n",
+                                   filename.c_str());
                             break;
                         }
                         iGame.save(fout);
                         fout.close();
                     }
                     break;
-                case 'q':
+                case L'q':
                     quit = 1;
                     break;
                 default:
@@ -658,55 +687,54 @@
 }
 
 
-void
-eliot_regexp_build_default_llist(struct search_RegE_list_t &llist)
+void eliot_regexp_build_default_llist(struct search_RegE_list_t &llist)
 {
-    memset (&llist,0,sizeof(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]));
-        }
-    
+
+    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())
         {
-            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;
-                        }
-                }
+            // 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)
+void eliot_regexp(const Dictionary& iDic, wchar_t *cmd,
+                  const wchar_t *delim, wchar_t **state)
 {
     /*
     printf("  x [] {1} {2} {3} : expressions rationnelles\n");
@@ -718,26 +746,23 @@
 
 #define DIC_RE_MAX (3*DIC_WORD_MAX) // yes, it's 3
 
-    char re[DIC_RE_MAX];
-    char buff[RES_REGE_MAX][DIC_WORD_MAX];
     struct search_RegE_list_t llist;
     eliot_regexp_build_default_llist(llist);
 
-    char *exp, *cnres, *clmin, *clmax;
+    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);
 
-    char delim[] = " \t";
-    exp   = strtok(NULL,delim);
-    cnres = strtok(NULL,delim);
-    clmin = strtok(NULL,delim);
-    clmax = strtok(NULL,delim);
-    
     if (exp == NULL)
     {
         return;
     }
-    int nres = cnres ? atoi(cnres) : 50;
-    int lmin = clmin ? atoi(clmin) : 1;
-    int lmax = clmax ? atoi(clmax) : DIC_WORD_MAX - 1;
+    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)
     {
@@ -746,54 +771,60 @@
     }
     else
     {
-        printf("bad length -%s,%s-\n",(const char*)clmin,(const char*)clmax);
+        printf("bad length -%s,%s-\n", (const char*)clmin, (const char*)clmax);
         return;
     }
-    
-    strncpy(re,exp,DIC_RE_MAX);
 
-    printf("search for %s (%d,%d,%d)\n",re,nres,lmin,lmax);
-    Dic_search_RegE(iDic,re,buff,&llist);
-    
+    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++)
+    for (int i = 0; i < RES_REGE_MAX && i < nres && buff[i][0]; i++)
     {
-        printf("%s\n",buff[i]);
+        printf("%s\n", convertToMb(buff[i]).c_str());
         nresult++;
     }
-    printf("%d printed results\n",nresult);
+    printf("%d printed results\n", nresult);
 }
 
-void
-main_loop(const Dictionary &iDic)
+
+void main_loop(const Dictionary &iDic)
 {
-    char *token;
-    char *commande = NULL;
-    char delim[] = " \t";
+    wchar_t *token;
+    wchar_t *state;
+    wchar_t *commande = NULL;
+    wchar_t delim[] = L" \t";
     int quit = 0;
 
     printf("[?] pour l'aide\n");
     while (quit == 0)
     {
         commande = rl_gets();
-        token = strtok(commande, delim);
+        token = wcstok(commande, delim, &state);
         if (token)
         {
             switch (token[0])
             {
-                case '?':
+                case L'?':
                     help();
                     break;
-                case 'c':
-                    token = next_token_filename(NULL, delim);
+                case L'c':
+                    token = next_token_filename(NULL, delim, &state);
                     if (token == NULL)
                     {}
                     else
                     {
+                        string filename = convertToMb(token);
                         FILE* fin;
-                        if ((fin = fopen(token, "r")) == NULL)
+                        if ((fin = fopen(filename.c_str(), "r")) == NULL)
                         {
-                            printf("impossible d'ouvrir %s\n", token);
+                            printf("impossible d'ouvrir %s\n",
+                                   filename.c_str());
                             break;
                         }
                         Game *game = Game::load(fin, iDic);
@@ -813,7 +844,7 @@
                         }
                     }
                     break;
-                case 'e':
+                case L'e':
                 {
                     // New training game
                     Training *game = 
GameFactory::Instance()->createTraining(iDic);
@@ -822,59 +853,59 @@
                     GameFactory::Instance()->releaseGame(*game);
                     break;
                 }
-                case 'd':
+                case L'd':
                 {
                     int i;
                     // New duplicate game
-                    token = next_token_digit(NULL, delim);
+                    token = next_token_digit(NULL, delim, &state);
                     if (token == NULL)
                     {
                         help();
                         break;
                     }
                     Duplicate *game = 
GameFactory::Instance()->createDuplicate(iDic);
-                    for (i = 0; i < atoi(token); i++)
+                    for (i = 0; i < _wtoi(token); i++)
                         game->addHumanPlayer();
-                    token = next_token_digit(NULL, delim);
+                    token = next_token_digit(NULL, delim, &state);
                     if (token == NULL)
                     {
                         help();
                         break;
                     }
-                    for (i = 0; i < atoi(token); i++)
+                    for (i = 0; i < _wtoi(token); i++)
                         game->addAIPlayer();
                     game->start();
                     loop_duplicate(*game);
                     GameFactory::Instance()->releaseGame(*game);
                     break;
                 }
-                case 'l':
+                case L'l':
                 {
                     int i;
                     // New free game
-                    token = next_token_digit(NULL, delim);
+                    token = next_token_digit(NULL, delim, &state);
                     if (token == NULL)
                     {
                         help();
                         break;
                     }
                     FreeGame *game = 
GameFactory::Instance()->createFreeGame(iDic);
-                    for (i = 0; i < atoi(token); i++)
+                    for (i = 0; i < _wtoi(token); i++)
                         game->addHumanPlayer();
-                    token = next_token_digit(NULL, delim);
+                    token = next_token_digit(NULL, delim, &state);
                     if (token == NULL)
                     {
                         help();
                         break;
                     }
-                    for (i = 0; i < atoi(token); i++)
+                    for (i = 0; i < _wtoi(token); i++)
                         game->addAIPlayer();
                     game->start();
                     loop_freegame(*game);
                     GameFactory::Instance()->releaseGame(*game);
                     break;
                 }
-                case 'D':
+                case L'D':
                 {
                     // New duplicate game
                     Duplicate *game = 
GameFactory::Instance()->createDuplicate(iDic);
@@ -885,7 +916,7 @@
                     GameFactory::Instance()->releaseGame(*game);
                     break;
                 }
-                case 'L':
+                case L'L':
                 {
                     // New free game
                     FreeGame *game = 
GameFactory::Instance()->createFreeGame(iDic);
@@ -896,11 +927,11 @@
                     GameFactory::Instance()->releaseGame(*game);
                     break;
                 }
-                case 'x':
-                    // Regular expression tests 
-                    eliot_regexp(iDic);
+                case L'x':
+                    // Regular expression tests
+                    eliot_regexp(iDic, NULL, delim, &state);
                     break;
-                case 'q':
+                case L'q':
                     quit = 1;
                     break;
                 default:
@@ -912,11 +943,13 @@
 }
 
 
-int
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
     char dic_path[100];
 
+    // Let the user choose the locale
+    setlocale(LC_ALL, "");
+
     Dictionary dic = NULL;
 
     if (argc != 2 && argc != 3)
@@ -968,9 +1001,11 @@
 
     Dic_destroy(dic);
 
-    // Free the readline static variable
+    // Free the readline static variable and its wide equivalent
     if (line_read)
         free(line_read);
+    if (wline_read)
+        free(wline_read);
 
     return 0;
 }
Index: eliot/utils/game_io.cpp
diff -u eliot/utils/game_io.cpp:1.8 eliot/utils/game_io.cpp:1.9
--- eliot/utils/game_io.cpp:1.8 Sun Jan  1 19:32:44 2006
+++ eliot/utils/game_io.cpp     Sun Jan 22 12:23:53 2006
@@ -20,11 +20,13 @@
 
 #include <iomanip>
 #include <string>
+#include "stdlib.h"
 
 #include "game_io.h"
 #include "game.h"
 #include "training.h"
 #include "player.h"
+#include "encoding.h"
 
 using namespace std;
 
@@ -124,7 +126,7 @@
         out << " " << (char)(row - BOARD_MIN + 'A') << " ";
         for (col = BOARD_MIN; col <= BOARD_MAX; col++)
         {
-            char l = iGame.getBoard().getChar(row, col);
+            wchar_t l = iGame.getBoard().getChar(row, col);
             int wm = iGame.getBoard().getWordMultiplier(row, col);
             int tm = iGame.getBoard().getLetterMultiplier(row, col);
 
@@ -134,7 +136,7 @@
                 out << " " << ((tm == 3) ? '*' : '+');
             else
                 out << " -";
-            out << (l ? l : '-');
+            out << (l ? convertToMb(l) : "-");
         }
         out << endl;
     }
@@ -150,7 +152,7 @@
     {
         if (iGame.getBag().in(it->toChar()) > 9)
             out << " ";
-        out << setw(2) << it->toChar();
+        out << setw(2) << convertToMb(it->toChar());
     }
     out << endl;
 
@@ -164,7 +166,7 @@
 
 void GameIO::printPlayedRack(ostream &out, const Game &iGame, int n)
 {
-    out << 
iGame.getCurrentPlayer().getCurrentRack().toString(PlayedRack::RACK_SIMPLE) << 
endl;
+    out << 
convertToMb(iGame.getCurrentPlayer().getCurrentRack().toString(PlayedRack::RACK_SIMPLE))
 << endl;
 }
 
 
@@ -173,7 +175,7 @@
     for (int j = 0; j < iGame.getNPlayers(); j++)
     {
         out << "Joueur " << j << ": ";
-        out << 
iGame.getPlayer(j).getCurrentRack().toString(PlayedRack::RACK_SIMPLE) << endl;
+        out << 
convertToMb(iGame.getPlayer(j).getCurrentRack().toString(PlayedRack::RACK_SIMPLE))
 << endl;
     }
 }
 
@@ -182,13 +184,13 @@
 {
     const Results &res = iGame.getResults();
     Round r = res.get(num);
-    string word = r.getWord();
+    wstring word = r.getWord();
     if (word.size() == 0)
         return;
-    out << word << string(16 - word.size(), ' ')
+    out << convertToMb(word) << string(16 - word.size(), ' ')
         << (r.getBonus() ? '*' : ' ')
         << setw(4) << r.getPoints()
-        << ' ' << r.getCoord().toString();
+        << ' ' << convertToMb(r.getCoord().toString());
 }
 
 
Index: eliot/utils/ncurses.cpp
diff -u eliot/utils/ncurses.cpp:1.20 eliot/utils/ncurses.cpp:1.21
--- eliot/utils/ncurses.cpp:1.20        Sun Jan  1 19:32:44 2006
+++ eliot/utils/ncurses.cpp     Sun Jan 22 12:23:53 2006
@@ -38,6 +38,7 @@
 #include "player.h"
 #include "history.h"
 #include "turn.h"
+#include "encoding.h"
 
 using namespace std;
 
@@ -199,9 +200,9 @@
     drawBox(win, y + yOff, x, m_game->getNPlayers() + 2, 25, _(" Racks "));
     for (int i = 0; i < m_game->getNPlayers(); i++)
     {
-        string rack = 
m_game->getPlayer(i).getCurrentRack().toString(PlayedRack::RACK_SIMPLE);
         if (m_game->getMode() != Game::kTRAINING && i == m_game->currPlayer())
             attron(A_BOLD);
+        string rack = 
convertToMb(m_game->getPlayer(i).getCurrentRack().toString(PlayedRack::RACK_SIMPLE));
         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())
@@ -212,7 +213,7 @@
 
     // Display a message when the search is complete
     if (m_game->getMode() == Game::kTRAINING &&
-        static_cast<Training*>(m_game)->getHistory().getSize())
+        static_cast<Training*>(m_game)->getResults().size())
     {
         mvwprintw(win, y + 2*yOff - 1, x + 2, _("Search complete"));
     }
@@ -231,7 +232,7 @@
     drawBox(win, y, x, h, 25, _(" Search results "));
     m_boxY = y + 1;
     m_boxLines = h - 2;
-    m_boxLinesData = tr_game->getHistory().getSize();
+    m_boxLinesData = tr_game->getResults().size();
 
     int i;
     const Results& res = tr_game->getResults();
@@ -239,12 +240,12 @@
                          i < m_boxStart + m_boxLines; i++)
     {
         const Round &r = res.get(i);
-        string coord = r.getCoord().toString();
+        wstring coord = r.getCoord().toString();
         boxPrint(win, i, x + 1, "%3d %s%s %3s",
                  r.getPoints(),
-                 r.getWord().c_str(),
+                 convertToMb(r.getWord()).c_str(),
                  string(h - 3 - r.getWordLen(), ' ').c_str(),
-                 coord.c_str());
+                 convertToMb(coord).c_str());
     }
     // Complete the list with empty lines, to avoid trails
     for (; i < m_boxStart + m_boxLines; i++)
@@ -275,12 +276,12 @@
     {
         const Turn& t = m_game->getHistory().getTurn(i);
         const Round& r = t.getRound();
-        string word = r.getWord();
-        string coord = r.getCoord().toString();
+        string word = convertToMb(r.getWord());
+        string coord = convertToMb(r.getCoord().toString());
         boxPrint(win, i + 2, x + 2,
                  "%2d   %8s   %s%s   %3s   %3d   %1d   %c",
-                 i + 1, t.getPlayedRack().toString().c_str(), word.c_str(),
-                 string(15 - word.size(), ' ').c_str(),
+                 i + 1, convertToMb(t.getPlayedRack().toString()).c_str(),
+                 word.c_str(), string(15 - word.size(), ' ').c_str(),
                  coord.c_str(), r.getPoints(),
                  t.getPlayer(), r.getBonus() ? '*' : ' ');
     }
@@ -362,7 +363,7 @@
     if (readString(win, y + 1, x + xOff, 15, word) &&
         readString(win, y + 2, x + xOff, 3, coord))
     {
-        int res = m_game->play(coord, word);
+        int res = m_game->play(convertToWc(coord), convertToWc(word));
         if (res)
         {
             drawStatus(win, LINES - 1, 0, _("Incorrect or misplaced word"));
@@ -382,7 +383,7 @@
     string word;
     if (readString(win, y + 2, x + 2, 15, word))
     {
-        int res = Dic_search_word(m_game->getDic(), word.c_str());
+        int res = Dic_search_word(m_game->getDic(), convertToWc(word).c_str());
         char s[100];
         if (res)
             snprintf(s, 100, _("The word '%s' exists"), word.c_str());
@@ -471,7 +472,7 @@
     string letters;
     if (readString(win, y + 2, x + 2, 7, letters))
     {
-        int res = iGame.pass(letters, m_game->currPlayer());
+        int res = iGame.pass(convertToWc(letters), m_game->currPlayer());
         if (res)
         {
             drawStatus(win, LINES - 1, 0, _("Cannot pass the turn"));
@@ -491,7 +492,7 @@
     string letters;
     if (readString(win, y + 2, x + 2, 7, letters, kJOKER))
     {
-        iGame.setRackManual(false, letters);
+        iGame.setRackManual(false, convertToWc(letters));
     }
     m_state = DEFAULT;
     clearRect(win, y, x, 4, 32);
@@ -718,7 +719,7 @@
             else
                 m_state = RESULTS;
             m_boxStart = 0;
-            clear();
+            clearRect(m_win, 3, 54, 30, 25);
             return 1;
 
         // Toggle dots display
Index: eliot/wxwin/auxframes.cc
diff -u eliot/wxwin/auxframes.cc:1.20 eliot/wxwin/auxframes.cc:1.21
--- eliot/wxwin/auxframes.cc:1.20       Sun Jan  1 19:34:05 2006
+++ eliot/wxwin/auxframes.cc    Sun Jan 22 12:23:53 2006
@@ -41,6 +41,7 @@
 #include "training.h"
 #include "player.h"
 #include "game.h"
+#include "encoding.h"
 
 #include "configdb.h"
 #include "auxframes.h"
@@ -258,7 +259,7 @@
         result->SetLabel(wxT("pas de dictionnaire"));
         return;
     }
-    if (Dic_search_word(dic, word->GetValue().mb_str()))
+    if (Dic_search_word(dic, word->GetValue().wc_str()))
         result->SetLabel(wxT("existe"));
     else
         result->SetLabel(wxT("n'existe pas"));
@@ -294,7 +295,7 @@
 
 {
     game = g;
-    savedword = "";
+    savedword = L"";
 
     wxBoxSizer *sizer_v = new wxBoxSizer(wxVERTICAL);
     listbox = new wxListBox(this, ListBoxID);
@@ -380,20 +381,19 @@
 void
 Plus1Frame::refresh()
 {
-    std::string rack;
     //debug("      Plus1Frame::refresh start\n");
-    rack = game->getCurrentPlayer().getCurrentRack().toString();
+    std::wstring rack = game->getCurrentPlayer().getCurrentRack().toString();
     //debug("         CurrentPlayer -> rack : %s\n",rack.c_str());
 
     if (savedword == rack)
-       {
-           noresult = false; // keep old results
-           //debug("      Plus1Frame::refresh end, no change\n");
-           return;
-       }
+    {
+        noresult = false; // keep old results
+        //debug("      Plus1Frame::refresh end, no change\n");
+        return;
+    }
     savedword = rack;
 
-    char buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
+    wchar_t buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
     Dic_search_7pl1(game->getDic(), rack.c_str(), buff, 
config.getJokerPlus1());
 
     listbox->Clear();
@@ -403,15 +403,15 @@
     for (int i = 0; i < DIC_LETTERS; i++)
     {
         if (i && buff[i][0][0])
-           {
-               res[resnum++] = wxString(wxT("+")) + (wxChar)(i + 'A' - 1);
-               noresult = false;
-           }
-       for (int j = 0; j < RES_7PL1_MAX && buff[i][j][0]; j++)
-           {
-               res[resnum++] = wxString(wxT("  ")) + wxU(buff[i][j]);
-               noresult = false;
-           }
+        {
+            res[resnum++] = wxString(wxT("+")) + (wxChar)(i + 'A' - 1);
+            noresult = false;
+        }
+        for (int j = 0; j < RES_7PL1_MAX && buff[i][j][0]; j++)
+        {
+            res[resnum++] = wxString(wxT("  ")) + wxU(buff[i][j]);
+            noresult = false;
+        }
     }
     listbox->Set(resnum, res);
     //debug("      Plus1Frame::refresh end\n");
@@ -424,30 +424,28 @@
 void
 BenjFrame::refresh()
 {
-    std::string word;
-
     if (game->getMode() != Game::kTRAINING)
-       return;
+        return;
 
-    word = ((Training*)game)->getTestPlayWord();
+    std::wstring word = static_cast<Training*>(game)->getTestPlayWord();
     if (savedword == word)
-       {
-           noresult = false; // keep old results
-           return;
-       }
+    {
+        noresult = false; // keep old results
+        return;
+    }
     savedword = word;
     //debug("   BenjFrame::refresh : %s\n",word.c_str());
-    char wordlist[RES_BENJ_MAX][DIC_WORD_MAX];
+    wchar_t wordlist[RES_BENJ_MAX][DIC_WORD_MAX];
     Dic_search_Benj(game->getDic(), word.c_str(), wordlist);
 
     wxString res[RES_BENJ_MAX];
     int resnum = 0;
     for (int i = 0; (i < RES_BENJ_MAX) && (wordlist[i][0]); i++)
-       {
-           res[resnum++] = wxU(wordlist[i]);
-           //debug("      BenjFrame : %s (%d)\n",wordlist[i],resnum);
-           noresult = false;
-       }
+    {
+        res[resnum++] = wxU(wordlist[i]);
+        //debug("      BenjFrame : %s (%d)\n",wordlist[i],resnum);
+        noresult = false;
+    }
     listbox->Set(resnum, res);
 }
 
@@ -459,30 +457,28 @@
 void
 RaccFrame::refresh()
 {
-    std::string word;
-
     if (game->getMode() != Game::kTRAINING)
-       return;
+        return;
 
-    word = ((Training*)game)->getTestPlayWord();
+    std::wstring word = static_cast<Training*>(game)->getTestPlayWord();
     if (savedword == word)
-       {
-           noresult = false; // keep old results
-           return;
-       }
+    {
+        noresult = false; // keep old results
+        return;
+    }
     savedword = word;
     //debug("   RaccFrame::refresh : %s\n",word.c_str());
-    char wordlist[RES_RACC_MAX][DIC_WORD_MAX];
+    wchar_t wordlist[RES_RACC_MAX][DIC_WORD_MAX];
     Dic_search_Racc(game->getDic(), word.c_str(), wordlist);
 
     wxString res[RES_RACC_MAX];
     int resnum = 0;
     for (int i = 0; (i < RES_RACC_MAX) && (wordlist[i][0]); i++)
-       {
-           res[resnum++] = wxU(wordlist[i]);
-           //debug("      RaccFrame : %s (%d)\n",wordlist[i],resnum);
-           noresult = false;
-       }
+    {
+        res[resnum++] = wxU(wordlist[i]);
+        //debug("      RaccFrame : %s (%d)\n",wordlist[i],resnum);
+        noresult = false;
+    }
     listbox->Set(resnum, res);
 }
 
@@ -532,10 +528,10 @@
 #ifdef DEBUG
     mos << std::string(30,'-') << std::endl;
     mos << "Player History\n";
-    mos << m_game.getPlayer(0).toString();
+    mos << convertToMb(m_game.getPlayer(0).toString());
     mos << std::string(30,'-') << std::endl;
     mos << "Game History\n";
-    mos << m_game.getHistory().toString();
+    mos << convertToMb(m_game.getHistory().toString());
 #endif
     textbox->Clear();
     textbox->AppendText( wxU( mos.str().c_str() ) );
@@ -570,30 +566,30 @@
 ResultFrame::Refresh(refresh_t WXUNUSED(force))
 {
     if (reslist != NULL)
-       {
-           reslist->Show(false);
-           //debug("ResultFrame refresh\n");
-           reslist->Refresh();
-           reslist->Show(true);
-       }
+    {
+        reslist->Show(false);
+        //debug("ResultFrame refresh\n");
+        reslist->Refresh();
+        reslist->Show(true);
+    }
 }
 
 void
 ResultFrame::Search()
 {
     if (reslist != NULL)
-       {
-           reslist->Search();
-       }
+    {
+        reslist->Search();
+    }
 }
 
 int
 ResultFrame::GetSelected()
 {
     if (reslist != NULL)
-       {
-           return reslist->GetSelected();
-       }
+    {
+        return reslist->GetSelected();
+    }
     return -1;
 }
 
Index: eliot/wxwin/auxframes.h
diff -u eliot/wxwin/auxframes.h:1.6 eliot/wxwin/auxframes.h:1.7
--- eliot/wxwin/auxframes.h:1.6 Sun Jan  1 19:34:05 2006
+++ eliot/wxwin/auxframes.h     Sun Jan 22 12:23:53 2006
@@ -78,12 +78,12 @@
     ConfigDB    config;
 
 public:
-    AuxFrame (wxFrame*, int, wxString, wxString);
+    AuxFrame(wxFrame*, int, wxString, wxString);
     ~AuxFrame();
 
     typedef enum {
-       REFRESH,
-       FORCE_REFRESH
+        REFRESH,
+        FORCE_REFRESH
     } refresh_t;
 
     void SwitchDisplay();
@@ -99,7 +99,7 @@
 {
 protected:
     bool      noresult;
-    string    savedword;
+    wstring   savedword;
     Game      *game;
     wxButton  *button;
     wxListBox *listbox;
Index: eliot/wxwin/gfxresult.cc
diff -u eliot/wxwin/gfxresult.cc:1.4 eliot/wxwin/gfxresult.cc:1.5
--- eliot/wxwin/gfxresult.cc:1.4        Sun Jan  1 19:34:05 2006
+++ eliot/wxwin/gfxresult.cc    Sun Jan 22 12:23:53 2006
@@ -57,7 +57,7 @@
 {
     mf = _mf;
     game = _game;
-    savedrack = std::string("");
+    savedrack = L"";
     results = new wxListCtrl(this, ListCtrl_ID);
 #if defined(ENABLE_LC_NO_HEADER)
     results->SetSingleStyle(wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
@@ -99,7 +99,7 @@
 GfxResult::SetGame(Game* g)
 {
     game = g;
-    savedrack = std::string("");
+    savedrack = L"";
     results->DeleteAllItems();
 }
 
@@ -110,21 +110,21 @@
 GfxResult::Refresh()
 {
     if (game == NULL)
-       return;
+        return;
 
     debug("   GfxResult::Refresh : ");
-    std::string rack = game->getCurrentPlayer().getCurrentRack().toString();
+    std::wstring rack = game->getCurrentPlayer().getCurrentRack().toString();
 
     if (savedrack != rack)
-       {
-           debug("changed (%s -> %s)",savedrack.c_str(),rack.c_str());
-           savedrack = rack;
-           results->DeleteAllItems();
-       }
+    {
+        debug("changed (%ls -> %ls)",savedrack.c_str(),rack.c_str());
+        savedrack = rack;
+        results->DeleteAllItems();
+    }
     else
-       {
-           debug("unchanged");
-       }
+    {
+        debug("unchanged");
+    }
     debug("\n");
 }
 
@@ -136,7 +136,7 @@
 {
     debug("GfxResult::Search()\n");
     if (game == NULL)
-       return;
+        return;
 
     ((Training*)game)->search();
 
@@ -146,21 +146,21 @@
     const Results &res = ((Training*)game)->getResults();
     debug("   GfxResult::Search size = %d\n",res.size());
     for (int i = 0; i < res.size(); i++)
-       {
-           Round r = res.get(i);
-           //debug("    adding %s\n",r.toString().c_str());
-           wxString pts;
-           wxString word   = wxU(r.getWord().c_str());
-           wxString coords = wxU(r.getCoord().toString().c_str());
-           wxChar   bonus  = r.getBonus() ?  wxT('*') : wxT(' ');
-           pts << r.getPoints();
-
-           long tmp = results->InsertItem(i, word);
-           results->SetItemData(tmp, i);
-           tmp = results->SetItem(i, 1, bonus);
-           tmp = results->SetItem(i, 2, coords);
-           tmp = results->SetItem(i, 3, pts);
-       }
+    {
+        Round r = res.get(i);
+        //debug("    adding %s\n",r.toString().c_str());
+        wxString pts;
+        wxString word   = wxU(r.getWord().c_str());
+        wxString coords = wxU(r.getCoord().toString().c_str());
+        wxChar   bonus  = r.getBonus() ?  wxT('*') : wxT(' ');
+        pts << r.getPoints();
+
+        long tmp = results->InsertItem(i, word);
+        results->SetItemData(tmp, i);
+        tmp = results->SetItem(i, 1, bonus);
+        tmp = results->SetItem(i, 2, coords);
+        tmp = results->SetItem(i, 3, pts);
+    }
 
     for (int i = 0; i < 4; i++)
         results->SetColumnWidth(i, wxLIST_AUTOSIZE);
@@ -168,10 +168,10 @@
     //results->Show();
 
     if (res.size() > 0)
-       {
-           results->SetItemState(0, wxLIST_STATE_SELECTED, 
wxLIST_STATE_SELECTED | wxLIST_MASK_STATE);
-           ((Training*)game)->testPlay(0);
-       }
+    {
+        results->SetItemState(0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED 
| wxLIST_MASK_STATE);
+        ((Training*)game)->testPlay(0);
+    }
 }
 
 /* ************************************************** */
@@ -194,9 +194,9 @@
 {
     //debug("   GfxResult::OnListCtrlSelected\n");
     if (event.m_itemIndex > -1)
-       {
-           mf->TestPlay(event.m_itemIndex); 
-       }
+    {
+        mf->TestPlay(event.m_itemIndex);
+    }
 }
 
 /* ************************************************** */
@@ -207,10 +207,10 @@
 {
     //debug("   GfxResult::OnListCtrlActivated");
     if (event.m_itemIndex > -1)
-       {
-           mf->Play(1);
-           results->DeleteAllItems();
-       }
+    {
+        mf->Play(1);
+        results->DeleteAllItems();
+    }
 }
 
 /* ************************************************** */
Index: eliot/wxwin/gfxresult.h
diff -u eliot/wxwin/gfxresult.h:1.3 eliot/wxwin/gfxresult.h:1.4
--- eliot/wxwin/gfxresult.h:1.3 Sun Jan  1 19:34:05 2006
+++ eliot/wxwin/gfxresult.h     Sun Jan 22 12:23:53 2006
@@ -27,18 +27,17 @@
 #ifndef _RESLIST_H
 #define _RESLIST_H
 
-/**
- *
- */
+#include <string>
 #include <wx/listctrl.h>
 
 class MainFrame;
 
+
 class GfxResult : public wxControl
 {
  private:
     MainFrame    *mf;
-    std::string  savedrack;
+    std::wstring  savedrack;
     Game         *game;
     wxListCtrl   *results;
     ConfigDB     config;
Index: eliot/wxwin/mainframe.cc
diff -u eliot/wxwin/mainframe.cc:1.18 eliot/wxwin/mainframe.cc:1.19
--- eliot/wxwin/mainframe.cc:1.18       Sun Jan  1 19:33:51 2006
+++ eliot/wxwin/mainframe.cc    Sun Jan 22 12:23:53 2006
@@ -443,12 +443,12 @@
             return;
        }
 
-    std::string r = "";
+    std::wstring r;
 
     if (m_game->getHistory().getSize() >= 0)
-       {
-           r = m_game->getCurrentPlayer().getCurrentRack().toString();
-       }
+    {
+        r = m_game->getCurrentPlayer().getCurrentRack().toString();
+    }
 
     rack->SetValue(wxU(r.c_str()));
     // update gfxboard and all frames
@@ -962,13 +962,12 @@
 MainFrame::SetRack(Game::set_rack_mode mode, wxString srack)
 {
     int res = 0;
-    std::string str;
     wxString msg;
     bool check = config.getRackChecking();
 
-    ((Training*)m_game)->removeTestPlay();
-    str = (const char*)srack.mb_str();
-    res = ((Training*)m_game)->setRack(mode, check, str);
+    static_cast<Training*>(m_game)->removeTestPlay();
+    std::wstring str = srack.c_str();
+    res = static_cast<Training*>(m_game)->setRack(mode, check, str);
 
     switch (res)
        {
@@ -993,8 +992,8 @@
            break;
        }
 
-    std::string r = m_game->getCurrentPlayer().getCurrentRack().toString();
-    debug("MainFrame::SetRack : setvalue %s\n",r.c_str());
+    std::wstring r = m_game->getCurrentPlayer().getCurrentRack().toString();
+    debug("MainFrame::SetRack : setvalue %ls\n",r.c_str());
     rack->SetValue(wxU(r.c_str()));
     UpdateFrames();
     UpdateStatusBar();
Index: eliot/wxwin/searchpanel.cc
diff -u eliot/wxwin/searchpanel.cc:1.14 eliot/wxwin/searchpanel.cc:1.15
--- eliot/wxwin/searchpanel.cc:1.14     Mon Dec 26 13:03:22 2005
+++ eliot/wxwin/searchpanel.cc  Sun Jan 22 12:23:53 2006
@@ -139,8 +139,8 @@
 PCross::compute_enter(wxCommandEvent&)
 {
   int  i;
-  char rack[DIC_WORD_MAX];
-  char buff[RES_CROS_MAX][DIC_WORD_MAX];
+  wchar_t rack[DIC_WORD_MAX];
+  wchar_t buff[RES_CROS_MAX][DIC_WORD_MAX];
 
   if (!check_dic())
     return;
@@ -154,7 +154,7 @@
       return;
     }
 
-  strncpy(rack, t->GetValue().mb_str(), DIC_WORD_MAX);
+  wcsncpy(rack, t->GetValue().wc_str(), DIC_WORD_MAX);
   Dic_search_Cros(dic,rack,buff);
 
   int resnum = 0;
@@ -183,8 +183,8 @@
 PPlus1::compute_enter(wxCommandEvent&)
 {
   int  i,j;
-  char rack[DIC_WORD_MAX];
-  char buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
+  wchar_t rack[DIC_WORD_MAX];
+  wchar_t buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX];
 
   if (!check_dic())
     return;
@@ -198,7 +198,7 @@
       return;
     }
 
-  strncpy(rack, t->GetValue().mb_str(), DIC_WORD_MAX);
+  wcsncpy(rack, t->GetValue().wc_str(), DIC_WORD_MAX);
   Dic_search_7pl1(dic,rack,buff,TRUE);
 
   int resnum = 0;
@@ -308,15 +308,15 @@
 void
 PRegExp::compute_enter(wxCommandEvent&)
 {
-  char re[DIC_RE_MAX];
-  char buff[RES_REGE_MAX][DIC_WORD_MAX];
+  wchar_t re[DIC_RE_MAX];
+  wchar_t buff[RES_REGE_MAX][DIC_WORD_MAX];
 
   if (!check_dic())
     return;
 
   build_letter_lists();
-  strncpy(re, t->GetValue().mb_str(),DIC_RE_MAX);
-  debug("PRegExp::compute_enter for %s",re);
+  wcsncpy(re, t->GetValue().wc_str(),DIC_RE_MAX);
+  debug("PRegExp::compute_enter for %ls",re);
 
   int lmin = atoi((const char*)omin->GetValue().mb_str());
   int lmax = atoi((const char*)omax->GetValue().mb_str());




reply via email to

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