VC版八皇后
一. 功能需求:
1. 可以让玩家摆棋,并让电脑推断是否正确
2. 能让电脑给予帮助(给出全部可能结果)
3. 实现悔棋功能
4. 实现重置功能
5. 加入点按键音效果更佳
二. 整体设计计:
1. 核心算法:
递归实现(回溯算法):
思路:按行分别安排皇后(Q),Q数目眼下为8.
Q1从第一行第一列開始到最后一列,先放在第一列;
Q2从第二行第一列到最后一列,每次都检查冲突,不冲突才干够落子;
依次尝试Qm… 假设Qm没有可摆放的位置,则返回Qm-1,同一时候Qm-1放弃刚才的位置;
当Q1尝试过首行的全部列的位置后,算法结束。
统计递归并罗列全部解法。
2. 详细功能实现的设计:
(1) 电脑推断玩家的摆法正确与否:
对每个棋子向右、下、右下和左下四个方向检查,若遇到不论什么一个方向存在棋子,则返回错误,若八个棋子都遍历完后都不冲突,则返回正确。
(2) 电脑给予帮助:
调用核心算法,遍历全部结果,并显示结果
(3) 实现悔棋:
用栈来存储每一个棋子的位置,以实现悔棋。
(4) 实现重置:
将二维数组赋值为空,并显示。
(5) 加音乐:
使用sndPlaySound(lpSound1,SND_ASYNC|SND_MEMORY)函数播放音乐。
三. 具体设计:
1. 电脑推断玩家的摆法正确与否:
//-------------电脑检查玩家摆放是否正确----------------
bool CQueenDlg::Check()
{
intcolumn = -1;
introw = -1;
intcount = 0;
for(int i = 0; i < 8; i++)
{
for(int j = 0 ; j < 8; j++)
{
if(Image[i][j]== 1 || Image[i][j] == 2)//若找到皇后,向左、下、右下、左下扫描看是否有与其在同一条线上的皇后
{
count++;
if(column== j || row == i) //若右或下方是否有与其在一条斜线上的棋子
{
returnfalse;
}
column= j;
row= i;
intm = i+1;
intn = j+1;
while(m< 8 && n < 8) //检查其右下方是否有与其在一条斜线上的棋子
{
if(Image[m][n]== 1 || Image[m][n] == 2)
{
returnfalse;
}
m++;
n++;
}
m= i+1;
n= j-1;
while(m < 8 && n >-1)//检查其左下方是否有与其在一条斜线上的棋子
{
if(Image[m][n]== 1 || Image[m][n] == 2)
{
returnfalse;
}
m++;
n--;
}
}
}
}
if(count!= 8)
{returnfalse;}
returntrue;
}
2. 电脑给予帮助:
//------------------存储摆放的结果.----------------
voidCQueenDlg::StoreAllResult()
{
inti,j;
// InitImage();
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(line[i]==j)
{
if(Image[j][i]== 0)
{
StoreImage[answer][j][i] = 1;
}
elseif(Image[j][i] == -1)
{
StoreImage[answer][j][i] = 2;
}
}
}
}
answer++;
}
//-----------推断摆放的位置是否正确,不对返回1,正确返回0.-------------
int CQueenDlg::Judge(int t)
{
inti,n=0;
for(i=0;i<t;i++)
{
if(line[i]==line[t])
{
n=1;
break;
}
if(line[i]+i==line[t]+t)
{
n=1;
break;
}
if(line[i]-i==line[t]-t)
{
n=1;
break;
}
}
returnn;
}
//--------------主要控制函数.----------------
void CQueenDlg::control(intn)
{
intt=8;
for(line[n]=0;line[n]<t;line[n]++)
{
if(Judge(n))
continue;
else
{
if(n!=7)
control(n+1);
else
{
StoreAllResult();
}
}
}
}
3. 实现悔棋:
//---------悔棋(消息响应函数)-----------------
void CQueenDlg::OnBtnReback()
{
//TODO: Add your control notification handler code here
introw,column;
if(!IsComputerHelp)
{
if(queen!= 0)
{
queen--;
row= storeStep[queen].row;//存放每一个棋子的位置(即列号)
column= storeStep[queen].column;
if(Image[row][column]== 1) //原皇后背景为白色,设置为白色
{
Image[row][column]= 0;
}
elseif(Image[row][column] == 2) //原皇后背景为黑色,设置为黑色
{
Image[row][column]= -1;
}
Invalidate(FALSE);
}
}
}
4. 实现重置:
//-----------初始化界面的二维数组---------------
void CQueenDlg::InitImage()
{
intm = 0;
for(inti = 0; i < 8 ; i++)
{
for(intj = 0; j < 8; j++)
{
if(m%2== 0)
{
Image[i][j]= 0;
}
else
{
Image[i][j]= -1;
}
m++;
}
m++;
}
}
5. 加音乐:
void CQueenDlg::PlayMusic(int Id)
{
////////////加按键音
switch(Id)
{
case1:res=FindResource(::AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDR_WAVE_PUTSTONE),"WAVE");break;//落子音乐
case 2:res=FindResource(::AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDR_WAVE_ERROR),"WAVE");break;//不能落子音乐
case3:res=FindResource(::AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDR_WAVE_WIN),"WAVE");break; //玩家胜利音乐
case4:res=FindResource(::AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDR_WAVE_LOSE),"WAVE");break; //玩家失败音乐
default:break;
}
hSound1=LoadResource(::AfxGetApp()->m_hInstance,res);
lpSound1=(LPSTR)LockResource(hSound1);
sndPlaySound(lpSound1,SND_ASYNC|SND_MEMORY);
}
四. 測试与实现:
五. 总结:
通过对八皇后问题的求解,使我对递归算法有了更进一步的了解,类似八皇后及迷宫这种问题都能够用回溯算法来解决。这些都是数据结构与算法中重要的算法,当时学的不是非常好,通过不断地练习才逐步掌握了。
本程序的长处:实现了八皇后的基本功能,实现了悔棋功能,界面友好,有音乐提示等。
本程序的缺点:仅仅实现了八皇后,而没能实现五皇后、六皇后等其它格式,提示与找出玩家错误不足等。
VC版八皇后的更多相关文章
- 【算法导论】八皇后问题的算法实现(C、MATLAB、Python版)
八皇后问题是一道经典的回溯问题.问题描述如下:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8*8个方格),使它们谁也不能被吃掉? 看到这个问题,最容易想 ...
- 算法学习 八皇后问题的递归实现 java版 回溯思想
1.问题描述 八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或 ...
- Python 八皇后问题
八皇后问题描述:在一个8✖️8的棋盘上,任意摆放8个棋子,要求任意两个棋子不能在同一行,同一列,同一斜线上,问有多少种解法. 规则分析: 任意两个棋子不能在同一行比较好办,设置一个队列,队列里的每个元 ...
- 【算法】八皇后问题 Python实现
[八皇后问题] 问题: 国际象棋棋盘是8 * 8的方格,每个方格里放一个棋子.皇后这种棋子可以攻击同一行或者同一列或者斜线(左上左下右上右下四个方向)上的棋子.在一个棋盘上如果要放八个皇后,使得她们互 ...
- LeetCode 回溯法 别人的小结 八皇后 递归
#include <iostream> #include <algorithm> #include <iterator> #include <vector&g ...
- Python解决八皇后问题的代码【解读】
八皇后问题 来自于西方象棋(现在叫 国际象棋,英文chess),详情可见百度百科. 在西方象棋中,有一种叫做皇后的棋子,在棋盘上,如果双方的皇后在同一行.同一列或同一斜线上,就会互相攻击. 八皇后问题 ...
- 八皇后问题Python实现
八皇后问题描述 问题: 国际象棋棋盘是8 * 8的方格,每个方格里放一个棋子.皇后这种棋子可以攻击同一行或者同一列或者斜线(左上左下右上右下四个方向)上的棋子.在一个棋盘上如果要放八个皇后,使得她们互 ...
- 八皇后算法的另一种实现(c#版本)
八皇后: 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于 ...
- 数据结构0103汉诺塔&八皇后
主要是从汉诺塔及八皇后问题体会递归算法. 汉诺塔: #include <stdio.h> void move(int n, char x,char y, char z){ if(1==n) ...
随机推荐
- C++ 指针—02 指针与引用的对照
★同样点: ●都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:而引用则是某块内存的别名. ★不同点: ●指针是一个实体,而引用仅是个别名: ●引用仅仅能在定义时被初始化一次,之后不可变: ...
- 【 D3.js 入门系列 --- 8 】 对话操作(事件)
本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 这一节介绍怎样进行对话的操作,如鼠标单击,鼠标滑过等. 对一个被 ...
- hdu3811(状态压缩dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3811 题目大意:给定1~N个数,求出至少满足一个条件的排列总数.M个条件如下:Ai位置的数为Bi 分析 ...
- 启动、停止、重启 MySQL 常见的操作方法:
启动.停止.重启 MySQL 常见的操作方法: 简单罗列 一.启动方式 1.使用 service 启动:service mysqld start 2.使用 mysqld 脚本启动:/etc/inint ...
- 【译】ASP.NET MVC 5 教程 - 6:通过控制器访问模型的数据
原文:[译]ASP.NET MVC 5 教程 - 6:通过控制器访问模型的数据 在本节中,你将新建一个MoviesController 类,并编写获取电影数据的代码,使用视图模板将数据展示在浏览器中. ...
- c#怎样获取excel单元格的RGB颜色
这段时间一直在做office的工作.前2天获取单元格的颜色的问题一直没搞明确. 開始我想用的就是Npoi.主要前一部分的工作都是用Npoi完毕的 row.GetCell(j).CellStyle.Fi ...
- WPF界面设计技巧(4)—自定义列表项样式
原文:WPF界面设计技巧(4)-自定义列表项样式 有前面修改按钮样式的基础,我们可以尝试来定制一个即好看又好用的 ListBox ,今天先来讲“好看”部分. 打开 Microsoft Visual S ...
- hdu 2051 Bitset (java)
问题: 之前做过类似题,但这次仍然不能解决相关问题. 字符串倒过来输:StringBuffer str=new StringBuffer(s); s=str.reverse().toString() ...
- 算法8-4:Kruskal算法
Kruskal算法用于计算一个图的最小生成树.这个算法的过程例如以下: 依照边的权重从小到达进行排序 依次将每条边添加到最小生成树中,除非这条边会造成回路 实现思路 第一个步骤须要对边进行排序,排序方 ...
- php判断页面是电脑登录还是手机登录
首先说最根本的解决方法: 手机访问时,会附带发送user-agent信息,这个信息里面会有手机号码信息,那么如果能取得手机号码,则可以肯定是通过手机wap访问的.但是目前 中国移动已经屏蔽了user- ...