eliot-dev
[Top][All Lists]
Advanced

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

[Eliot-dev] Changes to eliot/game/game_io.cpp [antoine-1]


From: eliot-dev
Subject: [Eliot-dev] Changes to eliot/game/game_io.cpp [antoine-1]
Date: Sun, 23 Oct 2005 14:38:23 -0400

Index: eliot/game/game_io.cpp
diff -u /dev/null eliot/game/game_io.cpp:1.1.2.1
--- /dev/null   Sun Oct 23 18:38:23 2005
+++ eliot/game/game_io.cpp      Sun Oct 23 18:38:18 2005
@@ -0,0 +1,465 @@
+/*****************************************************************************
+ * Copyright (C) 1999-2005 Eliot
+ * Authors: Antoine Fraboulet <address@hidden>
+ *          Olivier Teuliere  <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *****************************************************************************/
+
+/* $Id: game_io.cpp,v 1.1.2.1 2005/10/23 18:38:18 afrab Exp $ */
+
+/**
+ *  \file   game_io.cpp
+ *  \brief  Eliot game class file load/save handling
+ *  \author Antoine Fraboulet & Olivier Teuliere
+ *  \date   2002 - 2005
+ */
+
+#include "pldrack.h"
+#include "round.h"
+#include "turn.h"
+#include "player.h"
+#include "game.h"
+#include "game_factory.h"
+
+/*************************
+ * Ident string used to identify saved Eliot games
+ *************************/
+#define IDENT_STRING "Eliot"
+#define IDENT_FORMAT_14 ""
+#define IDENT_FORMAT_15 "1.5"
+
+
+/********************************************************
+ *
+ * Loading games
+ *
+ ********************************************************/
+
+Game * Game::load(FILE *fin, const Dictionary iDic)
+{
+    char buff[4096];
+    char delim[] = " \t\n|";
+    char *token;
+
+    // Check characteristic string
+    if (fgets(buff, sizeof(buff), fin) == NULL)
+        return NULL;
+    if ((token = strtok(buff, delim)) == NULL)
+        return NULL;
+
+    /* checks for IDENT_STRING and file format */
+    if (std::string(token) != IDENT_STRING)
+        return NULL;
+
+    if ((token = strtok(NULL, delim)) == NULL)
+      {
+       //std::cerr << "loading file format 1.4\n";
+       return Game::gameLoadFormat_14(fin,iDic);
+      }
+
+    if (std::string(token) == std::string(IDENT_FORMAT_15))
+      {
+       //std::cerr << "loading file format 1.5\n";
+       return Game::gameLoadFormat_15(fin,iDic);
+      }
+
+    return NULL;
+}
+
+
+Game* Game::gameLoadFormat_14(FILE *fin, const Dictionary iDic)
+{
+     Tile tile;
+     char buff[4096];
+     char rack[20];
+     char word[20];
+     char pos [5];
+     char delim[]=" \t\n";
+     char *token;
+     Game *pGame = NULL;
+
+     pGame = GameFactory::Instance()->createTraining(iDic);
+     pGame->start();
+
+     while(fgets(buff,sizeof(buff),fin))
+       {
+         token = strtok(buff,delim);
+         if (token != NULL)
+           {
+             if (strcmp(token,"total")==0)
+               {
+                 break;
+              } 
+
+             /* rack */
+            strncpy(rack,token,sizeof(rack));
+            
((Training*)pGame)->setRack(PlayedRack::RACK_MANUAL,false,std::string(rack));
+
+             /* word */
+            token = strtok(NULL,delim);
+            if (!token || strcmp(token,"total")==0)
+              {
+                //std::cerr << "break2" << endl;
+                break;
+              }
+
+            strncpy(word,token,sizeof(word));
+            //std::cerr << "\t" << word << " ";
+            /* bonus */
+            if ((token = strtok(NULL,delim)) == NULL)
+              break;
+            /* points */
+            if (token[0]=='*')  
+              {
+                //std::cerr << token << " \t";
+                if ((token = strtok(NULL,delim)) == NULL)
+                  break;
+              }
+
+            /* pos 1 */
+            if ((token = strtok(NULL,delim)) == NULL)
+              break;
+            //std::cerr << "(" << token << " ";
+            strncpy(pos,token,sizeof(pos));
+
+            /* pos 2 */
+            if ((token = strtok(NULL,delim)) == NULL)
+               break;
+            //std::cerr << token << ")";
+            strncat(pos,token,sizeof(pos));
+            //std::cerr << pos << endl;
+
+            pGame->play(0,std::string(pos),std::string(word));
+         }
+       }
+     return pGame;
+}
+
+
+Game* Game::gameLoadFormat_15(FILE *fin, const Dictionary iDic)
+{
+    Game *pGame = NULL;
+#if 0
+    char buff[4096];
+    int num;
+    char rack[20];
+    char word[20];
+    char ref[4];
+    int pts;
+    int player;
+    char *pos;
+    Tile tile;
+
+    while (fgets(buff, sizeof(buff), fin))
+    {
+        // Indication of game type
+        pos = strstr(buff, "Game type: ");
+        if (pos != NULL)
+        {
+            // No Game object should have been created yet
+            if (pGame != NULL)
+            {
+                delete pGame;
+                return NULL;
+            }
+            // Create the correct Game object
+            if (strstr(buff, "Training"))
+                pGame = GameFactory::Instance()->createTraining(iDic);
+            else if (strstr(buff, "Free game"))
+                pGame = GameFactory::Instance()->createFreeGame(iDic);
+            else if (strstr(buff, "Duplicate"))
+                pGame = GameFactory::Instance()->createDuplicate(iDic);
+            else
+                return NULL;
+            // Read next line
+            continue;
+        }
+
+        // Players type
+        pos = strstr(buff, "Player ");
+        if (pos != NULL && pGame != NULL)
+        {
+            int nb = 0;
+            char type[20];
+            if (sscanf(pos, "Player %d: %19s", &nb, type) > 1)
+            {
+             if (pGame->getMode() != kTRAINING)
+               {
+                 if (std::string(type) == "Human")
+                    pGame->addHumanPlayer();
+                 else if (std::string(type) == "Computer")
+                    pGame->addAIPlayer();
+                 else
+                    ;
+               }
+            }
+            // Read next line
+            continue;
+        }
+
+        // Last racks
+        pos = strstr(buff, "Rack ");
+        if (pos != NULL && pGame != NULL)
+        {
+            int nb = 0;
+            char letters[20];
+            if (sscanf(pos, "Rack %d: %19s", &nb, letters) > 1)
+            {
+                // Create the played rack
+                PlayedRack pldrack;
+                char *r = letters;
+                if (strchr(r, '+'))
+                {
+                    while (*r != '+')
+                    {
+                        pldrack.addOld(Tile(*r));
+                        r++;
+                    }
+                    r++;
+                }
+                while (*r)
+                {
+                    pldrack.addNew(Tile(*r));
+                    r++;
+                }
+
+                // Give the rack to the player
+                pGame->m_players[nb]->setCurrentRack(pldrack);
+            }
+            // Read next line
+            continue;
+        }
+
+        // Skip columns title
+        if (strstr(buff, "==") != NULL ||
+            strstr(buff, "| PTS | P |") != NULL)
+        {
+            continue;
+        }
+
+        if (std::string(buff) != "\n" && pGame != NULL)
+        {
+            char bonus = 0;
+            int res = sscanf(buff, "   %2d | %8s | %s | %3s | %3d | %1d | %c",
+                             &num, rack, word, ref, &pts, &player, &bonus);
+            if (res < 6)
+                continue;
+
+            // Integrity checks
+            // TODO: add more checks
+            if (pts < 0)
+                continue;
+            if (player < 0 || player > pGame->getNPlayers())
+                continue;
+            if (bonus && bonus != '*')
+                continue;
+
+            // Build a rack for the correct player
+            PlayedRack pldrack;
+            char *r = rack;
+            if (strchr(r, '+'))
+            {
+                while (*r != '+')
+                {
+                    pldrack.addOld(Tile(*r));
+                    r++;
+                }
+                r++;
+            }
+
+            while (*r)
+            {
+                pldrack.addNew(Tile(*r));
+                r++;
+            }
+
+            // Build a round
+            Round round;
+            round.setPoints(pts);
+            if (bonus == '*')
+                round.setBonus(1);
+
+            if (isalpha(ref[0]))
+            {
+                // Horizontal word
+                round.setDir(HORIZONTAL);
+                round.setRow(ref[0] - 'A' + 1);
+                round.setCol(atoi(ref + 1));
+
+                for (unsigned int i = 0; i < strlen(word); i++)
+                {
+                    tile = Tile(word[i]);
+
+                    if (!pGame->m_board.getTile(round.getRow(), round.getCol() 
+ i).isEmpty())
+                    {
+                        round.addRightFromBoard(tile);
+                    }
+                    else
+                    {
+                        round.addRightFromRack(tile, islower(word[i]));
+                        pGame->m_bag.takeTile((islower(word[i])) ? 
Tile::Joker() : tile);
+                    }
+                }
+            }
+            else
+            {
+                // Vertical word
+                round.setDir(VERTICAL);
+                round.setRow(ref[strlen(ref) - 1] - 'A' + 1);
+                round.setCol(atoi(ref));
+
+                for (unsigned int i = 0; i < strlen(word); i++)
+                {
+                    tile = Tile(word[i]);
+
+                    if (!pGame->m_board.getTile(round.getRow() + i, 
round.getCol()).isEmpty())
+                    {
+                        round.addRightFromBoard(tile);
+                    }
+                    else
+                    {
+                        round.addRightFromRack(tile, islower(word[i]));
+                        pGame->m_bag.takeTile((islower(word[i])) ? 
Tile::Joker() : tile);
+                    }
+                }
+            }
+
+            pGame->m_currPlayer = player;
+            // Update the rack for the player
+            pGame->m_players[player]->setCurrentRack(pldrack);
+            // End the turn for the current player (this creates a new rack)
+            pGame->m_players[player]->playRound(num - 1, round);
+            // Play the round
+            pGame->helperPlayRound(round);
+        }
+    }
+
+    // Finalize the game
+    if (pGame)
+    {
+        // We don't really know whose turn it is, but at least we know that
+        // the game was saved while a human was to play.
+        for (int i = 0; i < pGame->getNPlayers(); i++)
+        {
+            if (pGame->m_players[i]->isHuman())
+            {
+                pGame->m_currPlayer = i;
+                break;
+            }
+        }
+    }
+#endif
+    return pGame;
+}
+
+/********************************************************
+ *
+ * Loading games
+ *
+ ********************************************************/
+
+void Game::save(std::ostream &out) const
+{
+    if (getNPlayers() == 1)
+       {
+           gameSaveFormat_14(out);
+       }
+    else
+       {
+           gameSaveFormat_15(out);
+       }
+}
+
+
+void Game::gameSaveFormat_14(std::ostream &out) const
+{
+    int i;
+    char buff[100];
+    const char decal[]="  ";
+    out << IDENT_STRING << std::endl << std::endl;
+    for(i = 0; i < m_history.getSize(); i++) 
+       {
+           Turn t = m_history.getTurn(i);
+           out << decal << t.toString() << std::endl;
+       }
+    out << std::endl;
+    out << decal << "total" << std::string(24,' ');
+    sprintf(buff,"%4d", m_players[0]->getPoints());
+    out << buff << std::endl;
+}
+
+
+void Game::gameSaveFormat_15(std::ostream &out) const
+{
+#if 0
+    const std::string decal = "   ";
+    // "Header" of the game
+    out << IDENT_STRING << " " << IDENT_FORMAT_15 << std::endl << std::endl;
+    // Game type
+    out << "Game type: " << getModeAsString() << std::endl;
+    // Player list
+    for (int i = 0; i < getNPlayers(); i++)
+    {
+        out << "Player " << i << ": ";
+        if (m_players[i]->isHuman())
+            out << "Human" << std::endl;
+        else
+            out << "Computer" << std::endl;
+    }
+    out << std::endl;
+
+    // Title of the columns
+    char line[100];
+    out << decal << " N |   RACK   |    SOLUTION     | REF | PTS | P | BONUS" 
<< std::endl;
+    out << decal << "===|==========|=================|=====|=====|===|======" 
<< std::endl;
+
+    // Print the game itself
+    for (int i = 0; i < getNRounds(); i++)
+    {
+        std::string word = getPlayedWord(i);
+        std::string coord = getPlayedCoords(i);
+        sprintf(line, "%2d | %8s | %s%s | %3s | %3d | %1d | %c",
+                i + 1, 
+               getPlayedRack(i).c_str(),              /* pldrack     */
+               word.c_str(),                          /* word        */
+                std::string(15 - word.size(), ' ').c_str(), /* fill spaces */
+                coord.c_str(),                         /* coord       */
+               getPlayedPoints(i),
+                getPlayedPlayer(i), 
+               getPlayedBonus(i) ? '*' : ' ');
+
+        out << decal << line << std::endl;
+    }
+
+    // A game has no points in total (should it be the sum of all player's 
points)
+    //    out << std::endl << decal << "Total: " << m_points << std::endl;
+
+    // Print current rack for all the players
+    out << std::endl;
+    for (int i = 0; i < getNPlayers(); i++)
+    {
+        std::string rack = m_players[i]->getCurrentRack().toString();
+        out << "Rack " << i << ": " << rack << std::endl;
+    }
+#endif
+}
+
+
+
+/// Local Variables:
+/// mode: hs-minor
+/// c-basic-offset: 4
+/// End:




reply via email to

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