eliot-dev
[Top][All Lists]
Advanced

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

[Eliot-dev] eliot game/bag.cpp game/bag.h game/board.cpp ga... [cppdic]


From: eliot-dev
Subject: [Eliot-dev] eliot game/bag.cpp game/bag.h game/board.cpp ga... [cppdic]
Date: Mon, 31 Dec 2007 16:32:25 +0000

CVSROOT:        /cvsroot/eliot
Module name:    eliot
Branch:         cppdic
Changes by:     Olivier Teulière <ipkiss>      07/12/31 16:32:25

Modified files:
        game           : bag.cpp bag.h board.cpp board_search.cpp 
                         duplicate.cpp duplicate.h freegame.cpp 
                         freegame.h game.cpp game.h pldrack.cpp 
                         pldrack.h rack.h training.cpp 
        test           : duplicate_2_ai.input duplicate_2_ai.ref 
                         duplicate_humans_ai.input 
                         duplicate_humans_ai.ref freegame_3_ai.input 
                         freegame_3_ai.ref freegame_change.input 
                         freegame_change.ref freegame_passing.input 
                         freegame_passing.ref 

Log message:
         - Use unsigned int instead of int in some places
         - Renamed a few methods for consistency
         - Game::helperSetRackRandom() has been rewritten, the previous version 
is now called Game::helperSetRackRandomOld()
           * the function doesn't need to be called in a (possibly 
never-ending) while() loop anymore
           * it handles rejects properly
           * the new function is used in duplicate and freegame modes
           * the old function is used only in training mode (this will change 
after the release)
         - Updated regression scenarii

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/game/bag.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.7.2.4&r2=1.7.2.5
http://cvs.savannah.gnu.org/viewcvs/eliot/game/bag.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.8.2.4&r2=1.8.2.5
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.14.2.6&r2=1.14.2.7
http://cvs.savannah.gnu.org/viewcvs/eliot/game/board_search.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.11.2.6&r2=1.11.2.7
http://cvs.savannah.gnu.org/viewcvs/eliot/game/duplicate.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.16.2.5&r2=1.16.2.6
http://cvs.savannah.gnu.org/viewcvs/eliot/game/duplicate.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.12.2.4&r2=1.12.2.5
http://cvs.savannah.gnu.org/viewcvs/eliot/game/freegame.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.18.2.8&r2=1.18.2.9
http://cvs.savannah.gnu.org/viewcvs/eliot/game/freegame.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.11.2.3&r2=1.11.2.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.31.2.12&r2=1.31.2.13
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.29.2.9&r2=1.29.2.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/pldrack.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.9.2.4&r2=1.9.2.5
http://cvs.savannah.gnu.org/viewcvs/eliot/game/pldrack.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.12.2.4&r2=1.12.2.5
http://cvs.savannah.gnu.org/viewcvs/eliot/game/rack.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.9.2.3&r2=1.9.2.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/training.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.17.2.6&r2=1.17.2.7
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_2_ai.input?cvsroot=eliot&only_with_tag=cppdic&r1=1.1&r2=1.1.6.1
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_2_ai.ref?cvsroot=eliot&only_with_tag=cppdic&r1=1.3&r2=1.3.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_humans_ai.input?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/duplicate_humans_ai.ref?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_3_ai.input?cvsroot=eliot&only_with_tag=cppdic&r1=1.1&r2=1.1.6.1
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_3_ai.ref?cvsroot=eliot&only_with_tag=cppdic&r1=1.3&r2=1.3.2.1
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_change.input?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.6.1&r2=1.1.6.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_change.ref?cvsroot=eliot&only_with_tag=cppdic&r1=1.2.4.1&r2=1.2.4.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_passing.input?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.6.1&r2=1.1.6.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/freegame_passing.ref?cvsroot=eliot&only_with_tag=cppdic&r1=1.3.2.2&r2=1.3.2.3

Patches:
Index: game/bag.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/bag.cpp,v
retrieving revision 1.7.2.4
retrieving revision 1.7.2.5
diff -u -b -r1.7.2.4 -r1.7.2.5
--- game/bag.cpp        25 Dec 2007 12:39:15 -0000      1.7.2.4
+++ game/bag.cpp        31 Dec 2007 16:32:22 -0000      1.7.2.5
@@ -50,7 +50,7 @@
 }
 
 
-unsigned int Bag::nVowels() const
+unsigned int Bag::getNbVowels() const
 {
     map<Tile, int>::const_iterator it;
     int v = 0;
@@ -64,7 +64,7 @@
 }
 
 
-unsigned int Bag::nConsonants() const
+unsigned int Bag::getNbConsonants() const
 {
     map<Tile, int>::const_iterator it;
     int c = 0;
@@ -98,15 +98,58 @@
 }
 
 
