📄 display.cpp
字号:
/*
Sudoku Quick and Easy Solver
Copyright (C) 2005 Suhaib Chishtie
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 2
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "stdafx.h"
#include "Sudoku.h"
#include "Display.h"
#include "MultiSol.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDisplay dialog
CDisplay::CDisplay(CWnd* pParent /*=NULL*/)
: CDialog(CDisplay::IDD, pParent)
{
//{{AFX_DATA_INIT(CDisplay)
//}}AFX_DATA_INIT
}
CDisplay::~CDisplay()
{
unsigned j, k;
for (j=0; j<9; j++){
for (k=0; k<9; k++){
if (pCell[j][k])
delete pCell[j][k];
}
}
for (j=0; j<1000; j++)
if (solutions[j])
free(solutions[j]);
}
void CDisplay::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDisplay)
DDX_Control(pDX, IDC_TIME, m_Time);
DDX_Control(pDX, IDC_COMBO5, m_ComboBox);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDisplay, CDialog)
//{{AFX_MSG_MAP(CDisplay)
ON_BN_CLICKED(IDC_BUTTON_STEP, OnButtonStep)
ON_BN_CLICKED(IDC_BUTTON_FINISH, OnButtonFinish)
ON_BN_CLICKED(IDQUICKSOLVE, OnQuicksolve)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDisplay message handlers
BOOL CDisplay::OnInitDialog()
{
unsigned j, k, startx, x, y, id;
CString str = _T("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}{\\colortbl ;\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green255\\blue0;\\red0\\green0\\blue255;}\\fs17 1\\cf2 2\\cf1 3\n4..\r\\cf3 7\\cf4 8\\cf1 9");
PARAFORMAT pf;
pf.cbSize = sizeof(PARAFORMAT);
pf.dwMask = PFM_ALIGNMENT;
pf.wAlignment = PFA_CENTER;
// CString str = _T("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}{\\colortbl ;\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green255\\blue0;\\red0\\green0\\blue255;}\\fs17 x\\cf1 1\\cf1 2\\cf1 3\\cf1 4\\cf1 5\\cf1 6\\cf1 7\\cf1 8\\cf1 9");
//CString str = _T("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}{\\colortbl ;\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green255\\blue0;\\red0\\green0\\blue255;}\\fs17 x\\cf1 1\\cf1 2\\cf1 3\\cf1 4\\cf1 5\\cf1 6\\cf1 7\\cf1 8\\cf1 9);
CDialog::OnInitDialog();
cellDefaultColor = RGB(230,230,230);
cellHighColor = RGB(255, 230, 230);
hThread = NULL;
QuickSolve = 0;
// TODO: Add extra initialization here
id = 500;
startx = 20;
y = 70;
for (j=0; j<9; j++){
x = startx;
for (k=0; k<9; k++){
RedBits[j][k] = BlueBits[j][k] = 0;
pCell[j][k] = new CRichEditCtrl;
pCell[j][k]->Create(ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
CRect(x, y, x+50, y+50), this, id);
pCell[j][k]->SetParaFormat(pf); // Set the paragraph.
//pCell[j][k]->SetCenter();
pCell[j][k]->SetBackgroundColor(FALSE, cellDefaultColor );
//pCell[j][k]->SetRTF(str);
pCell[j][k]->SetWindowText("");
x += 50+5;
if ( !((k+1)%3) )
x+= 5;
}
y += 50+5;
if ( !((j+1)%3) )
y += 5;
}
msgstr = _T("Orignal puzzle is");
SetMsg();
dump_all();
NoOfSol = 0;
for (j=0; j<1000; j++)
solutions[j] = NULL;
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CDisplay::WaitForButton()
{
//m_BStep.EnableWindow(TRUE);
WaitForSingleObject(hButtonEvent, INFINITE);
ResetEvent(hButtonEvent);
}
void CDisplay::OnButtonStep()
{
// TODO: Add your control notification handler code here
/*if (!FirstTime){
FirstTime = 1;
}else{
//m_BStep.EnableWindow(FALSE);
SetEvent(hButtonEvent);
}*/
solve() ;
}
void CDisplay::OnButtonFinish()
{
// TODO: Add your control notification handler code here
while (solve() > 0)
UpdateWindow();
//solve() ;
}
/***********************************/
/*------------------------------------------------------------*/
unsigned CDisplay::NoOfPoss(unsigned cell)
{
unsigned bitmap, poss=0;
for (bitmap=0x01; bitmap<=0x100; bitmap <<= 1)
poss += ( (cell & bitmap) ? 1 : 0);
return poss;
}
void CDisplay::ErrorMsg(CString msg)
{
AfxMessageBox(msg);
}
void CDisplay::SetMsg()
{
m_ComboBox.AddString( (LPCTSTR) msgstr);
m_ComboBox.SetCurSel(m_ComboBox.GetCount()-1);
/*m_MsgList.AddString( (LPCTSTR) msgstr);
m_MsgList.SetSel((m_MsgList.GetCount()) );*/
}
void CDisplay::SetRowColor(unsigned i)
{
unsigned j;
for (j=0; j<9; j++)
pCell[i][j]->SetBackgroundColor(FALSE, cellHighColor);
}
void CDisplay::SetColColor(unsigned i)
{
unsigned j;
for (j=0; j<9; j++)
pCell[j][i]->SetBackgroundColor(FALSE, cellHighColor);
}
void CDisplay::Set3x3Color(unsigned row, unsigned col)
{
unsigned j, k;
row = row - (row % 3);
col = col - (col % 3);
for (j=row; j<row+3; j++)
for (k=col; k<col+3; k++)
pCell[j][k]->SetBackgroundColor(FALSE, cellHighColor);
}
/*------------------------------------------------------------*/
void CDisplay::dump_cell(unsigned cell)
{
unsigned bm, val;
CString tmp;
msgstr += _T("(");
for (val=1, bm=0x1; val<=9; val++,bm<<=1){
if (cell & bm){
tmp.Format("%d", val);
msgstr += tmp;
}
}
msgstr += ")";
}
/*------------------------------------------------------------
Set the value to the only cell with the posslibitiy
in a row / col / 3x3
------------------------------------------------------------*/
unsigned CDisplay::eliminate_lonely()
{
unsigned ret_val;
if (QuickSolve){
ret_val = eliminate_lonely_row();
ret_val += eliminate_lonely_col();
ret_val += eliminate_lonely_3x3();
return ret_val;
}else{
if (!eliminate_lonely_row())
if(!eliminate_lonely_col())
if(!eliminate_lonely_3x3())
return 0;
}
return 1;
}
/*------------------------------------------------------------
Eliminate cross 3x3 based on possibilities in a row / col
------------------------------------------------------------*/
unsigned CDisplay::eliminate_lonely_cross()
{
unsigned ret_val;
if (QuickSolve){
ret_val = eliminate_lonely_row_cross();
ret_val += eliminate_lonely_col_cross();
ret_val += eliminate_lonely_3x3_cross();
return ret_val;
} else {
if(!eliminate_lonely_row_cross())
if(!eliminate_lonely_col_cross())
if(!eliminate_lonely_3x3_cross())
return 0;
}
return 1;
}
/*------------------------------------------------------------
Eliminate cross 3x3 based on possibilities in a row
------------------------------------------------------------*/
unsigned CDisplay::eliminate_lonely_row_cross()
{
unsigned j, k, i;
unsigned last_k[4], cell[4], RB[4];
unsigned elim=0, possbl, bm, elim_3x3;;
for (j=0; j<9; j++){
for (bm=0x1; bm<=0x100; bm<<=1){
possbl = 0;
for (k=0; k<9; k++){
if (all[j][k] & bm){
last_k[possbl] = k;
cell[possbl] = all[j][k];
RB[possbl] = RedBits[j][k];
possbl++;
if (possbl >= 3)
break;
}
}
if ( (possbl > 1) && (possbl < 3) ){
for (i=1; i<possbl; i++)
if ( (last_k[i]/3) != (last_k[0]/3) )
break;
if (i == possbl){
if ( (elim_3x3=eliminate_3x3_dup(j, last_k[0], bm)) ){
for (i=0; i<possbl; i++){
all[j][last_k[i]] = cell[i];
if (!QuickSolve)
RedBits[j][last_k[i]] = RB[i];
}
if (elim_3x3 > possbl) {
if (!QuickSolve) {
Set3x3Color(j, last_k[0]);
for (i=1; i<possbl; i++)
BlueBits[j][last_k[i]] = bm;
tmpstr.Format("In row %d, eliminated values of ", j);
msgstr = tmpstr;
dump_cell(bm);
tmpstr.Format("from 3x3 at (%d, %d)", j, last_k[0]);
msgstr += tmpstr;
SetMsg();
//pMsg->SetRTF(msgstr);
return 1;
}else
elim++;
}
}
}
}
}
}
return elim;
}
/*------------------------------------------------------------
Eliminate cross 3x3 based on possibilities in a col
------------------------------------------------------------*/
unsigned CDisplay::eliminate_lonely_col_cross()
{
unsigned j, k, i;
unsigned last_j[4], cell[4], RB[4];
unsigned elim=0, possbl, bm, elim_3x3;
for (k=0; k<9; k++){
for (bm=0x1; bm<=0x100; bm<<=1){
possbl = 0;
for (j=0; j<9; j++){
if (all[j][k] & bm){
last_j[possbl] = j;
cell[possbl] = all[j][k];
if (!QuickSolve)
RB[possbl] = RedBits[j][k];
possbl++;
if (possbl >= 3)
break;
}
}
if ( (possbl > 1) && (possbl < 3) ){
for (i=1; i<possbl; i++)
if ( (last_j[i]/3) != (last_j[0]/3) )
break;
if (i == possbl){
if ( (elim_3x3=eliminate_3x3_dup(last_j[0], k, bm)) ){
for (i=0; i<possbl; i++){
all[last_j[i]][k] = cell[i];
if (!QuickSolve)
RedBits[last_j[i]][k] = RB[i];
}
if (elim_3x3 > possbl) {
if (!QuickSolve) {
Set3x3Color(last_j[0], k);
for (i=1; i<possbl; i++)
BlueBits[last_j[i]][k] = bm;
tmpstr.Format("In col %d, eliminated values of ", k);
msgstr = tmpstr;
dump_cell(bm);
tmpstr.Format("from 3x3 at (%d, %d)", last_j[0], k);
msgstr += tmpstr;
SetMsg();
//pMsg->SetRTF(msgstr);
return 1;
}else
elim++;
}
}
}
}
}
}
return elim;
}
/*------------------------------------------------------------
Eliminate cross 3x3 based on possibilities in a col
------------------------------------------------------------*/
unsigned CDisplay::eliminate_lonely_3x3_cross()
{
unsigned row, col, i, j, k;
unsigned last_j[4], last_k[4], cell[4], RB[4];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -