Big changes of project structure

This commit is contained in:
2015-06-20 13:46:30 +03:00
parent 71641535db
commit aa1a2101ed
13 changed files with 617 additions and 515 deletions

78
src/crossexport.cpp Normal file
View File

@@ -0,0 +1,78 @@
#include "crossexport.hpp"
void fillCross(FilledCrossword &cross){
for ( size_t i = 0; i < cross.words.size(); ++i ) {
if ( cross.words.at(i).direct == true ) {
for (size_t j = 0; j < cross.words.at(i).len; ++j){
cross.grid.at(cross.words.at(i).x+j).at(cross.words.at(i).y) = cross.ans.at(i).at(j);
}
} else {
for (size_t j = 0; j < cross.words.at(i).len; ++j)
cross.grid.at(cross.words.at(i).x).at(cross.words.at(i).y+j) = cross.ans.at(i).at(j);
}
}
}
wxString getGridString(const FilledCrossword &cross, wxChar space = wxT('-')){
const wxString LINE_END = wxTextFile::GetEOL();
wxString t_string;
FilledCrossword t_cross(cross);
if ( !t_cross.ans.empty() ) {
fillCross(t_cross);
}
for (size_t i = 0; i < t_cross.grid.at(0).size(); ++i){
for (size_t j = 0; j < t_cross.grid.size(); ++j){
if ( t_cross.grid.at(j).at(i) == CELL_BORDER )
t_string += space;
else
t_string += t_cross.grid.at(j).at(i);
}
t_string += LINE_END;
}
return t_string;
}
wxString getQuesString(const FilledCrossword &cross){
const wxString LINE_END = wxTextFile::GetEOL();
wxString t_string;
if ( !cross.ques.empty() ) { // == print questions
t_string += _("Vertical words:") + LINE_END;
for (size_t i = 0; i < cross.words.size(); ++i){
if (cross.words.at(i).direct == false)
t_string += wxString::Format(wxT("%d. "), cross.words.at(i).ind)
+ cross.ques.at(i) + LINE_END;
}
t_string += _("Horisontal words:") + LINE_END;
for (size_t i = 0; i < cross.words.size(); ++i){
if (cross.words.at(i).direct == true)
t_string += wxString::Format(wxT("%d. "), cross.words.at(i).ind)
+ cross.ques.at(i) + LINE_END;
}
}
return t_string;
}
void exportToString(const FilledCrossword &cross, wxString &str_out, wxChar space = wxT('-')){
str_out += getGridString(cross, space) + getQuesString(cross);
}
bool exportToFile(const FilledCrossword &cross, const wxString path){
wxTextFile f(path);
if ( f.Exists() )
return false;
f.Create();
f.Open(path);
wxString cont;
exportToString(cross, cont);
f.AddLine(cont);
f.Write();
f.Close();
return true;
}

View File