-Tile Bag::selectRandom()
+Tile Bag::selectRandom() const
 {
-    map<Tile, int>::const_iterator it;
-    int n;
     double max = m_ntiles;
+    ASSERT(max > 0, "The bag is empty");
+
+    int n = (int)(max * rand() / (RAND_MAX + 1.0));
+
+    map<Tile, int>::const_iterator it;
+    for (it = m_tilesMap.begin(); it != m_tilesMap.end(); it++)
+    {
+        if (n < it->second)
+            return it->first;
+        n -= it->second;
+    }
+    ASSERT(false, "We should not come here");
+    return Tile();
+}
+
+
+Tile Bag::selectRandomVowel() const
+{
+    double max = getNbVowels();
+    ASSERT(max > 0, "Not enough vowels in the bag");
+
+    int n = (int)(max * rand() / (RAND_MAX + 1.0));
 
-    n = (int)(max * rand() / (RAND_MAX + 1.0));
+    map<Tile, int>::const_iterator it;
+    for (it = m_tilesMap.begin(); it != m_tilesMap.end(); it++)
+    {
+        if (!it->first.isVowel())
+            continue;
+        if (n < it->second)
+            return it->first;
+        n -= it->second;
+    }
+    ASSERT(false, "We should not come here");
+    return Tile();
+}
+
+
+Tile Bag::selectRandomConsonant() const
+{
+    double max = getNbConsonants();
+    ASSERT(max > 0, "Not enough consonants in the bag");
+
+    int n = (int)(max * rand() / (RAND_MAX + 1.0));
+
+    map<Tile, int>::const_iterator it;
     for (it = m_tilesMap.begin(); it != m_tilesMap.end(); it++)
     {
+        if (!it->first.isConsonant())
+            continue;
         if (n < it->second)
             return it->first;
         n -= it->second;

Index: game/bag.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/bag.h,v
retrieving revision 1.8.2.4
retrieving revision 1.8.2.5
diff -u -b -r1.8.2.4 -r1.8.2.5
--- game/bag.h  25 Dec 2007 12:39:15 -0000      1.8.2.4
+++ game/bag.h  31 Dec 2007 16:32:22 -0000      1.8.2.5
@@ -48,18 +48,30 @@
 
     /**
      * Return how many tiles/vowels/consonants are available
-     * Warning: b.nVowels() + b.nConsonants() != b.nTiles(),
+     * Warning: b.getNbVowels() + b.getNbConsonants() != b.getNbTiles(),
      * because of the jokers and the 'Y'.
      */
-    unsigned int nTiles() const  { return m_ntiles; }
-    unsigned int nVowels() const;
-    unsigned int nConsonants() const;
+    unsigned int getNbTiles() const  { return m_ntiles; }
+    unsigned int getNbVowels() const;
+    unsigned int getNbConsonants() const;
 
     /**
      * Return a random available tile
      * The tile is not taken out of the bag.
      */
-    Tile selectRandom();
+    Tile selectRandom() const;
+
+    /**
+     * Return a random available vowel.
+     * The tile is not taken out of the bag.
+     */
+    Tile selectRandomVowel() const;
+
+    /**
+     * Return a random available consonant.
+     * The tile is not taken out of the bag.
+     */
+    Tile selectRandomConsonant() const;
 
     void operator=(const Bag &iOther);
 

Index: game/board.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board.cpp,v
retrieving revision 1.14.2.6
retrieving revision 1.14.2.7
diff -u -b -r1.14.2.6 -r1.14.2.7
--- game/board.cpp      25 Dec 2007 12:39:15 -0000      1.14.2.6
+++ game/board.cpp      31 Dec 2007 16:32:22 -0000      1.14.2.7
@@ -247,7 +247,7 @@
     int l, p;
     bool isolated = true;
 
-    int fromrack = 0;
+    unsigned int fromrack = 0;
     int pts = 0;
     int ptscross = 0;
     int wordmul = 1;

Index: game/board_search.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/board_search.cpp,v
retrieving revision 1.11.2.6
retrieving revision 1.11.2.7
diff -u -b -r1.11.2.6 -r1.11.2.7
--- game/board_search.cpp       25 Dec 2007 12:39:15 -0000      1.11.2.6
+++ game/board_search.cpp       31 Dec 2007 16:32:22 -0000      1.11.2.7
@@ -39,21 +39,17 @@
                                 Matrix<bool> &iJokerMx,
                                 Results &iResults, Round &iWord)
 {
-    int i, pts, ptscross;
-    int l, t, fromrack;
-    int len, row, col, wordmul;
+    unsigned int fromrack = 0;
+    int pts      = 0;
+    int ptscross = 0;
+    int wordmul  = 1;
 
-    fromrack = 0;
-    pts      = 0;
-    ptscross = 0;
-    wordmul  = 1;
+    unsigned int len = iWord.getWordLen();
 
-    len = iWord.getWordLen();
+    int row = iWord.getCoord().getRow();
+    int col = iWord.getCoord().getCol();
 
-    row = iWord.getCoord().getRow();
-    col = iWord.getCoord().getCol();
-
-    for (i = 0; i < len; i++)
+    for (unsigned int i = 0; i < len; i++)
     {
         if (!iTilesMx[row][col+i].isEmpty())
         {
@@ -62,6 +58,7 @@
         }
         else
         {
+            int l;
             if (!iWord.isJoker(i))
                 l = iWord.getTile(i).getPoints() *
                     iBoard.getLetterMultiplier(row, col + i);
@@ -70,7 +67,7 @@
             pts += l;
             wordmul *= iBoard.getWordMultiplier(row, col + i);
 
-            t = iPointsMx[row][col+i];
+            int t = iPointsMx[row][col+i];
             if (t >= 0)
                 ptscross += (t + l) * iBoard.getWordMultiplier(row, col + i);
             fromrack++;
@@ -342,7 +339,7 @@
     LeftPart(*this, iDic, m_tilesRow, m_crossRow,
              m_pointRow, m_jokerRow,
              copyRack, partialword, oResults, iDic.getRoot(), row, col,
-             copyRack.nTiles() - 1);
+             copyRack.getNbTiles() - 1);
 }
 
 /// Local Variables:

Index: game/duplicate.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/duplicate.cpp,v
retrieving revision 1.16.2.5
retrieving revision 1.16.2.6
diff -u -b -r1.16.2.5 -r1.16.2.6
--- game/duplicate.cpp  25 Dec 2007 12:39:16 -0000      1.16.2.5
+++ game/duplicate.cpp  31 Dec 2007 16:32:23 -0000      1.16.2.6
@@ -38,17 +38,6 @@
 }
 
 
-int Duplicate::setRackRandom(unsigned int p, bool iCheck, set_rack_mode mode)
-{
-    int res;
-    do
-    {
-        res = helperSetRackRandom(p, iCheck, mode);
-    } while (res == 2);
-    return res;
-}
-
-
 int Duplicate::play(const wstring &iCoord, const wstring &iWord)
 {
     // Perform all the validity checks, and try to fill a round
@@ -108,7 +97,7 @@
     m_currPlayer = 0;
 
     // Complete the rack for the player that just played
-    int res = setRackRandom(m_currPlayer, true, RACK_NEW);
+    int res = helperSetRackRandom(m_currPlayer, true, RACK_NEW);
     // End of the game?
     if (res == 1)
     {

Index: game/duplicate.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/duplicate.h,v
retrieving revision 1.12.2.4
retrieving revision 1.12.2.5
diff -u -b -r1.12.2.4 -r1.12.2.5
--- game/duplicate.h    25 Dec 2007 12:39:16 -0000      1.12.2.4
+++ game/duplicate.h    31 Dec 2007 16:32:23 -0000      1.12.2.5
@@ -95,7 +95,6 @@
     Duplicate(const Dictionary &iDic);
 
     void playMove(const Move &iMove, unsigned int p);
-    int setRackRandom(unsigned int, bool, set_rack_mode);
 
     /// Make the AI player whose ID is p play its turn
     void playAI(unsigned int p);

Index: game/freegame.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/freegame.cpp,v
retrieving revision 1.18.2.8
retrieving revision 1.18.2.9
diff -u -b -r1.18.2.8 -r1.18.2.9
--- game/freegame.cpp   25 Dec 2007 12:39:16 -0000      1.18.2.8
+++ game/freegame.cpp   31 Dec 2007 16:32:23 -0000      1.18.2.9
@@ -42,17 +42,6 @@
 }
 
 
-int FreeGame::setRackRandom(unsigned int p, bool iCheck, set_rack_mode mode)
-{
-    int res;
-    do
-    {
-        res = helperSetRackRandom(p, iCheck, mode);
-    } while (res == 2);
-    return res;
-}
-
-
 int FreeGame::play(const wstring &iCoord, const wstring &iWord)
 {
     // Perform all the validity checks, and try to fill a round
@@ -123,7 +112,7 @@
     // Set the initial racks of the players
     for (unsigned int i = 0; i < getNPlayers(); i++)
     {
-        setRackRandom(i, false, RACK_NEW);
+        helperSetRackRandom(i, false, RACK_NEW);
     }
 
     m_currPlayer = 0;
@@ -141,7 +130,7 @@
 int FreeGame::endTurn()
 {
     // Complete the rack for the player that just played
-    if (setRackRandom(m_currPlayer, false, RACK_NEW) == 1)
+    if (helperSetRackRandom(m_currPlayer, false, RACK_NEW) == 1)
     {
         // End of the game
         endGame();
@@ -216,7 +205,7 @@
     // still allowed to pass
     Bag bag(m_dic);
     realBag(bag);
-    if (bag.nTiles() < 7 && !iToChange.empty())
+    if (bag.getNbTiles() < 7 && !iToChange.empty())
     {
         return 1;
     }

Index: game/freegame.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/freegame.h,v
retrieving revision 1.11.2.3
retrieving revision 1.11.2.4
diff -u -b -r1.11.2.3 -r1.11.2.4
--- game/freegame.h     25 Dec 2007 12:39:16 -0000      1.11.2.3
+++ game/freegame.h     31 Dec 2007 16:32:23 -0000      1.11.2.4
@@ -83,8 +83,6 @@
     // Private constructor to force using the GameFactory class
     FreeGame(const Dictionary &iDic);
 
-    int setRackRandom(unsigned int, bool, set_rack_mode);
-
     /// Make the AI player whose ID is p play its turn
     void playAI(unsigned int p);
 

Index: game/game.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.cpp,v
retrieving revision 1.31.2.12
retrieving revision 1.31.2.13
diff -u -b -r1.31.2.12 -r1.31.2.13
--- game/game.cpp       25 Dec 2007 12:39:16 -0000      1.31.2.12
+++ game/game.cpp       31 Dec 2007 16:32:23 -0000      1.31.2.13
@@ -35,7 +35,7 @@
 #include "debug.h"
 
 
-const int Game::RACK_SIZE    =  7;
+const unsigned int Game::RACK_SIZE =  7;
 const int Game::BONUS_POINTS = 50;
 
 Game::Game(const Dictionary &iDic):
@@ -242,19 +242,33 @@
 int Game::helperSetRackRandom(unsigned int p, bool iCheck, set_rack_mode mode)
 {
     ASSERT(p < getNPlayers(), "Wrong player number");
+    // FIXME: RACK_MANUAL shouldn't be in the enum
+    ASSERT(mode != RACK_MANUAL, "Invalid rack mode");
 
-    int nold, min;
+    // When iCheck is true, we must make sure that there are at least 2 vowels
+    // and 2 consonants in the rack up to the 15th turn, and at least one of
+    // each starting from the 16th turn.
+    // So before trying to fill the rack, we'd better make sure there is a way
+    // to complete the rack with these constraints...
+    unsigned int min = 0;
+    if (iCheck)
+    {
+        // 2 vowels and 2 consonants are needed up to the 15th turn
+        if (m_history.getSize() < 15)
+            min = 2;
+        else
+            min = 1;
+    }
 
     // Make a copy of the current player's rack
     PlayedRack pld = getPlayer(p).getCurrentRack();
-    nold = pld.nOld();
+    int nold = pld.getNbOld();
 
     // Create a copy of the bag in which we can do everything we want,
     // and take from it the tiles of the players rack so that "bag"
     // contains the right number of tiles.
     Bag bag(m_dic);
     realBag(bag);
-
     if (mode == RACK_NEW && nold != 0)
     {
         // We may have removed too many letters from the bag (i.e. the 'new'
@@ -286,8 +300,212 @@
         debug("Game::helperSetRackRandom not a random mode\n");
     }
 
+    // Get the tiles remaining on the rack
+    vector<Tile> tiles;
+    pld.getOldTiles(tiles);
+    ASSERT(tiles.size() < RACK_SIZE,
+           "Cannot complete the rack, it is already complete");
+
+    bool jokerAdded = false;
+    // Are we dealing with a normal game or a joker game?
+    if (m_variant == kJOKER)
+    {
+        // 1) Is there already a joker in the remaining letters of the rack?
+        bool jokerFound = false;
+        for (unsigned int i = 0; i < tiles.size(); i++)
+        {
+            if (tiles[i].isJoker())
+            {
+                jokerFound = true;
+                break;
+            }
+        }
+
+        // 2) If there was no joker, we add one if possible
+        if (!jokerFound && bag.in(Tile::Joker()))
+        {
+            jokerAdded = true;
+            pld.addNew(Tile::Joker());
+            tiles.push_back(Tile::Joker());
+        }
+
+        // 3) Remove all the jokers from the bag, to avoid taking another one
+        for (unsigned int i = 0; i < bag.in(Tile::Joker()); ++i)
+        {
+            bag.takeTile(Tile::Joker());
+        }
+    }
+
+    // Nothing in the rack, nothing in the bag --> end of the (free)game
+    if (bag.getNbTiles() == 0 && pld.getNbTiles() == 0)
+    {
+        return 1;
+    }
+    // End of game condition
+    if (iCheck)
+    {
+        if (bag.getNbVowels() == 0 || bag.getNbConsonants() == 0 ||
+            bag.getNbTiles() == 1)
+        {
+            return 1;
+        }
+    }
+
+    // Handle reject:
+    // Now that the joker has been dealt with, we try to complete the rack
+    // with truly random tiles. If it meets the requirements (i.e. if there
+    // are at least "min" vowels and "min" consonants in the rack), fine.
+    // Otherwise, we reject the rack completely, and we try again
+    // to complete it, but this time we ensure by construction that the
+    // requirements will be met.
+    while (bag.getNbTiles() != 0 && pld.getNbTiles() < RACK_SIZE)
+    {
+        Tile l = bag.selectRandom();
+        bag.takeTile(l);
+        pld.addNew(l);
+    }
+
+    if (!pld.checkRack(min, min))
+    {
+        // Bad luck... we have to reject the rack
+        vector<Tile> rejectedTiles;
+        pld.getAllTiles(rejectedTiles);
+        for (unsigned int i = 0; i < rejectedTiles.size(); i++)
+        {
+            bag.replaceTile(rejectedTiles[i]);
+        }
+        pld.reset();
+        // Do not mark the rack as rejected if it was empty
+        if (nold > 0)
+            pld.setReject();
+
+        // Restore the joker if we are in a joker game
+        if (jokerAdded)
+            pld.addNew(Tile::Joker());
+
+        // Count the needed consonants and vowels in the rack
+        // (i.e. minimum required, minus what we already have in the rack)
+        unsigned int neededVowels = min;
+        unsigned int neededConsonants = min;
+        for (unsigned int i = 0; i < tiles.size(); ++i)
+        {
+            if (neededVowels > 0 && tiles[i].isVowel())
+                neededVowels--;
+            if (neededConsonants > 0 && tiles[i].isConsonant())
+                neededConsonants--;
+        }
+
+        // Check whether it is possible to complete the rack properly
+        if (bag.getNbVowels() < neededVowels ||
+            bag.getNbConsonants() < neededConsonants)
+        {
+            return 1;
+        }
+
+        // RACK_SIZE - tiles.size() is the number of letters to add to the rack
+        if (neededVowels > RACK_SIZE - tiles.size() ||
+            neededConsonants > RACK_SIZE - tiles.size())
+        {
+            // We cannot fill the rack with enough vowels or consonants!
+            // Actually this should never happen, but it doesn't hurt to 
check...
+            // FIXME: this test is not completely right, because it supposes no
+            // letter can be at the same time a vowel and a consonant
+            return 3;
+        }
+
+        // Get the required vowels and consonants first
+        for (unsigned int i = 0; i < neededVowels; ++i)
+        {
+            Tile l = bag.selectRandomVowel();
+            bag.takeTile(l);
+            pld.addNew(l);
+            // Handle the case where the vowel can also be considered
+            // as a consonant
+            if (l.isConsonant() && neededConsonants > 0)
+                neededConsonants--;
+        }
+        for (unsigned int i = 0; i < neededConsonants; ++i)
+        {
+            Tile l = bag.selectRandomConsonant();
+            bag.takeTile(l);
+            pld.addNew(l);
+        }
+
+        // The difficult part is done:
+        //  - we have handled joker games
+        //  - we have handled the checks
+        // Now complete the rack with truly random letters
+        while (bag.getNbTiles() != 0 && pld.getNbTiles() < RACK_SIZE)
+        {
+            Tile l = bag.selectRandom();
+            bag.takeTile(l);
+            pld.addNew(l);
+        }
+    }
+
+    // Shuffle the new tiles, to hide the order we imposed (joker first in a
+    // joker game, then needed vowels, then needed consonants, and rest of the
+    // rack)
+    pld.shuffleNew();
+
+    // Post-condition check. This should never fail, of course :)
+    ASSERT(pld.checkRack(min, min), "helperSetRackRandom() is buggy!")
+
+    // Until now we didn't modify anything except local variables.
+    // Let's "commit" the changes
+    m_players[p]->setCurrentRack(pld);
+
+    return 0;
+}
+
+
+int Game::helperSetRackRandomOld(unsigned int p, bool iCheck, set_rack_mode 
mode)
+{
+    ASSERT(p < getNPlayers(), "Wrong player number");
+
+    // Make a copy of the current player's rack
+    PlayedRack pld = getPlayer(p).getCurrentRack();
+    int nold = pld.getNbOld();
+
+    // Create a copy of the bag in which we can do everything we want,
+    // and take from it the tiles of the players rack so that "bag"
+    // contains the right number of tiles.
+    Bag bag(m_dic);
+    realBag(bag);
+
+    if (mode == RACK_NEW && nold != 0)
+    {
+        // We may have removed too many letters from the bag (i.e. the 'new'
+        // letters of the player)
+        vector<Tile> tiles;
+        pld.getNewTiles(tiles);
+        for (unsigned int i = 0; i < tiles.size(); i++)
+        {
+            bag.replaceTile(tiles[i]);
+        }
+        pld.resetNew();
+    }
+    else if (mode == RACK_NEW && nold == 0 || mode == RACK_ALL)
+    {
+        // Replace all the tiles in the bag before choosing random ones
+        vector<Tile> tiles;
+        pld.getAllTiles(tiles);
+        for (unsigned int i = 0; i < tiles.size(); i++)
+        {
+            bag.replaceTile(tiles[i]);
+        }
+        // RACK_NEW with an empty rack is equivalent to RACK_ALL
+        pld.reset();
+        // Do not forget to update nold, for the RACK_ALL case
+        nold = 0;
+    }
+    else
+    {
+        debug("Game::helperSetRackRandomOld not a random mode\n");
+    }
+
     // Nothing in the rack, nothing in the bag --> end of the game
-    if (bag.nTiles() == 0 && pld.nTiles() == 0)
+    if (bag.getNbTiles() == 0 && pld.getNbTiles() == 0)
     {
         return 1;
     }
@@ -297,17 +515,17 @@
     // them from the 16th turn.
     // So before trying to fill the rack, we'd better make sure there is a way
     // to complete the rack with these constraints...
-    min = 0;
+    unsigned int min = 0;
     if (iCheck)
     {
-        int oldc, oldv;
+        unsigned int oldc, oldv;
 
-        if (bag.nVowels() == 0 || bag.nConsonants() == 0)
+        if (bag.getNbVowels() == 0 || bag.getNbConsonants() == 0)
         {
             return 1;
         }
         // 2 vowels and 2 consonants are needed up to the 15th turn
-        if (bag.nVowels() > 1 && bag.nConsonants() > 1
+        if (bag.getNbVowels() > 1 && bag.getNbConsonants() > 1
             && m_history.getSize() < 15)
             min = 2;
         else
@@ -362,7 +580,7 @@
         Tile l;
         // FIXME: this can be an infinite loop if the only tile left in the
         // bag is a joker!
-        while (bag.nTiles() != 0 && pld.nTiles() != RACK_SIZE)
+        while (bag.getNbTiles() != 0 && pld.getNbTiles() != RACK_SIZE)
         {
             l = bag.selectRandom();
             if (!l.isJoker())
@@ -376,7 +594,7 @@
     {
         // Get new tiles from the bag
         Tile l;
-        while (bag.nTiles() != 0 && pld.nTiles() != RACK_SIZE)
+        while (bag.getNbTiles() != 0 && pld.getNbTiles() != RACK_SIZE)
         {
             l = bag.selectRandom();
             bag.takeTile(l);
@@ -384,7 +602,7 @@
         }
     }
 
-    if (iCheck && !pld.checkRack(min,min))
+    if (iCheck && !pld.checkRack(min, min))
         return 2;
 
     m_players[p]->setCurrentRack(pld);
@@ -427,12 +645,12 @@
     if (iCheck)
     {
         int min;
-        if (m_bag.nVowels() > 1 && m_bag.nConsonants() > 1
+        if (m_bag.getNbVowels() > 1 && m_bag.getNbConsonants() > 1
             && m_history.getSize() < 15)
             min = 2;
         else
             min = 1;
-        if (!pld.checkRack(min,min))
+        if (!pld.checkRack(min, min))
             return 2;
     }
 

Index: game/game.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.h,v
retrieving revision 1.29.2.9
retrieving revision 1.29.2.10
diff -u -b -r1.29.2.9 -r1.29.2.10
--- game/game.h 25 Dec 2007 12:39:17 -0000      1.29.2.9
+++ game/game.h 31 Dec 2007 16:32:23 -0000      1.29.2.10
@@ -48,7 +48,7 @@
 {
 public:
     /// Game specs.
-    static const int RACK_SIZE;
+    static const unsigned int RACK_SIZE;
     static const int BONUS_POINTS;
 
 
@@ -234,12 +234,42 @@
      * Possible return values:
      *  0: everything went fine
      *  1: the game is over
+     *  3: there is no chance to set the rack with the vowels/consonants
+     *     constraints
+     *
+     * Completing a rack randomly is more complex than it seems, because we
+     * must take into account several constraints:
+     *  - if iCheck is true, we must ensure that the rack contains a minimum
+     *    number of vowels and consonants (2 of each in the 15 first moves of
+     *    the game, 1 of each after)
+     *  - the game is over if the (real) bag contains only vowels or only
+     *    consonants, and in particular if it contains only one letter
+     *  - some letters (in particular the joker) can count both as a vowel and
+     *    as a consonant (but not at the same time)
+     *  - in a joker game, the joker must be present in the rack unless there
+     *    is no joker left in the bag. In addition, we must prevent that both
+     *    jokers are present in the rack at the same time
+     *  - if completing a rack doesn't meet the requirements on the vowels and
+     *    consonants, we must reject the rack completely (but only once,
+     *    otherwise we have no guarantee that the rejects will stop 
eventually).
+     *    This also means we have to check whether completing the rack with the
+     *    requirements is possible...
+     */
+    int helperSetRackRandom(unsigned int p, bool iCheck, set_rack_mode mode);
+
+    /**
+     * Set the rack randomly for the player p
+     * Possible return values:
+     *  0: everything went fine
+     *  1: the game is over
      *  2: the rack was checked and was not correct (try calling the
      *     function again)
      *  3: there is no chance to set the rack with the vowels/consonants
      *     constraints
+     *
+     * @deprecated: use helperSetRackRandom instead
      */
-    int helperSetRackRandom(unsigned int p, bool iCheck, set_rack_mode mode);
+    int helperSetRackRandomOld(unsigned int p, bool iCheck, set_rack_mode 
mode);
 
     /**
      * Set the rack for the player p with the given letters

Index: game/pldrack.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/pldrack.cpp,v
retrieving revision 1.9.2.4
retrieving revision 1.9.2.5
diff -u -b -r1.9.2.4 -r1.9.2.5
--- game/pldrack.cpp    25 Dec 2007 12:39:18 -0000      1.9.2.4
+++ game/pldrack.cpp    31 Dec 2007 16:32:23 -0000      1.9.2.5
@@ -26,10 +26,9 @@
  *  \date   2002 - 2005
  */
 
-#include "rack.h"
+#include <algorithm>
 #include "pldrack.h"
-
-#include "debug.h"
+#include "rack.h"
 
 
 PlayedRack::PlayedRack()
@@ -76,6 +75,7 @@
 {
     m_oldTiles.clear();
     m_newTiles.clear();
+    m_reject = false;
 }
 
 
@@ -134,13 +134,13 @@
 
 void PlayedRack::setManual(const wstring& iLetters)
 {
-    unsigned int i;
     reset();
 
     // An empty rack is OK
     if (iLetters.empty())
         return;
 
+    unsigned int i;
     for (i = 0; i < iLetters.size() && iLetters[i] != L'+'; i++)
     {
         addOld(Tile(iLetters[i]));
@@ -156,11 +156,11 @@
 }
 
 
-bool PlayedRack::checkRack(int cMin, int vMin) const
+bool PlayedRack::checkRack(unsigned int cMin, unsigned int vMin) const
 {
     vector<Tile>::const_iterator it;
-    int v = 0;
-    int c = 0;
+    unsigned int v = 0;
+    unsigned int c = 0;
 
     for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
     {
@@ -176,10 +176,9 @@
 }
 
 
-void PlayedRack::operator=(const PlayedRack &iOther)
+void PlayedRack::shuffleNew()
 {
-    m_oldTiles = iOther.m_oldTiles;
-    m_newTiles = iOther.m_newTiles;
+    std::random_shuffle(m_newTiles.begin(), m_newTiles.end());
 }
 
 
@@ -188,25 +187,23 @@
     wstring s;
     vector<Tile>::const_iterator it;
 
-    if (nOld() > 0)
+    if (mode >= RACK_EXTRA && m_reject)
     {
-        for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
-            s += it->toChar();
+        s += L"-";
     }
 
-    if (mode > RACK_SIMPLE && nOld() > 0 && nNew() > 0)
+    if (getNbOld() > 0)
     {
-        s += L"+";
+        for (it = m_oldTiles.begin(); it != m_oldTiles.end(); it++)
+            s += it->toChar();
     }
 
-    if (mode > RACK_EXTRA  && m_reject)
+    if (mode > RACK_SIMPLE && getNbOld() > 0 && getNbNew() > 0)
     {
-        s += L"-";
-        // new rack: reject
-        // not after a scrabble
+        s += L"+";
     }
 
-    if (nNew() > 0)
+    if (getNbNew() > 0)
     {
         for (it = m_newTiles.begin(); it != m_newTiles.end(); it++)
             s += it->toChar();

Index: game/pldrack.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/pldrack.h,v
retrieving revision 1.12.2.4
retrieving revision 1.12.2.5
diff -u -b -r1.12.2.4 -r1.12.2.5
--- game/pldrack.h      25 Dec 2007 12:39:18 -0000      1.12.2.4
+++ game/pldrack.h      31 Dec 2007 16:32:24 -0000      1.12.2.5
@@ -59,10 +59,11 @@
     void setOld(const Rack &iRack);
     void setNew(const Rack &iRack);
     void setManual(const wstring& iLetters);
+    void setReject(bool iReject = true) { m_reject = iReject; }
 
-    int nTiles() const  { return nNew() + nOld(); }
-    int nNew() const    { return m_newTiles.size(); }
-    int nOld() const    { return m_oldTiles.size(); }
+    unsigned int getNbTiles() const  { return getNbNew() + getNbOld(); }
+    unsigned int getNbNew() const    { return m_newTiles.size(); }
+    unsigned int getNbOld() const    { return m_oldTiles.size(); }
 
     void addNew(const Tile &t);
     void addOld(const Tile &t);
@@ -70,9 +71,10 @@
     void getOldTiles(vector<Tile> &oTiles) const;
     void getAllTiles(vector<Tile> &oTiles) const;
 
-    bool checkRack(int cMin, int vMin) const;
+    bool checkRack(unsigned int cMin, unsigned int vMin) const;
 
-    void operator=(const PlayedRack &iOther);
+    /// Randomly change the order of the "new" tiles
+    void shuffleNew();
 
     enum display_mode
     {

Index: game/rack.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/rack.h,v
retrieving revision 1.9.2.3
retrieving revision 1.9.2.4
diff -u -b -r1.9.2.3 -r1.9.2.4
--- game/rack.h 25 Dec 2007 12:39:18 -0000      1.9.2.3
+++ game/rack.h 31 Dec 2007 16:32:24 -0000      1.9.2.4
@@ -46,8 +46,8 @@
 public:
     Rack();
 
-    int nTiles() const          { return m_ntiles; }
-    bool isEmpty() const        { return nTiles() == 0; }
+    unsigned int getNbTiles() const      { return m_ntiles; }
+    bool isEmpty() const        { return getNbTiles() == 0; }
 
     unsigned int in(const Tile &t) const { return m_tiles[t.toCode()]; }
     void add(const Tile &t)     { m_tiles[t.toCode()]++; m_ntiles++; }
@@ -60,7 +60,7 @@
 private:
     /// Vector indexed by tile codes, containing the number of tiles
     vector<unsigned int> m_tiles;
-    int m_ntiles;
+    unsigned int m_ntiles;
 };
 
 #endif

Index: game/training.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/training.cpp,v
retrieving revision 1.17.2.6
retrieving revision 1.17.2.7
diff -u -b -r1.17.2.6 -r1.17.2.7
--- game/training.cpp   25 Dec 2007 12:39:18 -0000      1.17.2.6
+++ game/training.cpp   31 Dec 2007 16:32:24 -0000      1.17.2.7
@@ -49,7 +49,7 @@
     m_results.clear();
     do
     {
-        res = helperSetRackRandom(m_currPlayer, iCheck, mode);
+        res = helperSetRackRandomOld(m_currPlayer, iCheck, mode);
         try_number ++;
     } while (res == 2 && try_number < MAX_RANDOM_TRY);
     // 0 : ok

Index: test/duplicate_2_ai.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/duplicate_2_ai.input,v
retrieving revision 1.1
retrieving revision 1.1.6.1
diff -u -b -r1.1 -r1.1.6.1
--- test/duplicate_2_ai.input   16 Apr 2005 15:47:59 -0000      1.1
+++ test/duplicate_2_ai.input   31 Dec 2007 16:32:24 -0000      1.1.6.1
@@ -3,6 +3,7 @@
 a T
 a l
 a p
+a g
 q
 q
 

Index: test/duplicate_2_ai.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/duplicate_2_ai.ref,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -b -r1.3 -r1.3.2.1
--- test/duplicate_2_ai.ref     1 Jan 2006 19:25:10 -0000       1.3
+++ test/duplicate_2_ai.ref     31 Dec 2007 16:32:24 -0000      1.3.2.1
@@ -3,14 +3,14 @@
 mode duplicate
 [?] pour l'aide
 commande> a S
-Joueur 0:  866
-Joueur 1:  866
+Joueur 0:  835
+Joueur 1:  835
 commande> a T
-Joueur 0: RTTUW
-Joueur 1: RTTUW
+Joueur 0: NNRT
+Joueur 1: NNRT
 commande> a l
  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ?
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 1 0 1 0 0 0 0
+ 0 0 0 1 0 0 2 0 0 0 0 1 0 2 0 0 0 1 1 1 0 0 0 0 0 0 0
 commande> a p
 Eliot 1.5
 
@@ -20,30 +20,48 @@
 
     N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
    ===|==========|=================|=====|=====|===|======
-    1 |  EA?AEBF | FABAcEE         |  H4 |  80 | 0 | *
-    2 |  LMUAEYE | YEBLE           |  6F |  38 | 0 |  
-    3 | AMU+JEIG | MEJUGEAI        |  9G |  78 | 0 | *
-    4 |  LEHNMGA | HALE            |  8L |  46 | 0 |  
-    5 | GMN+NSEO | MENSONGE        |  O1 |  83 | 0 | *
-    6 |  ARAURIU | RAIRA           |  5B |  21 | 0 |  
-    7 | UU+TSDEA | RUSTAUDE        |  B5 |  63 | 0 | *
-    8 |  ONIAVPD | VIDA            | A12 |  45 | 0 |  
-    9 | NOP+SONE | PENONS          |  K1 |  33 | 0 |  
-   10 | O+OXTOLN | LUX             |  J8 |  32 | 0 |  
-   11 | NOOOT+SZ | ZOOS            | 11E |  38 | 0 |  
-   12 | NOT+MIAI | DOMINAIT        | 14A |  74 | 0 | *
-   13 |  CERPFEO | FEROCE          | 15G |  47 | 0 |  
-   14 | P+BSVQIU | PIQUAS          |  C1 |  32 | 0 |  
-   15 | BV+ETLIE | LEVITE          |  A1 |  39 | 0 |  
-   16 | B+RLD?UC | PUBLiC          |  1C |  36 | 0 |  
-   17 | DR+NTERR | DENREE          |  2J |  22 | 0 |  
-   18 | RRT+TUKE | TREK            | 13F |  36 | 0 |  
-   19 | RTU+THWI | HAI             |  7G |  23 | 0 |  
+    1 |  ?EBAAEF | FABAcEE         |  H4 |  80 | 0 | *
+    2 |  KEELIFE | KIEF            | 10F |  36 | 0 |  
+    3 | EEEL+IJX | FIXEE           |  4H |  34 | 0 |  
+    4 | EJL+RANS | JALES           |  J6 |  49 | 0 |  
+    5 | NR+OAHPU | HURON           |  5K |  28 | 0 |  
+    6 | AP+MOEIA | LIPOME          |  8J |  36 | 0 |  
+    7 | AA+SMOND | ADONNAMES       |  O1 |  86 | 0 | *
+    8 |  LEATCYL | MAYE            |  N8 |  36 | 0 |  
+    9 | CLLT+EAB | COBALT          |  M7 |  37 | 0 |  
+   10 | EL+OSEAH | HELES           | 13I |  46 | 0 |  
+   11 | AO+NUCSR | CORANS          | 11C |  41 | 0 |  
+   12 | U+DEZONU | NOUEZ           | L10 |  47 | 0 |  
+   13 | DEU+MTOR | DOTEZ           | 14H |  28 | 0 |  
+   14 | MRU+Q?IU | QUIpU           | 15D |  66 | 0 |  
+   15 | MR+WILUT | KAWI            | F10 |  22 | 0 |  
+   16 | LMRTU+RS | MULOTS          |  D8 |  18 | 0 |  
+   17 | RR+TERPI | PELER           | K11 |  29 | 0 |  
+   18 | IRRT+EII | TRIMER          |  8A |  21 | 0 |  
+   19 | II+ETEVA | EVITERAI        |  B3 |  65 | 0 | *
+   20 |  NUERTNV | CUVE            | C11 |  30 | 0 |  
 
-   Total: 866
+   Total: 835
 
-Rack 0: RTTUW
-Rack 1: RTTUW
+Rack 0: NNRT
+Rack 1: NNRT
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   -  -  -  -  -  -  -  T  -  -  -  -  -  -  -
+ B   -  -  E  V  I  T  E  R  A  I  -  -  -  -  -
+ C   -  -  -  -  -  -  -  I  -  -  C  U  V  E  -
+ D   -  -  -  -  -  -  -  M  U  L  O  T  S  -  Q
+ E   -  -  -  -  -  -  -  E  -  -  R  -  -  -  U
+ F   -  -  -  -  -  -  -  R  -  K  A  W  I  -  I
+ G   -  -  -  -  -  -  -  -  -  I  N  -  -  -  p
+ H   -  -  -  F  A  B  A  c  E  E  S  -  -  D  U
+ I   -  -  -  I  -  -  -  -  -  F  -  -  H  O  -
+ J   -  -  -  X  -  J  A  L  E  S  -  -  E  T  -
+ K   -  -  -  E  H  -  -  I  -  -  P  E  L  E  R
+ L   -  -  -  E  U  -  -  P  -  N  O  U  E  Z  -
+ M   -  -  -  -  R  -  C  O  B  A  L  T  S  -  -
+ N   -  -  -  -  O  -  -  M  A  Y  E  -  -  -  -
+ O   A  D  O  N  N  A  M  E  S  -  -  -  -  -  -
 commande> q
 fin du mode duplicate
 commande> q

Index: test/duplicate_humans_ai.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/Attic/duplicate_humans_ai.input,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- test/duplicate_humans_ai.input      20 Dec 2007 08:47:09 -0000      1.1.2.1
+++ test/duplicate_humans_ai.input      31 Dec 2007 16:32:24 -0000      1.1.2.2
@@ -5,15 +5,16 @@
 a S
 a T
 n 1
-j MoTIVE 11F
+j DISAIENT 11A
 a S
-j VIDaME G6
+j DESTINAI 11E
 a S
-j FINASSE 12C
-j FANS i6
+a t
+j FRiPE 10K
+j sERF M11
 a S
 a t
-a gm
+a g
 a p
 q
 q

Index: test/duplicate_humans_ai.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/Attic/duplicate_humans_ai.ref,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- test/duplicate_humans_ai.ref        20 Dec 2007 08:47:10 -0000      1.1.2.1
+++ test/duplicate_humans_ai.ref        31 Dec 2007 16:32:24 -0000      1.1.2.2
@@ -3,9 +3,9 @@
 mode duplicate
 [?] pour l'aide
 commande> a T
-Joueur 0: DYSIATO
-Joueur 1: DYSIATO
-Joueur 2: DYSIATO
+Joueur 0: ATOYDSI
+Joueur 1: ATOYDSI
+Joueur 2: ATOYDSI
 commande> j DOSAIT H4
 commande> j DOSAIT h5
 commande> a S
@@ -13,45 +13,47 @@
 Joueur 1:   14
 Joueur 2:   30
 commande> a T
-Joueur 0: DIEF?MV
-Joueur 1: DIEF?MV
-Joueur 2: DIEF?MV
+Joueur 0: DIAEINS
+Joueur 1: DIAEINS
+Joueur 2: DIAEINS
 commande> n 1
-commande> j MoTIVE 11F
+commande> j DISAIENT 11A
 commande> a S
 Joueur 0:   18
-Joueur 1:   32
+Joueur 1:   82
 Joueur 2:   30
-commande> j VIDaME G6
+commande> j DESTINAI 11E
 commande> a S
-Joueur 0:   47
-Joueur 1:   32
-Joueur 2:   59
-commande> j FINASSE 12C
-commande> j FANS i6
+Joueur 0:  104
+Joueur 1:   82
+Joueur 2:  116
+commande> a t
+P?RBFEG
+commande> j FRiPE 10K
+commande> j sERF M11
 commande> a S
-Joueur 0:   78
-Joueur 1:   57
-Joueur 2:   94
+Joueur 0:  126
+Joueur 1:  103
+Joueur 2:  145
 commande> a t
-UFEQBZS
-commande> a gm
+GPEEMTB
+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   -  -  +  -  -  V  I  D  a  M  E  -  +  -  -
- H   F  A  I  N  E  S  -  O  Y  A  T  S  -  -  @
- I   -  -  +  -  -  -  +  -  +  -  -  -  +  -  -
- J   -  *  -  -  -  *  -  -  -  *  -  -  -  *  -
- K   -  -  -  -  #  -  -  -  -  -  #  -  -  -  -
- L   +  -  -  #  -  -  -  +  -  -  -  #  -  -  +
- M   -  -  #  -  -  -  +  -  +  -  -  -  #  -  -
- N   -  #  -  -  -  *  -  -  -  *  -  -  -  #  -
- O   @  -  -  +  -  -  -  @  -  -  -  +  -  -  @
+ A   -  -  -  -  -  -  -  -  -  -  -  F  -  -  -
+ B   -  -  -  -  -  -  -  -  -  -  -  i  -  -  -
+ C   -  -  -  -  -  -  -  -  -  -  -  B  -  -  -
+ D   -  -  -  -  -  -  -  -  -  -  -  R  -  -  -
+ E   -  -  -  -  -  -  -  -  -  -  D  E  -  -  -
+ F   -  -  -  -  -  -  -  -  -  -  E  -  -  -  -
+ G   -  -  -  -  -  -  -  -  -  -  S  -  -  -  -
+ H   -  -  -  -  -  -  -  O  Y  A  T  S  -  -  -
+ I   -  -  -  -  -  -  -  -  -  -  I  -  -  -  -
+ J   -  -  -  -  -  -  -  -  -  -  N  -  -  -  -
+ K   -  -  -  -  -  -  -  -  -  -  A  -  -  -  -
+ L   -  -  -  -  -  -  -  -  -  -  I  -  -  -  -
+ M   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ N   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+ O   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
 commande> a p
 Eliot 1.5
 
@@ -62,15 +64,15 @@
 
     N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
    ===|==========|=================|=====|=====|===|======
-    1 |  DYSIATO | OYATS           |  H8 |  30 | 2 |  
-    2 | DI+EF?MV | VIDaME          |  G6 |  29 | 0 |  
-    3 | F+USIENA | FAINES          |  H1 |  35 | 2 |  
+    1 |  ATOYDSI | OYATS           |  H8 |  30 | 2 |  
+    2 | DI+AEINS | DESTINAI        | 11E |  86 | 0 | *
+    3 |  P?RBFEG | FiBRE           | 12A |  29 | 2 |  
 
-   Total: 94
+   Total: 145
 
-Rack 0: U+FEQBZS
-Rack 1: U+FEQBZS
-Rack 2: U+FEQBZS
+Rack 0: GP+EEMTB
+Rack 1: GP+EEMTB
+Rack 2: GP+EEMTB
 commande> q
 fin du mode duplicate
 commande> q

Index: test/freegame_3_ai.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_3_ai.input,v
retrieving revision 1.1
retrieving revision 1.1.6.1
diff -u -b -r1.1 -r1.1.6.1
--- test/freegame_3_ai.input    16 Apr 2005 15:47:59 -0000      1.1
+++ test/freegame_3_ai.input    31 Dec 2007 16:32:24 -0000      1.1.6.1
@@ -2,6 +2,7 @@
 a T
 a S
 a p
+a g
 q
 q
 

Index: test/freegame_3_ai.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_3_ai.ref,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -b -r1.3 -r1.3.2.1
--- test/freegame_3_ai.ref      1 Jan 2006 19:25:10 -0000       1.3
+++ test/freegame_3_ai.ref      31 Dec 2007 16:32:24 -0000      1.3.2.1
@@ -4,12 +4,12 @@
 [?] pour l'aide
 commande> a T
 Joueur 0: 
-Joueur 1: DEPKAS
-Joueur 2: DILMQ
+Joueur 1: IN
+Joueur 2: GO
 commande> a S
-Joueur 0:  398
-Joueur 1:  266
-Joueur 2:  205
+Joueur 0:  395
+Joueur 1:  291
+Joueur 2:  343
 commande> a p
 Eliot 1.5
 
@@ -20,31 +20,51 @@
 
     N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
    ===|==========|=================|=====|=====|===|======
-    1 |  RTADHIR | HARDI           |  H4 |  26 | 0 |  
-    2 |  ANO?EEA | ANEE            |  I4 |  18 | 1 |  
-    3 |  WIG?TEN | IWaN            |  J1 |  38 | 2 |  
-    4 | RT+NTEIU | INTUITER        |  1F |  77 | 0 | *
-    5 | AO?+TFBA | BAFOuAT         |  J7 |  69 | 1 | *
-    6 | EGT+OSTR | GROTTES         |  9B |  70 | 2 | *
-    7 |  UEEOERE | GOUREE          |  B9 |  18 | 0 |  
-    8 |  EAMIZUO | INTUITEREZ      |  1F |  57 | 1 |  
-    9 |  XRUMGRQ | GRAUX           | 12H |  34 | 2 |  
-   10 | EE+ONLAS | ENOLATES        |  E4 |  82 | 0 | *
-   11 | AIMOU+NN | NOMINAUX        |  L5 |  69 | 1 | *
-   12 | MQR+LIHJ | HI              |  F6 |  28 | 2 |  
-   13 |  PLCYEFE | CAPEYE          |  3I |  52 | 0 |  
-   14 |  EVLETDE | VOLETE          |  D8 |  39 | 1 |  
-   15 | JLMQR+OB | ROB             |  O3 |  25 | 2 |  
-   16 | FL+UUSML | FULL            |  D1 |  26 | 0 |  
-   17 | DE+ICPEV | VICE            |  C2 |  32 | 1 |  
-   18 | JLMQ+DSI | JANS            |  5G |  24 | 2 |  
-   19 | MSU+SAAI | ASSUMAI         | 15A |  85 | 0 | *
+    1 |  RAHITRD | HARDI           |  H4 |  26 | 0 |  
+    2 |  ?TIEXFA | FAXAIEnT        |  5E | 126 | 1 | *
+    3 |  ATOSBUF | BOUTEFAS        |  J1 |  73 | 2 | *
+    4 | RT+AREEN | ENTERRAI        |  8A |  77 | 0 | *
+    5 |  RZUGNSS | AZURS           |  F5 |  34 | 1 |  
+    6 |  MIMLLOP | PLOMB           |  1F |  30 | 2 |  
+    7 |  EEMNETV | VETEMENT        |  C6 |  78 | 0 | *
+    8 | GNRS+PEN | PURGES          |  3I |  24 | 1 |  
+    9 | ILM+HSVI | VIS             | 14A |  25 | 2 |  
+   10 |  AWELOUB | WAX             |  G3 |  36 | 0 |  
+   11 | NN+ELEEE | ENLEVE          | A10 |  30 | 1 |  
+   12 | HILM+?IC | aLCHIMIE        |  A1 | 101 | 2 | *
+   13 | BELOU+LS | SOLUBLES        |  N3 |  64 | 0 | *
+   14 | EN+ACTAA | ATACA           |  O8 |  34 | 1 |  
+   15 |  UEJNRYO | JURON           |  M9 |  61 | 2 |  
+   16 |  UANSKIQ | QUASI           | 14J |  69 | 0 |  
+   17 | EN+DERIO | RESOLUBLES      |  N1 |  24 | 1 |  
+   18 | EY+GOUID | YUE             |  B1 |  42 | 2 |  
+   19 |    KN+ET | KOTA            | 12L |  26 | 0 |  
+   20 |    DEINO | DORE            |  1L |  21 | 1 |  
+   21 |     DGIO | CEDI            |  3A |  14 | 2 |  
+   22 |       EN | NE              |  L8 |  14 | 0 |  
 
-   Total: 869
+   Total: 1029
 
 Rack 0: 
-Rack 1: DEP+KAS
-Rack 2: DILMQ
+Rack 1: IN
+Rack 2: GO
+commande> a g
+     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+ A   a  L  C  H  I  M  I  E  -  E  N  L  E  V  E
+ B   Y  U  E  -  -  -  -  N  -  -  -  -  -  I  -
+ C   -  -  D  -  -  V  E  T  E  M  E  N  T  S  -
+ D   -  -  I  -  -  -  -  E  -  -  -  -  -  -  -
+ E   -  -  -  -  F  -  -  R  -  -  -  -  -  -  -
+ F   P  -  -  -  A  Z  U  R  S  -  -  -  -  -  -
+ G   L  -  W  A  X  -  -  A  -  -  -  -  -  -  -
+ H   O  -  -  H  A  R  D  I  -  -  -  -  -  -  -
+ I   M  -  P  -  I  -  -  -  -  -  -  -  -  -  -
+ J   B  O  U  T  E  F  A  S  -  -  -  -  -  Q  -
+ K   -  -  R  -  n  -  -  -  -  -  -  -  -  U  -
+ L   D  -  G  -  T  -  -  N  E  -  -  K  -  A  -
+ M   O  -  E  -  -  -  -  -  J  U  R  O  N  S  -
+ N   R  E  S  O  L  U  B  L  E  S  -  T  -  I  -
+ O   E  -  -  -  -  -  -  A  T  A  C  A  -  -  -
 commande> q
 fin du mode partie libre
 commande> q

Index: test/freegame_change.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_change.input,v
retrieving revision 1.1.6.1
retrieving revision 1.1.6.2
diff -u -b -r1.1.6.1 -r1.1.6.2
--- test/freegame_change.input  23 Dec 2007 23:12:45 -0000      1.1.6.1
+++ test/freegame_change.input  31 Dec 2007 16:32:24 -0000      1.1.6.2
@@ -2,13 +2,13 @@
 a T
 p JID
 a T
-p auouel
+p aowalt
 a T
-p WX
+p MA
 a T
-p WA
+p MN
 a T
-p KEEEAAI
+p SGEEEAI
 a T
 a p
 q

Index: test/freegame_change.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_change.ref,v
retrieving revision 1.2.4.1
retrieving revision 1.2.4.2
diff -u -b -r1.2.4.1 -r1.2.4.2
--- test/freegame_change.ref    23 Dec 2007 23:12:45 -0000      1.2.4.1
+++ test/freegame_change.ref    31 Dec 2007 16:32:24 -0000      1.2.4.2
@@ -3,28 +3,28 @@
 mode partie libre
 [?] pour l'aide
 commande> a T
-Joueur 0: NEIJEDN
-Joueur 1: UUEALEO
+Joueur 0: JNNEDEI
+Joueur 1: TLAEOWA
 commande> p JID
 commande> a T
-Joueur 0: EENNWTA
-Joueur 1: UUEALEO
-commande> p auouel
+Joueur 0: EENNMEN
+Joueur 1: TLAEOWA
+commande> p aowalt
 commande> a T
-Joueur 0: EENNWTA
-Joueur 1: EEAKEIA
-commande> p WX
+Joueur 0: EENNMEN
+Joueur 1: EEEGAIS
+commande> p MA
 commande> a T
-Joueur 0: EENNWTA
-Joueur 1: EEAKEIA
-commande> p WA
+Joueur 0: EENNMEN
+Joueur 1: EEEGAIS
+commande> p MN
 commande> a T
-Joueur 0: EENNTOD
-Joueur 1: EEAKEIA
-commande> p KEEEAAI
+Joueur 0: EEENNER
+Joueur 1: EEEGAIS
+commande> p SGEEEAI
 commande> a T
-Joueur 0: EENNTOD
-Joueur 1: UNLEUSS
+Joueur 0: EEENNER
+Joueur 1: HAAUAUO
 commande> a p
 Eliot 1.5
 
@@ -34,15 +34,15 @@
 
     N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
    ===|==========|=================|=====|=====|===|======
-    1 |  NEIJEDN | (-JID)          |  -  |   0 | 0 |
-    2 |  UUEALEO | (-AUOUEL)       |  -  |   0 | 1 |
-    3 | EENN+WTA | (-WA)           |  -  |   0 | 0 |
-    4 | E+EAKEIA | (-KEEEAAI)      |  -  |   0 | 1 |
+    1 |  JNNEDEI | (-JID)          |  -  |   0 | 0 |
+    2 |  TLAEOWA | (-AOWALT)       |  -  |   0 | 1 |
+    3 | EENN+MEN | (-MN)           |  -  |   0 | 0 |
+    4 | E+EEGAIS | (-SGEEEAI)      |  -  |   0 | 1 |
 
    Total: 0
 
-Rack 0: EENNT+OD
-Rack 1: UNLEUSS
+Rack 0: EEENN+ER
+Rack 1: HAAUAUO
 commande> q
 fin du mode partie libre
 commande> q

Index: test/freegame_passing.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_passing.input,v
retrieving revision 1.1.6.1
retrieving revision 1.1.6.2
diff -u -b -r1.1.6.1 -r1.1.6.2
--- test/freegame_passing.input 14 Dec 2007 18:12:33 -0000      1.1.6.1
+++ test/freegame_passing.input 31 Dec 2007 16:32:24 -0000      1.1.6.2
@@ -25,6 +25,7 @@
 p
 p
 p
+p
 a S
 a T
 a p

Index: test/freegame_passing.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/freegame_passing.ref,v
retrieving revision 1.3.2.2
retrieving revision 1.3.2.3
diff -u -b -r1.3.2.2 -r1.3.2.3
--- test/freegame_passing.ref   23 Dec 2007 23:12:45 -0000      1.3.2.2
+++ test/freegame_passing.ref   31 Dec 2007 16:32:25 -0000      1.3.2.3
@@ -11,7 +11,8 @@
 EGISSTU
 commande> p UIET
 commande> a t
-GSSDIDB
+GSSTAUV
+commande> p
 commande> p
 commande> p
 commande> p
@@ -33,10 +34,10 @@
 commande> p
 commande> p
 commande> a S
-Joueur 0:  -12
-Joueur 1:  836
+Joueur 0:  -11
+Joueur 1:  778
 commande> a T
-Joueur 0: BDDGISS
+Joueur 0: AGSSTUV
 Joueur 1: 
 commande> a p
 Eliot 1.5
@@ -47,56 +48,58 @@
 
     N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS
    ===|==========|=================|=====|=====|===|======
-    1 |  TISSUEG | (PASS)          |  -  |   0 | 0 |
-    2 |  RENLOHL | HERON           |  H4 |  24 | 1 |  
+    1 |  SEUTISG | (PASS)          |  -  |   0 | 0 |
+    2 |  LXCORNU | ROUX            |  H8 |  26 | 1 |  
     3 |  EGISSTU | (PASS)          |  -  |   0 | 0 |
-    4 | LL+XUORC | OCREUX          |  5E |  34 | 1 |  
+    4 | CLN+?BEC | CiNECLUB        | 10B |  75 | 1 | *
     5 |  EGISSTU | (-UIET)         |  -  |   0 | 0 |
-    6 | LL+NAECT | CALLENT         |  I7 |  73 | 1 | *
-    7 | GSS+DIDB | (PASS)          |  -  |   0 | 0 |
-    8 |  ?EMTOEO | ENTOlOME        | 12H |  70 | 1 | *
-    9 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   10 |  MLZESLS | MEZES           | O11 |  45 | 1 |  
-   11 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   12 | LLS+IUEG | GOUILLES        |  E4 |  68 | 1 | *
-   13 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   14 |  TVAWLAE | AWELE           | 10A |  34 | 1 |  
-   15 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   16 | ATV+PUFA | PAVAT           |  A7 |  30 | 1 |  
-   17 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   18 | AFU+AIAE | FA              |  G7 |  24 | 1 |  
-   19 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   20 | AAEIU+YU | YEUX            |  J2 |  42 | 1 |  
-   21 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   22 | AAIU+TEN | NEZ             | 13M |  31 | 1 |  
-   23 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   24 | AAITU+IR | AUTRE           | 14K |  21 | 1 |  
-   25 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   26 | AII+MPNA | PAMAI           | 15G |  26 | 1 |  
-   27 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   28 | IN+IUURE | TUNES           | 11A |  20 | 1 |  
-   29 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   30 | IIRU+RNF | NIF             | 11K |  24 | 1 |  
-   31 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   32 | IRRU+OEI | HOUER           |  4H |  18 | 1 |  
-   33 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   34 | IIRU+TSE | YETIS           |  2J |  28 | 1 |  
-   35 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   36 | IRU+ETHO | HERE            |  3I |  27 | 1 |  
-   37 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   38 | IOTU+?JN | SUJeTION        |  N2 |  66 | 1 | *
-   39 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   40 |  SEVDQIR | DEVENIRS        |  C7 |  36 | 1 |  
-   41 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   42 | Q+BAKIAE | KABIG           |  4A |  54 | 1 |  
-   43 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   44 |      AEQ | QUE             |  6D |  18 | 1 |  
-   45 |  BDDGISS | (PASS)          |  -  |   0 | 0 |
-   46 |        A | KA              |  A4 |  11 | 1 |  
+    6 |  LLESYEO | YOLES           |  J6 |  52 | 1 |  
+    7 | GSS+TAUV | (PASS)          |  -  |   0 | 0 |
+    8 | EL+AAOGT | GALETA          | 11A |  29 | 1 |  
+    9 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   10 | O+RTEUMI | MORUTIER        |  8A |  80 | 1 | *
+   11 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   12 |  EUNPFUP | PFUT            |  E5 |  18 | 1 |  
+   13 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   14 | ENPU+FTE | FETE            | 12B |  33 | 1 |  
+   15 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   16 | NPU+NSIM | LUPINS          |  8J |  33 | 1 |  
+   17 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   18 | MN+UEWOI | WON             |  N6 |  32 | 1 |  
+   19 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   20 | EIMNU+MI | IMMUNS          |  O3 |  23 | 1 |  
+   21 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   22 | EI+IDRED | BIRDIE          | I10 |  22 | 1 |  
+   23 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   24 | DE+RJAAT | DEJETA          | 15H |  45 | 1 |  
+   25 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   26 | AR+ENQEE | CAFRE           | B10 |  20 | 1 |  
+   27 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   28 | AEENQ+BR | BADERNE         | 13G |  26 | 1 |  
+   29 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   30 | Q+EAZAEL | ZEN             | L11 |  24 | 1 |  
+   31 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   32 | AAELQ+RA | RALA            |  I3 |  16 | 1 |  
+   33 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   34 | AEQ+LDEH | HADALE          |  4H |  28 | 1 |  
+   35 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   36 | EQ+SI?AI | QuASI           | N10 |  65 | 1 |  
+   37 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   38 | EI+TVHEO | HIT             |  5K |  26 | 1 |  
+   39 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   40 | EEOV+ONK | OVE             | A13 |  25 | 1 |  
+   41 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   42 | EKNO+SIN | KIEFS           |  6B |  39 | 1 |  
+   43 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   44 |      NNO | NAY             |  6H |  12 | 1 |  
+   45 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   46 |       NO | ZOU             | 11L |  11 | 1 |  
+   47 |  AGSSTUV | (PASS)          |  -  |   0 | 0 |
+   48 |        N | NI              |  M7 |   7 | 1 |  
 
-   Total: 824
+   Total: 767
 
-Rack 0: BDDGISS
+Rack 0: AGSSTUV
 Rack 1: 
 commande> q
 fin du mode partie libre




reply via email to

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