下载自

http://www.newxing.com/Code/VC/game/1750.html

运行界面如下;

看下类图;

资源;

主对话框;

源码说明:

本人机对弈程序采用了多种搜索算法.以下是本程序主要的类说明:
   1.CEveluation类:估值类,对给定的棋盘进行估值.

2.CMoveGenerator类:走法产生器,对给定的棋盘局面搜索出所有可能的走法.

3.CSearchEngine类:搜索引擎基类.
   4.CNegaMaxEngine类:负极大值法搜索引擎.
   5.CAlphaBetaEngine类:采用了Alpha-Beta剪枝技术的搜索引擎.
   6.CFAlphaBetaEngine类:fail-softalpha-beta搜索引擎.
   7.CHistoryHeuristic类:历史启发类.
   8.CAlphabeta_HHEngine类:带历史启发的Alpha-Beta搜索引擎.
   9.CAspirationSearch类:渴望搜索引擎.
   10.CIDAlphabetaEngine类:迭代深化搜索引擎.
   11.CMTD_fEngine类:MTD(f)搜索引擎.
   12.CTranspositionTable类:置换表.
   13.CAlphaBeta_TTEngine类:加置换表的Alpha-Beta搜索引擎.
   14.CPVS_Engine类:极小窗口搜索引擎.
   15.CNegaScout_TT_HH类:使用了置换表和历史启发的NegaScout搜索引擎.
本程序还具有悔棋,还原功能,还可以记录走法.

那么该源码可以参照写各类搜索引擎;

下面看下其部分代码;主对话框类;

可以看到最多的函数类别是各种菜单的消息映射函数;如下;

BEGIN_MESSAGE_MAP(CChessDlg, CDialog)//{{AFX_MSG_MAP(CChessDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_COMMAND(IDM_SETCHESSBOARD, OnSetchessboard)ON_COMMAND(IDM_SET, OnSet)ON_COMMAND(IDM_ABOUT, OnAbout)ON_COMMAND(IDM_OPENFILE, OnOpenfile)ON_COMMAND(IDM_SAVEFILE, OnSavefile)ON_COMMAND(IDM_SCBOVER, OnScbover)ON_COMMAND(IDM_RPAWN, OnRpawn)ON_COMMAND(IDM_RCANON, OnRcanon)ON_COMMAND(IDM_RCAR, OnRcar)ON_COMMAND(IDM_RHORSE, OnRhorse)ON_COMMAND(IDM_RELEPHANT, OnRelephant)ON_COMMAND(IDM_RBISHOP, OnRbishop)ON_COMMAND(IDM_RKING, OnRking)ON_COMMAND(IDM_BPAWN, OnBpawn)ON_COMMAND(IDM_BCANON, OnBcanon)ON_COMMAND(IDM_BCAR, OnBcar)ON_COMMAND(IDM_BHORSE, OnBhorse)ON_COMMAND(IDM_BELEPHANT, OnBelephant)ON_COMMAND(IDM_BBISHOP, OnBbishop)ON_COMMAND(IDM_BKING, OnBking)ON_COMMAND(IDM_DELETE, OnDelete)ON_WM_RBUTTONDOWN()ON_WM_LBUTTONDBLCLK()ON_WM_CLOSE()ON_COMMAND(IDM_CLEARCB, OnClearcb)ON_COMMAND(IDM_NEWGAME, OnNewgame)ON_BN_CLICKED(IDC_BTNCOMPUTER, OnBtncomputer)ON_BN_CLICKED(IDC_BTNUNDO, OnBtnundo)ON_BN_CLICKED(IDC_BTNREDO, OnBtnredo)ON_LBN_DBLCLK(IDC_LISTCHESSRECORD, OnDblclkListchessrecord)ON_BN_CLICKED(IDC_BTN_STOP, OnBtnStop)ON_LBN_SELCHANGE(IDC_LISTCHESSRECORD, OnSelchangeListchessrecord)ON_COMMAND(IDM_PREVIEW, OnPreview)ON_COMMAND(IDM_PREVIEWOVER, OnPreviewover)ON_COMMAND(IDM_HELP, OnHelp)ON_COMMAND(IDM_INVERSECB, OnInversecb)//}}AFX_MSG_MAP
END_MESSAGE_MAP()

