📄 godlg.cpp
字号:
#include "stdafx.h"
#include "Sieger.h"
#include "GoDlg.h"
#include "Go.h"
static UINT WM_COMPUTER_DONE=RegisterWindowMessage("User");
HANDLE hComputerInvolve;
HANDLE hComputerDo;
CGo* pBoard;
UINT ComputerThink(LPVOID param)
{
while(WaitForSingleObject(hComputerInvolve,0)==WAIT_OBJECT_0)
{
WaitForSingleObject(hComputerDo,INFINITE);
if(WaitForSingleObject(hComputerInvolve,0)!=WAIT_OBJECT_0)return 0;
int n=pBoard->ComputerChoice();
ResetEvent(hComputerDo);
::PostMessage((HWND)param,WM_COMPUTER_DONE,n,0);
}
return 0;
}
IMPLEMENT_DYNAMIC(CGoDlg, CDialog)
BEGIN_MESSAGE_MAP(CGoDlg, CDialog)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_BN_CLICKED(IDC_BUTTON_Black, OnBnClickedButtonBlack)
ON_BN_CLICKED(IDC_BUTTON_White, OnBnClickedButtonWhite)
ON_BN_CLICKED(IDC_Start, OnBnClickedStart)
ON_BN_CLICKED(IDC_ReStart, OnBnClickedRestart)
ON_BN_CLICKED(IDC_BUTTON_UNDO, OnBnClickedButtonUndo)
ON_BN_CLICKED(IDC_BUTTON_SAVE, OnBnClickedButtonSave)
ON_BN_CLICKED(IDC_BUTTON_LOAD, OnBnClickedButtonLoad)
ON_REGISTERED_MESSAGE(WM_COMPUTER_DONE,OnComputerDone)
END_MESSAGE_MAP()
BOOL CGoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_pBlackBrush = new CBrush;
m_pWhiteBrush = new CBrush;
m_pBlackBrush->CreateSolidBrush(0);
m_pWhiteBrush->CreateSolidBrush(0xffffff);
m_nRoles[BLACK]=HUMAN;
m_nRoles[WHITE]=HUMAN;
m_nStart=0;
m_LoadFile="";
hComputerInvolve=CreateEvent(NULL, TRUE, FALSE, NULL);
hComputerDo=CreateEvent(NULL, TRUE, FALSE, NULL);
ResetEvent(hComputerInvolve);
ResetEvent(hComputerDo);
return TRUE;
}
void CGoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BUTTON_Black, m_Button_Black);
DDX_Control(pDX, IDC_BUTTON_White, m_Button_White);
DDX_Control(pDX, IDC_Start, m_Button_Start);
DDX_Control(pDX, IDC_ReStart, m_Button_ReStart);
DDX_Control(pDX, IDC_BUTTON_UNDO, m_Button_Undo);
DDX_Control(pDX, IDC_BUTTON_SAVE, m_Button_Save);
DDX_Control(pDX, IDC_BUTTON_LOAD, m_Button_Load);
}
CGoDlg::~CGoDlg()
{
delete m_pBlackBrush;
delete m_pWhiteBrush;
CloseHandle(hComputerInvolve);
CloseHandle(hComputerDo);
}
int CGoDlg::GetTurn()
{
if(!m_nStart)return CLOSED;
int i=Board.nSteps%2;
if(m_nRoles[i])return COMPUTER;
else return HUMAN;
}
void CGoDlg::OnPaint()
{
//创建内存作图环境
CPaintDC dc(this);
CDC MemDC;
MemDC.CreateCompatibleDC(NULL);
CBitmap MemBitmap;
MemBitmap.CreateCompatibleBitmap(&dc,400,400);
MemDC.SelectObject(&MemBitmap);
//画蓝色背景
MemDC.FillSolidRect(0,0,400,400,0xff9999);
//画棋盘边框
CRect rect(19,19,382,382);
MemDC.FrameRect(&rect,m_pBlackBrush);
//画棋盘纵横线
for(int i=1;i<20;i++)
{
MemDC.MoveTo(20,i*20);
MemDC.LineTo(380,i*20);
MemDC.MoveTo(i*20,20);
MemDC.LineTo(i*20,380);
}
//画星
MemDC.SelectObject(m_pBlackBrush);
for(i=0;i<9;i++)
{
MemDC.Ellipse(i%3*120+75,i/3*120+75,i%3*120+85,i/3*120+85);
}
//画棋子
for(i=0;i<361;i++)
{
if(Board.pHolder[i])
{
if(Board.pHolder[i]->nColor==BLACK)MemDC.SelectObject(m_pBlackBrush);
else MemDC.SelectObject(m_pWhiteBrush);
MemDC.Ellipse(i%19*20+10,i/19*20+10,i%19*20+30,i/19*20+30);
}
}
//在最后一步棋上画标记
if(Board.nSteps)
{
int n=Board.nSteps-1;
i=Board.StepList[n];
if(n%2)MemDC.SelectObject(m_pBlackBrush);
else MemDC.SelectObject(m_pWhiteBrush);
MemDC.Ellipse(i%19*20+15,i/19*20+15,i%19*20+25,i/19*20+25);
}
//拷贝到显示设备并清除内存草稿
dc.BitBlt(0,0,400,400,&MemDC,0,0,SRCCOPY);
MemBitmap.DeleteObject();
MemDC.DeleteDC();
if(m_nRoles[0])m_Button_Black.SetWindowText(_T("机"));
else m_Button_Black.SetWindowText(_T("人"));
if(m_nRoles[1])m_Button_White.SetWindowText(_T("机"));
else m_Button_White.SetWindowText(_T("人"));
if(m_nStart)m_Button_Start.SetWindowText(_T("暂停"));
else m_Button_Start.SetWindowText(_T("开始"));
}
void CGoDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
//判断是否轮到用户下子
if(GetTurn()!=HUMAN)return;
//判断鼠标是否点击在落子区
if((point.x<10)||(point.x>=390)||(point.y<10)||(point.y>=390))return;
//计算鼠标点击位在棋盘上的位置
int x=(point.x-20)/20;
int y=(point.y-20)/20;
if((point.x>20)&&(point.x%20>10))x++;
if((point.y>20)&&(point.y%20>10))y++;
int n=y*19+x;
//若用户下子合法,通知程序重绘棋盘并下子
if(!Board.CanGo(n))return;
Board.Go(n);
Invalidate(FALSE);
//判断是否轮到并通知程序下下一步
if(GetTurn()==COMPUTER)SetEvent(hComputerDo);
else ResetEvent(hComputerDo);
CDialog::OnLButtonDown(nFlags, point);
}
void CGoDlg::OnBnClickedButtonBlack()
{
m_nRoles[BLACK]=1-m_nRoles[BLACK];
Invalidate(FALSE);
}
void CGoDlg::OnBnClickedButtonWhite()
{
m_nRoles[WHITE]=1-m_nRoles[WHITE];
Invalidate(FALSE);
}
void CGoDlg::OnBnClickedStart()
{
m_nStart=1-m_nStart;
if(m_nStart)
{
m_Button_Black.EnableWindow(FALSE);
m_Button_White.EnableWindow(FALSE);
m_Button_ReStart.EnableWindow(FALSE);
m_Button_Undo.EnableWindow(FALSE);
m_Button_Save.EnableWindow(FALSE);
m_Button_Load.EnableWindow(FALSE);
if(m_nRoles[BLACK]||m_nRoles[WHITE])
{
pBoard=&Board;
SetEvent(hComputerInvolve);
HWND hWnd=GetSafeHwnd();
AfxBeginThread(ComputerThink,hWnd);
if(GetTurn()==COMPUTER)SetEvent(hComputerDo);
else ResetEvent(hComputerDo);
}
}
else
{
pBoard=NULL;
m_Button_Black.EnableWindow(TRUE);
m_Button_White.EnableWindow(TRUE);
m_Button_ReStart.EnableWindow(TRUE);
m_Button_Undo.EnableWindow(TRUE);
m_Button_Save.EnableWindow(TRUE);
m_Button_Load.EnableWindow(TRUE);
ResetEvent(hComputerInvolve);
SetEvent(hComputerDo);
}
Invalidate(FALSE);
}
void CGoDlg::OnBnClickedRestart()
{
Board.Reset();
Invalidate(FALSE);
}
void CGoDlg::OnBnClickedButtonUndo()
{
int n=Board.nSteps-2;
Board.Reset();
for(int i=0;i<n;i++)
{
Board.Go(Board.StepList[i]);
}
Invalidate(FALSE);
}
void CGoDlg::OnBnClickedButtonSave()
{
CString outfile;
CFileDialog* pFileDlg=new CFileDialog(FALSE,"go",m_LoadFile,OFN_OVERWRITEPROMPT,"Go Files|*.go||",this);
INT_PTR nResp=pFileDlg->DoModal();
if(nResp==IDOK)outfile=pFileDlg->GetPathName();
else{delete pFileDlg;return;}
delete pFileDlg;
CFile* pOutFile=new CFile();
if(!pOutFile->Open(outfile,CFile::modeCreate|CFile::modeWrite))
{
AfxMessageBox("文件无法打开");
delete pOutFile;
return;
}
pOutFile->SetLength(0);
pOutFile->SeekToBegin();
char ch[2];
for(int i=0;i<Board.nSteps;i++)
{
ch[0]=Board.StepList[i]%19+'A';
ch[1]=Board.StepList[i]/19+'A';
pOutFile->Write(ch,2);
}
pOutFile->Close();
delete pOutFile;
}
void CGoDlg::OnBnClickedButtonLoad()
{
CFileDialog* pFileDlg=new CFileDialog(TRUE,"go",NULL,OFN_HIDEREADONLY,"Go Files|*.go||",this);
INT_PTR nResp=pFileDlg->DoModal();
if(nResp==IDOK)m_LoadFile=pFileDlg->GetPathName();
else{delete pFileDlg;return;}
delete pFileDlg;
CFile* pInFile=new CFile();
if(!pInFile->Open(m_LoadFile,CFile::modeRead))
{
AfxMessageBox("文件无法打开");
delete pInFile;
return;
}
pInFile->SeekToBegin();
Board.Reset();
char ch[2];
UINT num;
do
{
num=pInFile->Read(ch,2);
Board.Go(int(ch[1]-'A')*19+int(ch[0]-'A'));
}
while(num!=0);
pInFile->Close();
delete pInFile;
Invalidate(FALSE);
}
LRESULT CGoDlg::OnComputerDone(WPARAM wParam, LPARAM lParam)
{
ResetEvent(hComputerDo);
int n=UINT(wParam);
if(n<361)
{
Board.Go(n);
if(GetTurn()==COMPUTER)SetEvent(hComputerDo);
}
else
{
m_nStart=0;
m_Button_Black.EnableWindow(TRUE);
m_Button_White.EnableWindow(TRUE);
m_Button_ReStart.EnableWindow(TRUE);
m_Button_Undo.EnableWindow(TRUE);
m_Button_Save.EnableWindow(TRUE);
m_Button_Load.EnableWindow(TRUE);
ResetEvent(hComputerInvolve);
ResetEvent(hComputerDo);
}
Invalidate(FALSE);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -