⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shuductrl.cpp

📁 CreateData.cpp 文件是产生9x9矩形的数字算法 ShuDu.java 文件只是为了更好的理解数独一个文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ShuDuCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "ShuDu.h"
#include "ShuDuCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CShuDuCtrl

CShuDuCtrl::CShuDuCtrl()
{
	beInitialized = FALSE;
	GameStarted = FALSE;

	//游戏位置
	GameRect.SetRect(5,5,5+9*(PIC_WIDTH+16),5+9*(PIC_HEIGHT+16));
	NumberLeftRect.SetRect(GameRect.right+10,GameRect.top,
		GameRect.right+10+PIC_WIDTH+16,GameRect.top + 9*(PIC_HEIGHT+16));

	//options
	GameLevel = 1; //NORMAL
	beShowAvNumbers = FALSE;
	beShowDragbAreas = TRUE;
	beShowSelectNum = TRUE;

	InitGameData();
}

CShuDuCtrl::~CShuDuCtrl()
{
	memDC.SelectObject(pOldSave);
	SaveScrBitmap.DeleteObject();
	SmallFont.DeleteObject();
}
//功能函数

void CShuDuCtrl::Initialize()
{
	if(beInitialized) return;

	//生成位图列表
	GamePicList.Create(32,32,ILC_COLOR16|ILC_MASK,9,1);
	CBitmap bmp;
	for(UINT id = IDB_1; id<=IDB_9; id++)
	{
		bmp.DeleteObject();
		if(bmp.LoadBitmap(id))	GamePicList.Add(&bmp,RGB(0,0,0));
	}
	//创建字体
	SmallFont.CreateFont(12,0,0,0,FW_NORMAL,0,0,0,1,
			OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"Arial");

	//生成游戏位图
	CDC* pDC = GetDC();
	memDC.CreateCompatibleDC(pDC);
	GetClientRect(&rectClient);
	SaveScrBitmap.CreateCompatibleBitmap(pDC,rectClient.Width(),rectClient.Height());
				
	pOldSave = memDC.SelectObject(&SaveScrBitmap);
	ReleaseDC(pDC);

	PrepareBitmap();
	beInitialized = TRUE;

}
void CShuDuCtrl::EnableNumbers(BOOL active)
{
	if(beShowAvNumbers == active) return;
	else
	{
		beShowAvNumbers = active;
		Invalidate();
	}
}
void CShuDuCtrl::EnableAreas(BOOL active)
{
	if(beShowDragbAreas == active)return;
	else
	{
		beShowDragbAreas = active;
		Invalidate();
	}
}
void CShuDuCtrl::EnableSelectNum(BOOL active)
{
	if(beShowSelectNum == active)return;
	else
	{
		beShowSelectNum = active;
		Invalidate();
	}
}


void CShuDuCtrl::StartGame(int Data[9][9])
{
	if(!beInitialized)
		Initialize();

	InitGameData();


	//复制数据
	for(int  i=0;i<9;i++)
	{
		for(int j=0;j<9;j++)
		{
			m_GameData[i][j] = Data[i][j];
			MarkData[i][j] = 1;
		}
	}
	//剪除去部分数字
	DeleteSomeNumbers();
	GameStarted = TRUE;
	GameCompleted = FALSE;
	//显示游戏位图
	DrawGameBitmap();

}

void CShuDuCtrl::PrepareBitmap()
{
	CRect rect = rectClient;
	memDC.Rectangle(&rect);
	rect.DeflateRect(1,1,1,1);
	memDC.FillSolidRect(&rect,RGB(192,192,192));

	//画网格以及剩余数字
	DrawGameMetrix(&memDC);
	//画托放跟踪区域
	if(beShowDragbAreas)
	{
		DrawDragAreas(&memDC);
	}
	//画可用数字
	if(beShowAvNumbers)
	{
		DrawAviNumbers(&memDC);
	}

	if(beShowSelectNum)
	{
		DrawSelectNumber(&memDC);
	}
//	DrawStartPos(&memDC);
	//画已经放置好的数字图片
	DrawGameNumbers(&memDC);
	//画托拽图片和目标网格
	DrawDragNumber(&memDC);
}

