/[eliot]/eliot/game/freegame.cpp
ViewVC logotype

Diff of /eliot/game/freegame.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by ipkiss, Sun Oct 23 14:53:43 2005 UTC revision 1.12.2.1 by afrab, Sun Oct 23 17:16:24 2005 UTC
# Line 33  Line 33 
33  #include "debug.h"  #include "debug.h"
34    
35    
36  FreeGame::FreeGame(const Dictionary &iDic): Game(iDic)  FreeGame::FreeGame(const Dictionary iDic): Game(iDic)
37  {  {
38  }  }
39    
   
40  FreeGame::~FreeGame()  FreeGame::~FreeGame()
41  {  {
42  }  }
43    
44    int FreeGame::play(int player, Round& round)
 int FreeGame::setRackRandom(int p, bool iCheck, set_rack_mode mode)  
45  {  {
46      int res;    return 0;
     do  
     {  
         res = helperSetRackRandom(p, iCheck, mode);  
     } while (res == 2);  
     return res;  
47  }  }
48    
49    int FreeGame::back()
 int FreeGame::play(const string &iCoord, const string &iWord)  
 {  
     /* Perform all the validity checks, and fill a round */  
     Round round;  
   
     int res = checkPlayedWord(iCoord, iWord, round);  
     if (res != 0)  
     {  
         return res;  
     }  
   
     /* Update the rack and the score of the current player */  
     m_players[m_currPlayer]->addPoints(round.getPoints());  
     m_players[m_currPlayer]->endTurn(round, getNRounds());  
   
     /* Everything is OK, we can play the word */  
     helperPlayRound(round);  
   
     /* Next turn */  
     // XXX: Should it be done by the interface instead?  
     endTurn();  
   
     return 0;  
 }  
   
   
 void FreeGame::freegameAI(int n)  
 {  
     ASSERT(0 <= n && n < getNPlayers(), "Wrong player number");  
     ASSERT(!m_players[n]->isHuman(), "AI requested for a human player");  
   
     AIPlayer *player = static_cast<AIPlayer*>(m_players[n]);  
   
     player->compute(*m_dic, m_board, getNRounds());  
     if (player->changesLetters())  
     {  
         helperPass(player->getChangedLetters(), n);  
         endTurn();  
     }  
     else  
     {  
         const Round &round = player->getChosenRound();  
         /* Update the rack and the score of the current player */  
         player->addPoints(round.getPoints());  
         player->endTurn(round, getNRounds());  
   
         helperPlayRound(round);  
         endTurn();  
     }  
 }  
   
   
 int FreeGame::start()  
 {  
     ASSERT(getNPlayers(), "Cannot start a game without any player");  
   
     /* Set the initial racks of the players */  
     for (int i = 0; i < getNPlayers(); i++)  
     {  
         setRackRandom(i, false, RACK_NEW);  
     }  
   
     // XXX  
     m_currPlayer = 0;  
   
     /* If the first player is an AI, make it play now */  
     if (!m_players[0]->isHuman())  
     {  
         freegameAI(0);  
     }  
   
     return 0;  
 }  
   
   
 int FreeGame::endTurn()  
50  {  {
51      /* Complete the rack for the player that just played */    return 0;
     if (setRackRandom(m_currPlayer, false, RACK_NEW) == 1)  
     {  
         /* End of the game */  
         end();  
         return 1;  
     }  
   
     /* Next player */  
     nextPlayer();  
   
     /* If this player is an AI, make it play now */  
     if (!m_players[m_currPlayer]->isHuman())  
     {  
         freegameAI(m_currPlayer);  
     }  
   
     return 0;  
 }  
   
   
 // Adjust the scores of the players with the points of the remaining tiles  
 void FreeGame::end()  
 {  
     vector<Tile> tiles;  
   
     // TODO: According to te rules of the game in the ODS, a game can end in 3  
     // cases:  
     // 1) no more letter in the bag, and one player has no letter in his rack  
     // 2) the game is "blocked", no one can play  
     // 3) the players have used all the time they had (for example: 30 min  
     //    in total, for each player)  
     // We currently handle case 1, and cannot handle case 3 until timers are  
     // implemented.  
     // For case 2, we need both to detect a blocked situation (not easy...) and  
     // to handle it in the end() method (very easy).  
   
     /* Add the points of the remaining tiles to the score of the current  
      * player (i.e. the first player with an empty rack), and remove them  
      * from the score of the players who still have tiles */  
     for (int i = 0; i < getNPlayers(); i++)  
     {  
         if (i != m_currPlayer)  
         {  
             const PlayedRack &pld = m_players[i]->getCurrentRack();  
             pld.getAllTiles(tiles);  
             for (unsigned int j = 0; j < tiles.size(); j++)  
             {  
                 m_players[i]->addPoints(- tiles[j].getPoints());  
                 m_players[m_currPlayer]->addPoints(tiles[j].getPoints());  
             }  
         }  
     }  
   
     /* Lock game */  
     m_finished = true;  
 }  
   
   
 int FreeGame::pass(const string &iToChange, int n)  
 {  
     if (m_finished)  
         return 3;  
   
     // According to the rules in the ODS, it is allowed to pass its turn (no  
     // need to change letters for that).  
     // TODO: However, if all the players pass their turn, the first one has to  
     // play, or change at least one letter. To implement this behaviour, we  
     // must also take care of blocked positions, where no one _can_ play (see  
     // also comment in the end() method).  
   
     // Convert the string into tiles  
     vector<Tile> tilesVect;  
     for (unsigned int i = 0; i < iToChange.size(); i++)  
     {  
         Tile tile(toupper(iToChange[i]));  
         tilesVect.push_back(tile);  
     }  
   
     int res = helperPass(tilesVect, n);  
     if (res == 0)  
         endTurn();  
     return res;  
 }  
   
   
 int FreeGame::helperPass(const vector<Tile> &iToChange, int n)  
 {  
     ASSERT(0 <= n && n < getNPlayers(), "Wrong player number");  
   
     // It is forbidden to change letters when the bag does not contain at  
     // least 7 letters (this is explicitely stated in the ODS).  
     Bag bag;  
     realBag(bag);  
     if (bag.nTiles() < 7)  
     {  
         return 1;  
     }  
   
     Player *player = m_players[n];  
     PlayedRack pld = player->getCurrentRack();  
     Rack rack;  
     pld.getRack(rack);  
   
     for (unsigned int i = 0; i < iToChange.size(); i++)  
     {  
         /* Remove the letter from the rack */  
         if (!rack.in(iToChange[i]))  
         {  
             return 2;  
         }  
         rack.remove(iToChange[i]);  
     }  
   
     pld.reset();  
     pld.setOld(rack);  
   
     player->setCurrentRack(pld);  
   
     // FIXME: the letters to change should not be in the bag while generating  
     // the new rack!  
   
     return 0;  
52  }  }
53    

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.12.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26