在对话框初始化函数中载入棋盘;

 BITMAP BitMap;m_BoardBmp.LoadBitmap(IDB_CHESSBOARD);m_BoardBmp.GetBitmap(&BitMap); //取BitMap 对象m_nBoardWidth=BitMap.bmWidth;  //棋盘宽度m_nBoardHeight=BitMap.bmHeight;//棋盘高度

如上;棋盘是一个位图;

在对话框构造函数中创建三个重要的用于思考的对象:

 m_pSE=new CNegaMaxEngine;//创建负极大值搜索引擎m_pMG=new CMoveGenerator;//创建走法产生器m_pEvel=new CEveluation; //创建估值核心

鼠标左键弹起时将用户走法压栈;也就是说用户走法用栈存储;

//---------将用户走法压栈---------m_cmBestMove.From.x=m_ptMoveChess.x;m_cmBestMove.From.y=m_ptMoveChess.y;m_cmBestMove.To.x=x;m_cmBestMove.To.y=y;m_cmBestMove.nChessID=m_MoveChess.nChessID;m_umUndoMove.cmChessMove=m_cmBestMove;m_umUndoMove.nChessID=m_byChessBoard[y][x];m_stackUndoMove.push(m_umUndoMove);//--------------------------------

......
typedef struct
{
short nChessID;  //表明是什么棋子
CHESSMANPOS From;//起始位置
CHESSMANPOS To;  //走到什么位置
int Score;       //走法的分数
}CHESSMOVE;

......

CHESSMOVE m_cmBestMove;

CHESSMOVE是一个结构体;

......

stack<UNDOMOVE> m_stackUndoMove;//记录走法的栈,便于悔棋

......

m_stackUndoMove是一个栈;

走法产生器;

根据不同的子判断落点是否符合中国象棋规则;例如象,往四个方向走田字:

void CMoveGenerator::Gen_ElephantMove(BYTE position[10][9],int i,int j,int nPly)
{int x,y;//插入右下方的有效走法x=j+2;y=i+2;if(x<9 && y<10 && IsValidMove(position,j,i,x,y,m_nUserChessColor))AddMove(j,i,x,y,nPly,position[i][j]);//插入右上方的有效走法x=j+2;y=i-2;if(x<9 && y>=0 && IsValidMove(position,j,i,x,y,m_nUserChessColor))AddMove(j,i,x,y,nPly,position[i][j]);//插入左下方的有效走法x=j-2;y=i+2;if(x>=0 && y<10 && IsValidMove(position,j,i,x,y,m_nUserChessColor))AddMove(j,i,x,y,nPly,position[i][j]);//插入左上方的有效走法x=j-2;y=i-2;if(x>=0 && y>=0 && IsValidMove(position,j,i,x,y,m_nUserChessColor))AddMove(j,i,x,y,nPly,position[i][j]);
}

搜索引擎基类;其他搜索引擎继承此类;

