eliot-dev
[Top][All Lists]
Advanced

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

[Eliot-dev] eliot game/duplicate.cpp game/duplicate.h game/...


From: Olivier Teulière
Subject: [Eliot-dev] eliot game/duplicate.cpp game/duplicate.h game/...
Date: Sat, 24 Jan 2009 17:11:08 +0000

CVSROOT:        /cvsroot/eliot
Module name:    eliot
Changes by:     Olivier Teulière <ipkiss>       09/01/24 17:11:08

Modified files:
        game           : duplicate.cpp duplicate.h game.cpp 
                         public_game.cpp public_game.h 
        test           : training_dict.input training_dict.ref 
        utils          : eliottxt.cpp 

Log message:
         - Throw exceptions in case of problem in Duplicate::setPlayer()
         - Clean up of the text interface:
            - removed all uses of wcstok()
            - factorized common code
            - made code a bit more robust

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/game/duplicate.cpp?cvsroot=eliot&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/eliot/game/duplicate.h?cvsroot=eliot&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game.cpp?cvsroot=eliot&r1=1.54&r2=1.55
http://cvs.savannah.gnu.org/viewcvs/eliot/game/public_game.cpp?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/public_game.h?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_dict.input?cvsroot=eliot&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/eliot/test/training_dict.ref?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/utils/eliottxt.cpp?cvsroot=eliot&r1=1.32&r2=1.33

Patches:
Index: game/duplicate.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/duplicate.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- game/duplicate.cpp  30 Nov 2008 20:55:46 -0000      1.29
+++ game/duplicate.cpp  24 Jan 2009 17:11:07 -0000      1.30
@@ -21,6 +21,14 @@
 #include <boost/foreach.hpp>
 #include <sstream>
 
+#include "config.h"
+#if ENABLE_NLS
+#   include <libintl.h>
+#   define _(String) gettext(String)
+#else
+#   define _(String) String
+#endif
+
 #include "duplicate.h"
 #include "game_exception.h"
 #include "dic.h"
@@ -273,16 +281,19 @@
 }
 
 
-int Duplicate::setPlayer(unsigned int p)
+void Duplicate::setPlayer(unsigned int p)
 {
     ASSERT(p < getNPlayers(), "Wrong player number");
 
     // Forbid switching to an AI player
     if (!m_players[p]->isHuman())
-        return 1;
+        throw GameException(_("Cannot switch to a non-human player"));
+
+    // Forbid switching back to a player who has already played
+    if (hasPlayed(p))
+        throw GameException(_("Cannot switch to a player who has already 
played"));
 
     m_currPlayer = p;
-    return 0;
 }
 
 

Index: game/duplicate.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/duplicate.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- game/duplicate.h    30 Nov 2008 20:55:46 -0000      1.20
+++ game/duplicate.h    24 Jan 2009 17:11:07 -0000      1.21
@@ -79,13 +79,13 @@
 
     /**
      * Set the current player, given its ID.
-     * The given player ID must correspond to a human player, which did not
+     * The given player ID must correspond to a human player, who did not
      * play yet for this turn.
-     * Possible return values:
-     *  0: everything went fine
-     *  1: the player is not human
+     * @param p: ID of the player
+     * @exception GameException: Thrown if the player is not human or if
+     *      he has already played
      */
-    int setPlayer(unsigned int p);
+    void setPlayer(unsigned int p);
 
     /// Return true if the player has played for the current turn
     virtual bool hasPlayed(unsigned int iPlayerId) const;

Index: game/game.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game.cpp,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -b -r1.54 -r1.55
--- game/game.cpp       24 Jan 2009 10:28:20 -0000      1.54
+++ game/game.cpp       24 Jan 2009 17:11:07 -0000      1.55
@@ -22,6 +22,7 @@
 #include <boost/foreach.hpp>
 #include <sstream>
 
+#include "config.h"
 #if ENABLE_NLS
 #   include <libintl.h>
 #   define _(String) gettext(String)

Index: game/public_game.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/public_game.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- game/public_game.cpp        24 Jan 2009 10:28:21 -0000      1.3
+++ game/public_game.cpp        24 Jan 2009 17:11:07 -0000      1.4
@@ -226,9 +226,9 @@
 }
 
 
-int PublicGame::duplicateSetPlayer(unsigned int p)
+void PublicGame::duplicateSetPlayer(unsigned int p)
 {
-    return getDuplicateGame(m_game).setPlayer(p);
+    getDuplicateGame(m_game).setPlayer(p);
 }
 
 /***************************/

Index: game/public_game.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/public_game.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- game/public_game.h  24 Jan 2009 10:28:21 -0000      1.3
+++ game/public_game.h  24 Jan 2009 17:11:07 -0000      1.4
@@ -207,13 +207,13 @@
 
     /**
      * Set the current player, given its ID.
-     * The given player ID must correspond to a human player, which did not
+     * The given player ID must correspond to a human player, who did not
      * play yet for this turn.
-     * Possible return values:
-     *  0: everything went fine
-     *  1: the player is not human
+     * @param p: ID of the player
+     * @exception GameException: Thrown if the player is not human or if
+     *      he has already played
      */
-    int duplicateSetPlayer(unsigned int p);
+    void duplicateSetPlayer(unsigned int p);
 
     /***************
      * FreeGame games

Index: test/training_dict.input
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_dict.input,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- test/training_dict.input    16 Apr 2005 15:47:59 -0000      1.1
+++ test/training_dict.input    24 Jan 2009 17:11:07 -0000      1.2
@@ -2,8 +2,9 @@
 d MAISON
 d WXE
 d GenTiLLeSse
-d JOKE?
-d P0U3T
+d pouet
+d café
+d maïs
+d mais
 q
 q
-

Index: test/training_dict.ref
===================================================================
RCS file: /cvsroot/eliot/eliot/test/training_dict.ref,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- test/training_dict.ref      23 Nov 2008 08:33:17 -0000      1.3
+++ test/training_dict.ref      24 Jan 2009 17:11:07 -0000      1.4
@@ -9,10 +9,14 @@
 le mot -WXE- n'existe pas
 commande> d GenTiLLeSse
 le mot -GenTiLLeSse- existe
-commande> d JOKE?
-le mot -JOKE- n'existe pas
-commande> d P0U3T
-le mot -P- n'existe pas
+commande> d pouet
+le mot -pouet- n'existe pas
+commande> d café
+le mot -café- n'existe pas
+commande> d maïs
+le mot -maïs- n'existe pas
+commande> d mais
+le mot -mais- existe
 commande> q
 fin du mode entraînement
 commande> q

Index: utils/eliottxt.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/utils/eliottxt.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- utils/eliottxt.cpp  24 Jan 2009 10:28:22 -0000      1.32
+++ utils/eliottxt.cpp  24 Jan 2009 17:11:08 -0000      1.33
@@ -20,6 +20,8 @@
 
 #include "config.h"
 
+#include <boost/foreach.hpp>
+#include <boost/tokenizer.hpp>
 #include <wchar.h>
 #include <fstream>
 #include <iostream>
@@ -49,6 +51,11 @@
 #include "settings.h"
 
 
+// Use a more friendly type name for the tokenizer
+typedef boost::tokenizer<boost::char_separator<wchar_t>,
+        std::wstring::const_iterator,
+        std::wstring> Tokenizer;
+
 /* A static variable for holding the line. */
 static wchar_t *wline_read = NULL;
 
@@ -111,105 +118,91 @@
 }
 
 
