Ejemplo n.º 1
0
Move Move::createPlaceMove(UVString placeString, LetterString word)
{
	int row = 0, column = 0;
	bool horizontal = true;

	UVString rowString, colString;
	if (iswdigit(placeString[0]))
	{
		rowString = placeString.substr(0, iswdigit(placeString[1])? 2 : 1);
		colString = placeString.substr(iswdigit(placeString[1])? 2 : 1);
	}
	else
	{
		horizontal = false;
		colString = placeString.substr(0, 1);
		rowString = placeString.substr(1);
	}

	UVStringStream ss(rowString);
	ss >> row;
	--row; // zero index it

	column = towupper(colString[0]) - MARK_UV('A');

	if (row < 0 || row > 9999)
		row = 0;
	if (column < 0 || column > 9999)
		column = 0;

	return createPlaceMove(row, column, horizontal, word);
}
Ejemplo n.º 2
0
bool GaddagFactory::pushWord(const UVString &word)
{
	UVString leftover;
    Quackle::LetterString encodedWord = m_alphas->encode(word, &leftover);
	if (leftover.empty())
	{
		pushWord(encodedWord);
		return true;
	}

	++m_unencodableWords;
	return false;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
GaddagFactory::GaddagFactory(const UVString &alphabetFile)
	: m_encodableWords(0), m_unencodableWords(0), m_alphas(NULL)
{
	if (!alphabetFile.empty())
	{
		QuackleIO::FlexibleAlphabetParameters *flexure = new QuackleIO::FlexibleAlphabetParameters;
		flexure->load(QuackleIO::Util::uvStringToQString(alphabetFile));
		m_alphas = flexure;
	}

	// So the separator is sorted to last.
	m_root.t = false;
	m_root.c = QUACKLE_NULL_MARK;  // "_"
	m_root.pointer = 0;
	m_root.lastchild = true;

	m_hash.int32ptr[0] = m_hash.int32ptr[1] = m_hash.int32ptr[2] = m_hash.int32ptr[3] = 0;
}
Ejemplo n.º 5
0
void Reporter::reportPosition(const GamePosition &position, ComputerPlayer *computerPlayer, UVString *report)
{
	UVOStringStream s;

	UVOStringStream titleStream;

	if (!position.gameOver())
		titleStream << position.currentPlayer().name() << MARK_UV(": Turn ") << position.turnNumber() << MARK_UV('\n');

	const Quackle::PlayerList players(position.endgameAdjustedScores());

	for (PlayerList::const_iterator it = players.begin(); it != players.end(); ++it)
	{
		s.width(3);
		s << right << ((*it) == position.currentPlayer()? MARK_UV("->") : MARK_UV(" "));
		s << MARK_UV(' ');
		s.width(24);
		s << left << (*it).name() << MARK_UV(' ');
		s.width(9);
		s << (*it).rack().toString() << MARK_UV(' ');
		s.width(4);
		s << (*it).score();
		s << MARK_UV('\n');
	}

	if (computerPlayer && !position.gameOver())
	{
		computerPlayer->setPosition(position);

		if (position.committedMove().isAMove())
			computerPlayer->considerMove(position.committedMove());

		const unsigned int movesToShow = 10;
		MoveList moves = computerPlayer->moves(movesToShow);

		int ourMoveIndex = 0;
		int i = 1;
		for (Quackle::MoveList::const_iterator it = moves.begin(); it != moves.end(); ++it, ++i)
		{
			if ((*it) == position.committedMove())
			{
				ourMoveIndex = i;
				break;
			}
		}

		bool isUrp = false;

		if (position.committedMove().isAMove())
		{
			// our move not in list
			if (ourMoveIndex == 0)
			{
				if (moves.size() == movesToShow)
					moves.pop_back();

				isUrp = true;
				ourMoveIndex = movesToShow;
				moves.push_back(position.committedMove());
			}
		}

		int highestScore = 0;
		double highestEquity = 0;
		unsigned int widestPositionString = 0;
		unsigned int widestMove = 0;
		bool hasWinPercentages = false;
		const Quackle::MoveList::const_iterator end(moves.end());
		for (Quackle::MoveList::const_iterator it = moves.begin(); it != end; ++it)
		{
			if ((*it).prettyTiles().length() > widestMove)
				widestMove = (*it).prettyTiles().length();
			if ((*it).positionString().length() > widestPositionString)
				widestPositionString = (*it).positionString().length();
			if ((*it).win > 0)
				hasWinPercentages = true;
			if ((*it).equity > highestEquity)
				highestEquity = (*it).equity;
			if ((*it).score > highestScore)
				highestScore = (*it).score;
		}

		s << MARK_UV("--");

		UVOStringStream headerStream;
		headerStream << computerPlayer->name();

		headerStream << "'s choices (your play: ";
		if (isUrp)
			headerStream << "urp";
		else
			headerStream << ourMoveIndex;
		headerStream << ")";

		s.width(43);
		s << setfill(MARK_UV('-'));
		s << left << headerStream.str() << MARK_UV('\n');
		s << setfill(MARK_UV(' '));

		i = 1;
		for (Quackle::MoveList::const_iterator it = moves.begin(); it != end; ++it, ++i)
		{
			// column 2, the valuation.
			s.width(5);
			if ((*it).equity > (highestEquity - .01) && (*it).equity < (highestEquity + .01))
			{
				s << MARK_UV("best");
			}
			else
			{
				s << right << showpoint;
				s.precision(3);
				s << (highestEquity - (*it).equity);
			}

			s << (i == ourMoveIndex? MARK_UV("*") : MARK_UV(" "));

			// column 3, the position string.
			s << left;
			s.width(widestPositionString);
			switch ((*it).action)
			{
			case Move::Place:
				s << (*it).positionString();
				break;

			case Move::Exchange:
				s << MARK_UV("xch");
				break;

			case Move::Pass:
				s << MARK_UV("pas");
				break;
			case Move::UnusedTilesBonus:
			case Move::TimePenalty:
			case Move::Nonmove:
				break;
			}
			s << MARK_UV(" ");

			// column 4, the word
			s.width(widestMove);
			s << left << QUACKLE_ALPHABET_PARAMETERS->userVisible((*it).prettyTiles()) << MARK_UV(" ");

			// column 5, the score
			s.width(highestScore >= 100? 3 : (highestScore >= 10? 2 : 1));
			s << left << (*it).score << MARK_UV(" ");

			// column 6, the win percentage
			if (hasWinPercentages)
			{
				s.precision(4);
				s.width(5);
				s << showpoint << ((*it).win * 100.0) << MARK_UV("% ");
			}

			// column 7, the leave

			s << (position.currentPlayer().rack() - (*it)).toString() << MARK_UV('\n');
		}
	}

	if (position.gameOver())
	{
		s << MARK_UV("\n Game over.\n\n");
	}

	int j = 0;
	UVString wrappedTiles;
	LongLetterString unseenTiles = position.unseenBag().tiles();
	for (Quackle::LongLetterString::const_iterator it = unseenTiles.begin(); it != unseenTiles.end(); ++it, ++j)
	{
		if (j >= 44)
		{
			wrappedTiles += MARK_UV('\n');
			j = 0;
		}

		wrappedTiles += QUACKLE_ALPHABET_PARAMETERS->userVisible(*it);
	}

	s << MARK_UV("--");
	s.width(43);
	s << setfill(MARK_UV('-'));
	s << MARK_UV("Tracking") << MARK_UV('\n');
	s << wrappedTiles << MARK_UV("  ") << unseenTiles.size() << MARK_UV('\n');

	UVString reportString = s.str();
	UVString boardString = position.board().toString();
	
	*report = titleStream.str();

	// Ensure that the board ends with a newline.
	boardString += MARK_UV("\n");

	// Put board and report side by side.
	UVString::const_iterator boardIt = boardString.begin();
	UVString::const_iterator reportIt = reportString.begin();
	UVString::const_iterator reportLineBeginning = reportString.begin();
	UVString::const_iterator boardLineBeginning = boardString.begin();
	const UVString::const_iterator reportEnd = reportString.end();
	const UVString::const_iterator boardEnd = boardString.end();
	while (true)
	{
		if (boardIt == boardEnd && reportIt == reportEnd)
			break;

		if (boardIt != boardEnd && (*boardIt) != MARK_UV('\n'))
		{
			++boardIt;
			continue;
		}

		if (reportIt != reportEnd && (*reportIt) != MARK_UV('\n'))
		{
			++reportIt;
			continue;
		}

		if (boardIt != boardEnd)
		{
			report->append(boardLineBeginning, boardIt);
		}
		if (reportIt != reportEnd)
		{
			report->append(MARK_UV(" "));
			report->append(reportLineBeginning, reportIt);
		}

		boardLineBeginning = boardIt + 1;
		reportLineBeginning = reportIt + 1;

		if (boardIt != boardEnd)
			++boardIt;
		if (reportIt != reportEnd)
			++reportIt;

		report->append(MARK_UV("\n"));
	}
}
Ejemplo n.º 6
0
int main(int argc, char **argv) {
	QCoreApplication a(argc, argv);

	GetOpt opts;
	QString alphabet;
	opts.addOption('a', "alphabet", &alphabet);
	if (!opts.parse())
		return 1;

	if (alphabet.isNull())
		alphabet = "english";

	Quackle::AlphabetParameters *alphas = 0;
	QString alphabetFile = QString("../data/alphabets/%1.quackle_alphabet").arg(alphabet);
	UVcout << "Using alphabet file: " << QuackleIO::Util::qstringToString(alphabetFile) << endl;
	QuackleIO::FlexibleAlphabetParameters *flexure = new QuackleIO::FlexibleAlphabetParameters;
	flexure->load(alphabetFile);
	alphas = flexure;

	QString leavesFilename = "superleaves.raw";
	QFile file(leavesFilename);
	if (!file.exists())
	{
		UVcout << "leaves file does not exist: " << QuackleIO::Util::qstringToString(leavesFilename) << endl;
		return false;
	}

	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		UVcout << "Could not open " << QuackleIO::Util::qstringToString(leavesFilename) << endl;
		return false;
	}

	QTextStream stream(&file);
	stream.setCodec(QTextCodec::codecForName("UTF-8"));

	ofstream out("encoded");

	int encodableLeaves = 0;
	int unencodableLeaves = 0;

  while (!stream.atEnd()) {
		QString leaveQString;
		stream >> leaveQString;
		double value;
		stream >> value;
		//UVcout << "value: " << value << endl;

		UVString leaveString = QuackleIO::Util::qstringToString(leaveQString);

		if (stream.atEnd())
			break;

		//UVcout << "read original string: " << originalString << endl;
		UVString leftover;
    Quackle::LetterString encodedLeave = alphas->encode(leaveString, &leftover);
		if (leftover.empty())
		{
			unsigned char leavelength = encodedLeave.length();
			out.write((char*)(&leavelength), 1);
			out.write(encodedLeave.begin(), encodedLeave.length());
			unsigned short int intvalue = (value + 128) * 256;
			//UVcout << "intvalue: " << intvalue << endl;
			out.write((char*)(&intvalue), 2);
			++encodableLeaves;
		}
		else
		{
			//UVcout << "not encodable without leftover: " << originalString << endl;
			++unencodableLeaves;
		}
    }

	file.close();
	delete alphas;

	UVcout << "encodable leaves: " << encodableLeaves << ", unencodable leaves: " << unencodableLeaves << endl;

}
Ejemplo n.º 7
0
int MiniDawgMaker::executeFromArguments()
{
	GetOpt opts;
	QString alphabet;
	opts.addOption('a', "alphabet", &alphabet);
	if (!opts.parse())
		return 1;

	if (alphabet.isNull())
		alphabet = "english";

	Quackle::AlphabetParameters *alphas = 0;
	QString alphabetFile = QString("../data/alphabets/%1.quackle_alphabet").arg(alphabet);
	UVcout << "Using alphabet file: " << QuackleIO::Util::qstringToString(alphabetFile) << endl;
	QuackleIO::FlexibleAlphabetParameters *flexure = new QuackleIO::FlexibleAlphabetParameters;
	flexure->load(alphabetFile);
	alphas = flexure;

    root.t = false;
		root.insmallerdict = false;
		root.playability = 0;
    root.c = QUACKLE_BLANK_MARK;
    root.pointer = 0;
    root.lastchild = true;

	QString smallerDictFilename = "smaller.raw";
	QFile smallerDict(smallerDictFilename);
	if (!smallerDict.exists())
	{
		UVcout << "smaller dictionary does not exist: " << QuackleIO::Util::qstringToString(smallerDictFilename) << endl;
		return false;
	}

	if (!smallerDict.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		UVcout << "Could not open " << QuackleIO::Util::qstringToString(smallerDictFilename) << endl;
		return false;
	}

	QTextStream smallerStream(&smallerDict);
	smallerStream.setCodec(QTextCodec::codecForName("UTF-8"));
	
	while (!smallerStream.atEnd())
	{
		QString originalQString;
		smallerStream >> originalQString;
		//UVcout << "this word is in the smaller dictionary: " << QuackleIO::Util::qstringToString(originalQString) << endl;
		smallerMap[originalQString] = true;
	}

	QString playabilityFilename = "playabilities.raw";
	QFile playability(playabilityFilename);
	if (!playability.exists())
	{
		UVcout << "playability does not exist: " << QuackleIO::Util::qstringToString(playabilityFilename) << endl;
		return false;
	}

	if (!playability.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		UVcout << "Could not open " << QuackleIO::Util::qstringToString(playabilityFilename) << endl;
		return false;
	}

	QTextStream playabilityStream(&playability);
	playabilityStream.setCodec(QTextCodec::codecForName("UTF-8"));
	
	while (!playabilityStream.atEnd())
	{
		int pb;
		playabilityStream >> pb;
		QString originalQString;
		playabilityStream >> originalQString;
		//UVcout << "playability: " << QuackleIO::Util::qstringToString(originalQString) << " " << pb << endl;
		playabilityMap[originalQString] = pb;
	}

	QString dawgFilename = "dawginput.raw";
	QFile file(dawgFilename);
	if (!file.exists())
	{
		UVcout << "dawg does not exist: " << QuackleIO::Util::qstringToString(dawgFilename) << endl;
		return false;
	}

	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		UVcout << "Could not open " << QuackleIO::Util::qstringToString(dawgFilename) << endl;
		return false;
	}

	QTextStream stream(&file);
	stream.setCodec(QTextCodec::codecForName("UTF-8"));

	int encodableWords = 0;
	int unencodableWords = 0;

    while (!stream.atEnd())
	{
		QString originalQString;
    stream >> originalQString;

		bool inSmaller = smallerMap[originalQString];
		int pb = playabilityMap[originalQString];

		if (stream.atEnd())
			break;

		UVString originalString = QuackleIO::Util::qstringToString(originalQString);

		//UVcout << "read original string: " << originalString;
		//if (!inSmaller) UVcout << "#";
		//UVcout << endl;

		UVString leftover;
        Quackle::LetterString encodedWord = alphas->encode(originalString, &leftover);
		if (leftover.empty())
		{
			//for (Quackle::LetterString::iterator it = encodedWord.begin(); it != encodedWord.end(); ++it)
				//UVcout << "got encoded letter: " << (int)(*it) << endl;

			root.pushword(encodedWord, inSmaller, pb);
			++encodableWords;
		}
		else
		{
			UVcout << "not encodable without leftover: " << originalString << endl;
			++unencodableWords;
		}
    }

	file.close();
	delete alphas;

	UVcout << "encodable words: " << encodableWords << ", unencodable words: " << unencodableWords << endl;

    nodelist.push_back(&root);
    root.print("");    
	UVcout << "nodelist.size(): " << nodelist.size() << endl;

	minimize();

	ofstream out("output.dawg", ios::out | ios::binary);

    for (unsigned int i = 0; i < nodelist.size(); i++) {
        //cout << nodelist[i]->c << " " << nodelist[i]->pointer << " " << nodelist[i]->t << " " << nodelist[i]->lastchild << endl;
		Node* n = nodelist[i];
		unsigned int p;
		if (nodelist[i]->deleted)
		{
			p = (unsigned int)(nodelist[i]->cloneof->pointer);
			// n = nodelist[i]->cloneof;
		}
		else
			p = (unsigned int)(nodelist[i]->pointer);
        
        char bytes[7];
        unsigned char n1 = (p & 0x00FF0000) >> 16;
        unsigned char n2 = (p & 0x0000FF00) >>  8;
        unsigned char n3 = (p & 0x000000FF);
        unsigned char n4 = n->c - QUACKLE_FIRST_LETTER;
				
				unsigned int pb = n->playability;
				unsigned char n5 = (pb & 0x00FF0000) >> 16;
				unsigned char n6 = (pb & 0x0000FF00) >>  8;
				unsigned char n7 = (pb & 0x000000FF);

        if (n->t) {
            n4 |= 32;
        }
        if (n->lastchild) {
            n4 |= 64;
        }
				if (n->insmallerdict) {
						n4 |= 128;
				}

        bytes[0] = n1; bytes[1] = n2; bytes[2] = n3; bytes[3] = n4;
				bytes[4] = n5; bytes[5] = n6; bytes[6] = n7;
        out.write(bytes, 7);
    }
}