//Download by http://www.NewXing.com
// SearchEngine.h: interface for the CSearchEngine class.
//
//#if !defined(AFX_SEARCHENGINE_H__7A7237B9_0908_45D8_B102_94E342B174A5__INCLUDED_)
#define AFX_SEARCHENGINE_H__7A7237B9_0908_45D8_B102_94E342B174A5__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#include "Eveluation.h"
#include "MoveGenerator.h"
#include "GradientProgressCtrl.h"//搜索引擎的基类
class CSearchEngine
{
public:CSearchEngine();virtual ~CSearchEngine();public:virtual SearchAGoodMove(BYTE position[10][9])=0;        //走下一步CHESSMOVE GetBestMove(){return m_cmBestMove;};            //得到最佳走法UNDOMOVE GetUndoMove(){return m_umUndoMove;};           //得到悔棋走法void SetSearchDepth(int nDepth){m_nSearchDepth=nDepth;};//设定最大搜索深度void SetEveluator(CEveluation* pEval){m_pEval=pEval;};  //设定估值引擎void SetMoveGenerator(CMoveGenerator* pMG){m_pMG =pMG;};//设定走法产生器void SetThinkProgress(CGradientProgressCtrl* pThinkProgress){m_pThinkProgress=pThinkProgress;};//设定显示思考进度的进度条void SetUserChessColor(int nUserChessColor){m_nUserChessColor=nUserChessColor;};//设定用户为黑方或红方void UndoChessMove(BYTE position[10][9],CHESSMOVE* move,BYTE nChessID);//悔棋void RedoChessMove(BYTE position[10][9],CHESSMOVE* move);              //还原protected:int IsGameOver(BYTE position[10][9],int nDepth);//判断是否已分胜负BYTE MakeMove(CHESSMOVE* move);                  //根据某一走法产生走了之后的棋盘void UnMakeMove(CHESSMOVE* move,BYTE nChessID); //恢复为走过之前的棋盘   public:int m_nUserChessColor;protected:CGradientProgressCtrl* m_pThinkProgress;//用以显示思考进度的进度条指针BYTE CurPosition[10][9];     //搜索时用于记录当前节点棋盘状态的数组CHESSMOVE m_cmBestMove;         //记录最佳走法UNDOMOVE m_umUndoMove;CMoveGenerator* m_pMG;            //走法产生器CEveluation* m_pEval;            //估值核心int m_nSearchDepth;               //最大搜索深度int m_nMaxDepth;                //当前搜索的最大搜索深度
};#endif // !defined(AFX_SEARCHENGINE_H__7A7237B9_0908_45D8_B102_94E342B174A5__INCLUDED_)

CoolButton类;用于绘制主界面左下角的四个按钮;可以参照写自己的cool 按钮类;

//Download by http://www.NewXing.com
// CoolButton.cpp : implementation file
//#include "stdafx.h"
#include "CoolButton.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CCoolButtonCCoolButton::CCoolButton()
{
#ifdef XS_FLAT_BUTTONm_MouseOnButton=FALSE;
#endifm_hIcon=NULL;m_cyIcon=0;m_cxIcon=0;
}CCoolButton::~CCoolButton()
{
}BEGIN_MESSAGE_MAP(CCoolButton, CButton)//{{AFX_MSG_MAP(CCoolButton)ON_WM_MOUSEMOVE()ON_WM_KILLFOCUS()//}}AFX_MSG_MAP
END_MESSAGE_MAP()/
// CCoolButton message handlersvoid CCoolButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{// TODO: Add your code to draw the specified itemCDC * pDC=CDC::FromHandle(lpDIS->hDC);unsigned int  IsPressed =(lpDIS->itemState&ODS_SELECTED);unsigned int  IsFocused =(lpDIS->itemState&ODS_FOCUS);unsigned int  IsDisabled =(lpDIS->itemState&ODS_DISABLED);CRect itemRect = lpDIS->rcItem;#ifndef XS_FLAT_BUTTONif(IsFocused){CBrush br(RGB(0,0,0));pDC->FrameRect(&itemRect,&br);itemRect.DeflateRect(1,1);}
#endif//Fill with bkcolorCBrush br(GetSysColor(COLOR_BTNFACE));pDC->FillRect(&itemRect,&br);//Is pressed?if(IsPressed){
#ifdef XS_FLAT_BUTTON//浅边界笔CPen penBtnHiLight(PS_SOLID,0,GetSysColor(COLOR_BTNHILIGHT));//阴影笔CPen penBtnShadow(PS_SOLID,0,GetSysColor(COLOR_BTNSHADOW));//绘边界阴影pDC->SelectObject(penBtnShadow);pDC->MoveTo(itemRect.left,itemRect.bottom-1);pDC->LineTo(itemRect.left,itemRect.top);pDC->LineTo(itemRect.right,itemRect.top);//绘浅边界pDC->SelectObject(penBtnHiLight);pDC->MoveTo(itemRect.left,itemRect.bottom-1);pDC->LineTo(itemRect.right-1,itemRect.bottom-1);pDC->LineTo(itemRect.right-1,itemRect.top-1);
#elseCBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW));pDC->FrameRect(&itemRect,&brBtnShadow);
#endif}else//没按下{CPen penBtnHiLight(PS_SOLID,0,GetSysColor(COLOR_BTNHILIGHT));CPen pen3DLight(PS_SOLID,0,GetSysColor(COLOR_3DLIGHT));CPen penBtnShadow(PS_SOLID,0,GetSysColor(COLOR_BTNSHADOW));CPen pen3DDKShadow(PS_SOLID,0,GetSysColor(COLOR_3DDKSHADOW));#ifdef XS_FLAT_BUTTONif(m_MouseOnButton==TRUE){pDC->SelectObject(penBtnHiLight);pDC->MoveTo(itemRect.left,itemRect.bottom-1);pDC->LineTo(itemRect.left,itemRect.top);pDC->LineTo(itemRect.right,itemRect.top);//pDC->SelectObject(penBtnShadow);pDC->MoveTo(itemRect.left,itemRect.bottom-1);pDC->LineTo(itemRect.right-1,itemRect.bottom-1);pDC->LineTo(itemRect.right-1,itemRect.top-1);}
#elsepDC->SelectObject(penBtnHiLight);pDC->MoveTo(itemRect.left,itemRect.bottom-1);pDC->LineTo(itemRect.left,itemRect.top);pDC->LineTo(itemRect.right,itemRect.top);pDC->SelectObject(pen3DLight);pDC->MoveTo(itemRect.left+1,itemRect.bottom-1);pDC->LineTo(itemRect.left+1,itemRect.top+1);pDC->LineTo(itemRect.right,itemRect.top+1);pDC->SelectObject(pen3DDKShadow);pDC->MoveTo(itemRect.left,itemRect.bottom-1);pDC->LineTo(itemRect.right-1,itemRect.bottom-1);pDC->LineTo(itemRect.right-1,itemRect.top-1);pDC->SelectObject(penBtnShadow);pDC->MoveTo(itemRect.left+1,itemRect.bottom-2);pDC->LineTo(itemRect.right-2,itemRect.bottom-2);pDC->LineTo(itemRect.right-2,itemRect.top);
#endif}#ifndef XS_FLAT_BUTTON//if(IsFocused){CRect focusRect = itemRect;focusRect.DeflateRect(3,3);pDC->DrawFocusRect(&focusRect);}
#endif//获取文本CString title;GetWindowText(title);//绘制图标if(m_hIcon!=NULL){CRect iconRect = lpDIS->rcItem;//根据标题是否存在来设置不同的图标位置if(title.IsEmpty()==TRUE){iconRect.left+=((iconRect.Width()-m_cxIcon)/2);}else{iconRect.left+=6;}iconRect.top+=((iconRect.Height()-m_cyIcon)/2);if(IsPressed)iconRect.OffsetRect(1,1);pDC->DrawIcon(iconRect.TopLeft(),m_hIcon);}//绘标题CRect captionRect = lpDIS->rcItem;captionRect.left+=m_cxIcon;if(title.IsEmpty()==FALSE){pDC->SetBkMode(TRANSPARENT);captionRect.OffsetRect(0,-1);if(IsPressed)captionRect.OffsetRect(1,1);if(IsDisabled){captionRect.OffsetRect(1,1);pDC->SetTextColor(GetSysColor(COLOR_BTNHILIGHT));pDC->DrawText(title,-1,captionRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);captionRect.OffsetRect(-1,-1);pDC->SetTextColor(GetSysColor(COLOR_BTNSHADOW));pDC->DrawText(title,-1,captionRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);}else{pDC->DrawText(title,-1,captionRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);}}
}#ifdef XS_FLAT_BUTTON
void CCoolButton::OnMouseMove(UINT nFlags, CPoint point)
{// TODO: Add your message handler code here and/or call defaultCWnd* pWnd;CWnd* pParent;CButton::OnMouseMove(nFlags, point);pWnd=GetActiveWindow();pParent=GetOwner();if((m_MouseOnButton==FALSE)&&(GetCapture()!=this)&&((pWnd!=NULL)&&(pWnd->m_hWnd==pParent->m_hWnd))){SetCapture();SetFocus();m_MouseOnButton=TRUE;Invalidate();UpdateWindow();}else{CRect rc;GetClientRect(&rc);if(!rc.PtInRect(point)){m_MouseOnButton=FALSE;Invalidate();UpdateWindow();ReleaseCapture();}}
}
#endif#ifdef XS_FLAT_BUTTON
void CCoolButton::OnKillFocus(CWnd* pNewWnd)
{CButton::OnKillFocus(pNewWnd);// TODO: Add your message handler code hereif(m_MouseOnButton==TRUE){m_MouseOnButton=FALSE;Invalidate();UpdateWindow();}
}
#endifvoid CCoolButton::SetIcon(HICON hIcon, BYTE cx, BYTE cy)
{m_hIcon  = hIcon;m_cxIcon = cx;  m_cyIcon = cy;
}BOOL CCoolButton::SubclassDlgItem(UINT nID, CWnd *pParent)
{BOOL retValue=CButton::SubclassDlgItem(nID,pParent);LONG bs=::GetWindowLong(m_hWnd,GWL_STYLE);bs|=BS_OWNERDRAW;::SetWindowLong(m_hWnd,GWL_STYLE,bs);return retValue;
}

余下的有空再分析吧;

搜索算法是利用计算机的高性能来有目的的穷举一个问题解空间的部分或所有的可能情况,从而求出问题的解的一种方法。
搜索算法实际上是根据初始条件和扩展规则构造一棵“解答树”并寻找符合目标状态的节点的过程。

Minimax算法又名极小化极大算法,是一种找出失败的最大可能性中的最小值的算法。Minimax算法常用于棋类等由两方较量的游戏和程序,这类程序由两个游戏者轮流,每次执行一个步骤。我们众所周知的五子棋、象棋等都属于这类程序,所以说Minimax算法是基于搜索的博弈算法的基础。该算法是一种零总和算法,即一方要在可选的选项中选择将其优势最大化的选择,而另一方则选择令对手优势最小化的方法。

VC++源码分析 - 中国象棋源码分析相关推荐

  1. C++基础升华:编写的中国象棋源码

    VC++编写的中国象棋源码,支持悔棋功能,而且我觉得这象棋的智商相当高,玩了下竟然每次都输,可能我象棋水平太菜.本游戏源代码开源,在VC6.0下可顺利编译,游戏可选择难易程序,运行界面也挺友好. 项目 ...

  2. 分享网上找到的一个中国象棋源码

    代码的结构挺好,mvc模式的,给大家分享出来 原创不易,转载请注明出处:分享网上找到的一个中国象棋源码 部分代码 Controller.java package com.zuidaima.chess. ...

  3. 中国象棋源码c语言,中国象棋C语言源代码.doc

    中国象棋C语言源代码 *chess.c*/ #include "dos.h" #include "stdio.h" /**/ #define RED 7 #de ...

  4. android象棋源码 ai,中国象棋代码,参考象眼,AI算法相当给力

    [实例简介] 中国象棋代码,参考象眼,AI算法相当给力 [实例截图] [核心代码] chineseChess └── chineseChess ├── AndroidManifest.xml ├── ...

  5. YOLOV5融合SE注意力机制和SwinTransformer模块开发实践的中国象棋检测识别分析系统

    本文紧接前文: <基于yolov5s实践国际象棋目标检测模型开发> <yolov5s融合SPD-Conv用于提升小目标和低分辨率图像检测性能实践五子棋检测识别> 首先来看下最终 ...

  6. 手把手教学!利用C++制作中国象棋,界面MFC内含详细源码!

    VC++中国象棋源码附毕业设计文档资料,源程序编译于VC++6.0或者VS2003版本,二者任选其一都可以,项目文件完整. 总项目展示: 制作过程截图: 代码展示: 效果展示: 这是我要和大家分享的基 ...

  7. PiMuseum-游戏开发入门级教程-中国象棋-Chapter-3

    PiMuseum-游戏开发入门级教程-中国象棋-Chapter-3 导语 游戏引擎 游戏引擎概念及其组件 光影效果 动画组件 物理系统 渲染系统 通信模块 初始化游戏引擎 选择游戏引擎 接入游戏引擎 ...

  8. PiMuseum-游戏开发入门级教程-中国象棋-Chapter-1

    PiMuseum-游戏开发入门级教程-中国象棋-Chapter-1 导语 游戏本质 中国象棋-数据建模 棋盘数据模型 棋子数据模型 棋子-車 棋子-兵/卒 源码链接 导语 <头号玩家>的问 ...

  9. PiMuseum-游戏开发入门级教程-中国象棋-Chapter-2

    PiMuseum-游戏开发入门级教程-中国象棋-Chapter-2 导语 中国象棋-数据建模 棋子数据模型 棋子-马 棋盘数据操作 源码链接 导语 在上一篇系列文章中国象棋 - Chapter 1中阐 ...

