diff --git a/GUI.cpp b/GUI.cpp index b62b09b..1bb8b72 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -5659,117 +5659,6 @@ void __fastcall XgGoNextPane(HWND hwnd, BOOL bNext) } } -// パターンを現在の盤面から取得。 -XG_PATDATA XgGetCurrentPat(void) -{ - // コピーする盤を選ぶ。 - XG_Board *pxw = (xg_bSolved && xg_bShowAnswer) ? &xg_solution : &xg_xword; - - // クロスワードの文字列を取得する。 - std::wstring text; - pxw->GetString(text); - - for (auto& ch : text){ - switch (ch) - { - case ZEN_SPACE: - case ZEN_BLACK: - case '\n': - case '\r': - case 0x250F: // ┏ - case 0x2501: // ━ - case 0x2513: // ┓ - case 0x2503: // ┃ - case 0x2517: // ┗ - case 0x251B: // ┛ - break; - default: - ch = ZEN_SPACE; - break; - } - } - - XG_PATDATA pat = { xg_nCols, xg_nRows, text }; - - XgGetPatternData(pat); - return pat; -} - -// パターン編集。 -BOOL XgPatEdit(HWND hwnd, BOOL bAdd) -{ - // パターンを読み込む。 - patterns_t patterns; - if (!XgLoadPatterns(L"PAT.txt", patterns)) - return FALSE; - - // ソートして一意化する。 - XgSortAndUniquePatterns(patterns); - - // 現在の盤面のパターンを取得。 - XG_PATDATA cur_pat = XgGetCurrentPat(); - - // 分断禁。 - if (XgIsPatternDividedByBlocks(cur_pat)) - return FALSE; - - // 反転・転置した盤面も考慮。 - auto transposed = XgTransposePattern(cur_pat); - auto flip_h = XgFlipPatternH(cur_pat); - auto flip_v = XgFlipPatternV(cur_pat); - auto flip_hv = XgFlipPatternH(flip_v); - - if (bAdd) { // 追加。 - patterns.push_back(cur_pat); - patterns.push_back(transposed); - patterns.push_back(flip_h); - patterns.push_back(flip_v); - patterns.push_back(flip_hv); - } else { // 削除。 - patterns_t temp_pats; // 一時的なパターン - for (const auto& pat : patterns) { - if (pat.text == cur_pat.text || - pat.text == transposed.text || - pat.text == flip_h.text || - pat.text == flip_v.text || - pat.text == flip_hv.text) - { - continue; - } - temp_pats.push_back(pat); - } - patterns = std::move(temp_pats); - } - - // 反転・転置を考慮して一意化する。 - patterns_t temp_pats; // 一時的なパターン - for (const auto& pat : patterns) { - if (XgIsPatternDividedByBlocks(pat)) - continue; - auto transposed = XgTransposePattern(pat); - auto flip_h = XgFlipPatternH(pat); - auto flip_v = XgFlipPatternV(pat); - auto flip_hv = XgFlipPatternH(flip_v); - temp_pats.erase( - std::remove_if(temp_pats.begin(), temp_pats.end(), [&](const XG_PATDATA& pat2) noexcept { - return transposed.text == pat2.text || - flip_h.text == pat2.text || - flip_v.text == pat2.text || - flip_hv.text == pat2.text; - }), - temp_pats.end() - ); - temp_pats.push_back(pat); - } - patterns = std::move(temp_pats); - - // ソートして一意化する。 - XgSortAndUniquePatterns(patterns); - - // パターンを書き込む。 - return XgSavePatterns(L"PAT2.txt", patterns); -} - // コマンドを実行する。 void __fastcall MainWnd_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT /*codeNotify*/) { diff --git a/XG_PatternDialog.hpp b/XG_PatternDialog.hpp index 02a4b95..809005f 100644 --- a/XG_PatternDialog.hpp +++ b/XG_PatternDialog.hpp @@ -98,25 +98,8 @@ class XG_PatternDialog : public XG_Dialog if (!XgLoadPatterns(szPath, s_patterns)) return FALSE; - // 反転・転置したパターンも追加する。 - patterns_t temp_pats; - for (auto& pat : s_patterns) { - if (XgIsPatternDividedByBlocks(pat)) - continue; - temp_pats.push_back(pat); - auto transposed = XgTransposePattern(pat); - auto flip_h = XgFlipPatternH(pat); - auto flip_v = XgFlipPatternV(pat); - auto flip_hv = XgFlipPatternH(flip_v); - temp_pats.push_back(transposed); - temp_pats.push_back(flip_h); - temp_pats.push_back(flip_v); - temp_pats.push_back(flip_hv); - } - s_patterns = std::move(temp_pats); - // ソートして一意化する。 - XgSortAndUniquePatterns(s_patterns); + XgSortAndUniquePatterns(s_patterns, TRUE); // 抽出する。 patterns_t pats; diff --git a/XWordGiver.cpp b/XWordGiver.cpp index 01d987d..599c5f3 100644 --- a/XWordGiver.cpp +++ b/XWordGiver.cpp @@ -514,8 +514,47 @@ BOOL XgSavePatterns(LPCWSTR pszFileName, const patterns_t& patterns) } // ソートして一意化する。 -VOID XgSortAndUniquePatterns(patterns_t& patterns) +VOID XgSortAndUniquePatterns(patterns_t& patterns, BOOL bExpand) { + patterns_t temp_pats; // 一時的なパターン + if (bExpand) { + // 反転・転置したパターンも追加する。 + for (const auto& pat : patterns) { + if (XgIsPatternDividedByBlocks(pat)) + continue; + temp_pats.push_back(pat); + auto transposed = XgTransposePattern(pat); + auto flip_h = XgFlipPatternH(pat); + auto flip_v = XgFlipPatternV(pat); + auto flip_hv = XgFlipPatternH(flip_v); + temp_pats.push_back(transposed); + temp_pats.push_back(flip_h); + temp_pats.push_back(flip_v); + temp_pats.push_back(flip_hv); + } + } else { + // 反転・転置を考慮して一意化する。 + for (const auto& pat : patterns) { + if (XgIsPatternDividedByBlocks(pat)) + continue; + auto transposed = XgTransposePattern(pat); + auto flip_h = XgFlipPatternH(pat); + auto flip_v = XgFlipPatternV(pat); + auto flip_hv = XgFlipPatternH(flip_v); + temp_pats.erase( + std::remove_if(temp_pats.begin(), temp_pats.end(), [&](const XG_PATDATA& pat2) noexcept { + return transposed.text == pat2.text || + flip_h.text == pat2.text || + flip_v.text == pat2.text || + flip_hv.text == pat2.text; + }), + temp_pats.end() + ); + temp_pats.push_back(pat); + } + } + patterns = std::move(temp_pats); + // ソートする。 std::sort(patterns.begin(), patterns.end(), [](const XG_PATDATA& a, const XG_PATDATA& b) { if (a.num_columns < b.num_columns) @@ -536,6 +575,96 @@ VOID XgSortAndUniquePatterns(patterns_t& patterns) patterns.erase(last, patterns.end()); } +// パターンを現在の盤面から取得。 +XG_PATDATA XgGetCurrentPat(void) +{ + // コピーする盤を選ぶ。 + XG_Board *pxw = (xg_bSolved && xg_bShowAnswer) ? &xg_solution : &xg_xword; + + // クロスワードの文字列を取得する。 + std::wstring text; + pxw->GetString(text); + + for (auto& ch : text){ + switch (ch) + { + case ZEN_SPACE: + case ZEN_BLACK: + case '\n': + case '\r': + case 0x250F: // ┏ + case 0x2501: // ━ + case 0x2513: // ┓ + case 0x2503: // ┃ + case 0x2517: // ┗ + case 0x251B: // ┛ + break; + default: + ch = ZEN_SPACE; + break; + } + } + + // パターンのデータを扱いやすいよう、加工する。 + XG_PATDATA pat = { xg_nCols, xg_nRows, text }; + XgGetPatternData(pat); + + return pat; +} + +// パターン編集。 +BOOL XgPatEdit(HWND hwnd, BOOL bAdd) +{ + // パターンを読み込む。 + patterns_t patterns; + if (!XgLoadPatterns(L"PAT.txt", patterns)) + return FALSE; + + // ソートして一意化する。 + XgSortAndUniquePatterns(patterns, FALSE); + + // 現在の盤面のパターンを取得。 + XG_PATDATA cur_pat = XgGetCurrentPat(); + + // 分断禁。 + if (XgIsPatternDividedByBlocks(cur_pat)) + return FALSE; + + // 反転・転置した盤面も考慮。 + auto transposed = XgTransposePattern(cur_pat); + auto flip_h = XgFlipPatternH(cur_pat); + auto flip_v = XgFlipPatternV(cur_pat); + auto flip_hv = XgFlipPatternH(flip_v); + + if (bAdd) { // 追加。 + patterns.push_back(cur_pat); + patterns.push_back(transposed); + patterns.push_back(flip_h); + patterns.push_back(flip_v); + patterns.push_back(flip_hv); + } else { // 削除。 + patterns_t temp_pats; // 一時的なパターン + for (const auto& pat : patterns) { + if (pat.text == cur_pat.text || + pat.text == transposed.text || + pat.text == flip_h.text || + pat.text == flip_v.text || + pat.text == flip_hv.text) + { + continue; + } + temp_pats.push_back(pat); + } + patterns = std::move(temp_pats); + } + + // ソートして一意化する。 + XgSortAndUniquePatterns(patterns, FALSE); + + // パターンを書き込む。 + return XgSavePatterns(L"PAT2.txt", patterns); +} + ////////////////////////////////////////////////////////////////////////////// // 候補があるか? diff --git a/XWordGiver.hpp b/XWordGiver.hpp index d4a6441..2af85a2 100644 --- a/XWordGiver.hpp +++ b/XWordGiver.hpp @@ -1492,13 +1492,15 @@ XG_PATDATA XgFlipPatternH(const XG_PATDATA& pat); // パターンを垂直に反転する。 XG_PATDATA XgFlipPatternV(const XG_PATDATA& pat); // ソートして一意化する。 -VOID XgSortAndUniquePatterns(patterns_t& patterns); +VOID XgSortAndUniquePatterns(patterns_t& patterns, BOOL bExpand); // パターンが黒マスルールに適合するか? BOOL __fastcall XgPatternRuleIsOK(const XG_PATDATA& pat); // パターンのデータを扱いやすいよう、加工する。 void XgGetPatternData(XG_PATDATA& pat); // パターンデータを書き込む。 BOOL XgSavePatterns(LPCWSTR pszFileName, const patterns_t& patterns); +// パターン編集。 +BOOL XgPatEdit(HWND hwnd, BOOL bAdd); ////////////////////////////////////////////////////////////////////////////// // ボックス。