Beispiel #1
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;
	}
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
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;
		}
	}
}