/*
* 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;
}