最新文章

  1. 使用CV2和Keras OCR从图像中删除文本
  2. 2000行代码实现软渲染引擎
  3. 《AutoCAD全套园林图纸绘制自学手册》一第1章 园林设计基本概念1.1 概述
  4. 运放搭建主动滤波电路
  5. 字符串题目---2判断两个字符串是否为变形词
  6. vector 查找结构体对象_面试大厂回来,我狠补了一把算法和数据结构
  7. 技术实践第三期|HashTag在Redis集群环境下的使用
  8. 在 CodeIgniter 中使用 jQuery 实现 AJAX
  9. oracle 连接数_Oracle多租户数据库资源管理,就这么简单
  10. SolrCloud Hello Word
  11. python定义矩阵
  12. Java Map 集合实现类
  13. @程序员,不会设计项目?有了这个工具,轻轻松松
  14. 如何用Matlab计算相关系数和偏相关系数
  15. outlook qr码在哪里_聚合码微信支付宝申请开通,商家融合收款码实现一码支付,如何申请微信和支付宝合并收款码?聚合码支持信用卡、花呗、微信和支付宝收款...
  16. Python 集合符号
  17. 如何轻松入门西门子 SCL(结构化控制语言) | 附官方教程下载
  18. 【Kind2(基于SMT的自动模型检查器)学习笔记】基本语法
  19. 电脑上个别按键失灵可能原因
  20. Android App 导出APK安装包以及制作App图标讲解及实战(图文解释 简单易懂)

热门文章

  1. Python+opencv 机器视觉 - 基于霍夫圈变换算法检测图像中的圆形实例演示
  2. Python 爬虫篇 - 通过urllib.request伪装成浏览器绕过反爬虫爬取网页所有连接实例演示,urllib2库的安装
  3. C#委托及事件 详解(讲得比较透彻)
  4. stm32中字节对齐问题(__align(n),__packed用法)
  5. ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 A题 Visiting Peking University
  6. iterp2函数--------二维数据内插值
  7. FisherFace 进行人脸分裂
  8. Normal Bayes 分类器过程详解
  9. 第三章:3.6 典型信号傅里叶变换
  10. 支持向量机ModuleNotFoundError: No module named ‘sklearn.datasets.samples_generator‘