//画网格以及剩余数字
void CShuDuCtrl::DrawGameMetrix(CDC *pDC)
{
	int w = PIC_WIDTH+16;
	int h = PIC_HEIGHT+16;
	int l = GameRect.left;
	int t = GameRect.top;

	COLORREF clr = RGB(230,230,230);
	pDC->FillSolidRect(&GameRect,RGB(255,255,255));

	CRect rect;
	rect.left = l + 3*w;
	rect.right = rect.left + 3*w;
	rect.top = t ;
	rect.bottom = rect.top+3*h;
	pDC->FillSolidRect(&rect,clr);
	rect.left = l;
	rect.right = rect.left + 3*w;
	rect.top = t + 3*h;
	rect.bottom = rect.top+3*h;
	pDC->FillSolidRect(&rect,clr);
	rect.left = l+6*w;
	rect.right = rect.left + 3*w;
	rect.top = t + 3*h;
	rect.bottom = rect.top+3*h;
	pDC->FillSolidRect(&rect,clr);
	rect.left = l + 3*w;
	rect.right = rect.left + 3*w;
	rect.top = t + 6*h;
	rect.bottom = rect.top+3*h;
	pDC->FillSolidRect(&rect,clr);
	for(int i=0;i<=9;i++)
	{
		pDC->MoveTo(l, t + i*h);
		pDC->LineTo(GameRect.right, t + i*h);
		pDC->MoveTo(l+ i*w, t);
		pDC->LineTo(l+ i*w, GameRect.bottom);
	}

	//检查冲突数字,标记为红色
	if( NeedCheck)
	{
		if(! CheckErrors(pDC))
			NeedCheck = FALSE; //没有错误,下次不再检查
	}

	//left
	pDC->FillSolidRect(&NumberLeftRect,RGB(255,255,255));

	CFont* pOld = pDC->SelectObject(&SmallFont);
	pDC->SetBkMode(TRANSPARENT);

	pDC->MoveTo(NumberLeftRect.left , NumberLeftRect.top);
	pDC->LineTo(NumberLeftRect.left , NumberLeftRect.bottom);
	pDC->LineTo(NumberLeftRect.right, NumberLeftRect.bottom);
	pDC->LineTo(NumberLeftRect.right, NumberLeftRect.top);
	for(i=0;i<9;i++)
	{
		pDC->MoveTo(NumberLeftRect.left, NumberLeftRect.top+i*h);
		pDC->LineTo(NumberLeftRect.left + w, NumberLeftRect.top+ i*h);
		pDC->MoveTo(NumberLeftRect.left + w -12, NumberLeftRect.top+ i*h);
		pDC->LineTo(NumberLeftRect.left + w -12, NumberLeftRect.top+ i*h + 12);
		pDC->LineTo(NumberLeftRect.left + w , NumberLeftRect.top+ i*h + 12);
		if(NumberLeft[i]>0)
		{
			GamePicList.Draw(pDC,i,CPoint(NumberLeftRect.left + 8, NumberLeftRect.top + i*h + 14),ILD_NORMAL);
			CString str;
			str.Format("%d",NumberLeft[i]);
			pDC->TextOut(NumberLeftRect.right -9, NumberLeftRect.top + i*h +1 ,str);
		}
	}
	pDC->SelectObject(pOld);

}

