Do not always reject completely a rack containing letters not in the bag anymore.

This could be a rack containing an incomplete input sequence for a tile...
This commit is contained in:
Olivier Teulière 2012-05-15 22:01:14 +02:00
parent 0c1634d530
commit 7868593cb2
3 changed files with 35 additions and 5 deletions

View file

@ -265,7 +265,8 @@ void Header::buildCaches()
m_displayCache[i + 1] = it->second[0]; m_displayCache[i + 1] = it->second[0];
} }
// Create a string with all the characters possibly used // Create a string with all the characters possibly used,
// and another one with the characters used in multi-char input strings
m_inputChars.reserve(m_letters.size()); m_inputChars.reserve(m_letters.size());
BOOST_FOREACH(wchar_t wch, m_letters) BOOST_FOREACH(wchar_t wch, m_letters)
{ {
@ -279,8 +280,14 @@ void Header::buildCaches()
{ {
BOOST_FOREACH(wchar_t chr, str) BOOST_FOREACH(wchar_t chr, str)
{ {
if (m_inputChars.find(towupper(chr)) == string::npos) wchar_t upChr = towupper(chr);
m_inputChars.append(1, towupper(chr)); if (m_inputChars.find(upChr) == string::npos)
m_inputChars.append(1, upChr);
if (str.size() > 1 &&
m_multiCharInputChars.find(upChr) == wstring::npos)
{
m_multiCharInputChars.append(1, upChr);
}
} }
} }
} }
@ -288,6 +295,12 @@ void Header::buildCaches()
} }
bool Header::isMultiCharPart(wchar_t iChar) const
{
return m_multiCharInputChars.find(towupper(iChar)) != wstring::npos;
}
wchar_t Header::getCharFromCode(unsigned int iCode) const wchar_t Header::getCharFromCode(unsigned int iCode) const
{ {
// Safety check // Safety check

View file

@ -125,6 +125,11 @@ public:
const map<wchar_t, vector<wstring> > & getDisplayInputData() const { return m_displayAndInputData; } const map<wchar_t, vector<wstring> > & getDisplayInputData() const { return m_displayAndInputData; }
/**
* Return true if the given char is part of a multi-char input string, false otherwise
*/
bool isMultiCharPart(wchar_t iChar) const;
/** /**
* Return the letter corresponding to the given code * Return the letter corresponding to the given code
*/ */
@ -183,6 +188,9 @@ private:
/// Characters usable to input the dictionary letters /// Characters usable to input the dictionary letters
wstring m_inputChars; wstring m_inputChars;
/// Characters part of a multi-char input string
wstring m_multiCharInputChars;
/// Points of the letters /// Points of the letters
vector<uint8_t> m_points; vector<uint8_t> m_points;

View file

@ -25,6 +25,7 @@
#include "qtcommon.h" #include "qtcommon.h"
#include "dic.h" #include "dic.h"
#include "header.h"
#include "bag.h" #include "bag.h"
#include "coord.h" #include "coord.h"
#include "history.h" #include "history.h"
@ -150,15 +151,23 @@ QValidator::State RackValidator::validate(QString &input, int &) const
return Intermediate; return Intermediate;
QString qinput = qfw(intInput); QString qinput = qfw(intInput);
// The letters must be in the bag // The letters must be in the bag...
State state = Acceptable;
for (int i = 0; i < qinput.size(); ++i) for (int i = 0; i < qinput.size(); ++i)
{ {
if ((unsigned int)qinput.count(qinput[i], Qt::CaseInsensitive) > if ((unsigned int)qinput.count(qinput[i], Qt::CaseInsensitive) >
m_bag.in(intInput[i])) m_bag.in(intInput[i]))
{ {
return Invalid; // ... except if they are part of a multichar input string
if (dic.getHeader().isMultiCharPart(intInput[i]))
state = Intermediate;
else
state = Invalid;
break;
} }
} }
if (state != Acceptable)
return state;
if (m_strict) if (m_strict)
{ {