summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game.cpp7
-rw-r--r--move.cpp19
-rw-r--r--move.h4
-rw-r--r--quacker/boarddisplay.cpp2
-rw-r--r--quacker/graphicalreporter.cpp1
-rw-r--r--quacker/quacker.cpp4
-rw-r--r--quackleio/gcgio.cpp15
-rw-r--r--quackleio/util.cpp4
-rw-r--r--reporter.cpp1
9 files changed, 44 insertions, 13 deletions
diff --git a/game.cpp b/game.cpp
index 845e864..242556c 100644
--- a/game.cpp
+++ b/game.cpp
@@ -357,6 +357,11 @@ int GamePosition::validateMove(const Move &move) const
}
break;
+ case Move::BlindExchange:
+ if (!exchangeAllowed())
+ ret |= TooLateExchange;
+ break;
+
case Move::UnusedTilesBonus:
case Move::TimePenalty:
ret = InvalidAction;
@@ -783,7 +788,7 @@ bool GamePosition::incrementTurn()
}
}
- if ((m_moveMade.action == Move::Place && m_moveMade.effectiveScore() == 0) || m_moveMade.action == Move::Exchange || m_moveMade.action == Move::Pass)
+ if ((m_moveMade.action == Move::Place && m_moveMade.effectiveScore() == 0) || m_moveMade.action == Move::Exchange || m_moveMade.action == Move::BlindExchange || m_moveMade.action == Move::Pass)
++m_scorelessTurnsInARow;
else
m_scorelessTurnsInARow = 0;
diff --git a/move.cpp b/move.cpp
index eaaf8b6..7f77dc5 100644
--- a/move.cpp
+++ b/move.cpp
@@ -48,6 +48,10 @@ bool operator==(const Move &move1, const Move &move2)
ret = (Quackle::String::alphabetize(move1.tiles()) == Quackle::String::alphabetize(move2.tiles()));
break;
+ case Quackle::Move::BlindExchange:
+ ret = (move1.tiles().length() == move2.tiles().length());
+ break;
+
case Quackle::Move::Pass:
case Quackle::Move::Nonmove:
case Quackle::Move::TimePenalty:
@@ -124,6 +128,7 @@ UVString Move::xml() const
break;
case Exchange:
+ case BlindExchange:
actionString = MARK_UV("exchange");
includeTiles = true;
break;
@@ -180,10 +185,12 @@ UVString Move::toString() const
{
UVOStringStream ss;
- if (action == Quackle::Move::Pass)
- ss << "- ";
- else if (action == Quackle::Move::Exchange)
- ss << "-" << QUACKLE_ALPHABET_PARAMETERS->userVisible(m_tiles);
+ if (action == Quackle::Move::Pass)
+ ss << "- ";
+ else if (action == Quackle::Move::Exchange)
+ ss << "-" << QUACKLE_ALPHABET_PARAMETERS->userVisible(m_tiles);
+ else if (action == Quackle::Move::BlindExchange)
+ ss << "-" << m_tiles.length();
else if (action == Quackle::Move::Nonmove)
ss << "nonmove";
else if (action == Quackle::Move::TimePenalty)
@@ -290,11 +297,11 @@ Move Move::createChallengedPhoney(int zeroIndexedRow, int zeroIndexedColumn, boo
return move;
}
-Move Move::createExchangeMove(LetterString tilesToExchange)
+Move Move::createExchangeMove(LetterString tilesToExchange, bool isBlind)
{
Move move;
- move.action = Move::Exchange;
+ move.action = isBlind ? Move::BlindExchange : Move::Exchange;
move.setTiles(tilesToExchange);
move.score = 0;
diff --git a/move.h b/move.h
index f4d1827..e628b52 100644
--- a/move.h
+++ b/move.h
@@ -43,7 +43,7 @@ namespace Quackle
class Move
{
public:
- enum Action { Place = 0, Exchange, Pass, UnusedTilesBonus, TimePenalty, Nonmove };
+ enum Action { Place = 0, Exchange, BlindExchange, Pass, UnusedTilesBonus, TimePenalty, Nonmove };
// creates a pass move with 0 equity;
// tiles is "", score and equity are zero
@@ -124,7 +124,7 @@ public:
static Move createChallengedPhoney(UVString placeString, LetterString word);
static Move createChallengedPhoney(int zeroIndexedRow, int zeroIndexedColumn, bool horizontal, LetterString word);
- static Move createExchangeMove(LetterString tilesToExchange);
+ static Move createExchangeMove(LetterString tilesToExchange, bool isBlind);
static Move createUnusedTilesBonus(LetterString unusedTiles, int bonus);
static Move createTimePenalty(int penalty);
static Move createPassMove();
diff --git a/quacker/boarddisplay.cpp b/quacker/boarddisplay.cpp
index 2f570c6..85b551b 100644
--- a/quacker/boarddisplay.cpp
+++ b/quacker/boarddisplay.cpp
@@ -178,7 +178,7 @@ void BoardWithQuickEntry::processCommand(const QString &command)
if (isPass)
move = Quackle::Move::createPassMove();
else
- move = Quackle::Move::createExchangeMove(encodedLetters);
+ move = Quackle::Move::createExchangeMove(encodedLetters, isIntConvertable);
}
else
{
diff --git a/quacker/graphicalreporter.cpp b/quacker/graphicalreporter.cpp
index 2fb0842..a7ca9f5 100644
--- a/quacker/graphicalreporter.cpp
+++ b/quacker/graphicalreporter.cpp
@@ -192,6 +192,7 @@ void GraphicalReporter::reportPosition(const Quackle::GamePosition &position, Qu
}
case Quackle::Move::Exchange:
+ case Quackle::Move::BlindExchange:
default:
item = QuackleIO::Util::moveToDetailedString(*it);
break;
diff --git a/quacker/quacker.cpp b/quacker/quacker.cpp
index be70c14..ffe6531 100644
--- a/quacker/quacker.cpp
+++ b/quacker/quacker.cpp
@@ -396,7 +396,9 @@ void TopLevel::setCandidateMove(const Quackle::Move &move)
ensureUpToDateSimulatorMoveList();
}
- if (!m_game->currentPosition().currentPlayer().racksAreKnown() && !m_game->currentPosition().currentPlayer().rack().contains(prettiedMove.usedTiles()))
+ if (!m_game->currentPosition().currentPlayer().racksAreKnown() &&
+ !m_game->currentPosition().currentPlayer().rack().contains(prettiedMove.usedTiles()) &&
+ prettiedMove.action != Quackle::Move::BlindExchange)
{
m_game->currentPosition().setCurrentPlayerRack(Quackle::Rack(prettiedMove.usedTiles()));
}
diff --git a/quackleio/gcgio.cpp b/quackleio/gcgio.cpp
index dfe23a0..9209be5 100644
--- a/quackleio/gcgio.cpp
+++ b/quackleio/gcgio.cpp
@@ -168,10 +168,21 @@ Quackle::Game *GCGIO::read(QTextStream &stream, int flags)
else if (firstMoveBite.startsWith("-"))
{
const QString exchangedLetters = firstMoveBite.right(firstMoveBite.length() - 1);
- if (exchangedLetters.isEmpty())
+ bool isLetterCount = false;
+ uint letterCount = exchangedLetters.toUInt(&isLetterCount);
+
+ if (exchangedLetters.isEmpty() || (isLetterCount && letterCount == 0))
move = Quackle::Move::createPassMove();
+ else if (isLetterCount)
+ {
+ Quackle::LetterString encodedLetters;
+
+ for (uint i = 0; i < letterCount; ++i)
+ encodedLetters.push_back(QUACKLE_BLANK_MARK);
+ move = Quackle::Move::createExchangeMove(encodedLetters, true);
+ }
else
- move = Quackle::Move::createExchangeMove(Util::encode(exchangedLetters));
+ move = Quackle::Move::createExchangeMove(Util::encode(exchangedLetters), false);
}
else if (firstMoveBite.startsWith("(time)"))
{
diff --git a/quackleio/util.cpp b/quackleio/util.cpp
index 5530f16..901c65e 100644
--- a/quackleio/util.cpp
+++ b/quackleio/util.cpp
@@ -55,6 +55,10 @@ QString Util::moveToDetailedString(const Quackle::Move &move)
ret = QObject::tr("Exch. %1").arg(prettyTiles);
break;
+ case Quackle::Move::BlindExchange:
+ ret = QObject::tr("Exch. %1").arg(move.tiles().length());
+ break;
+
case Quackle::Move::UnusedTilesBonus:
ret = QObject::tr("2*(%1)").arg(letterStringToQString(Util::alphagram(move.usedTiles())));
break;
diff --git a/reporter.cpp b/reporter.cpp
index c844afa..7054763 100644
--- a/reporter.cpp
+++ b/reporter.cpp
@@ -156,6 +156,7 @@ void Reporter::reportPosition(const GamePosition &position, ComputerPlayer *comp
break;
case Move::Exchange:
+ case Move::BlindExchange:
s << MARK_UV("xch");
break;