-wchar_t * next_token_alpha(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
+wstring checkAlphaToken(const vector<wstring> &tokens, uint8_t index)
 {
-    wchar_t *token = _wcstok(cmd, delim, state);
-    if (token == NULL)
-        return NULL;
-    int i;
-    for (i = 0; token[i] && iswalpha(token[i]); i++)
-        ;
-    token[i] = L'\0';
-    return token;
-}
-
-
-wchar_t * next_token_alphanum(wchar_t *cmd, const wchar_t *delim, wchar_t 
**state)
-{
-    wchar_t *token = _wcstok(cmd, delim, state);
-    if (token == NULL)
-        return NULL;
-    int i;
-    for (i = 0; token[i] && iswalnum(token[i]); i++)
-        ;
-    token[i] = L'\0';
-    return token;
+    if (tokens.size() <= index)
+        return L"";
+    const wstring &wstr = tokens[index];
+    BOOST_FOREACH(wchar_t wch, wstr)
+    {
+        if (!iswalpha(wch))
+            return L"";
+    }
+    return wstr;
 }
 
 
-wchar_t * next_token_alphaplusjoker(wchar_t *cmd, const wchar_t *delim, 
wchar_t **state)
+wstring checkAlphaNumToken(const vector<wstring> &tokens, uint8_t index)
 {
-    wchar_t *token = _wcstok(cmd, delim, state);
-    if (token == NULL)
-        return NULL;
-    int i;
-    for (i = 0; token[i] && (iswalpha(token[i]) ||
-                             token[i] == L'?'   ||
-                             token[i] == L'+');
-         i++)
-        ;
-    token[i] = L'\0';
-    return token;
+    if (tokens.size() <= index)
+        return L"";
+    const wstring &wstr = tokens[index];
+    BOOST_FOREACH(wchar_t wch, wstr)
+    {
+        if (!iswalnum(wch))
+            return L"";
+    }
+    return wstr;
 }
 
 
-wchar_t * next_token_digit(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
+wstring checkAlphaPlusJokerToken(const vector<wstring> &tokens, uint8_t index)
 {
-    wchar_t *token = _wcstok(cmd, delim, state);
-    if (token == NULL)
-        return NULL;
-    int i;
-    for (i = 0; token[i] && (iswdigit(token[i]) || token[i] == L'-'); i++)
-        ;
-    token[i] = L'\0';
-    return token;
+    if (tokens.size() <= index)
+        return L"";
+    const wstring &wstr = tokens[index];
+    BOOST_FOREACH(wchar_t wch, wstr)
+    {
+        if (!iswalpha(wch) && wch != L'+' && wch != L'?')
+            return L"";
+    }
+    return wstr;
 }
 
 
-wchar_t * next_token_cross(wchar_t *cmd, const wchar_t *delim, wchar_t **state)
+wstring checkNumToken(const vector<wstring> &tokens, uint8_t index)
 {
-    wchar_t *token = _wcstok(cmd, delim, state);
-    if (token == NULL)
-        return NULL;
-    int i;
-    for (i = 0; token[i] &&
-         (iswalpha(token[i]) || token[i] == L'.');
-         i++)
-        ;
-    token[i] = L'\0';
-    return token;
+    if (tokens.size() <= index)
+        return L"";
+    const wstring &wstr = tokens[index];
+    BOOST_FOREACH(wchar_t wch, wstr)
+    {
+        if (!iswdigit(wch) && wch != L'-')
+            return L"";
+    }
+    return wstr;
 }
 
 
-wchar_t * next_token_filename(wchar_t *cmd, const wchar_t *delim, wchar_t 
**state)
+wstring checkFileNameToken(const vector<wstring> &tokens, uint8_t index)
 {
-    wchar_t *token = _wcstok(cmd, delim, state);
-    if (token == NULL)
-        return NULL;
-    int i;
-    for (i = 0; token[i] && (iswalnum(token[i]) ||
-                             token[i] == L'.' ||
-                             token[i] == L'_'); i++)
-        ;
-    token[i] = L'\0';
-    return token;
+    if (tokens.size() <= index)
+        return L"";
+    const wstring &wstr = tokens[index];
+    BOOST_FOREACH(wchar_t wch, wstr)
+    {
+        if (!iswalpha(wch) && wch != L'.' && wch != L'_')
+            return L"";
+    }
+    return wstr;
 }
 
 
-void eliottxt_get_cross(const Dictionary &iDic, const wstring &iCros)
+wstring checkCrossToken(const vector<wstring> &tokens, uint8_t index)
 {
-    vector<wstring> wordList;
-    iDic.searchCross(iCros, wordList);
-
-    vector<wstring>::const_iterator it;
-    for (it = wordList.begin(); it != wordList.end(); it++)
+    if (tokens.size() <= index)
+        return L"";
+    const wstring &wstr = tokens[index];
+    BOOST_FOREACH(wchar_t wch, wstr)
     {
-        printf("  %s\n", convertToMb(*it).c_str());
+        if (!iswalpha(wch) && wch != L'.')
+            return L"";
     }
+    return wstr;
 }
 
 
-void help_training()
+void helpTraining()
 {
     printf("  ?    : aide -- cette page\n");
     printf("  a [g|l|p|r|t] : afficher :\n");
@@ -243,7 +236,7 @@
 }
 
 
-void help_freegame()
+void helpFreegame()
 {
     printf("  ?    : aide -- cette page\n");
     printf("  a [g|l|p|s|t] : afficher :\n");
@@ -268,7 +261,7 @@
 }
 
 
-void help_duplicate()
+void helpDuplicate()
 {
     printf("  ?    : aide -- cette page\n");
     printf("  a [g|l|p|s|t] : afficher :\n");
@@ -314,164 +307,285 @@
 }
 
 
-void display_data(const PublicGame &iGame, const wchar_t *delim, wchar_t 
**state)
+void displayData(const PublicGame &iGame, const vector<wstring> &tokens)
 {
-    const wchar_t *token;
-
-    token = next_token_alpha(NULL, delim, state);
-    if (token == NULL)
+    const wstring &displayType = checkAlphaNumToken(tokens, 1);
+    if (displayType == L"")
     {
         cout << "commande incomplète\n";
         return;
     }
-    switch (token[0])
-    {
-        case L'g':
-            switch (token[1])
-            {
-                case L'\0':
+    if (displayType == L"g")
                     GameIO::printBoard(cout, iGame);
-                    break;
-                case L'd':
+    else if (displayType == L"gd")
                     GameIO::printBoardDebug(cout, iGame);
-                    break;
-                case L'j':
+    else if (displayType == L"gj")
                     GameIO::printBoardJoker(cout, iGame);
-                    break;
-                case L'm':
+    else if (displayType == L"gm")
                     GameIO::printBoardMultipliers(cout, iGame);
-                    break;
-                case L'n':
+    else if (displayType == L"gn")
                     GameIO::printBoardMultipliers2(cout, iGame);
-                    break;
-                default:
-                    printf("commande inconnue\n");
-                    break;
-            }
-            break;
-        case L'j':
+    else if (displayType == L"j")
             cout << "Joueur " << iGame.getCurrentPlayer().getId() << endl;
-            break;
-        case L'l':
+    else if (displayType == L"l")
             GameIO::printNonPlayed(cout, iGame);
-            break;
-        case L'p':
-            switch (token[1])
-                {
-                case '\0':
-                    iGame.save(cout,PublicGame::kFILE_FORMAT_ADVANCED);
-                    break;
-                case 'd':
+    else if (displayType == L"p")
+        iGame.save(cout, PublicGame::kFILE_FORMAT_ADVANCED);
+    else if (displayType == L"pd")
                     GameIO::printGameDebug(cout, iGame);
-                    break;
-                default:
-                    printf("commande inconnue\n");
-                }
-            break;
-        case L'P':
-            iGame.save(cout,PublicGame::kFILE_FORMAT_STANDARD);
-            break;
-        case L'r':
-            token = next_token_digit(NULL, delim, state);
-            if (token == NULL)
+    else if (displayType == L"P")
+        iGame.save(cout, PublicGame::kFILE_FORMAT_STANDARD);
+    else if (displayType == L"r")
+    {
+        const wstring &limit = checkNumToken(tokens, 2);
+        if (limit == L"")
                 GameIO::printSearchResults(cout,
                                            iGame.trainingGetResults(),
                                            10);
             else
                 GameIO::printSearchResults(cout,
                                            iGame.trainingGetResults(),
-                                           _wtoi(token));
-            break;
-        case L's':
+                                       _wtoi(limit.c_str()));
+    }
+    else if (displayType == L"s")
             GameIO::printPoints(cout, iGame);
-            break;
-        case L'S':
+    else if (displayType == L"S")
             GameIO::printAllPoints(cout, iGame);
-            break;
-        case L't':
+    else if (displayType == L"t")
             GameIO::printPlayedRack(cout, iGame, iGame.getHistory().getSize());
-            break;
-        case L'T':
+    else if (displayType == L"T")
             GameIO::printAllRacks(cout, iGame);
-            break;
-        default:
+    else
             cout << "commande inconnue\n";
-            break;
-    }
 }
 
 
-void handleNavigation(PublicGame &iGame, wchar_t iChar)
+void commonCommands(PublicGame &iGame, const vector<wstring> &tokens)
 {
-    switch (iChar)
+    if (tokens[0][0] == L'a')
+        displayData(iGame, tokens);
+    else if (tokens[0][0] == L'd')
     {
-        case L'p':
+        const wstring &word = checkAlphaToken(tokens, 1);
+        if (word == L"")
+            helpDuplicate();
+        else
+        {
+            if (iGame.getDic().searchWord(word))
+                printf("le mot -%s- existe\n", convertToMb(word).c_str());
+            else
+                printf("le mot -%s- n'existe pas\n", 
convertToMb(word).c_str());
+        }
+    }
+    else if (tokens[0][0] == L'h')
+    {
+        const wstring &action = checkAlphaToken(tokens, 1);
+        if (action == L"" || action.size() != 1)
+            return;
+        if (action[0] == L'p')
             iGame.prevTurn();
-            break;
-        case L'n':
+        else if (action[0] == L'n')
             iGame.nextTurn();
-            break;
-        case L'f':
+        else if (action[0] == L'f')
             iGame.firstTurn();
-            break;
-        case L'l':
+        else if (action[0] == L'l')
             iGame.lastTurn();
-            break;
-        case L'r':
+        else if (action[0] == L'r')
             iGame.clearFuture();
-            break;
     }
+    else if (tokens[0][0] == L'j')
+    {
+        const wstring &word = checkAlphaToken(tokens, 1);
+        if (word == L"")
+            helpDuplicate();
+        else
+        {
+            const wstring &coord = checkAlphaNumToken(tokens, 2);
+            if (coord == L"")
+            {
+                helpDuplicate();
+                return;
+            }
+            int res = iGame.play(word, coord);
+            if (res != 0)
+                printf("Mot incorrect ou mal placé (%i)\n", res);
+        }
+    }
+    else if (tokens[0][0] == L's')
+    {
+        const wstring &word = checkFileNameToken(tokens, 1);
+        if (word != L"")
+        {
+            string filename = convertToMb(word);
+            ofstream fout(filename.c_str());
+            if (fout.rdstate() == ios::failbit)
+            {
+                printf("impossible d'ouvrir %s\n", filename.c_str());
+                return;
+            }
+            iGame.save(fout);
+            fout.close();
+        }
+    }
+}
+
+
+void handleRegexp(const Dictionary& iDic, const vector<wstring> &tokens)
+{
+    /*
+    printf("  x [] {1} {2} {3} : expressions rationnelles\n");
+    printf("          [] expression à rechercher\n");
+    printf("          {1} nombre de résultats à afficher\n");
+    printf("          {2} longueur minimum d'un mot\n");
+    printf("          {3} longueur maximum d'un mot\n");
+    */
+
+    if (tokens.size() < 2 || tokens.size() > 5)
+    {
+        printf("Invalid number of parameters\n");
+        return;
+    }
+
+    const wstring &regexp = tokens[1];
+    const wstring &cnres = checkNumToken(tokens, 2);
+    const wstring &clmin = checkNumToken(tokens, 3);
+    const wstring &clmax = checkNumToken(tokens, 4);
+
+    if (regexp == L"")
+        return;
+
+    unsigned int nres = (cnres != L"") ? _wtoi(cnres.c_str()) : 50;
+    unsigned int lmin = (clmin != L"") ? _wtoi(clmin.c_str()) : 1;
+    unsigned int lmax = (clmax != L"") ? _wtoi(clmax.c_str()) : DIC_WORD_MAX - 
1;
+
+    if (lmax > (DIC_WORD_MAX - 1) || lmin < 1 || lmin > lmax)
+    {
+        printf("bad length -%ls,%ls-\n", clmin.c_str(), clmax.c_str());
+        return;
+    }
+
+    printf("search for %s (%d,%d,%d)\n", convertToMb(regexp).c_str(),
+           nres, lmin, lmax);
+
+    vector<wstring> wordList;
+    try
+    {
+        iDic.searchRegExp(regexp, wordList, lmin, lmax, nres);
+    }
+    catch (InvalidRegexpException &e)
+    {
+        printf("Invalid regular expression: %s\n", e.what());
+        return;
+    }
+
+    BOOST_FOREACH(const wstring &wstr, wordList)
+    {
+        printf("%s\n", convertToMb(wstr).c_str());
+    }
+    printf("%d printed results\n", wordList.size());
 }
 
 
-void loop_training(PublicGame &iGame)
+void setSetting(const vector<wstring> &tokens)
 {
-    const wchar_t *token;
-    wchar_t *state;
-    wchar_t *commande = NULL;
-    wchar_t delim[] = L" \t";
-    int quit = 0;
-
-    cout << "mode entraînement\n";
-    cout << "[?] pour l'aide\n";
-    while (quit == 0)
-    {
-        commande = rl_gets();
-        token = _wcstok(commande, delim, &state);
-        if (token)
+    if (tokens.size() != 4)
+    {
+        printf("Invalid number of parameters\n");
+        return;
+    }
+    const wstring &type = checkAlphaToken(tokens, 1);
+    if (type == L"" || type.size() != 1 ||
+        (type[0] != L'b' && type[0] != L'i'))
         {
+        printf("Invalid type\n");
+        return;
+    }
+    const wstring &settingWide = tokens[2];
+    const wstring &value = tokens[3];
+
             try
             {
-                switch (token[0])
+        string setting = convertToMb(settingWide);
+        if (type == L"i")
+        {
+            Settings::Instance().setInt(setting, _wtoi(value.c_str()));
+        }
+        else if (type == L"b")
+        {
+            Settings::Instance().setBool(setting, _wtoi(value.c_str()));
+        }
+    }
+    catch (GameException &e)
+    {
+        string msg = "Error while changing a setting: " + string(e.what()) + 
"\n";
+        printf("%s", msg.c_str());
+        return;
+    }
+}
+
+
+void loopTraining(PublicGame &iGame)
+{
+    cout << "mode entraînement" << endl;
+    cout << "[?] pour l'aide" << endl;
+
+    bool quit = 0;
+    while (!quit)
+    {
+        wstring command = rl_gets();
+        // Split the command
+        vector<wstring> tokens;
+        boost::char_separator<wchar_t> sep(L" ");
+        Tokenizer tok(command, sep);
+        BOOST_FOREACH(const wstring &wstr, tok)
+        {
+            tokens.push_back(wstr);
+        }
+
+        if (tokens.empty())
+            continue;
+        if (tokens[0].size() > 1)
+        {
+            printf("%s\n", "Invalid command");
+            continue;
+        }
+
+        try
+        {
+            switch (tokens[0][0])
                 {
                     case L'?':
-                        help_training();
+                    helpTraining();
                         break;
                     case L'a':
-                        display_data(iGame, delim, &state);
+                case L'd':
+                case L'h':
+                case L'j':
+                case L's':
+                    commonCommands(iGame, tokens);
                         break;
                     case L'b':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token == NULL)
-                            help_training();
+                    {
+                        const wstring &type = checkAlphaToken(tokens, 1);
+                        if (type == L"")
+                            helpTraining();
                         else
                         {
-                            const wchar_t *word = next_token_alpha(NULL, 
delim, &state);
-                            if (word == NULL)
-                                help_training();
+                            const wstring &word = checkAlphaToken(tokens, 2);
+                            if (word == L"")
+                                helpTraining();
                             else
                             {
-                                switch (token[0])
+                                switch (type[0])
                                 {
                                     case L'b':
                                         {
                                             vector<wstring> wordList;
                                             iGame.getDic().searchBenj(word, 
wordList);
-                                            vector<wstring>::const_iterator it;
-                                            for (it = wordList.begin(); it != 
wordList.end(); ++it)
-                                                cout << convertToMb(*it) << 
endl;
-                                            break;
+                                            BOOST_FOREACH(const wstring &wstr, 
wordList)
+                                                cout << convertToMb(wstr) << 
endl;
                                         }
+                                        break;
                                     case L'p':
                                         {
                                             map<wchar_t, vector<wstring> > 
wordMap;
@@ -481,73 +595,34 @@
                                             {
                                                 if (it->first)
                                                     cout << "+" << 
convertToMb(it->first) << endl;
-                                                
vector<wstring>::const_iterator itWord;;
-                                                for (itWord = 
it->second.begin(); itWord != it->second.end(); itWord++)
+                                                BOOST_FOREACH(const wstring 
&wstr, it->second)
                                                 {
-                                                    cout << "  " << 
convertToMb(*itWord) << endl;
+                                                    cout << "  " << 
convertToMb(wstr) << endl;
                                                 }
                                             }
-                                            break;
                                         }
+                                        break;
                                     case L'r':
                                         {
                                             vector<wstring> wordList;
                                             iGame.getDic().searchRacc(word, 
wordList);
-                                            vector<wstring>::const_iterator it;
-                                            for (it = wordList.begin(); it != 
wordList.end(); ++it)
-                                                cout << convertToMb(*it) << 
endl;
-                                            break;
-                                        }
-                                }
-                            }
+                                            BOOST_FOREACH(const wstring &wstr, 
wordList)
+                                                cout << convertToMb(wstr) << 
endl;
                         }
                         break;
-                    case L'd':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token == NULL)
-                            help_training();
-                        else
-                        {
-                            if (iGame.getDic().searchWord(token))
-                            {
-                                printf("le mot -%s- existe\n",
-                                       convertToMb(token).c_str());
                             }
-                            else
-                            {
-                                printf("le mot -%s- n'existe pas\n",
-                                       convertToMb(token).c_str());
-                            }
-                        }
-                        break;
-                    case L'j':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token == NULL)
-                            help_training();
-                        else
-                        {
-                            int res;
-                            wchar_t *coord = next_token_alphanum(NULL, delim, 
&state);
-                            if (coord == NULL)
-                            {
-                                help_training();
-                                break;
                             }
-                            if ((res = iGame.play(token, coord)) != 0)
-                            {
-                                fprintf(stdout, "Mot incorrect ou mal placé 
(%i)\n",
-                                        res);
-                                break;
                             }
                         }
                         break;
                     case L'n':
-                        token = next_token_digit(NULL, delim, &state);
-                        if (token == NULL)
-                            help_training();
+                    {
+                        const wstring &num = checkNumToken(tokens, 1);
+                        if (num == L"")
+                            helpTraining();
                         else
                         {
-                            int n = _wtoi(token);
+                            int n = _wtoi(num.c_str());
                             if (n <= 0)
                             {
                                 if (n == 0)
@@ -564,23 +639,35 @@
                                     printf("mauvais argument\n");
                             }
                         }
+                    }
                         break;
                     case L'r':
                         iGame.trainingSearch();
                         break;
                     case L't':
-                        token = next_token_alphaplusjoker(NULL, delim, &state);
-                        if (token == NULL)
-                            help_training();
+                    {
+                        const wstring &letters = 
checkAlphaPlusJokerToken(tokens, 1);
+                        if (letters == L"")
+                            helpTraining();
                         else
-                            iGame.trainingSetRackManual(0, token);
+                            iGame.trainingSetRackManual(false, letters);
+                    }
                         break;
                     case L'x':
-                        token = next_token_cross(NULL, delim, &state);
-                        if (token == NULL)
-                            help_training();
+                    {
+                        const wstring &cross = checkCrossToken(tokens, 1);
+                        if (cross == L"")
+                            helpTraining();
                         else
-                            eliottxt_get_cross(iGame.getDic(), token);
+                        {
+                            vector<wstring> wordList;
+                            iGame.getDic().searchCross(cross, wordList);
+                            BOOST_FOREACH(const wstring &wstr, wordList)
+                            {
+                                printf("  %s\n", convertToMb(wstr).c_str());
+                            }
+                        }
+                    }
                         break;
                     case L'*':
                         iGame.trainingSetRackRandom(false, 
PublicGame::kRACK_ALL);
@@ -588,29 +675,8 @@
                     case L'+':
                         iGame.trainingSetRackRandom(false, 
PublicGame::kRACK_NEW);
                         break;
-                    case L's':
-                        token = next_token_filename(NULL, delim, &state);
-                        if (token != NULL)
-                        {
-                            string filename = convertToMb(token);
-                            ofstream fout(filename.c_str());
-                            if (fout.rdstate() == ios::failbit)
-                            {
-                                printf("impossible d'ouvrir %s\n",
-                                       filename.c_str());
-                                break;
-                            }
-                            iGame.save(fout);
-                            fout.close();
-                        }
-                        break;
-                    case L'h':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token != NULL)
-                            handleNavigation(iGame, token[0]);
-                        break;
                     case L'q':
-                        quit = 1;
+                    quit = true;
                         break;
                     default:
                         printf("commande inconnue\n");
@@ -622,108 +688,67 @@
                 printf("%s\n", e.what());
             }
         }
-    }
     printf("fin du mode entraînement\n");
 }
 
 
