summaryrefslogtreecommitdiff
path: root/quackleio
diff options
context:
space:
mode:
Diffstat (limited to 'quackleio')
-rw-r--r--quackleio/gcgio.cpp50
-rw-r--r--quackleio/gcgio.h1
-rw-r--r--quackleio/util.cpp13
-rw-r--r--quackleio/util.h1
4 files changed, 59 insertions, 6 deletions
diff --git a/quackleio/gcgio.cpp b/quackleio/gcgio.cpp
index cafbf49..b60d57c 100644
--- a/quackleio/gcgio.cpp
+++ b/quackleio/gcgio.cpp
@@ -30,6 +30,23 @@ GCGIO::GCGIO()
{
}
+Quackle::Game *GCGIO::read(const QString &filename, int flags)
+{
+ QFile file(filename);
+
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ UVcerr << "Could not open gcg " << QuackleIO::Util::qstringToString(filename) << endl;
+ return new Quackle::Game;
+ }
+
+ QTextStream in(&file);
+ Quackle::Game *ret = read(in, flags);
+ file.close();
+
+ return ret;
+}
+
Quackle::Game *GCGIO::read(QTextStream &stream, int flags)
{
Quackle::Game *ret = new Quackle::Game;
@@ -43,6 +60,7 @@ Quackle::Game *GCGIO::read(QTextStream &stream, int flags)
bool gameStarted = false;
QString line;
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
while (!stream.atEnd())
{
line = stream.readLine();
@@ -111,6 +129,11 @@ Quackle::Game *GCGIO::read(QTextStream &stream, int flags)
incompleteRack = Util::encode(rackString);
hasIncompleteRack = true;
}
+ else if (line.startsWith("#character-encoding"))
+ {
+ QString encoding{line.right(line.length() - 20).trimmed()};
+ stream.setCodec(QTextCodec::codecForName(encoding.toAscii()));
+ }
}
else if (line.startsWith(">"))
{
@@ -120,6 +143,7 @@ Quackle::Game *GCGIO::read(QTextStream &stream, int flags)
gameStarted = true;
}
+ UVString currentPlayer = Util::qstringToString(strings.front().mid(1, strings.front().size() - 2));
strings.pop_front();
if (strings.isEmpty())
@@ -135,10 +159,11 @@ Quackle::Game *GCGIO::read(QTextStream &stream, int flags)
if (rackString.startsWith("(") && rackString.endsWith(")"))
{
// end the game
- if (ret->hasPositions())
+ if (ret->hasPositions() && !ret->currentPosition().gameOver())
ret->commitCandidate(canMaintainCrosses);
else
ret->addPosition();
+ ret->currentPosition().setTileBonus(currentPlayer, Util::encode(rackString.mid(1, rackString.size() - 2)), strings.front().toInt());
continue;
}
@@ -162,10 +187,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)"))
{
@@ -293,6 +329,7 @@ bool GCGIO::canRead(QTextStream &stream) const
void GCGIO::write(const Quackle::Game &game, QTextStream &stream)
{
Quackle::PlayerList players = game.players();
+ stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
for (Quackle::PlayerList::iterator it = players.begin(); it != players.end(); ++it)
{
stream << "#player" << (*it).id() + 1 << " " << Util::uvStringToQString((*it).abbreviatedName()) << " " << Util::uvStringToQString((*it).name()) << endl;
@@ -324,11 +361,14 @@ void GCGIO::write(const Quackle::Game &game, QTextStream &stream)
outputScoreAddition = 0;
}
- stream << ">" << Util::uvStringToQString((*it).currentPlayer().abbreviatedName()) << ": " << Util::letterStringToQString((*it).currentPlayer().rack().alphaTiles()) << " " << Util::uvStringToQString(move.toString()) << " +" << outputScore << " " << outputScore + (*it).currentPlayer().score() << endl;
+ QString rackString = Util::letterStringToQString((*it).currentPlayer().rack().alphaTiles());
+ if (move.action == Quackle::Move::UnusedTilesBonusError)
+ rackString = QString();
+ stream << ">" << Util::uvStringToQString((*it).currentPlayer().abbreviatedName()) << ": " << rackString << " " << Util::uvStringToQString(move.toString()) << " +" << outputScore << " " << outputScore + (*it).currentPlayer().score() << endl;
if (move.isChallengedPhoney())
{
- stream << ">" << Util::uvStringToQString((*it).currentPlayer().abbreviatedName()) << ": " << Util::letterStringToQString((*it).currentPlayer().rack().alphaTiles()) << " -- -" << outputScore << " " << move.effectiveScore() + (*it).currentPlayer().score() << endl;
+ stream << ">" << Util::uvStringToQString((*it).currentPlayer().abbreviatedName()) << ": " << rackString << " -- -" << outputScore << " " << move.effectiveScore() + (*it).currentPlayer().score() << endl;
}
if (outputScoreAddition != 0)
diff --git a/quackleio/gcgio.h b/quackleio/gcgio.h
index 477f84f..a219c9f 100644
--- a/quackleio/gcgio.h
+++ b/quackleio/gcgio.h
@@ -30,6 +30,7 @@ public:
GCGIO();
~GCGIO() {};
+ virtual Quackle::Game *read(const QString &filename, int flags);
virtual Quackle::Game *read(QTextStream &stream, int flags);
virtual bool canRead(QTextStream &stream) const;
virtual void write(const Quackle::Game &game, QTextStream &stream);
diff --git a/quackleio/util.cpp b/quackleio/util.cpp
index cfd8672..2fca766 100644
--- a/quackleio/util.cpp
+++ b/quackleio/util.cpp
@@ -34,7 +34,7 @@ UtilSettings *UtilSettings::self()
}
UtilSettings::UtilSettings()
- : octothorpBritish(true), vowelFirst(false)
+ : octothorpBritish(true), vowelFirst(false), scoreInvalidAsZero(false)
{
m_self = this;
}
@@ -55,8 +55,15 @@ 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::UnusedTilesBonusError:
case Quackle::Move::UnusedTilesBonus:
ret = QObject::tr("2*(%1)").arg(letterStringToQString(Util::alphagram(move.usedTiles())));
+ if (move.action == Quackle::Move::UnusedTilesBonusError)
+ ret += " [Endgame Error]";
break;
case Quackle::Move::TimePenalty:
@@ -68,6 +75,7 @@ QString Util::moveToDetailedString(const Quackle::Move &move)
break;
case Quackle::Move::Place:
+ case Quackle::Move::PlaceError:
ret = uvStringToQString(move.positionString()) + " ";
ret += prettyTiles;
@@ -77,6 +85,9 @@ QString Util::moveToDetailedString(const Quackle::Move &move)
if (move.isChallengedPhoney())
ret = QObject::tr("%1 [Challenged Off]").arg(ret);
+ if (move.action == Quackle::Move::PlaceError)
+ ret += " [Endgame Misdraw]";
+
break;
}
diff --git a/quackleio/util.h b/quackleio/util.h
index 10a57a2..62545bb 100644
--- a/quackleio/util.h
+++ b/quackleio/util.h
@@ -42,6 +42,7 @@ public:
bool octothorpBritish;
bool vowelFirst;
+ bool scoreInvalidAsZero;
private:
static UtilSettings *m_self;