@@ -2,84 +2,19 @@
#define CROSSEXPORT_HPP
#include <wx/wx.h>
#include <wx/textfile.h>
#include "crossgen.hpp"
#include "crossbasetypes.hpp"
void fillCross(FilledCrossword &cross){
for ( size_t i = 0; i < cross.words.size(); ++i ) {
if ( cross.words.at(i).direct == true ) {
for (size_t j = 0; j < cross.words.at(i).len; ++j){
cross.grid.at(cross.words.at(i).x+j).at(cross.words.at(i).y) = cross.ans.at(i).at(j);
}
} else {
for (size_t j = 0; j < cross.words.at(i).len; ++j)
cross.grid.at(cross.words.at(i).x).at(cross.words.at(i).y+j) = cross.ans.at(i).at(j);
}
}
}
void fillCross(FilledCrossword &cross);
wxString getGridString(const FilledCrossword &cross, wxChar space = wxT('-')){
const wxString LINE_END = wxTextFile::GetEOL();
wxString t_string;
FilledCrossword t_cross(cross);
if ( !t_cross.ans.empty() ) {
fillCross(t_cross);
}
for (size_t i = 0; i < t_cross.grid.at(0).size(); ++i){
for (size_t j = 0; j < t_cross.grid.size(); ++j){
if ( t_cross.grid.at(j).at(i) == CELL_BORDER )
t_string += space;
else
t_string += t_cross.grid.at(j).at(i);
}
t_string += LINE_END;
}
return t_string;
}
wxString getGridString(const FilledCrossword &cross, wxChar space);
wxString getQuesString(const FilledCrossword &cross){
const wxString LINE_END = wxTextFile::GetEOL();
wxString t_string;
if ( !cross.ques.empty() ) { // == print questions
t_string += _("Vertical words:") + LINE_END;
for (size_t i = 0; i < cross.words.size(); ++i){
if (cross.words.at(i).direct == false)
t_string += wxString::Format(wxT("%d. "), cross.words.at(i).ind)
+ cross.ques.at(i) + LINE_END;
}
t_string += _("Horisontal words:") + LINE_END;
for (size_t i = 0; i < cross.words.size(); ++i){
if (cross.words.at(i).direct == true)
t_string += wxString::Format(wxT("%d. "), cross.words.at(i).ind)
+ cross.ques.at(i) + LINE_END;
}
}
return t_string;
}
wxString getQuesString(const FilledCrossword &cross);
void exportToString(const FilledCrossword &cross, wxString &str_out, wxChar space = wxT('-')){
str_out += getGridString(cross, space) + getQuesString(cross);
}
void exportToString(const FilledCrossword &cross, wxString &str_out, wxChar space);
bool exportToFile(const FilledCrossword &cross, const wxString path){
wxTextFile f(path);
if ( f.Exists() )
return false;
f.Create();
f.Open(path);
wxString cont;
exportToString(cross, cont);
f.AddLine(cont);
f.Write();
f.Close();
return true;
}
bool exportToFile(const FilledCrossword &cross, const wxString path);
#endif // CROSSEXPORT_HPP

252
src/crossgen.cpp Normal file
View File

