[Top][All Lists]
[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:
- [Eliot-dev] Changes to eliot/game/game_io.cpp [antoine-1],
eliot-dev <=