Example #1
0
void Rack::load(const LetterString &tiles)
{
	for (LetterString::const_iterator it = tiles.begin(); it != tiles.end(); ++it)
	{
		if (it != QUACKLE_NULL_MARK)
			m_tiles += *it;
	}
}
Example #2
0
LetterString Bag::someShuffledTiles() const
{
	LongLetterString shuffled(shuffledTiles());
	LetterString ret;
	int i = 0;
	for (LongLetterString::const_iterator it = shuffled.begin(); it != shuffled.end() && i < LETTER_STRING_MAXIMUM_LENGTH - 1; ++it, ++i)
		ret.push_back(*it);

	return ret;
}
Example #3
0
bool Bag::removeLetters(const LetterString &letters)
{
	bool ret = true;

	const LetterString::const_iterator end(letters.end());
	for (LetterString::const_iterator it = letters.begin(); it != end; ++it)
		if (!removeLetter(*it))
			ret = false;

	return ret;
}
Example #4
0
LetterString Move::wordTilesWithNoPlayThru() const
{
    LetterString word;
	LetterString used = usedTiles();

	const LetterString::const_iterator end(used.end());
	for (LetterString::const_iterator it = used.begin(); it != end; ++it)
        if (*it != QUACKLE_PLAYED_THRU_MARK)
            word += QUACKLE_ALPHABET_PARAMETERS->clearBlankness(*it);

	return word;
}
Example #5
0
double CatchallEvaluator::equity(const GamePosition &position, const Move &move) const
{
	//UVcout << "catchall being used on " << move.tiles() << endl;
	if (position.board().isEmpty())
	{
		double adjustment = 0;
	
		if (move.action == Move::Place)
		{
			int start = move.startcol;
			if (move.startrow < start)
				start = move.startrow;
		
			LetterString wordTiles = move.tiles();
		
			int length = wordTiles.length();
	
			int consbits = 0;
			for (signed int i = wordTiles.length() - 1; i >= 0; i--)
			{
				consbits <<= 1;
                if (QUACKLE_ALPHABET_PARAMETERS->isVowel(QUACKLE_ALPHABET_PARAMETERS->clearBlankness(wordTiles[i])))
					consbits |= 1;
			}

			adjustment = QUACKLE_STRATEGY_PARAMETERS->vcPlace(start, length, consbits);
		}
		else
			adjustment = 3.5;

		// UVcout << "placement adjustment for " << move << " is " << adjustment << endl;
		return ScorePlusLeaveEvaluator::equity(position, move) + adjustment;
	}
	
	else if (position.bag().size() > 0)
	{
		int leftInBagPlusSeven = position.bag().size() - move.usedTiles().length() + 7;
		double heuristicArray[13] =
		{
			0.0, -8.0, 0.0, -0.5, -2.0, -3.5, -2.0,
			2.0, 10.0, 7.0,  4.0, -1.0, -2.0
		};
		double timingHeuristic = 0.0;
		if (leftInBagPlusSeven < 13) timingHeuristic = heuristicArray[leftInBagPlusSeven];
		return ScorePlusLeaveEvaluator::equity(position, move) + timingHeuristic;
	}
	else
	{
		return endgameResult(position, move) + move.score;
	}
}
Example #6
0
bool StrategyParameters::loadSyn2(const string &filename)
{
    for (int i = 0; i < QUACKLE_FIRST_LETTER + QUACKLE_MAXIMUM_ALPHABET_SIZE; ++i)
        for (int j = 0; j < QUACKLE_FIRST_LETTER + QUACKLE_MAXIMUM_ALPHABET_SIZE; ++j)
            m_syn2[i][j] = 0;

    UVIFStream file(filename.c_str());

    if (!file.is_open())
    {
        cerr << "Could not open " << filename << " to load syn2" << endl;
        return false;
    }

    while (!file.eof())
    {
        UVString letters;
        file >> letters;

        if (letters.empty())
            continue;

        LetterString letterString = QUACKLE_ALPHABET_PARAMETERS->encode(letters);
        if (letterString.length() != 2)
        {
            UVcerr << "letter string " << letters << " can not be encoded into two letters while reading syn2" << endl;
            break;
        }

        if (file.eof())
            break;

        double value;
        file >> value;

        m_syn2[(int)letterString[0]][(int)letterString[1]] = value;
        m_syn2[(int)letterString[1]][(int)letterString[0]] = value;
    }

    file.close();
    return true;
}
Example #7
0
LetterString Bag::refill(Rack &rack, const LetterString &drawingOrder)
{
	LetterString ret(drawingOrder);

	for (int number = QUACKLE_PARAMETERS->rackSize() - rack.tiles().length(); number > 0 && !m_tiles.empty(); --number)
	{
		if (drawingOrder.empty())
			rack.setTiles(String::alphabetize(rack.tiles() + pluck()));
		else
		{
			removeLetter(String::back(ret));
			rack.setTiles(String::alphabetize(rack.tiles() + String::back(ret)));
			String::pop_back(ret);
		}
	}

	return ret;
}
Example #8
0
bool Rack::unload(const LetterString &used)
{
	// UVcout << *this << ".unload(" << used << ")" << endl;

	LetterString newtiles = m_tiles;
	bool ret = true;

	LetterString::const_iterator usedEnd(used.end());
	for (LetterString::const_iterator usedIt = used.begin(); usedIt != usedEnd; ++usedIt)
	{
		bool found = false;

		LetterString::iterator newEnd(newtiles.end());
		for (LetterString::iterator newIt = newtiles.begin(); newIt != newEnd; ++newIt)
		{
			if (*newIt == *usedIt)
			{
				*newIt = QUACKLE_NULL_MARK;
				found = true;
				break;
			}
		}

		if (!found)
			ret = false;
	}

	// UVcout << "newtiles: " << newtiles << endl;

	m_tiles.clear();

	LetterString::const_iterator newEnd(newtiles.end());
	for (LetterString::const_iterator newIt = newtiles.begin(); newIt != newEnd; ++newIt)
		if (*newIt != QUACKLE_NULL_MARK)
			m_tiles += *newIt; 

	return ret;
}
Example #9
0
void Bag::toss(const LetterString &letters)
{
	const LetterString::const_iterator end(letters.end());
	for (LetterString::const_iterator it = letters.begin(); it != end; ++it)
		m_tiles.push_back(*it);
}
Example #10
0
MoveList Board::allWordsFormedBy(const Move &move) const
{
	MoveList ret;

	if (move.tiles().length() > 1)
		ret.push_back(move);

	if (move.action == Move::Place)
	{
		if (m_empty)
		{
			ret.push_back(move);
		}
		else
		{
			LetterString word;

			if (move.horizontal)
			{
				int i = 0;
				for (const auto& it : move.tiles())
				{
					if (m_letters[move.startrow][i + move.startcol] == QUACKLE_NULL_MARK)
					{
						word.clear();
						word += it;

						int startRow = 0;
						for (int j = move.startrow - 1; j >= 0; --j)
						{
							if (m_letters[j][i + move.startcol] == QUACKLE_NULL_MARK)
							{
								startRow = j + 1;
								break;
							}
							else
							{
								word = m_letters[j][i + move.startcol] + word;
							}
						}

						for (int j = move.startrow + 1; j < m_height; ++j)
						{
							if (m_letters[j][i + move.startcol] == QUACKLE_NULL_MARK)
								j = m_height;
							else
								word += m_letters[j][i + move.startcol];
						}

						if (word.length() > 1)
						{
							ret.push_back(Move::createPlaceMove(startRow, (i + move.startcol), /* vertical */ false, word));
						}
					}
					i++;
				}
			}
			else
			{
				int i = 0;
				for (const auto& it : move.tiles())
				{
					if (m_letters[i + move.startrow][move.startcol] == QUACKLE_NULL_MARK)
					{
						word.clear();
						word += it;

						int startColumn = 0;
						for (int j = move.startcol - 1; j >= 0; --j)
						{
							if (m_letters[i + move.startrow][j] == QUACKLE_NULL_MARK)
							{
								startColumn = j + 1;
								break;
							}
							else
							{
								word = m_letters[i + move.startrow][j] + word;
							}
						}

						for (int j = move.startcol + 1; j < m_width; ++j)
						{
							if (m_letters[i + move.startrow][j] == QUACKLE_NULL_MARK)
								j = m_width;
							else
								word += m_letters[i + move.startrow][j];
						}

						if (word.length() > 1)
						{
							ret.push_back(Move::createPlaceMove((i + move.startrow), startColumn, /* horizontal */ true, word));
						}
						i++;
					}
				}
			}
		}
	}

	for (auto& it : ret)
	{
		it.setTiles(sanitizedTilesOfMove(it));
		it.setPrettyTiles(prettyTilesOfMove(it));
		it.score = score(it);
	}

	return ret;
}
Example #11
0
void Board::updateBritishness()
{
	Generator generator;

	LetterString word;
	for (int row = 0; row < m_height; row++)
	{
		for (int col = 0; col < m_width; col++)
		{
			bool isBritish = false;

			if (m_letters[row][col] != QUACKLE_NULL_MARK)
			{
				word.clear();
				word += QUACKLE_ALPHABET_PARAMETERS->clearBlankness(m_letters[row][col]);

				for (int j = row - 1; j >= 0; --j)
				{
					if (m_letters[j][col] == QUACKLE_NULL_MARK)
						break;
					else
						word = QUACKLE_ALPHABET_PARAMETERS->clearBlankness(m_letters[j][col]) + word;
				}

				for (int j = row + 1; j < m_height; ++j)
				{
					if (m_letters[j][col] == QUACKLE_NULL_MARK)
						break;
					else
						word += QUACKLE_ALPHABET_PARAMETERS->clearBlankness(m_letters[j][col]);
				}

				if (word.length() > 1)
				{
					WordWithInfo wordWithInfo;
					wordWithInfo.wordLetterString = word;
					generator.storeWordInfo(&wordWithInfo);

					if (wordWithInfo.british)
						isBritish = true;
				}

				word.clear();
				word += QUACKLE_ALPHABET_PARAMETERS->clearBlankness(m_letters[row][col]);

				for (int j = col - 1; j >= 0; --j)
				{
					if (m_letters[row][j] == QUACKLE_NULL_MARK)
						break;
					else
						word = QUACKLE_ALPHABET_PARAMETERS->clearBlankness(m_letters[row][j]) + word;
				}

				for (int j = col + 1; j < m_width; ++j)
				{
					if (m_letters[row][j] == QUACKLE_NULL_MARK)
						break;
					else
						word += QUACKLE_ALPHABET_PARAMETERS->clearBlankness(m_letters[row][j]);
				}

				if (word.length() > 1)
				{
					WordWithInfo wordWithInfo;
					wordWithInfo.wordLetterString = word;
					generator.storeWordInfo(&wordWithInfo);

					if (wordWithInfo.british)
						isBritish = true;
				}
			}

			m_isBritish[row][col] = isBritish;
		}
	}
}