/* * Quackle -- Crossword game artificial intelligence and analysis tool * Copyright (C) 2005-2019 Jason Katz-Brown, John O'Laughlin, and John Fultz. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "alphabetparameters.h" #include "boardparameters.h" #include "datamanager.h" #include "strategyparameters.h" using namespace Quackle; StrategyParameters::StrategyParameters() : m_hasSyn2(false) , m_hasWorths(false) , m_hasVcPlace(false) , m_hasBogowin(false) , m_hasSuperleaves(false) { } void StrategyParameters::initialize(const string &lexicon) { m_hasSyn2 = loadSyn2(DataManager::self()->findDataFile("strategy", lexicon, "syn2")); m_hasWorths = loadWorths(DataManager::self()->findDataFile("strategy", lexicon, "worths")); m_hasVcPlace = loadVcPlace(DataManager::self()->findDataFile("strategy", lexicon, "vcplace")); m_hasBogowin = loadBogowin(DataManager::self()->findDataFile("strategy", lexicon, "bogowin")); m_hasSuperleaves = loadSuperleaves(DataManager::self()->findDataFile("strategy", lexicon, "superleaves")); } 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; } bool StrategyParameters::loadBogowin(const string &filename) { for (int i = 0; i < m_bogowinArrayWidth; ++i) for (int j = 0; j < m_bogowinArrayHeight; ++j) m_bogowin[i][j] = 0; UVIFStream file(filename.c_str()); if (!file.is_open()) { cerr << "Could not open " << filename << " to load bogowin heuristic" << endl; return false; } while (!file.eof()) { int lead, unseen; double wins; file >> lead; file >> unseen; file >> wins; m_bogowin[lead + 300][unseen] = wins; } file.close(); return true; } bool StrategyParameters::loadWorths(const string &filename) { for (int i = 0; i < QUACKLE_FIRST_LETTER + QUACKLE_MAXIMUM_ALPHABET_SIZE; ++i) m_tileWorths[i] = 0; UVIFStream file(filename.c_str()); if (!file.is_open()) { cerr << "Could not open " << filename << " to load worths" << endl; return false; } while (!file.eof()) { UVString letters; file >> letters; if (letters.empty()) continue; LetterString letterString = QUACKLE_ALPHABET_PARAMETERS->encode(letters); if (letterString.length() != 1) { UVcerr << "letter string " << letters << " can not be encoded into one letter while reading worths" << endl; break; } if (file.eof()) break; double value; file >> value; m_tileWorths[(int)letterString[0]] = value; } file.close(); return true; } bool StrategyParameters::loadVcPlace(const string &filename) { for (int i = 0; i < QUACKLE_MAXIMUM_BOARD_SIZE; ++i) for (int j = 0; j < QUACKLE_MAXIMUM_BOARD_SIZE; ++j) for (int k = 0; k < 128; ++k) m_vcPlace[i][j][k] = 0; UVIFStream file(filename.c_str()); if (!file.is_open()) { cerr << "Could not open " << filename << " to load vcPlace heuristic" << endl; return false; } while (!file.eof()) { unsigned int start; file >> start; if (file.eof()) break; unsigned int length; file >> length; if (file.eof()) break; unsigned int consbits; file >> consbits; if (file.eof()) break; double value; file >> value; if ((start < QUACKLE_MAXIMUM_BOARD_SIZE) && (length < QUACKLE_MAXIMUM_BOARD_SIZE) && (consbits < 128)) m_vcPlace[start][length][consbits] = value; } file.close(); return true; } bool StrategyParameters::loadSuperleaves(const string &filename) { m_superleaves.clear(); ifstream file(filename.c_str(), ios::in | ios::binary); if (!file.is_open()) { cerr << "Could not open " << filename << " to load superleave heuristic" << endl; return false; } unsigned char leavesize; char leavebytes[16]; unsigned char intvalueint; unsigned char intvaluefrac; unsigned int intvalue; while (!file.eof()) { file.read((char*)(&leavesize), 1); file.read(leavebytes, leavesize); file.read((char*)(&intvaluefrac), 1); file.read((char*)(&intvalueint), 1); if (file.eof()) break; intvalue = (unsigned int)(intvalueint) * 256 + (unsigned int)(intvaluefrac); LetterString leave = LetterString(leavebytes, leavesize); double value = (double(intvalue) / 256.0) - 128.0; m_superleaves.insert(m_superleaves.end(), SuperLeavesMap::value_type(leave, value)); } file.close(); return true; }