@@ -0,0 +1,252 @@
#include "crossgen.hpp"
const wxChar CELL_CLEAR = wxT('+');
const wxChar CELL_BORDER = wxT('-');
const TransedChar TRANS_CLEAR = 0;
const TransedChar TRANS_BORDER = 1;
const uint32_t MAX_WORD_COUNT = 262144; // =2^18
void readDict(const wxString path, DictType &dict_out){
wxTextFile f;
f.Open(path);
for ( wxString str = f.GetFirstLine(); !f.Eof(); str = f.GetNextLine() ) {
wxString key,val;
int del_ind = str.Index('-');
key = str.Left(del_ind-1);
val = str.Right(str.size() - del_ind - 2);
dict_out[key] = val;
}
f.Close();
};
void readGrid(const wxString path, GridType &grid){
wxTextFile f;
f.Open(path);
wxString str = f.GetFirstLine();
grid.resize(str.size());
for (unsigned int i = 0; i < grid.size(); ++i)
grid.at(i).resize(f.GetLineCount());
wxLogDebug(wxT("Total lines: %d. First line is %s and size = %d"),f.GetLineCount(), str.c_str(),str.size());
unsigned int i = 0;
for ( ; !f.Eof(); str = f.GetNextLine() ) {
wxLogDebug(str);
for (unsigned int j = 0; j < str.size(); ++j)
grid.at(j).at(i) = str.at(j);
++i;
}
wxLogDebug(wxT("Прочитана сетка размером %d x %d"),
static_cast<int>(grid.size()), static_cast<int>(grid.at(0).size()));
f.Close();
}
wxString getFromTransed(const TransedWord &tw, const BackedCharsTransType &bchar_trans){
wxString s;
s.resize(tw.size());
for (size_t i = 0; i < tw.size(); ++i){
s[i] = bchar_trans.at(tw.at(i));
}
return s;
}
BackedCharsTransType getFromCharsTransed(const CharsTransType &char_trans){
BackedCharsTransType t;
for (auto it = char_trans.begin(); it != char_trans.end(); ++it)
t[it->second] = it->first;
return t;
}
void toWorkGridType(const GridType &grid, WorkGridType &grid_out){
grid_out.clear();
grid_out.resize(grid.size());
for (size_t i = 0; i < grid.size(); ++i){
grid_out.at(i).resize(grid.at(0).size());
for (size_t j = 0; j < grid.at(0).size(); ++j){
if ( grid.at(i).at(j) == CELL_CLEAR )
grid_out.at(i).at(j) = TRANS_CLEAR;
else
grid_out.at(i).at(j) = TRANS_BORDER;
}
}
}
void generateAllWords(const DictType &dict, AllWordsType &words_out,
CharsTransType &char_trans_out){
words_out.clear();
char_trans_out.clear();
char_trans_out[CELL_CLEAR] = TRANS_CLEAR;
char_trans_out[CELL_BORDER] = TRANS_BORDER;
static_assert(TRANS_CLEAR + 1 == TRANS_BORDER, "TRANS_CLEAR + 1 != TRANS_BORDER");
TransedChar st = TRANS_BORDER + 1;
for (auto it = dict.begin(); it != dict.end(); ++it){
if ( words_out.size() <= it->first.size() )
words_out.resize(it->first.size() + 2);
TransedWord t_tw(it->first.size());
for (size_t i = 0; i < it->first.size(); ++i){
auto cur_ch = it->first.at(i);
if ( char_trans_out.find(cur_ch) == char_trans_out.end() ){
char_trans_out[cur_ch] = st;
++st;
}
t_tw.at(i) = char_trans_out[cur_ch];
}
words_out.at(it->first.size()).push_back(t_tw);
}
}
void generateWordInfo(const GridType &grid, std::vector<WordInfo> &winfos_out){
wxLogDebug(wxT("Printing grid: "));
for (size_t i = 0; i < grid.size(); ++i){
wxString st;
for (size_t j = 0; j < grid.at(0).size(); ++j)
st += grid.at(i).at(j);
wxLogDebug(st);
}
size_t cur_ind = 1;
bool exist = false;
auto y_len = grid.at(0).size();
auto x_len = grid.size();
for (size_t j = 0; j < y_len; ++j){
for (size_t i = 0; i < x_len; ++i){
if ( grid.at(i).at(j) == CELL_CLEAR ) {
if ( ((j == 0) || (grid.at(i).at(j - 1) != CELL_CLEAR)) &&
(j !=y_len - 1) )
if ( grid.at(i).at(j+1) == CELL_CLEAR ) {
size_t cur_len = 1;
bool cont = true;
while ( (j + cur_len < y_len) && cont ) {
++cur_len;
if ( grid.at(i).at(j+cur_len-1) != CELL_CLEAR ) {
cont = false;
--cur_len;
}
}
exist = true;
WordInfo t;
t.x = i;
t.y = j;
t.len = cur_len;
t.ind = cur_ind;
t.direct = false;
winfos_out.push_back(t);
}
if ( ((i ==0) || (grid.at(i - 1).at(j) != CELL_CLEAR)) &&
(i != x_len - 1) )
if ( grid.at(i + 1).at(j) == CELL_CLEAR ){
size_t cur_len = 1;
bool cont = true;
while ((i + cur_len < x_len) && cont){
++cur_len;
if (grid.at(i+cur_len-1).at(j) != CELL_CLEAR){
cont = false;
--cur_len;
}
}
exist = true;
WordInfo t;
t.x = i;
t.y = j;
t.len = cur_len;
t.ind = cur_ind;
t.direct = true;
winfos_out.push_back(t);
}
if ( exist ){
exist = false;
++cur_ind;
}
}
}
}
}
/*
template <class T>
uint32_t getWordUniq(const T &w_ind, const T &w_len){
return w_ind + w_len * MAX_WORD_COUNT;
}
*/
bool procCross(
UsedWords used,
const AllWordsType &words,
WorkGridType grid,
const std::vector<WordInfo> &winfos,
const size_t cur_word_ind,
std::vector<TransedWord> &out
){
if (cur_word_ind == winfos.size())
return true;
WordInfo cur_wi = winfos.at(cur_word_ind);
size_t rand_add = rand() % 100000;
size_t cur_len = cur_wi.len;
size_t cur_words_size = words.at(cur_len).size();
for (size_t icw = 0; icw < cur_words_size; ++icw){
if (used.find(getWordUniq(icw,cur_len)) != used.end())
continue;
TransedWord cur_word = words.at(cur_len).at((icw + rand_add) % cur_words_size);
// Показывает, можно ли записать это слово в сетку
bool can_write = true;
if ( cur_wi.direct == false ){
for (size_t j = 0; j < cur_wi.len; ++j)
if ((grid.at(cur_wi.x).at(j + cur_wi.y) != TRANS_CLEAR) &&
(grid.at(cur_wi.x).at(j + cur_wi.y) != cur_word.at(j)))
can_write = false;
} else {
for (size_t j = 0; j < cur_wi.len; ++j)
if ((grid.at(cur_wi.x + j).at(cur_wi.y) != TRANS_CLEAR) &&
(grid.at(cur_wi.x + j).at(cur_wi.y) != cur_word.at(j)))
can_write = false;
}
if (can_write) {
UsedWords t_used(used);
t_used.insert(getWordUniq(icw,cur_len));
WorkGridType t_grid(grid);
if ( cur_wi.direct ){
for (size_t j = 0; j < cur_wi.len; ++j)
t_grid.at(cur_wi.x + j).at(cur_wi.y) = cur_word.at(j);
} else {
for (size_t j = 0; j < cur_wi.len; ++j)
t_grid.at(cur_wi.x).at(j + cur_wi.y) = cur_word.at(j);
}
if (procCross(t_used, words, t_grid, winfos, cur_word_ind + 1, out)){
out.push_back(cur_word);
return true;
}
}
}
return false;
}
void generateCross(const GridType &grid, const AllWordsType &words,
const CharsTransType &trans_type, std::vector<wxString> &words_out){
std::vector<WordInfo> winfos;
generateWordInfo(grid, winfos);
for (size_t i = 0; i < winfos.size(); ++i)
wxLogDebug(wxT("Word at (%d,%d) with len = %d and index = %d and dir = %d"),
winfos.at(i).x,winfos.at(i).y,winfos.at(i).len, winfos.at(i).ind, int(winfos.at(i).direct));
WorkGridType grid_work;
toWorkGridType(grid, grid_work);
UsedWords t_used;
std::vector< TransedWord > words_trans_out;
procCross(t_used, words, grid_work, winfos, 0, words_trans_out);
std::reverse(words_trans_out.begin(), words_trans_out.end());
BackedCharsTransType bctt = getFromCharsTransed(trans_type);
words_out.clear();
words_out.resize(words_trans_out.size());
std::transform(
words_trans_out.begin(),
words_trans_out.end(),
words_out.begin(), [bctt](const TransedWord &tw){
return getFromTransed(tw, bctt);
}
);
}

View File

@@ -11,168 +11,26 @@
#include "crossbasetypes.hpp"
const wxChar CELL_CLEAR = wxT('+');
const wxChar CELL_BORDER = wxT('-');
const TransedChar TRANS_CLEAR = 0;
const TransedChar TRANS_BORDER = 1;
const uint32_t MAX_WORD_COUNT = 262144; // =2^18
extern const wxChar CELL_CLEAR ;
extern const wxChar CELL_BORDER ;
extern const TransedChar TRANS_CLEAR ;
extern const TransedChar TRANS_BORDER ;
extern const uint32_t MAX_WORD_COUNT ;
void readDict(const wxString path, DictType &dict_out){
wxTextFile f;
f.Open(path);
for ( wxString str = f.GetFirstLine(); !f.Eof(); str = f.GetNextLine() ) {
wxString key,val;
int del_ind = str.Index('-');
key = str.Left(del_ind-1);
val = str.Right(str.size() - del_ind - 2);
dict_out[key] = val;
}
f.Close();
};
void readDict(const wxString path, DictType &dict_out);
void readGrid(const wxString path, GridType &grid){
wxTextFile f;
f.Open(path);
wxString str = f.GetFirstLine();
grid.resize(str.size());
for (unsigned int i = 0; i < grid.size(); ++i)
grid.at(i).resize(f.GetLineCount());
wxLogDebug(wxT("Total lines: %d. First line is %s and size = %d"),f.GetLineCount(), str.c_str(),str.size());
unsigned int i = 0;
for ( ; !f.Eof(); str = f.GetNextLine() ) {
wxLogDebug(str);
for (unsigned int j = 0; j < str.size(); ++j)
grid.at(j).at(i) = str.at(j);
++i;
}
wxLogDebug(wxT("Прочитана сетка размером %d x %d"),
static_cast<int>(grid.size()), static_cast<int>(grid.at(0).size()));
f.Close();
}
void readGrid(const wxString path, GridType &grid);
wxString getFromTransed(const TransedWord &tw, const BackedCharsTransType &bchar_trans){
wxString s;
s.resize(tw.size());
for (size_t i = 0; i < tw.size(); ++i){
s[i] = bchar_trans.at(tw.at(i));
}
return s;
}
wxString getFromTransed(const TransedWord &tw, const BackedCharsTransType &bchar_trans);
BackedCharsTransType getFromCharsTransed(const CharsTransType &char_trans){
BackedCharsTransType t;
for (auto it = char_trans.begin(); it != char_trans.end(); ++it)
t[it->second] = it->first;
return t;
}
BackedCharsTransType getFromCharsTransed(const CharsTransType &char_trans);
void toWorkGridType(const GridType &grid, WorkGridType &grid_out){
grid_out.clear();
grid_out.resize(grid.size());
for (size_t i = 0; i < grid.size(); ++i){
grid_out.at(i).resize(grid.at(0).size());
for (size_t j = 0; j < grid.at(0).size(); ++j){
if ( grid.at(i).at(j) == CELL_CLEAR )
grid_out.at(i).at(j) = TRANS_CLEAR;
else
grid_out.at(i).at(j) = TRANS_BORDER;
}
}
}
void toWorkGridType(const GridType &grid, WorkGridType &grid_out);
void generateAllWords(const DictType &dict, AllWordsType &words_out,
CharsTransType &char_trans_out){
words_out.clear();
char_trans_out.clear();
char_trans_out[CELL_CLEAR] = TRANS_CLEAR;
char_trans_out[CELL_BORDER] = TRANS_BORDER;
static_assert(TRANS_CLEAR + 1 == TRANS_BORDER, "TRANS_CLEAR + 1 != TRANS_BORDER");
TransedChar st = TRANS_BORDER + 1;
for (auto it = dict.begin(); it != dict.end(); ++it){
if ( words_out.size() <= it->first.size() )
words_out.resize(it->first.size() + 2);
TransedWord t_tw(it->first.size());
for (size_t i = 0; i < it->first.size(); ++i){
auto cur_ch = it->first.at(i);
if ( char_trans_out.find(cur_ch) == char_trans_out.end() ){
char_trans_out[cur_ch] = st;
++st;
}
t_tw.at(i) = char_trans_out[cur_ch];
}
words_out.at(it->first.size()).push_back(t_tw);
}
}
CharsTransType &char_trans_out);
void generateWordInfo(const GridType &grid, std::vector<WordInfo> &winfos_out){
wxLogDebug(wxT("Printing grid: "));
for (size_t i = 0; i < grid.size(); ++i){
wxString st;
for (size_t j = 0; j < grid.at(0).size(); ++j)
st += grid.at(i).at(j);
wxLogDebug(st);
}
size_t cur_ind = 1;
bool exist = false;
auto y_len = grid.at(0).size();
auto x_len = grid.size();
for (size_t j = 0; j < y_len; ++j){
for (size_t i = 0; i < x_len; ++i){
if ( grid.at(i).at(j) == CELL_CLEAR ) {
if ( ((j == 0) || (grid.at(i).at(j - 1) != CELL_CLEAR)) &&
(j !=y_len - 1) )
if ( grid.at(i).at(j+1) == CELL_CLEAR ) {
size_t cur_len = 1;
bool cont = true;
while ( (j + cur_len < y_len) && cont ) {
++cur_len;
if ( grid.at(i).at(j+cur_len-1) != CELL_CLEAR ) {
cont = false;
--cur_len;
}
}
exist = true;
WordInfo t;
t.x = i;
t.y = j;
t.len = cur_len;
t.ind = cur_ind;
t.direct = false;
winfos_out.push_back(t);
}
if ( ((i ==0) || (grid.at(i - 1).at(j) != CELL_CLEAR)) &&
(i != x_len - 1) )
if ( grid.at(i + 1).at(j) == CELL_CLEAR ){
size_t cur_len = 1;
bool cont = true;
while ((i + cur_len < x_len) && cont){
++cur_len;
if (grid.at(i+cur_len-1).at(j) != CELL_CLEAR){
cont = false;
--cur_len;
}
}
exist = true;
WordInfo t;
t.x = i;
t.y = j;
t.len = cur_len;
t.ind = cur_ind;
t.direct = true;
winfos_out.push_back(t);
}
if ( exist ){
exist = false;
++cur_ind;
}
}
}
}
}
void generateWordInfo(const GridType &grid, std::vector<WordInfo> &winfos_out);
template <class T>
uint32_t getWordUniq(const T &w_ind, const T &w_len){
@@ -186,79 +44,9 @@ bool procCross(
const std::vector<WordInfo> &winfos,
const size_t cur_word_ind,
std::vector<TransedWord> &out
){
if (cur_word_ind == winfos.size())
return true;
WordInfo cur_wi = winfos.at(cur_word_ind);
size_t rand_add = rand() % 100000;
size_t cur_len = cur_wi.len;
size_t cur_words_size = words.at(cur_len).size();
for (size_t icw = 0; icw < cur_words_size; ++icw){
if (used.find(getWordUniq(icw,cur_len)) != used.end())
continue;
TransedWord cur_word = words.at(cur_len).at((icw + rand_add) % cur_words_size);
// Показывает, можно ли записать это слово в сетку
bool can_write = true;
if ( cur_wi.direct == false ){
for (size_t j = 0; j < cur_wi.len; ++j)
if ((grid.at(cur_wi.x).at(j + cur_wi.y) != TRANS_CLEAR) &&
(grid.at(cur_wi.x).at(j + cur_wi.y) != cur_word.at(j)))
can_write = false;
} else {
for (size_t j = 0; j < cur_wi.len; ++j)
if ((grid.at(cur_wi.x + j).at(cur_wi.y) != TRANS_CLEAR) &&
(grid.at(cur_wi.x + j).at(cur_wi.y) != cur_word.at(j)))
can_write = false;
}
if (can_write) {
UsedWords t_used(used);
t_used.insert(getWordUniq(icw,cur_len));
WorkGridType t_grid(grid);
if ( cur_wi.direct ){
for (size_t j = 0; j < cur_wi.len; ++j)
t_grid.at(cur_wi.x + j).at(cur_wi.y) = cur_word.at(j);
} else {
for (size_t j = 0; j < cur_wi.len; ++j)
t_grid.at(cur_wi.x).at(j + cur_wi.y) = cur_word.at(j);
}
if (procCross(t_used, words, t_grid, winfos, cur_word_ind + 1, out)){
out.push_back(cur_word);
return true;
}
}
}
return false;
}
);
void generateCross(const GridType &grid, const AllWordsType &words,
const CharsTransType &trans_type, std::vector<wxString> &words_out){
std::vector<WordInfo> winfos;
generateWordInfo(grid, winfos);
for (size_t i = 0; i < winfos.size(); ++i)
wxLogDebug(wxT("Word at (%d,%d) with len = %d and index = %d and dir = %d"),
winfos.at(i).x,winfos.at(i).y,winfos.at(i).len, winfos.at(i).ind, int(winfos.at(i).direct));
WorkGridType grid_work;
toWorkGridType(grid, grid_work);
UsedWords t_used;
std::vector< TransedWord > words_trans_out;
procCross(t_used, words, grid_work, winfos, 0, words_trans_out);
std::reverse(words_trans_out.begin(), words_trans_out.end());
BackedCharsTransType bctt = getFromCharsTransed(trans_type);
words_out.clear();
words_out.resize(words_trans_out.size());
std::transform(
words_trans_out.begin(),
words_trans_out.end(),
words_out.begin(), [bctt](const TransedWord &tw){
return getFromTransed(tw, bctt);
}
);
}
const CharsTransType &trans_type, std::vector<wxString> &words_out);
#endif // CROSSGEN_HPP