//检查是否有错误
BOOL CShuDuCtrl::CheckErrors(CDC *pDC)
{
	if(!GameStarted)return 0;

	int w = PIC_WIDTH+16;
	int h = PIC_HEIGHT+16;
	int l = GameRect.left;
	int t = GameRect.top;

	CRect rect;

	COLORREF ErrorColor = RGB(255,50,50);
	//检查行
	int Pos1,Pos2,Pos3;
	BOOL FindError = FALSE;
	BOOL ReturnVal = FALSE;
	for(int i=0;i<9;i++)
	{
		for(int j=0;j<9;j++)
		{
			if(m_GameData[i][j] != 0)
			{
				for(int k=j+1;k<9;k++)
				{
					if(m_GameData[i][k] == m_GameData[i][j])
					{
						FindError = TRUE;
						ReturnVal = TRUE;
						Pos1 = i; //行
						Pos2 = j; Pos3 = k;
						break;
					}
				}
			}
			if(FindError)break;
		}
		if(FindError)break;
	}
	if(FindError)
	{
		rect.left = l + Pos2*w;
		rect.right = rect.left + w;
		rect.top = t + Pos1*h;
		rect.bottom = rect.top+h;
		rect.DeflateRect(2,2,2,2);
		pDC->FillSolidRect(&rect,ErrorColor);

		rect.left = l + Pos3*w;
		rect.right = rect.left + w;
		rect.top = t + Pos1*h;
		rect.bottom = rect.top+h;
		rect.DeflateRect(2,2,2,2);
		pDC->FillSolidRect(&rect,ErrorColor);
	}

	//检查列
	FindError = FALSE;
	for(i=0;i<9;i++)
	{
		for(int j=0;j<9;j++)
		{
			if(m_GameData[j][i] != 0)
			{
				for(int k=j+1;k<9;k++)
				{
					if(m_GameData[k][i] == m_GameData[j][i])
					{
						FindError = TRUE;
						ReturnVal = TRUE;
						Pos1 = i; //列
						Pos2 = j; Pos3 = k;
						break;
					}
				}
			}
			if(FindError)break;
		}
		if(FindError)break;
	}
	if(FindError)
	{
		rect.left = l + Pos1*w;
		rect.right = rect.left + w;
		rect.top = t + Pos2*h;
		rect.bottom = rect.top+h;
		rect.DeflateRect(2,2,2,2);
		pDC->FillSolidRect(&rect,ErrorColor);

		rect.left = l + Pos1*w;
		rect.right = rect.left + w;
		rect.top = t + Pos3*h;
		rect.bottom = rect.top+h;
		rect.DeflateRect(2,2,2,2);
		pDC->FillSolidRect(&rect,ErrorColor);
	}
	//检查九宫格
	FindError = FALSE;
	POINT position1, position2;
	int XPos[9], YPos[9];
	for(i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			//3*3的九宫格
			for(int k=0;k<9;k++)
			{
				XPos[k] = -1; //unused
				YPos[k] = -1; //unused
			}
			for(int m=i*3; m<i*3+3; m++)
			{
				for( int n=j*3; n<j*3+3; n++)
				{
					int num = m_GameData[m][n];
					if(num > 0 && num <=9)
					{
						if(XPos[num-1]>=0 || YPos[num-1]>=0) //Find Error
						{
							position1.x = XPos[num-1];
							position1.y = YPos[num-1];
							position2.x = n;
							position2.y = m;
							FindError = TRUE;
							ReturnVal = TRUE;
							break;
						}
						else
						{
							XPos[num-1] = n;
							YPos[num-1] = m;
						}
					}//if
				}//for

				if(FindError)break;
			}
			//Draw it
			if(FindError)
			{
				rect.left = l + position1.x*w;
				rect.right = rect.left + w;
				rect.top = t + position1.y*h;
				rect.bottom = rect.top+h;
				rect.DeflateRect(2,2,2,2);
				pDC->FillSolidRect(&rect,ErrorColor);

				rect.left = l + position2.x*w;
				rect.right = rect.left + w;
				rect.top = t + position2.y*h;
				rect.bottom = rect.top+h;
				rect.DeflateRect(2,2,2,2);
				pDC->FillSolidRect(&rect,ErrorColor);
			}
		}//for
	}//for

	return 	ReturnVal;
}

//画托放的区域
void CShuDuCtrl::DrawDragAreas(CDC* pDC)
{
	if(!GameStarted)return;
	int w = PIC_WIDTH+16;
	int h = PIC_HEIGHT+16;
	int l = GameRect.left;
	int t = GameRect.top;

	if(!beDragging) return;
	if(DragNumber < 1 || DragNumber>9)return;
	if(TargetCol<0 || TargetRow < 0 || 	TargetCol >= 9 || TargetRow >= 9)return;

	COLORREF RowColor = RGB(250,230,250); //浅色
	COLORREF GridColor = RGB(250,250,200);  //黄色
	COLORREF SameColor = RGB(255,0,0);

	CRect drawRect;
	//行,列
	for(int i=0;i<9;i++)
	{
		drawRect.left = l + i * w;
		drawRect.right = drawRect.left + w;
		drawRect.top = t + TargetRow * h;
		drawRect.bottom = drawRect.top + h;
		drawRect.DeflateRect(1,1,1,1);
		pDC->FillSolidRect(&drawRect,RowColor);

		drawRect.left = l + TargetCol * w;
		drawRect.right = drawRect.left + w;
		drawRect.top = t + i * h;
		drawRect.bottom = drawRect.top + h;
		drawRect.DeflateRect(1,1,1,1);
		pDC->FillSolidRect(&drawRect,RowColor);
	}

	//九宫格
	int sx = (TargetCol/3)*3;
	int sy = (TargetRow/3)*3;
	for(i=sy;i<sy+3;i++)
	{
		for(int j=sx; j<sx+3;j++)
		{
			drawRect.left = l + j * w;
			drawRect.right = drawRect.left + w;
			drawRect.top = t + i * h;
			drawRect.bottom = drawRect.top + h;
			drawRect.DeflateRect(1,1,1,1);
			pDC->FillSolidRect(&drawRect,GridColor);
		}
	}
}

//画原始数据的位置
void CShuDuCtrl::DrawStartPos(CDC *pDC)
{
	int w = PIC_WIDTH+16;
	int h = PIC_HEIGHT+16;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -