?? shuductrl.cpp
字號:
// 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 + -