eliot-dev
[Top][All Lists]
Advanced

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

[Eliot-dev] eliot dic/encoding.cpp game/board.cpp game/boar...


From: eliot-dev
Subject: [Eliot-dev] eliot dic/encoding.cpp game/board.cpp game/boar...
Date: Sat, 13 Sep 2008 21:32:48 +0000

CVSROOT:        /cvsroot/eliot
Module name:    eliot
Changes by:     Olivier Teulière <ipkiss>      08/09/13 21:32:48

Modified files:
        dic            : encoding.cpp 
        game           : board.cpp board.h cross.cpp debug.h game.cpp 
                         game.h game_io.cpp move.cpp training.cpp 
        po             : eliot.pot fr.po 
        qt             : player_widget.cpp 
        test           : driver duplicate_humans_ai.input 
                         duplicate_humans_ai.ref training_back.ref 
                         training_joker2.ref training_play.input 
                         training_play.ref training_rosace.ref 
        utils          : eliottxt.cpp 
Added files:
        test           : freegame_play.input freegame_play.ref 

Log message:
        Core:
         - Fixed a crash on Windows
         - Do not authorize words if the cross-checks are invalid (it was 
possible when playing a joker)
         - Fixed detextion of invalid moves
         - Improved unit tests, and fixed a bug in one of them
        
        Qt interface:
         - Do not allow playing a word if the coordinates are missing
         - Better focus

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/encoding.cpp?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board.cpp?cvsroot=eliot&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board.h?cvsroot=eliot&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/eliot/game/cross.cpp?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/debug.h?cvsroot=eliot&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.cpp?cvsroot=eliot&r1=1.40&r2=1.41
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.h?cvsroot=eliot&r1=1.34&r2=1.35
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game_io.cpp?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/move.cpp?cvsroot=eliot&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/eliot/game/training.cpp?cvsroot=eliot&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/eliot/po/eliot.pot?cvsroot=eliot&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/eliot/po/fr.po?cvsroot=eliot&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/player_widget.cpp?cvsroot=eliot&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/eliot/test/driver?cvsroot=eliot&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_humans_ai.input?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_humans_ai.ref?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_back.ref?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_joker2.ref?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_play.input?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_play.ref?cvsroot=eliot&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_rosace.ref?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_play.input?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_play.ref?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/eliottxt.cpp?cvsroot=eliot&r1=1.24&r2=1.25

Patches:
Index: dic/encoding.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/encoding.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- dic/encoding.cpp    28 Jul 2008 20:24:06 -0000      1.4
+++ dic/encoding.cpp    13 Sep 2008 21:32:45 -0000      1.5
@@ -148,6 +148,8 @@
 {
 #ifdef WIN32
     const unsigned int size = iWStr.size() * 4;
+    if (size == 0)
+        return "";
     char buf[size];
     // XXX: Assume the output is in UTF-8
     int nb = writeInUTF8(iWStr, buf, size, "convertToMb");

Index: game/board.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- game/board.cpp      9 Jan 2008 10:48:19 -0000       1.19
+++ game/board.cpp      13 Sep 2008 21:32:46 -0000      1.20
@@ -91,7 +91,8 @@
     m_crossCol(BOARD_REALDIM, Cross()),
     m_pointRow(BOARD_REALDIM, -1),
     m_pointCol(BOARD_REALDIM, -1),
-    m_testsRow(BOARD_REALDIM, 0)
+    m_testsRow(BOARD_REALDIM, 0),
+    m_isEmpty(true)
 {
     // No cross check allowed around the board
     for (int i = 0; i < BOARD_REALDIM; i++)
@@ -154,12 +155,11 @@
 
 void Board::addRound(const Dictionary &iDic, const Round &iRound)
 {
-    Tile t;
-
     int row = iRound.getCoord().getRow();
     int col = iRound.getCoord().getCol();
     if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
     {
+        Tile t;
         for (unsigned int i = 0; i < iRound.getWordLen(); i++)
         {
             if (m_tilesRow[row][col + i].isEmpty())
@@ -174,6 +174,7 @@
     }
     else
     {
+        Tile t;
         for (unsigned int i = 0; i < iRound.getWordLen(); i++)
         {
             if (m_tilesRow[row + i][col].isEmpty())
@@ -187,6 +188,7 @@
         }
     }
     buildCross(iDic);
+    m_isEmpty = false;
 #ifdef DEBUG
     checkDouble();
 #endif
@@ -195,12 +197,15 @@
 
 void Board::removeRound(const Dictionary &iDic, const Round &iRound)
 {
+    ASSERT(!m_isEmpty, "The board should not be empty");
     int row = iRound.getCoord().getRow();
     int col = iRound.getCoord().getCol();
     if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
     {
         for (unsigned int i = 0; i < iRound.getWordLen(); i++)
         {
+            ASSERT(iRound.getTile(i).toCode() == m_tilesRow[row][col + 
i].toCode(),
+                   "Invalid round removal");
             if (iRound.isPlayedFromRack(i))
             {
                 m_tilesRow[row][col + i] = Tile();
@@ -216,6 +221,8 @@
     {
         for (unsigned int i = 0; i < iRound.getWordLen(); i++)
         {
+            ASSERT(iRound.getTile(i).toCode() == m_tilesRow[row + 
i][col].toCode(),
+                   "Invalid round removal");
             if (iRound.isPlayedFromRack(i))
             {
                 m_tilesRow[row + i][col] = Tile();
@@ -231,6 +238,17 @@
 #ifdef DEBUG
     checkDouble();
 #endif
+
+    // Update the m_isEmpty flag
+    for (int i = 1; i <= BOARD_DIM; i++)
+    {
+        for (int j = 1; j <= BOARD_DIM; j++)
+        {
+            if (!m_tilesRow[i][j].isEmpty())
+                return;
+        }
+    }
+    m_isEmpty = true;
 }
 
 
@@ -240,8 +258,7 @@
                          Matrix<Cross> &iCrossMx,
                          Matrix<int> &iPointsMx,
                          Matrix<bool> &iJokerMx,
-                         Round &iRound,
-                         bool firstturn)
+                         Round &iRound)
 {
     Tile t;
     int l, p;
@@ -254,7 +271,11 @@
     int row = iRound.getCoord().getRow();
     int col = iRound.getCoord().getCol();
 
-    /* Is the word an extension of another word? */
+    // Is the word going out of the board?
+    if (col + iRound.getWordLen() > BOARD_MAX + 1)
+        return 8;
+
+    // Is the word an extension of another word?
     if (!iTilesMx[row][col - 1].isEmpty() ||
         !iTilesMx[row][col + iRound.getWordLen()].isEmpty())
     {
@@ -266,21 +287,18 @@
         t = iRound.getTile(i);
         if (!iTilesMx[row][col + i].isEmpty())
         {
-            /* There is already a letter on the board */
+            // There is already a letter on the board
             if (iTilesMx[row][col + i] != t)
             {
-                /* Check if it is only a joker */
+                // Check if it is only a joker
                 if ((iTilesMx[row][col+i].toCode() == t.toCode()) && 
iTilesMx[row][col+i].isJoker())
                 {
                     // Do nothing, we don't need to change the tile in the 
round
-                    // iRound.setJoker(i,true);
-                    debug("load: play on joker for letter %d (%lc)\n", i, 
iRound.getTile(i).toChar());
+                    //iRound.setJoker(i,true);
                 }
                 else
                 {
-                    debug("load: overwriting tile %lc with %lc\n",
-                          iTilesMx[row][col+i].toChar(),
-                          t.toChar());
+                    // Trying to overwrite a placed letter
                     return 2;
                 }
             }
@@ -293,10 +311,10 @@
         }
         else
         {
-            /* The letter is not yet on the board */
+            // The letter is not yet on the board
             if (iCrossMx[row][col + i].check(t))
             {
-                /* A non-trivial cross-check means an anchor square */
+                // A non-trivial cross-check means an anchor square
                 if (!iCrossMx[row][col + i].isAny())
                     isolated = false;
 
@@ -317,31 +335,31 @@
             }
             else
             {
-                /* The letter is not in the crosscheck */
+                // The letter is not in the crosscheck
                 return 3;
             }
         }
     }
 
-    /* There must be at least 1 letter from the rack */
+    // There must be at least 1 letter from the rack
     if (fromrack == 0)
         return 4;
 
     /* The word must cover at least one anchor square, except
      * for the first turn */
-    if (isolated && !firstturn)
+    if (isolated && !m_isEmpty)
         return 5;
-    /* The first word must be horizontal */
-    if (firstturn && iRound.getCoord().getDir() == Coord::VERTICAL)
+    // The first word must be horizontal
+    if (m_isEmpty && iRound.getCoord().getDir() == Coord::VERTICAL)
         return 6;
-    /* The first word must cover the H8 square */
-    if (firstturn
+    // The first word must cover the H8 square
+    if (m_isEmpty
         && (row != 8 || col > 8 || col + iRound.getWordLen() <= 8))
     {
         return 7;
     }
 
-    /* Set the iPointsMx and bonus */
+    // Set the iPointsMx and bonus
     pts = ptscross + pts * wordmul + Game::BONUS_POINTS * (fromrack == 
Game::RACK_SIZE);
     iRound.setPoints(pts);
     iRound.setBonus(fromrack == Game::RACK_SIZE);
@@ -350,13 +368,12 @@
 }
 
 
-int Board::checkRound(Round &iRound, bool firstturn)
+int Board::checkRound(Round &iRound)
 {
     if (iRound.getCoord().getDir() == Coord::HORIZONTAL)
     {
         return checkRoundAux(m_tilesRow, m_crossRow,
-                             m_pointRow, m_jokerRow,
-                             iRound, firstturn);
+                             m_pointRow, m_jokerRow, iRound);
     }
     else
     {
@@ -365,8 +382,7 @@
         iRound.accessCoord().swap();
 
         int res = checkRoundAux(m_tilesCol, m_crossCol,
-                                m_pointCol, m_jokerCol,
-                                iRound, firstturn);
+                                m_pointCol, m_jokerCol, iRound);
 
         // Restore the coordinates
         iRound.accessCoord().swap();
@@ -466,7 +482,7 @@
 
 string Board::getCellContent_row(int row, int col) const
 {
-    char buff[1024];  /* [ joker, mask, point, tiles ] */
+    char buff[1024];  // [ joker, mask, point, tiles ]
     sprintf(buff,CELL_STRING_FORMAT,
             // m_jokerRow[row][col] ? 'j':'.',
             m_crossRow[row][col].getHexContent().c_str(),

Index: game/board.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- game/board.h        9 Jan 2008 10:48:19 -0000       1.15
+++ game/board.h        13 Sep 2008 21:32:46 -0000      1.16
@@ -89,7 +89,7 @@
 
     void addRound(const Dictionary &iDic, const Round &iRound);
     void removeRound(const Dictionary &iDic, const Round &iRound);
-    int  checkRound(Round &iRound, bool iFirstTurn);
+    int  checkRound(Round &iRound);
 
     /**
      *
@@ -137,6 +137,9 @@
 
     Matrix<char> m_testsRow;
 
+    /// Flag indicating if the board is empty or if it has letters
+    bool m_isEmpty;
+
     static const int m_tileMultipliers[BOARD_REALDIM][BOARD_REALDIM];
     static const int m_wordMultipliers[BOARD_REALDIM][BOARD_REALDIM];
 
@@ -144,8 +147,7 @@
                       Matrix<Cross> &iCrossMx,
                       Matrix<int> &iPointsMx,
                       Matrix<bool> &iJokerMx,
-                      Round &iRound,
-                      bool firstturn);
+                      Round &iRound);
 #ifdef DEBUG
     void checkDouble();
 #endif

Index: game/cross.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/cross.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- game/cross.cpp      8 Jan 2008 13:52:37 -0000       1.8
+++ game/cross.cpp      13 Sep 2008 21:32:46 -0000      1.9
@@ -55,7 +55,7 @@
 
 bool Cross::check(const Tile& iTile) const
 {
-    return (iTile.isJoker() && m_mask != 0) || (m_mask & (1 << 
iTile.toCode()));
+    return m_mask & (1 << iTile.toCode());
 }
 
 

Index: game/debug.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/debug.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- game/debug.h        8 Jan 2008 13:52:37 -0000       1.12
+++ game/debug.h        13 Sep 2008 21:32:46 -0000      1.13
@@ -43,12 +43,6 @@
 #   define ASSERT(cond, msg)
 #endif
 
-#ifdef DEBUG
-#  define debug(x...) { fprintf(stderr,x); }
-#else
-#  define debug(x...)
-#endif
-
 #endif
 
 /// Local Variables:

Index: game/game.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -b -r1.40 -r1.41
--- game/game.cpp       31 Aug 2008 11:48:15 -0000      1.40
+++ game/game.cpp       13 Sep 2008 21:32:46 -0000      1.41
@@ -30,6 +30,7 @@
 #include "game_factory.h"
 #include "turn.h"
 #include "encoding.h"
+#include "game_exception.h"
 
 #include "debug.h"
 
@@ -70,7 +71,6 @@
     m_history.playMove(iPlayerId, m_history.getSize(), iMove);
 
     // Points
-    debug("    helper: %d points\n", iMove.getScore());
     m_points += iMove.getScore();
 
     // For moves corresponding to a valid round, we have much more
@@ -85,18 +85,22 @@
 
 void Game::helperPlayRound(unsigned int iPlayerId, const Round &iRound)
 {
+    // Copy the round, because we may need to modify it (case of
+    // the joker games).
+    Round round = iRound;
+
     // Before updating the bag and the board, if we are playing a "joker game",
     // we replace in the round the joker by the letter it represents
     // This is currently done by a succession of ugly hacks :-/
     if (m_variant == kJOKER)
     {
-        for (unsigned int i = 0; i < iRound.getWordLen(); i++)
+        for (unsigned int i = 0; i < round.getWordLen(); i++)
         {
-            if (iRound.isPlayedFromRack(i) && iRound.isJoker(i))
+            if (round.isPlayedFromRack(i) && round.isJoker(i))
             {
                 // Is the represented letter still available in the bag?
                 // XXX: this way to get the represented letter sucks...
-                Tile t(towupper(iRound.getTile(i).toChar()));
+                Tile t(towupper(round.getTile(i).toChar()));
                 Bag bag(m_dic);
                 realBag(bag);
                 // FIXME: realBag() does not give us a real bag in this
@@ -125,12 +129,11 @@
 
                 if (bag.in(t))
                 {
-                    // FIXME: A const_cast sucks too...
-                    const_cast<Round&>(iRound).setTile(i, t);
-                    // FIXME: This shouldn't be necessary either, this is only
+                    round.setTile(i, t);
+                    // FIXME: This shouldn't be necessary, this is only
                     // needed because of the stupid way of handling jokers in
                     // rounds
-                    const_cast<Round&>(iRound).setJoker(i, false);
+                    round.setJoker(i, false);
                 }
 
                 // In a joker game we should have only 1 joker in the rack
@@ -144,32 +147,30 @@
     // on the board. When going back in the game, we must only
     // replace played tiles.
     // We test a rack when it is set but tiles are left in the bag.
-    for (unsigned int i = 0; i < iRound.getWordLen(); i++)
+    for (unsigned int i = 0; i < round.getWordLen(); i++)
     {
-        if (iRound.isPlayedFromRack(i))
+        if (round.isPlayedFromRack(i))
         {
-            if (iRound.isJoker(i))
+            if (round.isJoker(i))
             {
                 m_bag.takeTile(Tile::Joker());
             }
             else
             {
-                m_bag.takeTile(iRound.getTile(i));
+                m_bag.takeTile(round.getTile(i));
             }
         }
     }
 
     // Update the board
-    m_board.addRound(m_dic, iRound);
+    m_board.addRound(m_dic, round);
 }
 
 
 int Game::back(unsigned int n)
 {
-    debug("Game::back %d\n",n);
-    // TODO: throw an exception
     if (m_history.getSize() < n)
-        return 1;
+        throw GameException("Cannot go back that far");
 
     for (unsigned int i = 0; i < n; i++)
     {
@@ -180,10 +181,8 @@
             continue;
 
         const Round &lastround = lastMove.getRound();
-        debug("Game::back last round %s\n",
-              convertToMb(lastround.toString()).c_str());
-        /* Remove the word from the board, and put its letters back
-         * into the bag */
+        // Remove the word from the board, and put its letters back
+        // into the bag
         m_board.removeRound(m_dic, lastround);
         for (unsigned int j = 0; j < lastround.getWordLen(); j++)
         {
@@ -195,9 +194,9 @@
                     m_bag.replaceTile(lastround.getTile(j));
             }
         }
-        /* Remove the points of this round */
+        // Remove the points of this round
         m_points -= lastround.getPoints();
-        /* Remove the turns */
+        // Remove the turns
         m_players[m_currPlayer]->removeLastTurn();
         m_history.removeLastTurn();
     }
@@ -209,13 +208,13 @@
 {
     vector<Tile> tiles;
 
-    /* Copy the bag */
+    // Copy the bag
     ioBag = m_bag;
 
-    /* The real content of the bag depends on the game mode */
+    // The real content of the bag depends on the game mode
     if (getMode() == kFREEGAME)
     {
-        /* In freegame mode, take the letters from all the racks */
+        // In freegame mode, take the letters from all the racks
         for (unsigned int i = 0; i < getNPlayers(); i++)
         {
             getPlayer(i).getCurrentRack().getAllTiles(tiles);
@@ -296,7 +295,7 @@
     }
     else
     {
-        debug("Game::helperSetRackRandom not a random mode\n");
+        throw GameException("Not a random mode");
     }
 
     // Get the tiles remaining on the rack
@@ -568,7 +567,6 @@
     oRound.accessCoord().setFromString(iCoord);
     if (!oRound.getCoord().isValid())
     {
-        debug("game: incorrect coordinates\n");
         return 2;
     }
 
@@ -596,7 +594,7 @@
 
     // Check the word position, compute its points,
     // and specify the origin of each letter (board or rack)
-    int res = m_board.checkRound(oRound, m_history.getSize() == 0);
+    int res = m_board.checkRound(oRound);
     if (res != 0)
         return res + 4;
 

Index: game/game.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -b -r1.34 -r1.35
--- game/game.h 28 Jan 2008 19:17:34 -0000      1.34
+++ game/game.h 13 Sep 2008 21:32:46 -0000      1.35
@@ -140,11 +140,12 @@
      *  4: not enough letters in the rack to play the word
      *  5: word is part of a longer one
      *  6: word overwriting an existing letter
-     *  7: invalid crosscheck, or word going out of the board
+     *  7: invalid crosscheck
      *  8: word already present on the board (no new letter from the rack)
      *  9: isolated word (not connected to the rest)
      * 10: first word not horizontal
      * 11: first word not covering the H8 square
+     * 12: word going out of the board
      */
     virtual int play(const wstring &iCoord, const wstring &iWord) = 0;
 

Index: game/game_io.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game_io.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- game/game_io.cpp    20 Jul 2008 12:15:52 -0000      1.9
+++ game/game_io.cpp    13 Sep 2008 21:32:46 -0000      1.10
@@ -34,7 +34,7 @@
 #include "freegame.h"
 #include "duplicate.h"
 #include "encoding.h"
-#include "debug.h"
+#include "game_exception.h"
 
 using namespace std;
 
@@ -63,37 +63,31 @@
     // Check characteristic string
     if (fgets(buff, sizeof(buff), fin) == NULL)
     {
-        debug("Game::load cannot load first line\n");
-        return NULL;
+        throw GameException("Cannot recognize the first line");
     }
 
     if ((token = strtok(buff, delim)) == NULL)
     {
-        debug("Game::load first line is empty\n");
-        return NULL;
+        throw GameException("The first line is empty");
     }
 
     /* checks for IDENT_STRING and file format */
     if (string(token) != IDENT_STRING)
     {
-        debug("Game::load IDENT_STRING %s unknown\n",token);
-        return NULL;
+        throw GameException("Invalid identity string: " + string(token));
     }
 
     if ((token = strtok(NULL, delim)) == NULL)
     {
-        debug("Game_io::loading file format 1.4\n");
         return Game::gameLoadFormat_14(fin,iDic);
     }
 
     if (string(token) == string(IDENT_FORMAT_15))
     {
-        debug("Game_io::loading file format 1.5\n");
         return Game::gameLoadFormat_15(fin,iDic);
     }
 
-    debug("Game::load unknown format %s\n",token);
-    return NULL;
+    throw GameException("Unknown format: " + string(token));
 }
 
 
@@ -110,7 +104,6 @@
     char *token;
     Game *pGame = NULL;
 
-    debug("Game::gameLoadFormat_14\n");
     pGame = GameFactory::Instance()->createTraining(iDic);
     pGame->start();
 
@@ -124,7 +117,6 @@
         token = strtok(buff, delim);
         if (token != NULL)
         {
-            debug("======== \n");
             if (strcmp(token, "total") == 0)
             {
                 break;
@@ -134,7 +126,6 @@
             strncpy(rack, token, sizeof(rack));
             static_cast<Training*>(pGame)->setRack(RACK_MANUAL, false,
                                                    convertToWc(rack));
-            debug("load: %8s ", rack);
             
             /* word */
             token = strtok(NULL, delim);
@@ -144,7 +135,6 @@
             }
 
             strncpy(word, token, sizeof(word));
-            debug(" %12s ", word);
             
             /* bonus */
             if ((token = strtok(NULL, delim)) == NULL)
@@ -153,14 +143,9 @@
             /* points */
             if (token[0] == '*')
             {
-                debug("%s\t", token);
                 if ((token = strtok(NULL, delim)) == NULL)
                     break;
             }
-            else
-            {
-                debug(" \t");
-            }
 
             /* pos 1 */
             if ((token = strtok(NULL, delim)) == NULL)
@@ -175,13 +160,16 @@
 
             //debug("%s)", token);
             strncat(pos, token, sizeof(pos));
-            debug("%s\n", pos);
 
             if ((ret = pGame->play(convertToWc(pos), convertToWc(word))))
             {
-                debug("loading error %d on line %d\n",ret,line);
                 GameFactory::Instance()->releaseGame(*pGame);
-                return NULL;
+                char tmp1[10];
+                snprintf(tmp1, 10, "%d", ret);
+                char tmp2[10];
+                snprintf(tmp2, 10, "%d", ret);
+                throw GameException("Loading error " + string(tmp1) +
+                                    " on line " + string(tmp2));
             }
         }
     }
@@ -215,32 +203,26 @@
             // Create the correct Game object
             if (strstr(buff, "Training"))
             {
-                debug("Game::gameLoadFormat_15 new Training\n");
                 pGame = GameFactory::Instance()->createTraining(iDic);
                 break;
             }
             else if (strstr(buff, "Free game"))
             {
-                debug("Game::gameLoadFormat_15 new Freegame\n");
                 pGame = GameFactory::Instance()->createFreeGame(iDic);
                 break;
             }
             else if (strstr(buff, "Duplicate"))
             {
-                debug("Game::gameLoadFormat_15 new Duplicate\n");
                 pGame = GameFactory::Instance()->createDuplicate(iDic);
                 break;
             }
             else
             {
-                debug("Game::gameLoadFormat_15 unknown Game type\n");
-                return NULL;
+                throw GameException("Unknown game type");
             }
         }
     }
 
-    debug("   Game type is ok, switching to player list\n");
-
     /***************/
     /* Player List */
     /***************/
@@ -257,25 +239,21 @@
             {
                 if (string(type) == "Human")
                 {
-                    debug("   add Human player\n");
                     pGame->addPlayer(new HumanPlayer);
                 }
                 else if (string(type) == "Computer")
                 {
                     if (pGame->getMode() == kTRAINING)
                     {
-                        debug("   mode == TRAINING, skip player list since we 
have a computer player\n");
                         break;
                     }
                     else
                     {
-                        debug("   add Computer player\n");
                         pGame->addPlayer(new AIPercent(1));
                     }
                 }
                 else
                 {
-                    debug("   unknown player, bailing out\n");
                     delete pGame;
                     return NULL;
                 }
@@ -283,13 +261,10 @@
         }
         else if (strstr(buff," N |   RACK   "))
         {
-            debug("   ok for player list, going turn list\n");
             break;
         }
     }
 
-    debug("   Player list ok, switching to turn list \n");
-
     /*************/
     /* Turn list */
     /*************/
@@ -299,20 +274,17 @@
         // Skip columns title
         if (strstr(buff,"| PTS | P |") != NULL)
         {
-            debug("   ** PTS line, skiping\n");
             continue;
         }
 
         // Skip columns title
         if (strstr(buff, "==") != NULL)
         {
-            debug("   ** == line, skiping\n");
             continue;
         }
 
         if (string(buff) == "\n")
         {
-            debug("   ** empty line\n");
             continue;
         }
 
@@ -327,32 +299,26 @@
         int res = sscanf(buff, "   %2d | %8s | %s | %3s | %3d | %1u | %c",
                          &num, rack, tmpWord, ref, &pts, &player, &bonus);
 
-        debug("   -- line %s",buff);
-
         if (res < 6)
         {
-            debug("   Game::load15 invalid line -%s-\n",buff);
             continue;
         }
 
-        debug("              %2d | %8s | %s | %3s | %3d | %1d | %c \n",
-              num, rack, tmpWord, ref, pts, player, bonus);
+        //debug("              %2d | %8s | %s | %3s | %3d | %1d | %c \n",
+        //      num, rack, tmpWord, ref, pts, player, bonus);
 
         // Integrity checks
         // TODO: add more checks
         if (pts < 0)
         {
-            debug("   Game::load15 line -%s- points < 0  ?\n",buff);
             continue;
         }
         if (player > pGame->getNPlayers())
         {
-            debug("   Game::load15 line -%s- too much player 
(%d>%d)",buff,player,pGame->getNPlayers());
             continue;
         }
         if (bonus && bonus != '*')
         {
-            debug("   Game::load15 line -%s- wring bonus sign\n",buff);
             continue;
         }
 
@@ -360,10 +326,9 @@
         PlayedRack pldrack;
         if (!iDic.validateLetters(convertToWc(rack)))
         {
-            debug("   Game::load15 rack invalid for the current dictionary\n");
+            throw GameException("Rack invalid for the current dictionary");
         }
         pldrack.setManual(convertToWc(rack));
-        debug("    history rack %s\n", 
convertToMb(pldrack.toString()).c_str());
 
         // Build a round
         Round round;

Index: game/move.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/move.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- game/move.cpp       8 Jan 2008 13:52:38 -0000       1.2
+++ game/move.cpp       13 Sep 2008 21:32:46 -0000      1.3
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 #include <wctype.h>
+#include <sstream>
 
 #include "move.h"
 
@@ -101,7 +102,16 @@
 
 wstring Move::toString() const
 {
-    // TODO
-    return L"";
+    wstringstream wss;
+    if (m_type == PASS)
+        wss << "PASS";
+    else if (m_type == CHANGE_LETTERS)
+        wss << "CHANGE=" << m_letters;
+    else if (m_type == INVALID_WORD)
+        wss << "INVALID: word=" << m_round.toString() << "  coords=" << 
m_coord;
+    else if (m_type == VALID_ROUND)
+        wss << "VALID: word=" << m_round.toString();
+    wss << "  score=" << m_score;
+    return wss.str();
 }
 

Index: game/training.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/training.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- game/training.cpp   28 Jan 2008 19:17:35 -0000      1.21
+++ game/training.cpp   13 Sep 2008 21:32:46 -0000      1.22
@@ -104,15 +104,9 @@
     int res = checkPlayedWord(iCoord, iWord, round);
     if (res != 0)
     {
-        debug("check returned with an error %d\n",res);
         return res;
     }
 
-    debug("play: %s %s %d\n",
-          convertToMb(round.getWord()).c_str(),
-          convertToMb(round.getCoord().toString()).c_str(),
-          round.getPoints());
-
     Move move(round);
     // Update the rack and the score of the current player
     // Player::endTurn() must be called before Game::helperPlayMove().
@@ -150,7 +144,6 @@
     // Search for the current player
     Rack r;
     m_players[m_currPlayer]->getCurrentRack().getRack(r);
-    debug("Training::search for %s\n", convertToMb(r.toString()).c_str());
     m_results.search(m_dic, m_board, r, m_history.beforeFirstRound());
 }
 

Index: po/eliot.pot
===================================================================
RCS file: /cvsroot/eliot/eliot/po/eliot.pot,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- po/eliot.pot        7 Sep 2008 21:06:17 -0000       1.14
+++ po/eliot.pot        13 Sep 2008 21:32:46 -0000      1.15
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-07 22:31+0200\n"
+"POT-Creation-Date: 2008-09-11 23:04+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <address@hidden>\n"
 "Language-Team: LANGUAGE <address@hidden>\n"
@@ -1538,67 +1538,71 @@
 "E.g.: H4 or 4H"
 msgstr ""
 
-#: qt/player_widget.cpp:173
+#: qt/player_widget.cpp:177
 msgid "Cannot play word: misplaced parentheses"
 msgstr ""
 
-#: qt/player_widget.cpp:194
+#: qt/player_widget.cpp:199
 msgid "Cannot play '%1' at position '%2':\n"
 msgstr ""
 
-#: qt/player_widget.cpp:198
+#: qt/player_widget.cpp:204
 msgid "Some letters are not valid for the current dictionary"
 msgstr ""
 
-#: qt/player_widget.cpp:201
+#: qt/player_widget.cpp:207
 msgid "Invalid coordinates"
 msgstr ""
 
-#: qt/player_widget.cpp:204
+#: qt/player_widget.cpp:210
 msgid "The word does not exist"
 msgstr ""
 
-#: qt/player_widget.cpp:207
+#: qt/player_widget.cpp:213
 msgid "The rack doesn't contain the letters needed to play this word"
 msgstr ""
 
-#: qt/player_widget.cpp:210
+#: qt/player_widget.cpp:216
 msgid "The word is part of a longer one"
 msgstr ""
 
-#: qt/player_widget.cpp:213
+#: qt/player_widget.cpp:219
 msgid "The word tries to replace an existing letter"
 msgstr ""
 
-#: qt/player_widget.cpp:216
-msgid "The word is going out of the board, or an orthogonal word is not valid"
+#: qt/player_widget.cpp:222
+msgid "An orthogonal word is not valid"
 msgstr ""
 
-#: qt/player_widget.cpp:219
+#: qt/player_widget.cpp:225
 msgid "The word is already present on the board at these coordinates"
 msgstr ""
 
-#: qt/player_widget.cpp:222
+#: qt/player_widget.cpp:228
 msgid "A word cannot be isolated (not connected to the placed words)"
 msgstr ""
 
-#: qt/player_widget.cpp:225
+#: qt/player_widget.cpp:231
 msgid "The first word of the game must be horizontal"
 msgstr ""
 
-#: qt/player_widget.cpp:228
+#: qt/player_widget.cpp:234
 msgid "The first word of the game must cover the H8 square"
 msgstr ""
 
-#: qt/player_widget.cpp:231
+#: qt/player_widget.cpp:237
+msgid "The word is going out of the board"
+msgstr ""
+
+#: qt/player_widget.cpp:240
 msgid "Incorrect or misplaced word (%1)"
 msgstr ""
 
-#: qt/player_widget.cpp:255
+#: qt/player_widget.cpp:264
 msgid "Cannot pass turn (%1)"
 msgstr ""
 
-#: qt/player_widget.cpp:257
+#: qt/player_widget.cpp:266
 msgid "Cannot change letters '%1' (%2)"
 msgstr ""
 

Index: po/fr.po
===================================================================
RCS file: /cvsroot/eliot/eliot/po/fr.po,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- po/fr.po    7 Sep 2008 21:06:17 -0000       1.15
+++ po/fr.po    13 Sep 2008 21:32:46 -0000      1.16
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: eliot 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-07 22:31+0200\n"
+"POT-Creation-Date: 2008-09-11 23:04+0200\n"
 "PO-Revision-Date: 2008-08-31 10:43+0100\n"
 "Last-Translator: Olivier Teuliere <address@hidden>\n"
 "Language-Team: French <address@hidden>\n"
@@ -1587,68 +1587,72 @@
 "et la colonne avant la rangée pour les mots verticaux.\n"
 "Ex. : H4 ou 4H"
 
-#: qt/player_widget.cpp:173
+#: qt/player_widget.cpp:177
 msgid "Cannot play word: misplaced parentheses"
 msgstr "Impossible de jouer le mot : parenthèses mal placées"
 
-#: qt/player_widget.cpp:194
+#: qt/player_widget.cpp:199
 msgid "Cannot play '%1' at position '%2':\n"
 msgstr "Impossible de jouer '%1' en '%2' :\n"
 
-#: qt/player_widget.cpp:198
+#: qt/player_widget.cpp:204
 msgid "Some letters are not valid for the current dictionary"
 msgstr ""
 "Le tirage contient des lettres incorrectes pour le dictionnaire courant"
 
-#: qt/player_widget.cpp:201
+#: qt/player_widget.cpp:207
 msgid "Invalid coordinates"
 msgstr "Coordonnées invalides"
 
-#: qt/player_widget.cpp:204
+#: qt/player_widget.cpp:210
 msgid "The word does not exist"
 msgstr "Le mot n'existe pas"
 
-#: qt/player_widget.cpp:207
+#: qt/player_widget.cpp:213
 msgid "The rack doesn't contain the letters needed to play this word"
 msgstr "Le chevalet ne contient pas les lettres permettant de jouer ce mot"
 
-#: qt/player_widget.cpp:210
+#: qt/player_widget.cpp:216
 msgid "The word is part of a longer one"
 msgstr "Le mot fait partie d'un autre mot plus long"
 
-#: qt/player_widget.cpp:213
+#: qt/player_widget.cpp:219
 msgid "The word tries to replace an existing letter"
 msgstr "Le mot remplace une lettre existante"
 
-#: qt/player_widget.cpp:216
-msgid "The word is going out of the board, or an orthogonal word is not valid"
-msgstr "Le mot sort de la grille, ou un mot orthogonal est invalide"
+#: qt/player_widget.cpp:222
+msgid "An orthogonal word is not valid"
+msgstr "Un mot perpendiculaire est invalide"
 
-#: qt/player_widget.cpp:219
+#: qt/player_widget.cpp:225
 msgid "The word is already present on the board at these coordinates"
 msgstr "Le mot est déjà présent sur la grille à cette position"
 
-#: qt/player_widget.cpp:222
+#: qt/player_widget.cpp:228
 msgid "A word cannot be isolated (not connected to the placed words)"
 msgstr "Un mot ne peut pas être isolé (non connecté aux autres mots 
placés)"
 
-#: qt/player_widget.cpp:225
+#: qt/player_widget.cpp:231
 msgid "The first word of the game must be horizontal"
 msgstr "Le premier mot de la partie doit être horizontal"
 
-#: qt/player_widget.cpp:228
+#: qt/player_widget.cpp:234
 msgid "The first word of the game must cover the H8 square"
 msgstr "Le premier mot de la partie doit couvrir la case H8"
 
-#: qt/player_widget.cpp:231
+#: qt/player_widget.cpp:237
+msgid "The word is going out of the board"
+msgstr "Le mot sort de la grille"
+
+#: qt/player_widget.cpp:240
 msgid "Incorrect or misplaced word (%1)"
 msgstr "Mot incorrect ou mal placé (%1)"
 
-#: qt/player_widget.cpp:255
+#: qt/player_widget.cpp:264
 msgid "Cannot pass turn (%1)"
 msgstr "Impossible de passer le tour (%1)"
 
-#: qt/player_widget.cpp:257
+#: qt/player_widget.cpp:266
 msgid "Cannot change letters '%1' (%2)"
 msgstr "Impossible de changer les lettres '%1' (%2)"
 

Index: qt/player_widget.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/player_widget.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- qt/player_widget.cpp        7 Sep 2008 21:06:17 -0000       1.7
+++ qt/player_widget.cpp        13 Sep 2008 21:32:47 -0000      1.8
@@ -160,6 +160,10 @@
 
 void PlayerWidget::on_lineEditPlay_returnPressed()
 {
+    if (!lineEditPlay->hasAcceptableInput() ||
+        !lineEditCoords->hasAcceptableInput())
+        return;
+
     // Convert the jokers to lowercase
     QString word = lineEditPlay->text().toUpper();
     int pos;
@@ -187,6 +191,7 @@
     if (res == 0)
     {
         emit gameUpdated();
+        lineEditPlay->setFocus();
     }
     else
     {
@@ -214,7 +219,7 @@
                 msg += _q("The word tries to replace an existing letter");
                 break;
             case 7:
-                msg += _q("The word is going out of the board, or an 
orthogonal word is not valid");
+                msg += _q("An orthogonal word is not valid");
                 break;
             case 8:
                 msg += _q("The word is already present on the board at these 
coordinates");
@@ -228,6 +233,9 @@
             case 11:
                 msg += _q("The first word of the game must cover the H8 
square");
                 break;
+            case 12:
+                msg += _q("The word is going out of the board");
+                break;
             default:
                 msg += _q("Incorrect or misplaced word (%1)").arg(1);
         }
@@ -306,7 +314,7 @@
     copy.remove(')');
     // The string is invalid if it contains characters not present
     // in the dictionary
-    if (!m_dic.validateLetters(qtw(copy)))
+    if (!m_dic.validateLetters(qtw(copy)) || copy.contains('?'))
         return Invalid;
 
     // Check the parentheses pairs

Index: test/driver
===================================================================
RCS file: /cvsroot/eliot/eliot/test/driver,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- test/driver 15 Jan 2008 14:56:38 -0000      1.8
+++ test/driver 13 Sep 2008 21:32:47 -0000      1.9
@@ -60,6 +60,8 @@
 # Free game mode
 #################
 
+# 1 human plays and/or passes
+freegame_play       7
 # The human player always passes, letting the AI player do what it wants
 freegame_passing    1
 # 2 human players, changing letters a lot

Index: test/duplicate_humans_ai.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/duplicate_humans_ai.input,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- test/duplicate_humans_ai.input      4 Jul 2008 19:03:13 -0000       1.4
+++ test/duplicate_humans_ai.input      13 Sep 2008 21:32:47 -0000      1.5
@@ -11,7 +11,7 @@
 a S
 a t
 j FRaYE 5E
-j hYPER 5G
+j BoY 5F
 a S
 a t
 a g

Index: test/duplicate_humans_ai.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/duplicate_humans_ai.ref,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- test/duplicate_humans_ai.ref        4 Jul 2008 19:03:13 -0000       1.4
+++ test/duplicate_humans_ai.ref        13 Sep 2008 21:32:47 -0000      1.5
@@ -30,10 +30,10 @@
 commande> a t
 P?RBFEG
 commande> j FRaYE 5E
-commande> j hYPER 5G
+commande> j BoY 5F
 commande> a S
 Joueur 0:  124
-Joueur 1:  106
+Joueur 1:   93
 Joueur 2:  138
 commande> a t
 BGPBEET

Index: test/training_back.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_back.ref,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- test/training_back.ref      4 Jul 2008 19:03:13 -0000       1.6
+++ test/training_back.ref      13 Sep 2008 21:32:47 -0000      1.7
@@ -107,6 +107,7 @@
  A B C D  E F G H I J K L M N O P Q R S T U V W X Y Z ?
  9 2 2 3 15 2 2 2 8 1 1 5 3 6 6 2 1 6 6 6 6 2 1 1 1 1 2
 commande> n -1
+Cannot go back that far
 commande> a s
 0
 commande> t IEIEIEF

Index: test/training_joker2.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_joker2.ref,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- test/training_joker2.ref    3 Mar 2008 22:14:00 -0000       1.4
+++ test/training_joker2.ref    13 Sep 2008 21:32:47 -0000      1.5
@@ -78,8 +78,8 @@
   3: GUEUSANt        *  66 11C
   4: NUaGEUSe        *  66 D1
   5: ENjUGUeS        *  64 D2
-  6: GUeUSENt        *  64 D6
-  7: GUEUSeNt        *  64 D3
+  6: GUEUSeNt        *  64 D3
+  7: GUeUSENt        *  64 D6
   8: NUaGeUSE        *  64 D4
   9: GUeUSENT        *  62 F1
  10: GUEUSaNT        *  60 F1

Index: test/training_play.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_play.input,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- test/training_play.input    4 Jul 2008 19:03:13 -0000       1.4
+++ test/training_play.input    13 Sep 2008 21:32:47 -0000      1.5
@@ -1,5 +1,6 @@
 e
 t IEJDEUE
+j INVéLID h4
 j INVALID XX
 j INVALID H5
 j MAUVAIS H5
@@ -7,7 +8,6 @@
 j JEUDI A6
 r
 a r
-n 0
 n 6
 a t
 t DEEIPEG
@@ -19,7 +19,13 @@
 j SE H7
 j SE G6
 j PIEGEE 7C
-j PIEGEES 7C
+j PIEGEES 7c
+a t
+a g
+j PIEGEE c7
+a t
+t ADEEPSS
+j DEPASSE b12
 a t
 a g
 q

Index: test/training_play.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_play.ref,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- test/training_play.ref      4 Jul 2008 19:03:13 -0000       1.6
+++ test/training_play.ref      13 Sep 2008 21:32:47 -0000      1.7
@@ -3,6 +3,8 @@
 mode entraînement
 [?] pour l'aide
 commande> t IEJDEUE
+commande> j INVéLID h4
+Mot incorrect ou mal placé (1)
 commande> j INVALID XX
 Mot incorrect ou mal placé (2)
 commande> j INVALID H5
@@ -25,7 +27,6 @@
   8: JEU                20 H8
   9: JE                 18 H7
  10: JE                 18 H8
-commande> n 0
 commande> n 6
 commande> a t
 DEEI
@@ -44,7 +45,7 @@
 Mot incorrect ou mal placé (7)
 commande> j PIEGEE 7C
 Mot incorrect ou mal placé (8)
-commande> j PIEGEES 7C
+commande> j PIEGEES 7c
 commande> a t
 EEEGIP
 commande> a g
@@ -64,6 +65,31 @@
  M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> j PIEGEE c7
+commande> a t
+P
+commande> t ADEEPSS
+commande> j DEPASSE b12
+Mot incorrect ou mal placé (12)
+commande> a t
+ADEEPSS
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  P  I  E  G  E  E  -  -  -
+ D   -  -  -  -  -  -  I  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  E  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  -  G  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  -  E  -  -  -  -  -  -  -  -
+ H   -  -  -  -  -  J  E  U  -  -  -  -  -  -  -
+ I   -  -  -  -  -  -  S  -  -  -  -  -  -  -  -
+ J   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ K   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ L   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
 commande> q
 fin du mode entraînement
 commande> q

Index: test/training_rosace.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_rosace.ref,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- test/training_rosace.ref    3 Mar 2008 22:14:00 -0000       1.4
+++ test/training_rosace.ref    13 Sep 2008 21:32:47 -0000      1.5
@@ -155,8 +155,8 @@
   3: GUEUSANt        *  66 11C
   4: NUaGEUSe        *  66 D1
   5: ENjUGUeS        *  64 D2
-  6: GUeUSENt        *  64 D6
-  7: GUEUSeNt        *  64 D3
+  6: GUEUSeNt        *  64 D3
+  7: GUeUSENt        *  64 D6
   8: NUaGeUSE        *  64 D4
   9: GUeUSENT        *  62 F1
  10: GUEUSaNT        *  60 F1

Index: utils/eliottxt.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/eliottxt.cpp,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- utils/eliottxt.cpp  31 Aug 2008 11:48:22 -0000      1.24
+++ utils/eliottxt.cpp  13 Sep 2008 21:32:47 -0000      1.25
@@ -44,6 +44,7 @@
 #include "player.h"
 #include "ai_percent.h"
 #include "encoding.h"
+#include "game_exception.h"
 
 
 /* A static variable for holding the line. */
@@ -406,6 +407,8 @@
         token = _wcstok(commande, delim, &state);
         if (token)
         {
+            try
+            {
             switch (token[0])
             {
                 case L'?':
@@ -571,6 +574,11 @@
                     break;
             }
         }
+            catch (GameException &e)
+            {
+                printf("%s\n", e.what());
+            }
+        }
     }
     printf("fin du mode entraînement\n");
 }
@@ -592,6 +600,8 @@
         token = _wcstok(commande, delim, &state);
         if (token)
         {
+            try
+            {
             switch (token[0])
             {
                 case L'?':
@@ -672,6 +682,11 @@
                     break;
             }
         }
+            catch (GameException &e)
+            {
+                printf("%s\n", e.what());
+            }
+        }
     }
     printf("fin du mode partie libre\n");
 }
@@ -693,6 +708,8 @@
         token = _wcstok(commande, delim, &state);
         if (token)
         {
+            try
+            {
             switch (token[0])
             {
                 case L'?':
@@ -781,12 +798,17 @@
                     break;
             }
         }
+            catch (GameException &e)
+            {
+                printf("%s\n", e.what());
+            }
+        }
     }
     printf("fin du mode duplicate\n");
 }
 
 
-void eliot_regexp(const Dictionary& iDic, wchar_t __attribute__((unused)) *cmd,
+void eliot_regexp(const Dictionary& iDic,
                   const wchar_t *delim, wchar_t **state)
 {
     /*
@@ -974,7 +996,7 @@
                 }
                 case L'x':
                     // Regular expression tests
-                    eliot_regexp(iDic, NULL, delim, &state);
+                    eliot_regexp(iDic, delim, &state);
                     break;
                 case L'q':
                     quit = 1;

Index: test/freegame_play.input
===================================================================
RCS file: test/freegame_play.input
diff -N test/freegame_play.input
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ test/freegame_play.input    13 Sep 2008 21:32:47 -0000      1.1
@@ -0,0 +1,15 @@
+l 1 0
+a t
+p
+a t
+a p
+p
+j MALvENU h4
+a t
+a p
+p
+j SAUTEES 11H
+a p
+a g
+q
+q

Index: test/freegame_play.ref
===================================================================
RCS file: test/freegame_play.ref
diff -N test/freegame_play.ref
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ test/freegame_play.ref      13 Sep 2008 21:32:47 -0000      1.1
@@ -0,0 +1,80 @@
+[?] pour l'aide
+commande> l 1 0
+mode partie libre
+[?] pour l'aide
+commande> a t
+AMLUNE?
+commande> p
+commande> a t
+AELMNU?
+commande> a p
+Eliot 1.5
+
+Game type: Free game
+Player 0: Human
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+    1 |  AMLUNE? | (PASS)          |  -  |   0 | 0 |
+
+   Total: 0
+
+Rack 0: AELMNU?
+commande> p
+commande> j MALvENU h4
+commande> a t
+ESEASTU
+commande> a p
+Eliot 1.5
+
+Game type: Free game
+Player 0: Human
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+    1 |  AMLUNE? | (PASS)          |  -  |   0 | 0 |
+    2 |  AELMNU? | (PASS)          |  -  |   0 | 0 |
+    3 |  AELMNU? | MALvENU         |  H4 |  68 | 0 | *
+
+   Total: 68
+
+Rack 0: ESEASTU
+commande> p
+commande> j SAUTEES 11H
+commande> a p
+Eliot 1.5
+
+Game type: Free game
+Player 0: Human
+
+    N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
+   ===|==========|=================|=====|=====|===|======
+    1 |  AMLUNE? | (PASS)          |  -  |   0 | 0 |
+    2 |  AELMNU? | (PASS)          |  -  |   0 | 0 |
+    3 |  AELMNU? | MALvENU         |  H4 |  68 | 0 | *
+    4 |  ESEASTU | (PASS)          |  -  |   0 | 0 |
+    5 |  AEESSTU | SAUTEES         | 11H |  72 | 0 | *
+
+   Total: 140
+
+Rack 0: MIWBRAE
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ F   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ G   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ H   -  -  -  M  A  L  v  E  N  U  S  -  -  -  -
+ I   -  -  -  -  -  -  -  -  -  -  A  -  -  -  -
+ J   -  -  -  -  -  -  -  -  -  -  U  -  -  -  -
+ K   -  -  -  -  -  -  -  -  -  -  T  -  -  -  -
+ L   -  -  -  -  -  -  -  -  -  -  E  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  E  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  S  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+commande> q
+fin du mode partie libre
+commande> q




reply via email to

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