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); }
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; }
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; }
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; }
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")); } }
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; }
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); } }