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

📄 godlg.cpp

📁 围棋人机对弈程序源码 此版本目前还只能下布局阶段
💻 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 + -