-void loop_freegame(PublicGame &iGame)
+void loopFreegame(PublicGame &iGame)
 {
-    const wchar_t *token;
-    wchar_t *state;
-    wchar_t *commande = NULL;
-    wchar_t delim[] = L" \t";
-    int quit = 0;
-
     printf("mode partie libre\n");
     printf("[?] pour l'aide\n");
-    while (quit == 0)
+
+    bool quit = 0;
+    while (!quit)
+    {
+        wstring command = rl_gets();
+        // Split the command
+        vector<wstring> tokens;
+        boost::char_separator<wchar_t> sep(L" ");
+        Tokenizer tok(command, sep);
+        BOOST_FOREACH(const wstring &wstr, tok)
     {
-        commande = rl_gets();
-        token = _wcstok(commande, delim, &state);
-        if (token)
+            tokens.push_back(wstr);
+        }
+
+        if (tokens.empty())
+            continue;
+        if (tokens[0].size() > 1)
         {
+            printf("%s\n", "Invalid command");
+            continue;
+        }
+
             try
             {
-                switch (token[0])
+            switch (tokens[0][0])
                 {
                     case L'?':
-                        help_freegame();
+                    helpFreegame();
                         break;
                     case L'a':
-                        display_data(iGame, delim, &state);
-                        break;
                     case L'd':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token == NULL)
-                            help_freegame();
-                        else
-                        {
-                            if (iGame.getDic().searchWord(token))
-                            {
-                                printf("le mot -%s- existe\n",
-                                       convertToMb(token).c_str());
-                            }
-                            else
-                            {
-                                printf("le mot -%s- n'existe pas\n",
-                                       convertToMb(token).c_str());
-                            }
-                        }
-                        break;
+                case L'h':
                     case L'j':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token == NULL)
-                            help_freegame();
-                        else
-                        {
-                            int res;
-                            wchar_t *coord = next_token_alphanum(NULL, delim, 
&state);
-                            if (coord == NULL)
-                            {
-                                help_freegame();
-                                break;
-                            }
-                            if ((res = iGame.play(token, coord)) != 0)
-                            {
-                                fprintf(stdout, "Mot incorrect ou mal placé 
(%i)\n",
-                                        res);
-                                break;
-                            }
-                        }
+                case L's':
+                    commonCommands(iGame, tokens);
                         break;
                     case L'p':
-                        token = next_token_alpha(NULL, delim, &state);
-                        /* You can pass your turn without changing any letter 
*/
-                        if (token == NULL)
-                            token = L"";
-
-                        if (iGame.freeGamePass(token) != 0)
-                            break;
-                        break;
-                    case L's':
-                        token = next_token_filename(NULL, delim, &state);
-                        if (token != NULL)
                         {
-                            string filename = convertToMb(token);
-                            ofstream fout(filename.c_str());
-                            if (fout.rdstate() == ios::failbit)
+                        wstring letters = L"";
+                        /* You can pass your turn without changing any letter 
*/
+                        if (tokens.size() > 1)
                             {
-                                printf("impossible d'ouvrir %s\n",
-                                       filename.c_str());
-                                break;
-                            }
-                            iGame.save(fout);
-                            fout.close();
+                            letters = checkAlphaToken(tokens, 1);
+                            if (letters == L"")
+                                fprintf(stderr, "Invalid letters\n");
                         }
+                        // XXX
+                        if (iGame.freeGamePass(letters) != 0)
                         break;
-                    case L'h':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token != NULL)
-                            handleNavigation(iGame, token[0]);
+                    }
                         break;
                     case L'q':
-                        quit = 1;
+                    quit = true;
                         break;
                     default:
                         printf("commande inconnue\n");
@@ -735,116 +760,69 @@
                 printf("%s\n", e.what());
             }
         }
-    }
     printf("fin du mode partie libre\n");
 }
 
 
-void loop_duplicate(PublicGame &iGame)
+void loopDuplicate(PublicGame &iGame)
 {
-    const wchar_t *token;
-    wchar_t *state;
-    wchar_t *commande = NULL;
-    wchar_t delim[] = L" \t";
-    int quit = 0;
-
     printf("mode duplicate\n");
     printf("[?] pour l'aide\n");
-    while (quit == 0)
+
+    bool quit = false;
+    while (!quit)
     {
-        commande = rl_gets();
-        token = _wcstok(commande, delim, &state);
-        if (token)
+        wstring command = rl_gets();
+        // Split the command
+        vector<wstring> tokens;
+        boost::char_separator<wchar_t> sep(L" ");
+        Tokenizer tok(command, sep);
+        BOOST_FOREACH(const wstring &wstr, tok)
         {
+            tokens.push_back(wstr);
+        }
+
+        if (tokens.empty())
+            continue;
+        if (tokens[0].size() > 1)
+        {
+            printf("%s\n", "Invalid command");
+            continue;
+        }
+
             try
             {
-                switch (token[0])
+            switch (tokens[0][0])
                 {
                     case L'?':
-                        help_duplicate();
+                    helpDuplicate();
                         break;
                     case L'a':
-                        display_data(iGame, delim, &state);
-                        break;
                     case L'd':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token == NULL)
-                            help_duplicate();
-                        else
-                        {
-                            if (iGame.getDic().searchWord(token))
-                            {
-                                printf("le mot -%s- existe\n",
-                                       convertToMb(token).c_str());
-                            }
-                            else
-                            {
-                                printf("le mot -%s- n'existe pas\n",
-                                       convertToMb(token).c_str());
-                            }
-                        }
-                        break;
+                case L'h':
                     case L'j':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token == NULL)
-                            help_duplicate();
-                        else
-                        {
-                            int res;
-                            wchar_t *coord = next_token_alphanum(NULL, delim, 
&state);
-                            if (coord == NULL)
-                            {
-                                help_duplicate();
-                                break;
-                            }
-                            if ((res = iGame.play(token, coord)) != 0)
-                            {
-                                fprintf(stdout, "Mot incorrect ou mal placé 
(%i)\n",
-                                        res);
-                                break;
-                            }
-                        }
+                case L's':
+                    commonCommands(iGame, tokens);
                         break;
                     case L'n':
-                        token = next_token_digit(NULL, delim, &state);
-                        if (token == NULL)
-                            help_duplicate();
+                    {
+                        const wstring &id = checkNumToken(tokens, 1);
+                        if (id == L"")
+                            helpDuplicate();
                         else
                         {
-                            int n = _wtoi(token);
+                            int n = _wtoi(id.c_str());
                             if (n < 0 || n >= (int)iGame.getNbPlayers())
                             {
                                 fprintf(stderr, "Numéro de joueur invalide\n");
                                 break;
                             }
-                            int res = iGame.duplicateSetPlayer(_wtoi(token));
-                            if (res == 1)
-                                fprintf(stderr, "Impossible de choisir un 
joueur non humain\n");
+                            iGame.duplicateSetPlayer(n);
                         }
-                        break;
-                    case L's':
-                        token = next_token_filename(NULL, delim, &state);
-                        if (token != NULL)
-                        {
-                            string filename = convertToMb(token);
-                            ofstream fout(filename.c_str());
-                            if (fout.rdstate() == ios::failbit)
-                            {
-                                printf("impossible d'ouvrir %s\n",
-                                       filename.c_str());
-                                break;
                             }
-                            iGame.save(fout);
-                            fout.close();
-                        }
-                        break;
-                    case L'h':
-                        token = next_token_alpha(NULL, delim, &state);
-                        if (token != NULL)
-                            handleNavigation(iGame, token[0]);
                         break;
                     case L'q':
-                        quit = 1;
+                    quit = true;
                         break;
                     default:
                         printf("commande inconnue\n");
@@ -856,134 +834,48 @@
                 printf("%s\n", e.what());
             }
         }
-    }
     printf("fin du mode duplicate\n");
 }
 
 
-void eliot_regexp(const Dictionary& iDic,
-                  const wchar_t *delim, wchar_t **state)
+void mainLoop(const Dictionary &iDic)
 {
-    /*
-    printf("  x [] {1} {2} {3} : expressions rationnelles\n");
-    printf("          [] expression à rechercher\n");
-    printf("          {1} nombre de résultats à afficher\n");
-    printf("          {2} longueur minimum d'un mot\n");
-    printf("          {3} longueur maximum d'un mot\n");
-    */
-
-    wchar_t *regexp = _wcstok(NULL, delim, state);
-    wchar_t *cnres = _wcstok(NULL, delim, state);
-    wchar_t *clmin = _wcstok(NULL, delim, state);
-    wchar_t *clmax = _wcstok(NULL, delim, state);
-
-    if (regexp == NULL)
-    {
-        return;
-    }
-    unsigned int nres = cnres ? _wtoi(cnres) : 50;
-    unsigned int lmin = clmin ? _wtoi(clmin) : 1;
-    unsigned int lmax = clmax ? _wtoi(clmax) : DIC_WORD_MAX - 1;
-
-    if (lmax > (DIC_WORD_MAX - 1) || lmin < 1 || lmin > lmax)
-    {
-        printf("bad length -%s,%s-\n", (const char*)clmin, (const char*)clmax);
-        return;
-    }
-
-    printf("search for %s (%d,%d,%d)\n", convertToMb(regexp).c_str(),
-           nres, lmin, lmax);
+    printf("[?] pour l'aide\n");
 
-    vector<wstring> wordList;
-    try
+    bool quit = false;
+    while (!quit)
     {
-        iDic.searchRegExp(regexp, wordList, lmin, lmax, nres);
-    }
-    catch (InvalidRegexpException &e)
+        wstring command = rl_gets();
+        // Split the command
+        vector<wstring> tokens;
+        boost::char_separator<wchar_t> sep(L" ");
+        Tokenizer tok(command, sep);
+        BOOST_FOREACH(const wstring &wstr, tok)
     {
-        printf("Invalid regular expression: %s\n", e.what());
-        return;
+            tokens.push_back(wstr);
     }
 
-    vector<wstring>::const_iterator it;
-    for (it = wordList.begin(); it != wordList.end(); it++)
-    {
-        printf("%s\n", convertToMb(*it).c_str());
-    }
-    printf("%d printed results\n", wordList.size());
-}
-
-
-void set_setting(const wchar_t *delim, wchar_t **state)
-{
-    wchar_t *type = next_token_alpha(NULL, delim, state);
-    if (type == NULL || (*type != L'b' && *type != L'i'))
-    {
-        printf("Invalid type\n");
-        return;
-    }
-    wchar_t *settingWide = _wcstok(NULL, delim, state);
-    if (settingWide == NULL)
-    {
-        printf("Invalid setting name\n");
-        return;
-    }
-    wchar_t *value = _wcstok(NULL, delim, state);
-    if (value == NULL)
+        if (tokens.empty())
+            continue;
+        if (tokens[0].size() > 1)
     {
-        printf("Invalid value\n");
-        return;
+            printf("%s\n", "Invalid command");
+            continue;
     }
 
     try
     {
-        string setting = convertToMb(settingWide);
-        if (*type == L'i')
-        {
-            Settings::Instance().setInt(setting, _wtoi(value));
-        }
-        else if (*type == L'b')
-        {
-            Settings::Instance().setBool(setting, _wtoi(value));
-        }
-    }
-    catch (GameException &e)
-    {
-        string msg = "Error while changing a setting: " + string(e.what()) + 
"\n";
-        printf("%s", msg.c_str());
-        return;
-    }
-
-}
-
-
-void main_loop(const Dictionary &iDic)
-{
-    const wchar_t *token;
-    wchar_t *state;
-    wchar_t *commande = NULL;
-    wchar_t delim[] = L" \t";
-    int quit = 0;
-
-    printf("[?] pour l'aide\n");
-    while (quit == 0)
-    {
-        commande = rl_gets();
-        token = _wcstok(commande, delim, &state);
-        if (token)
-        {
-            switch (token[0])
+            switch (tokens[0][0])
             {
                 case L'?':
                     help();
                     break;
                 case L'c':
-                    token = next_token_filename(NULL, delim, &state);
-                    if (token == NULL)
-                    {}
-                    else
                     {
-                        string filename = convertToMb(token);
+                        const wstring &wfileName = checkFileNameToken(tokens, 
1);
+                        if (wfileName != L"")
+                        {
+                            string filename = convertToMb(wfileName);
                         Game *tmpGame = 
GameFactory::Instance()->load(filename, iDic);
                         if (tmpGame == NULL)
                         {
@@ -995,19 +887,20 @@
                             switch (game->getMode())
                                 {
                                 case PublicGame::kTRAINING:
-                                    loop_training(*game);
+                                        loopTraining(*game);
                                     break;
                                 case PublicGame::kFREEGAME:
-                                    loop_freegame(*game);
+                                        loopFreegame(*game);
                                     break;
                                 case PublicGame::kDUPLICATE:
-                                    loop_duplicate(*game);
+                                        loopDuplicate(*game);
                                     break;
                                 }
                             //GameFactory::Instance()->releaseGame(*game);
                             delete game;
                         }
                     }
+                    }
                     break;
                 case L'e':
                 {
@@ -1015,67 +908,65 @@
                     Training *tmpGame = 
GameFactory::Instance()->createTraining(iDic);
                     PublicGame *game = new PublicGame(*tmpGame);
                     game->start();
-                    loop_training(*game);
+                        loopTraining(*game);
                     //GameFactory::Instance()->releaseGame(*game);
                     delete game;
-                    break;
                 }
+                    break;
                 case L'd':
                 {
-                    int i;
-                    // New duplicate game
-                    token = next_token_digit(NULL, delim, &state);
-                    if (token == NULL)
+                        if (tokens.size() != 3)
                     {
                         help();
                         break;
                     }
-                    Duplicate *tmpGame = 
GameFactory::Instance()->createDuplicate(iDic);
-                    PublicGame *game = new PublicGame(*tmpGame);
-                    for (i = 0; i < _wtoi(token); i++)
-                        game->addPlayer(new HumanPlayer);
-                    token = next_token_digit(NULL, delim, &state);
-                    if (token == NULL)
+                        const wstring &nbHuman = checkNumToken(tokens, 1);
+                        const wstring &nbAI = checkNumToken(tokens, 2);
+                        if (nbHuman == L"" || nbAI == L"")
                     {
                         help();
                         break;
                     }
-                    for (i = 0; i < _wtoi(token); i++)
+                        // New duplicate game
+                        Duplicate *tmpGame = 
GameFactory::Instance()->createDuplicate(iDic);
+                        PublicGame *game = new PublicGame(*tmpGame);
+                        for (int i = 0; i < _wtoi(nbHuman.c_str()); ++i)
+                            game->addPlayer(new HumanPlayer);
+                        for (int i = 0; i < _wtoi(nbAI.c_str()); ++i)
                         game->addPlayer(new AIPercent(1));
                     game->start();
-                    loop_duplicate(*game);
+                        loopDuplicate(*game);
                     //GameFactory::Instance()->releaseGame(*game);
                     delete game;
-                    break;
                 }
+                    break;
                 case L'l':
                 {
-                    int i;
-                    // New free game
-                    token = next_token_digit(NULL, delim, &state);
-                    if (token == NULL)
+                        if (tokens.size() != 3)
                     {
                         help();
                         break;
                     }
-                    FreeGame *tmpGame = 
GameFactory::Instance()->createFreeGame(iDic);
-                    PublicGame *game = new PublicGame(*tmpGame);
-                    for (i = 0; i < _wtoi(token); i++)
-                        game->addPlayer(new HumanPlayer);
-                    token = next_token_digit(NULL, delim, &state);
-                    if (token == NULL)
+                        const wstring &nbHuman = checkNumToken(tokens, 1);
+                        const wstring &nbAI = checkNumToken(tokens, 2);
+                        if (nbHuman == L"" || nbAI == L"")
                     {
                         help();
                         break;
                     }
-                    for (i = 0; i < _wtoi(token); i++)
+                        // New free game
+                        FreeGame *tmpGame = 
GameFactory::Instance()->createFreeGame(iDic);
+                        PublicGame *game = new PublicGame(*tmpGame);
+                        for (int i = 0; i < _wtoi(nbHuman.c_str()); i++)
+                            game->addPlayer(new HumanPlayer);
+                        for (int i = 0; i < _wtoi(nbAI.c_str()); i++)
                         game->addPlayer(new AIPercent(1));
                     game->start();
-                    loop_freegame(*game);
+                        loopFreegame(*game);
                     //GameFactory::Instance()->releaseGame(*game);
                     delete game;
-                    break;
                 }
+                    break;
                 case L'D':
                 {
                     // New duplicate game
@@ -1084,7 +975,7 @@
                     game->addPlayer(new HumanPlayer);
                     game->addPlayer(new AIPercent(1));
                     game->start();
-                    loop_duplicate(*game);
+                        loopDuplicate(*game);
                     //GameFactory::Instance()->releaseGame(*game);
                     delete game;
                     break;
@@ -1097,17 +988,17 @@
                     game->addPlayer(new HumanPlayer);
                     game->addPlayer(new AIPercent(1));
                     game->start();
-                    loop_freegame(*game);
+                        loopFreegame(*game);
                     //GameFactory::Instance()->releaseGame(*game);
                     delete game;
                     break;
                 }
                 case L'x':
                     // Regular expression tests
-                    eliot_regexp(iDic, delim, &state);
+                    handleRegexp(iDic, tokens);
                     break;
                 case L's':
-                    set_setting(delim, &state);
+                    setSetting(tokens);
                     break;
                 case L'q':
                     quit = 1;
@@ -1117,6 +1008,10 @@
                     break;
             }
         }
+        catch (GameException &e)
+        {
+            printf("%s\n", e.what());
+        }
     }
 }
 
@@ -1150,7 +1045,7 @@
         srand(seed);
         cerr << "Using seed: " << seed << endl;
 
-        main_loop(dic);
+        mainLoop(dic);
         GameFactory::Destroy();
 
         // Free the readline static variable




reply via email to

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