- The core is now able to handle "explosive games" ("parties détonantes"). No interface uses this ability yet.

- Fixed a bug in Game::helperSetRackRandom()
This commit is contained in:
Olivier Teulière 2009-01-14 21:53:37 +00:00
parent 229f1fcc14
commit 8b9478542a
5 changed files with 69 additions and 13 deletions

View file

@ -183,7 +183,7 @@ PlayedRack Game::helperSetRackRandom(const PlayedRack &iPld,
bool jokerAdded = false;
// Are we dealing with a normal game or a joker game?
if (m_variant == kJOKER)
if (m_variant == kJOKER || m_variant == kEXPLOSIVE)
{
// 1) Is there already a joker in the remaining letters of the rack?
bool jokerFound = false;
@ -205,7 +205,7 @@ PlayedRack Game::helperSetRackRandom(const PlayedRack &iPld,
}
// 3) Remove all the jokers from the bag, to avoid taking another one
for (unsigned int i = 0; i < bag.in(Tile::Joker()); ++i)
while (bag.in(Tile::Joker()))
{
bag.takeTile(Tile::Joker());
}
@ -323,6 +323,63 @@ PlayedRack Game::helperSetRackRandom(const PlayedRack &iPld,
}
}
// In explosive games, we have to perform a search, then replace the
// joker with the letter providing the best score
// A joker coming from a previous rack is not replaced
if (m_variant == kEXPLOSIVE && jokerAdded)
{
Rack rack;
pld.getRack(rack);
Results res;
res.search(getDic(), getBoard(), rack, getHistory().beforeFirstRound());
if (res.size())
{
PlayedRack pldCopy = pld;
// Get the best word
const Round & bestRound = res.get(0);
#ifdef DEBUG
cout << "helperSetRackRandom(): initial rack: "
<< convertToMb(pld.toString()) << " (best word: "
<< convertToMb(bestRound.getWord()) << ")" << endl;
#endif
// Identify the joker
for (unsigned int i = 0; i < bestRound.getWordLen(); ++i)
{
if (bestRound.isJoker(i) && bestRound.isPlayedFromRack(i))
{
const Tile &jokerTile = bestRound.getTile(i);
Tile replacingTile(towupper(jokerTile.toChar()));
#ifdef DEBUG
cout << "helperSetRackRandom(): replacing Joker with "
<< convertToMb(replacingTile.toChar()) << endl;
#endif
// If the bag does not contain this letter anymore,
// simply keep the joker in the rack.
if (bag.in(replacingTile))
{
// The bag contains the replacing letter
// We need to swap the joker (it is necessarily in the
// new tiles, because jokerAdded is true)
Rack tmpRack;
pld.getNew(tmpRack);
ASSERT(tmpRack.in(Tile::Joker()),
"No joker found in the new tiles!");
tmpRack.remove(Tile::Joker());
tmpRack.add(replacingTile);
pld.setNew(tmpRack);
// Make sure the invariant is still correct, otherwise we keep the joker
if (!pld.checkRack(min, min))
pld = pldCopy;
}
break;
}
}
}
}
// 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)
@ -331,12 +388,6 @@ PlayedRack Game::helperSetRackRandom(const PlayedRack &iPld,
// Post-condition check. This should never fail, of course :)
ASSERT(pld.checkRack(min, min), "helperSetRackRandom() is buggy!");
#if 0
// Until now we didn't modify anything except local variables.
// Let's "commit" the changes
m_players[p]->setCurrentRack(pld);
#endif
return pld;
}

View file

@ -75,7 +75,8 @@ public:
enum GameVariant
{
kNONE, // Normal game rules
kJOKER // Joker game
kJOKER, // Joker game
kEXPLOSIVE // "Explosive" game
};
/**

View file

@ -59,6 +59,8 @@ void PublicGame::setVariant(GameVariant iVariant)
{
if (iVariant == kJOKER)
m_game.setVariant(Game::kJOKER);
else if (iVariant == kEXPLOSIVE)
m_game.setVariant(Game::kEXPLOSIVE);
else
m_game.setVariant(Game::kNONE);
}

View file

@ -84,7 +84,8 @@ public:
enum GameVariant
{
kNONE, // Normal game rules
kJOKER // Joker game
kJOKER, // Joker game
kEXPLOSIVE // "Explosive" game
};
/**

View file

@ -35,8 +35,9 @@ class Rack;
/**
* This class allows to perform a search on the board for a given rack,
* and it offers accessors to the resulting rounds.
* The rounds are sorted by decreasing number of points (but there is no
* other ordering between 2 rounds with the same number of points).
* The rounds are sorted by decreasing number of points, then by alphabetical
* order (case insensitive), then by coordinates, then by alphabetical orderi
* again (case sensitive this time).
*/
class Results
{