Arbitration: do not accept blindly any rack in Intermediate state.

This fixes a bug with languages using multichar tiles.
This commit is contained in:
Olivier Teulière 2012-05-16 22:05:52 +02:00
parent c2290ab6cd
commit 0c1634d530
4 changed files with 53 additions and 32 deletions

View file

@ -83,6 +83,8 @@ ArbitrationWidget::ArbitrationWidget(QWidget *parent,
redPalette.setColor(QPalette::Text, Qt::red); redPalette.setColor(QPalette::Text, Qt::red);
// Define validators // Define validators
m_unstrictRackValidator =
ValidatorFactory::newRackValidator(this, m_game->getBag());
QValidator * val = QValidator * val =
ValidatorFactory::newRackValidator(this, m_game->getBag(), ValidatorFactory::newRackValidator(this, m_game->getBag(),
true, &m_game->getHistory(), true, &m_game->getHistory(),
@ -407,9 +409,19 @@ void ArbitrationWidget::rackEdited(const QString &iText)
try try
{ {
const wstring &input = m_game->getDic().convertFromInput(wfq(iText)); // Update the game rack if it is valid, or if it is "almost valid",
m_game->arbitrationSetRackManual(input); // i.e. in Intermediate state due to the duplicate constraints only.
emit gameUpdated(); // This is practical to have the rack updated letter by letter on the
// external board.
QString copy = iText;
int unused = 0;
if (lineEditRack->hasAcceptableInput() ||
m_unstrictRackValidator->validate(copy, unused) == QValidator::Acceptable)
{
const wstring &input = m_game->getDic().convertFromInput(wfq(iText));
m_game->arbitrationSetRackManual(input);
emit gameUpdated();
}
} }
catch (std::exception &e) catch (std::exception &e)
{ {

View file

@ -37,6 +37,7 @@ class QStandardItemModel;
class QSortFilterProxyModel; class QSortFilterProxyModel;
class QMenu; class QMenu;
class QPoint; class QPoint;
class QValidator;
class ArbitrationWidget: public QWidget, private Ui::ArbitrationWidget class ArbitrationWidget: public QWidget, private Ui::ArbitrationWidget
{ {
@ -102,6 +103,12 @@ private:
/// Accumulator used to build the table number /// Accumulator used to build the table number
KeyAccumulator *m_keyAccum; KeyAccumulator *m_keyAccum;
/**
* Validator less strict than the default one
* (it doesn't check duplicate constraints)
*/
QValidator *m_unstrictRackValidator;
/// Palette to write text in black /// Palette to write text in black
QPalette blackPalette; QPalette blackPalette;

View file

@ -106,23 +106,23 @@ class RackValidator: public QValidator
{ {
public: public:
RackValidator(QObject *parent, const Bag &iBag, RackValidator(QObject *parent, const Bag &iBag,
const History *iHistory, bool checkDuplicate, const History *iHistory, bool iStrict,
int iMaxLetters); int iMaxLetters);
virtual State validate(QString &input, int &pos) const; virtual State validate(QString &input, int &pos) const;
private: private:
const Bag &m_bag; const Bag &m_bag;
const History *m_history; const History *m_history;
bool m_checkDuplicate; bool m_strict;
int m_maxLetters; int m_maxLetters;
}; };
RackValidator::RackValidator(QObject *parent, const Bag &iBag, RackValidator::RackValidator(QObject *parent, const Bag &iBag,
const History *iHistory, bool checkDuplicate, const History *iHistory, bool iStrict,
int iMaxLetters) int iMaxLetters)
: QValidator(parent), m_bag(iBag), : QValidator(parent), m_bag(iBag),
m_history(iHistory), m_checkDuplicate(checkDuplicate), m_history(iHistory), m_strict(iStrict),
m_maxLetters(iMaxLetters) m_maxLetters(iMaxLetters)
{ {
} }
@ -160,30 +160,32 @@ QValidator::State RackValidator::validate(QString &input, int &) const
} }
} }
// Make sure we don't have too many letters... if (m_strict)
if (m_maxLetters > 0 && intInput.size() > (unsigned)m_maxLetters)
return Intermediate;
// ... or too few
if (m_maxLetters > 0 && intInput.size() < (unsigned)m_maxLetters &&
m_bag.getNbTiles() >= (unsigned)m_maxLetters)
{ {
return Intermediate; // Make sure we don't have too many letters...
} if (m_maxLetters > 0 && intInput.size() > (unsigned)m_maxLetters)
// Check that the rack has 2 consonants and 2 vocals
if (m_checkDuplicate)
{
PlayedRack pld;
pld.setManual(intInput);
int min;
if (m_bag.getNbVowels() > 1 && m_bag.getNbConsonants() > 1
&& m_history->getSize() < 15)
min = 2;
else
min = 1;
if (!pld.checkRack(min, min))
return Intermediate; return Intermediate;
// ... or too few
if (m_maxLetters > 0 && intInput.size() < (unsigned)m_maxLetters &&
m_bag.getNbTiles() >= (unsigned)m_maxLetters)
{
return Intermediate;
}
// Check that the rack has 2 consonants and 2 vocals
if (m_history != 0)
{
PlayedRack pld;
pld.setManual(intInput);
int min;
if (m_bag.getNbVowels() > 1 && m_bag.getNbConsonants() > 1
&& m_history->getSize() < 15)
min = 2;
else
min = 1;
if (!pld.checkRack(min, min))
return Intermediate;
}
} }
return Acceptable; return Acceptable;
@ -192,11 +194,11 @@ QValidator::State RackValidator::validate(QString &input, int &) const
QValidator *ValidatorFactory::newRackValidator(QObject *parent, QValidator *ValidatorFactory::newRackValidator(QObject *parent,
const Bag &iBag, const Bag &iBag,
bool checkDuplicate, bool iStrict,
const History *iHistory, const History *iHistory,
int iMaxLetters) int iMaxLetters)
{ {
return new RackValidator(parent, iBag, iHistory, checkDuplicate, iMaxLetters); return new RackValidator(parent, iBag, iHistory, iStrict, iMaxLetters);
} }
// }}} // }}}

View file

@ -50,7 +50,7 @@ public:
*/ */
static QValidator *newRackValidator(QObject *parent, static QValidator *newRackValidator(QObject *parent,
const Bag &iBag, const Bag &iBag,
bool checkDuplicate = false, bool iStrict = false,
const History *iHistory = 0, const History *iHistory = 0,
int iMaxLetters = 0); int iMaxLetters = 0);