c语言翻转棋ai算法,黑白棋游戏(也叫翻转棋)(AI 版)
黑白棋(也叫翻转棋)的棋盘是一个有8*8方格的棋盘。下棋时将棋下在空格中间,而不是像围棋一样下在交叉点上。开始时在棋盘正中有两白两黑四个棋子交叉放置,黑棋总是先下子。
下子的方法:把自己颜色的棋子放在棋盘的空格上,而当自己放下的棋子在横、竖、斜八个方向内有一个自己的棋子,则被夹在中间的全部翻转会成为自己的棋子。并且,只有在可以翻转棋子的地方才可以下子。
引用了QQ游戏黑白棋的图片。
游戏运行截图如下:
游戏中使用了大量图片、音乐、资源文件,<
href="http://www.easyx.cn/Files/samples/201203/BlackWhiteChessAI.zip"
style="text-decoration: none; color: rgb(0, 0,
127);">点这里下载该游戏的完整 VC 项目包>。
游戏代码如下(相关图片资源请下载完整 VC 项目包):
///
// 程序名称:黑白棋AI版
// 编译环境:Visual C++ 2010/6.0,EasyX_v20120304(beta)
// 程序编写:自然向日葵 1164359890@qq.com
// 最后更新:2012-3-24
//
//说明:人机对战版
#include // EasyX_2011惊蛰版
#include
#include
#pragma comment(lib, "Winmm.lib")
#define T(c) ((c == 'B') ? 'W' : 'B')
using namespace std;
const int difficult = 6;// 难度
const int move[8][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1},
{-1, -1}, {1, -1}, {1, 1}, {-1, 1}};
// 八个方向扩展
char map[8][8];// 棋盘
IMAGE img[5];// 保存图片
int black, white;// 双方的棋子数
int X, Y;// 白棋的下子点
void load(void);// 加载素材
void print(void);// 画棋盘
void draw(int, int, char);// 下当前子
int judge(int, int, char);// 判断当前是否可以落下
bool baidu(char);// 判断是否有棋可吃
bool quit(char);// 判断是否有棋存活
bool ask(void);// 弹出对话框
int D(char, int);// 动态规划
void play(void);// 游戏过程
void load(void)// 加载素材
{
// 加载图片
loadimage(&img[0], "图片\\空位.bmp");
loadimage(&img[1], "图片\\黑子.bmp");
loadimage(&img[2], "图片\\白子.bmp");
loadimage(&img[3], "图片\\黑子1.bmp");
loadimage(&img[4], "图片\\白子1.bmp");
// 加载音乐
mciSendString("open 音乐\\背景音乐.wma", NULL, 0, NULL);
mciSendString("open 音乐\\和局.wma", NULL, 0, NULL);
mciSendString("open 音乐\\胜利.wma", NULL, 0, NULL);
mciSendString("open 音乐\\失败.wma", NULL, 0, NULL);
mciSendString("open 音乐\\下子.wma", NULL, 0, NULL);
// 初始化棋盘
initgraph(340, 340);
IMAGE qipan;
loadimage(&qipan, "图片\\棋盘.bmp");
putimage(0, 0, &qipan);
setorigin(26, 26);
SetWindowText(GetHWnd(), "黑白棋AI版");
}
void print(void)// 画棋盘
{
int x, y;
black = white = 0;
for(x = 0; x < 8; x++)
for(y = 0; y < 8; y++)
switch(map[x][y])
{
case 0:
putimage(37 * y, 37 * x, &img[0]);
break;
case 'B':
putimage(37 * y, 37 * x, &img[1]);
black++;
break;
case 'W':
putimage(37 * y, 37 * x, &img[2]);
white++;
break;
}
}
void draw(int x, int y, char a)// 下当前子
{
char b = T(a);// 敌方子
int i, x1, y1, x2, y2;
bool sign;
for (i = 0; i < 8; i++)
{
sign = false;
x1 = x + move[i][0];
y1 = y + move[i][1];
while (0 <= x1 && x1 < 8 && 0 <= y1 && y1 < 8 && map[x1][y1])
{
if(map[x1][y1] == b)
sign = true;
else
{
if(sign)
{
x1 -= move[i][0];
y1 -= move[i][1];
x2 = x + move[i][0];
y2 = y + move[i][1];
while (((x <= x2 && x2 <= x1) || (x1 <= x2 && x2 <= x)) && ((y <= y2 && y2 <= y1) || (y1 <= y2 && y2 <= y)))
{
map[x2][y2] = a;
x2 += move[i][0];
y2 += move[i][1];
}
}
break;
}
x1 += move[i][0];
y1 += move[i][1];
}
}
map[x][y] = a;
}
int judge(int x, int y, char a)// 判断当前是否可以落下,同draw函数
{
if(map[x][y])// 如果当前不是空的返回0值
return 0;
char b = T(a);
int i, x1, y1;
int n = 0, sign;
for (i = 0; i < 8; i++)
{
sign = 0;
x1 = x + move[i][0];
y1 = y + move[i][1];
while (0 <= x1 && x1 < 8 && 0 <= y1 && y1 < 8 && map[x1][y1])
{
if(map[x1][y1] == b)
sign++;
else
{
n += sign;
break;
}
x1 += move[i][0];
y1 += move[i][1];
}
}
return n;// 返回可吃棋数
}
bool baidu(char c)// 判断是否有棋可吃
{
int x, y;
for(x = 0; x < 8; x++)
for(y = 0; y < 8; y++)
if(judge(x, y, c))
return true;
return false;
}
bool quit(char c)// 判断是否有棋存活
{
int x, y;
bool b = false, w = false;
for(x = 0; x < 8; x++)
for(y = 0; y < 8; y++)
{
if(map[x][y] == c)
return false;
}
return true;
}
bool ask(void)// 弹出对话框
{
HWND wnd = GetHWnd();
int key;
char str[50];
ostrstream strout(str, 50);
strout <
if (black == white)
strout <
else if(black > white)
strout <
else
strout <
strout <
if(black == white)
key = MessageBox(wnd, str, "和局", MB_YESNO | MB_ICONQUESTION);
else if(black > white)
key = MessageBox(wnd, str, "黑胜", MB_YESNO | MB_ICONQUESTION);
else
key = MessageBox(wnd, str, "白胜", MB_YESNO | MB_ICONQUESTION);
if(key == IDYES)
return true;
else
return false;
}
int D(char c, int step)
{
// 判断是否结束递归
if (step > difficult)// 约束步数之内
return 0;
if (!baidu(c))
{
if (baidu(T(c)))
return -D(T(c), step);
else
return 0;
}
int i, j, max = 0, temp, x, y;
bool ans = false;
// 建立临时数组
char **t = new char *[8];
for (i = 0; i < 8; i++)
t[i] = new char [8];
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
t[i][j] = map[i][j];
// 搜索解法
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
if (temp = judge(i, j, c))
{
draw(i, j, c);
temp -= D(T(c), step + 1);
if (temp > max || !ans)
{
max = temp;
x = i;
y = j;
ans = true;
}
for (int k = 0; k < 8; k++)
for (int l = 0; l < 8; l++)
map[k][l] = t[k][l];
}
// 撤销空间
for (i = 0; i < 8; i++)
delete [] t[i];
delete [] t;
// 如果是第一步则标识白棋下子点
if (step == 1)
{
X = x;
Y = y;
}
return max;// 返会最优解
}
void play(void)// 游戏过程
{
MOUSEMSG m;
int x, y;
// 初始化棋子
for(x = 0; x < 8; x++)
for(y = 0; y < 8; y++)
map[x][y] = 0;
map[3][4] = map[4][3] = 'B';
map[3][3] = map[4][4] = 'W';
// 开始游戏
print();
mciSendString("play 音乐\\背景音乐.wma from 0 repeat", NULL, 0, NULL);
do
{
if (baidu('B'))// 如果玩家有下子位置
{
A:
while(true)
{
m = GetMouseMsg();// 获取鼠标消息
if(m.uMsg == WM_LBUTTONDOWN && m.x - 26 < 37 * 8 && m.y - 26 < 37 * 8)
// 如果左键点击
break;
}
x = (m.y - 26) / 37;
y = (m.x - 26) / 37;
if(judge(x, y, 'B'))// 如果当前位置有效
{
draw(x, y, 'B');// 下子
mciSendString("play 音乐\\下子.wma from 0", NULL, 0, NULL);
print();
putimage(37 * y, 37 * x, &img[3]);// 标识下子点
}
else
goto A;
if (quit('W'))// 计算机是否失败
break;
}
if (baidu('W'))// 如果计算机有下子位置
{
clock_t start;
start = clock();
D('W', 1);// 搜索解法
while (clock() - start < CLOCKS_PER_SEC);
draw(X, Y, 'W');
print();
mciSendString("play 音乐\\下子.wma from 0", NULL, 0, NULL);
putimage(37 * Y, 37 * X, &img[4]);// 标识下子点
if (quit('B'))// 玩家是否失败
break;
}
}while (baidu('B') || baidu ('W'));
// 播放庆祝音乐
mciSendString("stop 音乐\\背景音乐.wma", NULL, 0, NULL);
if (black > white)
mciSendString("play 音乐\\胜利.wma from 0", NULL, 0, NULL);
else if (black < white)
mciSendString("play 音乐\\失败.wma from 0", NULL, 0, NULL);
else
mciSendString("play 音乐\\和局.wma from 0", NULL, 0, NULL);
}
// 主函数
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
load();
do
{
play();
} while(ask());
// 关闭音乐
mciSendString("close 音乐\\背景音乐.wma", NULL, 0, NULL);
mciSendString("close 音乐\\和局.wma", NULL, 0, NULL);
mciSendString("close 音乐\\胜利.wma", NULL, 0, NULL);
mciSendString("close 音乐\\失败.wma", NULL, 0, NULL);
mciSendString("close 音乐\\下子.wma", NULL, 0, NULL);
closegraph();
return 0;
}
c语言翻转棋ai算法,黑白棋游戏(也叫翻转棋)(AI 版)相关推荐
- C语言零基础项目:黑白棋游戏!详细思路+源码分享
每天一个C语言小项目,提升你的编程能力! <黑白棋>也叫翻转棋或者奥赛罗,其游戏过程是相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负.虽然规则简单,但是变化复杂,是典型的易学难精,奥 ...
- Visual C++实现黑白棋游戏实战三:核心算法设计与实现(附源码和资源 可用于大作业)
需要源码和资源请点赞关注收藏后评论区留言私信~~~ 在前面的博客中已经讲解了黑白棋游戏的菜单和各种对话框的实现,下面将对黑白棋游戏的核心算法的设计和实现进行讲解 一.棋盘窗口类的设计 黑白棋的棋盘窗口 ...
- c语言大作业黑白棋,C语言编写黑白棋游戏源代码.doc
C语言编写的黑白棋游戏源代码 /*3.3.4 源程序*/ #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x4b00 /*光标左键值 ...
- c语言写的黑白棋游戏代码,C语言编写的黑白棋游戏源代码..doc
C语言编写的黑白棋游戏源代码. C语言编写的黑白棋游戏/*3.3.4 源程序*/ #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x ...
- 黑白棋代码Linux程序,C语言编写的黑白棋游戏源代码.doc
PAGE PAGE 1 C语言编写的黑白棋游戏源代码 /*3.3.4 源程序*/ #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x ...
- c语言课程设计之黑白棋游戏,c语言课程设计黑白棋游戏.doc
您所在位置:网站首页 > 海量文档  > 学术论文 > 大学论文 c语言课程设计黑白棋游戏.doc26页 本文档一共被 ...
- c语言程序设计黑白棋游戏,C语言课程设计_黑白棋游戏
C语言课程设计_黑白棋游戏 C语言课程设计_黑白棋游戏 #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x4b00 /*光标左键值* ...
- Windows游戏设计(三)- 黑白棋游戏 - 使用Win32 SDK
注:以下程序为本人原创,写的不好,若有好的建议,望留言告知.而若能帮助一二访客,幸甚! 上回用Python 写黑白棋,后来想添加个最小最大规则搜索博弈树的算法,没能实现,于是想先用Win32 写一个, ...
- python+pyGame 黑白棋游戏
注:以下程序为根据相应的字符界面程序改编而来,写的不好,若有好的建议,望留言告知.而若能帮助一二访客,幸甚! 继续学习python. 为了学习起来更有趣,继续以游戏的方式来学习. 注:前几天学习了In ...
最新文章
- APP Store案例数据分析
- Windows Server 2008 RemoteApp(四)---发布应用程序
- MySql8.0.19最新版本创建用户分配权限演示,You have an error in your SQL syntax权限分配问题解决方法
- 「五大常用算法」一文图解分治算法和思想
- Compass样式重置
- 翻译 《Why Indy?》计划进度表
- 经常读书与不读书的人有什么区别?
- 故宫4天门票已售罄 五一假期大家都去哪儿“看一看”了?
- springboot 讯飞语音_讯飞智能语音鼠标实际体验感受
- 设计模式学习笔记(九)——Composite组合模式
- python读音有道-centos7安装有道词典(不能发音和取词)
- [除草]BZOJ 1435 [ZJOI2009]多米诺骨牌
- java导出下载文件_java导出excel及下载的实现-java下载文件
- 前端框架Vue(15)——vue-cli 仿网易云音乐 Demo,环境搭建到开发 Vue 全家桶练手项目
- [ActiveForm] -- ActiveForm::begin表单用法
- 【程序员读论文】题外篇:怎么读论文
- 输出英文字母ch在英文字母表中的位置
- ISM无需授权使用的无线频率
- 如何用 Node.js 实现一个简单的 Websocket 服务?
- 小米发明“永动机”:走路即可为智能设备充电