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);

}

四.  測试与实现:

五.  总结:

通过对八皇后问题的求解,使我对递归算法有了更进一步的了解,类似八皇后及迷宫这种问题都能够用回溯算法来解决。这些都是数据结构与算法中重要的算法,当时学的不是非常好,通过不断地练习才逐步掌握了。

本程序的长处:实现了八皇后的基本功能,实现了悔棋功能,界面友好,有音乐提示等。

本程序的缺点:仅仅实现了八皇后,而没能实现五皇后、六皇后等其它格式,提示与找出玩家错误不足等。

时间: 2024-10-26 19:07:18

VC版八皇后的相关文章

回溯算法解八皇后问题(java版)

八皇后问题是学习回溯算法时不得不提的一个问题,用回溯算法解决该问题逻辑比较简单. 下面用java版的回溯算法来解决八皇后问题. 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 思路是按行来规定皇后,第一行放第一个皇后,第二行放第二个,然后通过遍历所有列,来判断下一个皇后能否放在该列.直到所有皇后都放完,或者放哪

八皇后问题(回溯法&amp;枚举法)

作者 : 卿笃军 本文讨论了八皇后问题的三种解决方案: 一.枚举法 二.回溯法(递归版) 三.回溯法(非递归版) 本来这些代码是以前编写好的,没有发表,由于最近又学习到了八皇后问题,自己整理了一下发表了出来! 首先.说明一下何为八皇后问题,我也不去谷歌了,直接简单的说明一下: 八皇后问题,就是在一个8*8的平面棋盘上,要求你摆放8个棋子,要求:这8个棋子不能有2个在同一行,也不能有2个在同一列,同时一条斜线上面也不能有2个~~~~ 比如:4*4的棋盘,你可以这样摆放(4皇后问题): 以上图为参照

回溯法解决八皇后问题

八皇后问题是学习回溯算法时不得不提的一个问题,用回溯算法解决该问题逻辑比较简单. 下面用java版的回溯算法来解决八皇后问题. 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 思路是按行来规定皇后,第一行放第一个皇后,第二行放第二个,然后通过遍历所有列,来判断下一个皇后能否放在该列.直到所有皇后都放完,或者放哪

八皇后问题——回溯法(python&amp;&amp;JAVA)

八皇后问题,是一个古老而著名的问题,问题如下: 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 上边是一个8*8的国际棋盘,可以看到棋盘中的每个格子都标有数字.每个数字都是两位,十位数字表示该格子所在的行,而个位数字表示该格子所在的列. 这样不难发现,处在同一行的两个格子其十位数都相同,处在同一列的两个格子其个位数都相同,处在同一斜线的两个格子有:|两个数字个位数的差|=|两个数字十位数的差|. 主要的三个限制条件明白了

ybt1217 棋盘问题(八皇后加强版)

ybt1217 棋盘问题 [题目描述] 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. [输入] 输入含有多组测试数据. 每组数据的第一行是两个正整数n,k,用一个空格隔开,表示了将在一个n×n的矩阵内描述棋盘,以及摆放棋子的数目.(n≤8,k≤n) 当为?1?1时表示输入结束. 随后的n行描述了棋盘的形状:每行有n个字符,其中#表示棋盘区域,

[OpenJudge] 百练2754 八皇后

八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(即92个不同的皇后串).给出一个数b,要求输出第b个串.串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小. I

python解决八皇后问题

经典回溯算法:八皇后问题 算法要求: 在国际象棋棋盘上(8*8)放置八个皇后,使得任意两个皇后之间不能在同一行,同一列,也不能位于同于对角线上. 国际象棋的棋盘如下图所示: 问共有多少种不同的方法,并且指出各种不同的放法. # -*- coding:utf-8 -*- __author__ = "tyomcat" print("******八皇后问题的解决方法******") def next_col(current, n=8): length = len(curr

用遗传算法解八皇后问题

此算法收敛速度还可以,基本在1万代之内就能找到解 主程序 clear; clc; %% %八皇后问题,8X8的棋盘上,放置8个皇后,使之两两都不能攻击 %初始的状态,随机在棋盘上放置8个皇后,每列放一个 n = 8; %8皇后 %% %用遗传算法计算 %先随机获得几个个体,形成一个种群 %这个种群有10个个体 No_of_people = 10; people = randi(n,[No_of_people,n]); %计算每个初始种群的h值 people_h = ones(No_of_peop

关于八皇后问题

八皇后问题主要是关于实现递归程序方面的知识. 问题描述: 会下象棋的人都知道:皇后可以在横竖,斜线上不限步数的吃掉其他棋子,如何将八个皇后放在棋盘上,使他们谁都不被吃掉,这就是著名的八皇后问题.对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2....b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题有92组解.求出八皇后问题的所有解. 解题思路: 使用8*8矩阵作为模拟棋盘,以每一行为单位进行选择放置皇后,在放置皇后的同时将放置的皇后的控制范围画出,在