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

📄 blackwhitechessdlg.cpp

📁 这是一个简单的黑白棋程序
💻 CPP
字号:
// blackwhitechessDlg.cpp : implementation file
//

#include "stdafx.h"
#include "blackwhitechess.h"
#include "blackwhitechessDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBlackwhitechessDlg dialog

CBlackwhitechessDlg::CBlackwhitechessDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CBlackwhitechessDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBlackwhitechessDlg)
	m_Color = -1;
	m_BlackNum = 0;
	m_WhiteNumber = 0;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CBlackwhitechessDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBlackwhitechessDlg)
	DDX_Radio(pDX, IDC_RADIO1, m_Color);
	DDX_Text(pDX, IDC_EDIT1, m_BlackNum);
	DDX_Text(pDX, IDC_EDIT2, m_WhiteNumber);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBlackwhitechessDlg, CDialog)
	//{{AFX_MSG_MAP(CBlackwhitechessDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_WM_LBUTTONUP()
	ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
	ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBlackwhitechessDlg message handlers

BOOL CBlackwhitechessDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	m_Color = 0 ;
	m_WhiteNumber = 2;
	m_BlackNum = 2;
	UpdateData(false);
	ParaInit();
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CBlackwhitechessDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CBlackwhitechessDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
	CClientDC dc(this); // device context for painting
	CDC *md = new CDC;
	CBitmap *bitmap = new CBitmap;
	md->CreateCompatibleDC(&dc);
	bitmap->LoadBitmap(IDB_BITMAP1);
	md->SelectObject(bitmap);
	dc.BitBlt(0,0,450,450,md,0,0,SRCCOPY);
	delete md;
	delete bitmap;
	int i,j;
	for (i=1;i<9;i++) {
		for (j=1;j<9;j++) {
			if (Result[i][j]==-1) {
			ShowChess(IDB_BITMAP3,i,j);
			}else if (Result[i][j]==1) {
				ShowChess(IDB_BITMAP2,i,j);
			}
		}
	}
	for (i=0;i<AvilNum;i++ ) {
		ShowChess(IDB_BITMAP4,Point[i]);
	}


}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CBlackwhitechessDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CBlackwhitechessDlg::NextPoint(int n,node* no)
{
	int i,j,k,l,nx,ny;
		AvilNum= 0;
		for(i = 1;i < 9;i++)
			for(j = 1; j < 9;j++)
			{
				if(Result[i][j] == n)
				{
					for(k = -1;k <=1 ;k++)
						for(l = -1 ; l <=1  ; l++)
						{
							if(Result[i + k][j + l] ==  - n)
							{						
								nx = i + k;
								ny = j + l;	
								while(nx > 0 && nx < 9 && ny > 0 && ny < 9)
								{
									nx += k;
									ny += l;
									if(Result[nx][ny] == 0)
									{
										no[AvilNum].x = nx;
										no[AvilNum].y = ny;
										AvilNum ++;
										break;
									}
									else if(Result[nx][ny] == n)
										break;
								}
							}
						}
				}
			}
}

void CBlackwhitechessDlg::JudgeWinner(){
	CString msg;
	if(m_WhiteNumber > m_BlackNum)
	{
		msg.Format("白棋获胜!\n黑:%d\t白:%d",m_BlackNum,m_WhiteNumber);
		//msg = "黑棋获胜!你太厉害了!\n黑:"+m_WhiteNumber+"\n白:"+m_BlackNum;
		MessageBox(msg,"结果显示");
	}
	else if(m_BlackNum > m_WhiteNumber)
	{
		msg.Format("黑棋获胜!\n黑:%d\t白:%d",m_BlackNum,m_WhiteNumber);
		MessageBox(msg,"结果显示");
	}
	else if(m_BlackNum == m_WhiteNumber)
	{
		msg.Format("平局!\n黑:%d\t白:%d",m_BlackNum,m_WhiteNumber);
		MessageBox(msg,"结果显示");
	}
}

void CBlackwhitechessDlg::CountNum(){
	int i,j;
	m_WhiteNumber = 0;
	m_BlackNum = 0;
	for(i = 1;i < 9;i++)
		for(j = 1;j < 9;j++)
		{
			if(Result[i][j] == 1)
				m_WhiteNumber ++;
			else if(Result[i][j] == -1)
				m_BlackNum ++;
		}	
}

void CBlackwhitechessDlg::Reverse(int n,int x,int y)
{
	int i,j;
	int nx,ny;
	Result[x][y] = n;
	for(i = -1;i <= 1;i++)
		for(j = -1 ; j <= 1 ; j++)
		{
			if(Result[x + i][y + j] == - n)
			{						
				nx = x + i;
				ny = y + j;	
				while(nx > 0 && nx < 9 && ny > 0 && ny < 9)
				{
					nx += i;
					ny += j;
					if(Result[nx][ny] == n)
					{
						while(nx != x|| ny != y)
						{
							Result[nx][ny] = n;
							nx -= i;
							ny -= j;
						}
						break;
					}
					else if(Result[nx][ny] == 0)
						break;
				}
			}
		}
}

void CBlackwhitechessDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	memcpy(Result,Last,sizeof(int)*100);
	NextPoint(Color,Point);
	CountNum();
	this->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);	
	Invalidate(false);
	UpdateWindow();
	UpdateData(false);

}

void CBlackwhitechessDlg::OnButton2() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);
	ParaInit();
	Invalidate(false);
	UpdateWindow();
	UpdateData(false);
}
BOOL CBlackwhitechessDlg::Available(int x,int y){
	for (int i=0;i< AvilNum;i++) {
		if (Point[i].x == x&&Point[i].y == y) {
			return true;
		}
	}
	return false;
}

void CBlackwhitechessDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int x =(point.x-16)/50+1;
	int y= (point.y-13)/50+1;
	if (Available(x,y)) {
		memcpy(Last,Result,sizeof(int)*100);
		this->GetDlgItem(IDC_BUTTON1)->EnableWindow(true);	
		Reverse(Color,x,y);
		if ( Color== 1) {
			ShowChess(IDB_BITMAP2,x,y);
		}else{
			ShowChess(IDB_BITMAP3,x,y);
		}
		AvilNum =0;
		CountNum();
		UpdateData(false);
		Invalidate(false);
		UpdateWindow();
		if((m_BlackNum + m_WhiteNumber) == 64)
		{
			JudgeWinner();
		}else if((m_BlackNum + m_WhiteNumber) < 64)
			ComputerPlay();
	}else if(x<9&&x>0&&y<9&&y>0) {
		MessageBox("对不起,不能在这个地方落子!");
	}
     CDialog::OnLButtonUp(nFlags, point);
}

int CBlackwhitechessDlg::Search(int Cl,int Depth,int Alpha,int Beta){

	int i,BestValue;
	int tResult[10][10];
	int value;
	node AviPlc[40];
	int AviNum = AvilNum;
	int temp;
	NextPoint(Cl,AviPlc);
	if (AvilNum == 0||Depth ==0) {
		if (Color == 1) {
			return(2*AvilNum+m_WhiteNumber);
		}else
			return(2*AvilNum+m_BlackNum);
	}
	BestValue = INT_MIN;
	for (i=0;i<AvilNum;i++) {
		temp = AvilNum;
		memcpy(tResult,Result,sizeof(int)*100);
		Reverse(Cl,AviPlc[i].x,AviPlc[i].y);
		if (BestValue>Alpha) {
			Alpha = BestValue;
		}
		value = -Search(-Cl,Depth -1,-Beta,-Alpha);
		if (Depth == 1) {
			value += 4*PositionValue[AviPlc[i].x][AviPlc[i].y] ;
		}
		if (value > BestValue) {
			BestValue = value;
			if (Depth == MaxDepth) {
				BestPoint.x = AviPlc[i].x;
				BestPoint.y = AviPlc[i].y;
			}
		}
		memcpy(Result,tResult,sizeof(int)*100);
		AvilNum = temp;
		if (BestValue>Beta) {
			break;
		}
	}
	AvilNum = AviNum;
	return BestValue;
}

void CBlackwhitechessDlg::ParaInit(){
	UpdateData(true);
	int i,j;
	for (i=1;i<9;i++) {
		for (j=1;j<9;j++) {
			Result[i][j] = 0;
		}
	}
	if (m_Color == 0) {
		Color = -1;
		Result[4][4]=Result[5][5] = 1;
		Result[5][4] = Result [4][5] =-1;
		m_WhiteNumber = 2;
		m_BlackNum = 2;
	}else{
		Color = 1;
		Result[5][5] = 1;
		Result[5][4] = Result [4][5] =-1;
		Result[4][4] = Result [4][3] =-1;
		m_WhiteNumber = 1;
		m_BlackNum = 3;
	}
	NextPoint(Color,Point);
	MaxDepth = 6;
	Avilhuman = Avilcpu = true;
	for (i=1;i<5;i++) {
		for (j=1;j<5;j++) {
			PositionValue[i][j] = 15 - 2*(i + j - 2*(i%2 + j%2));
			PositionValue[i][9-j] =15 - 2*(i + j - 2*(i%2 + j%2));
			PositionValue[9-i][j] =15 - 2*(i + j - 2*(i%2 + j%2));
			PositionValue[9-i][9-j] =15 - 2*(i + j - 2*(i%2 + j%2));
		}
	}
}
void CBlackwhitechessDlg::Reverse(int n,node no){
	Reverse(n,no.x,no.y);
}
BOOL CBlackwhitechessDlg::ComputerPlay(){

		BestPoint.x = -1;
		BestPoint.y = -1;
		Search(-Color,MaxDepth,INT_MIN,INT_MAX);
		if (BestPoint.x == -1||BestPoint.y == -1) {
			MessageBox("计算机无子可下,轮到你下棋!");
			Avilcpu = false;
			if (!Avilhuman) {
				JudgeWinner();
				return false;
			}else{
				HumanPlay();
				return false;
			}
		}
		else 
		{
			Avilcpu = true;
			AvilNum = 0;
			Reverse(-Color,BestPoint);
			NextPoint(Color,Point);
			CountNum();
			UpdateData(false);
			if (Color ==1) {
				ShowChess(IDB_BITMAP3,BestPoint);
			}else
				ShowChess(IDB_BITMAP2,BestPoint);
			Invalidate(false);
			UpdateWindow();	
			if((m_BlackNum + m_WhiteNumber) == 64)
			{
				JudgeWinner();
				return true;
			}
		}
		return true;
}

BOOL CBlackwhitechessDlg::HumanPlay(){
	AvilNum = 0;
	NextPoint(Color,Point);
	if (AvilNum == 0) {
		MessageBox("你无子可下,轮到计算机下棋!");
		Avilhuman = false;
		if (!Avilcpu) {
			JudgeWinner();
			return false;
		}else{
			ComputerPlay();
		}
	}else{
		Avilhuman = true;
	}
	Invalidate(false);
	UpdateWindow();
	return Avilhuman;
}

void CBlackwhitechessDlg::ShowChess(UINT num,int x,int y){
	CClientDC dc(this); // device context for painting
	CDC *md = new CDC;
	CBitmap *bitmap = new CBitmap;
	md->CreateCompatibleDC(&dc);
	bitmap->LoadBitmap(num);
	md->SelectObject(bitmap);
	dc.BitBlt(x*50-29,y*50-32,50,50,md,0,0,SRCCOPY);
	delete md;
	delete bitmap;
}

void CBlackwhitechessDlg::ShowChess(UINT num,node no){
	ShowChess(num,no.x,no.y);
}

void CBlackwhitechessDlg::OnRadio1() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);
	this->OnButton2();
}

void CBlackwhitechessDlg::OnRadio2() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);
	this->OnButton2();
}

⌨️ 快捷键说明

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