当前只完成了单机人人对战  后续会完成联机和AI的实现

定义棋盘

typedef struct
{
int kind;
}Map; //棋盘 0为无子 1为黑子 2为白子 Map maps[line_number + 1][line_number + 1]; //定义棋盘

定义棋子

typedef struct
{
int x;
int y;
int kind;
}Record; //记录每一步棋的坐标 int point_x, point_y; //落子点的坐标
int kind_chess; //1为黑子 2为白子

 

 void Startup()
{ //当前棋盘没有落子 kind全部置为0;
for (int i = ; i <= line_number; i++)
{
for (int j = ; j <= line_number; j++)
{
maps[i][j].kind = ;
}
}
//各种参数初始化
flag_leftmouse = ;
number = ;
kind_chess = ;
step = width / (line_number + );
radius = step / - ;
initgraph(width, heigh);
//设置背景颜色
setbkcolor(RGB(, , ));
cleardevice(); setlinecolor(BLACK);
setlinestyle(PS_SOLID, );
// 画出棋盘横竖各line_number条交错的直线
for (int i = ; i <= line_number; i++)
{
line(i*step, * step, i*step, line_number * step);
line( * step, i*step, line_number * step, i*step);
}
button_left = step;
button_right = step * ;
button_top = (line_number + )*step - step / ;
button_bottom = heigh - step / ;
//画出悔棋键
settextcolor(BLACK);
settextstyle(step*-step/, step - step/, _T("宋体"));
outtextxy(button_left, button_top , _T("悔棋"));
//画出认输键
settextstyle(step * - step / , step - step / , _T("宋体"));
outtextxy(button_left+*step, button_top, _T("认输"));
}

初始化棋盘

 //判断落子后是否胜利 即五连子 x,y,kind 分别为行数,列数,棋子的颜色
int IsVictory(int x, int y, int kind)
{
//判断一列上是否有五连子
int i = x;
int j = y;
int count = ;
while (i >= && maps[i][j].kind == kind)
{
i--;
count++;
}
i = x + ;
while (i <= && maps[i][j].kind == kind)
{
i++;
count++;
}
if (count == ) return kind;
//判断一行上是否有五连子
i = x;
count = ;
while (j >= && maps[i][j].kind == kind)
{
j--;
count++;
}
j = y + ;
while (j <= && maps[i][j].kind == kind)
{
j++;
count++;
}
if (count == ) return kind;
//判断左斜方向是否有五连子
i = x;
j = y;
count = ;
while (i >= && j >= && maps[i][j].kind == kind)
{
j--;
i--;
count++;
}
i = x + ;
j = y + ;
while (j <= && i <= && maps[i][j].kind == kind)
{
j++;
i++;
count++;
}
if (count == ) return kind;
//判断右斜方向是否有五连子
i = x;
j = y;
count = ;
while (i <= && j >= && maps[i][j].kind == kind)
{
j--;
i++;
count++;
}
i = x - ;
j = y + ;
while (j <= && i >= && maps[i][j].kind == kind)
{
j++;
i--;
count++;
}
if (count == ) return kind;
return ;
}

判断胜利

 if (kind_chess ==  && maps[point_y / (step)][point_x / step].kind == ) //当前落子位置满足条件
{
//记录落子点 用于悔棋键
number++;
records[number].x = point_y / step;
records[number].y = point_x / step;
records[number].kind = ; //绘图 覆盖
setfillcolor(BLACK);
solidcircle(point_x, point_y, radius);
maps[point_y / step][point_x / step].kind = ;
kind_chess = ;
if (IsVictory(point_y / step, point_x / step, ) == )
{ settextcolor(BLACK);
settextstyle(, , _T("宋体"));
outtextxy(width / - , heigh / , _T("黑方胜"));
system("pause");
goto L1;
}
}

落子

 // 五子棋.cpp: 定义控制台应用程序的入口点。

 //头文件区
#include "stdafx.h"
#include <graphics.h>
#include <conio.h> //宏定义区
#define width 640
#define heigh 700 //定义窗口的长和宽
#define line_number 15 //定义棋盘的条数 横竖各line_number条线 //结构体定义区
typedef struct
{
int kind;
}Map; //棋盘 0为无子 1为黑子 2为白子
typedef struct
{
int x;
int y;
int kind;
}Record; //记录每一步棋的坐标
typedef struct {
int x;
int y;
}Point; //记录最佳点的坐标 //全局变量区
MOUSEMSG m;
int flag_leftmouse ; //标志是否按下左键
int point_x, point_y; //落子点的坐标
Map maps[line_number + ][line_number + ]; //定义棋盘
Record records[line_number * line_number + ]; //记录每一步落子的坐标
int kind_chess; //1为黑子 2为白子
int step ; //棋盘线与线之间的间距
int radius; //棋子半径
int number; //当前总落子数 int button_left; //按钮的上下左右界
int button_right;
int button_top;
int button_bottom; //初始化
void Startup()
{ //当前棋盘没有落子 kind全部置为0;
for (int i = ; i <= line_number; i++)
{
for (int j = ; j <= line_number; j++)
{
maps[i][j].kind = ;
}
}
//各种参数初始化
flag_leftmouse = ;
number = ;
kind_chess = ;
step = width / (line_number + );
radius = step / - ;
initgraph(width, heigh);
//设置背景颜色
setbkcolor(RGB(, , ));
cleardevice(); setlinecolor(BLACK);
setlinestyle(PS_SOLID, );
// 画出棋盘横竖各line_number条交错的直线
for (int i = ; i <= line_number; i++)
{
line(i*step, * step, i*step, line_number * step);
line( * step, i*step, line_number * step, i*step);
}
button_left = step;
button_right = step * ;
button_top = (line_number + )*step - step / ;
button_bottom = heigh - step / ;
//画出悔棋键
settextcolor(BLACK);
settextstyle(step*-step/, step - step/, _T("宋体"));
outtextxy(button_left, button_top , _T("悔棋"));
//画出认输键
settextstyle(step * - step / , step - step / , _T("宋体"));
outtextxy(button_left+*step, button_top, _T("认输"));
} //判断落子后是否胜利 即五连子 x,y,kind 分别为行数,列数,棋子的颜色
int IsVictory(int x, int y, int kind)
{
//判断一列上是否有五连子
int i = x;
int j = y;
int count = ;
while (i >= && maps[i][j].kind == kind)
{
i--;
count++;
}
i = x + ;
while (i <= && maps[i][j].kind == kind)
{
i++;
count++;
}
if (count == ) return kind;
//判断一行上是否有五连子
i = x;
count = ;
while (j >= && maps[i][j].kind == kind)
{
j--;
count++;
}
j = y + ;
while (j <= && maps[i][j].kind == kind)
{
j++;
count++;
}
if (count == ) return kind;
//判断左斜方向是否有五连子
i = x;
j = y;
count = ;
while (i >= && j >= && maps[i][j].kind == kind)
{
j--;
i--;
count++;
}
i = x + ;
j = y + ;
while (j <= && i <= && maps[i][j].kind == kind)
{
j++;
i++;
count++;
}
if (count == ) return kind;
//判断右斜方向是否有五连子
i = x;
j = y;
count = ;
while (i <= && j >= && maps[i][j].kind == kind)
{
j--;
i++;
count++;
}
i = x - ;
j = y + ;
while (j <= && i >= && maps[i][j].kind == kind)
{
j++;
i--;
count++;
}
if (count == ) return kind;
return ;
} //AI落子
/*void dropChessAt(Point p)
{
number++;
records[number].x = p.x;
records[number].y = p.y;
records[number].kind = 2; setfillcolor(WHITE);
solidcircle(p.y * step, p.x*step, radius);
maps[p.x][p.y].kind = 2;
kind_chess = 1;
if (IsVictory( p.x, p.y, 2) == 2)
{
settextcolor(WHITE);
settextstyle(48, 0, _T("宋体"));
outtextxy(width / 2 - 60, heigh / 2, _T("白方胜"));
system("pause");
}
}*/ //其中p为当前点,i为方向,取值为从1到8的整数,对应8个方向,
//j为相对于p点的坐标值。在函数体内要依据方向对p的x、y的值进行处理。返回该点的落子
//情况,0表示无子,1或2分别表示两个player,-1表示超出棋盘界。
/*int getLine(Point p, int i, int j)
{
int x = p.x, y = p.y;
switch (i)
{
case 1:
x = x - j; break; //上
case 2:
x = x + j; break; //下
case 3:
y = y - j; break; //左
case 4:
y = y + j; break; //右
case 5:
y = y + j; x = x - i; break; //右上
case 6:
y = y - j; x = x - i; break; //左上
case 7:
y = y + j; x = x + i; break; //右下
case 8:
y = y - j; x = x + i; break; //左下
default:
break;
}
if (x<1 || y<1 || x>line_number || y>line_number) return -1;
return maps[x][y].kind;
}*/ //估值函数(核心)
/*int envaluate(Point p, int kind)
{
Point dir[8];
dir[0].x = -1; dir[0].y = 0; //上
//dir[1].x = 1; dir[1].y = 0; //下
//dir[2].x = 0; dir[2].y = -1; //左
dir[1].x = 0; dir[1].y = 1; //右
dir[2].x = -1; dir[2].y = -1; //左上
dir[3].x = -1; dir[3].y = 1; //右上
//dir[6].x = 1; dir[6].y = -1; //左下
//dir[7].x = 1; dir[7].y = 1; //右下
int value = 0;
//敌对方是谁
int opposite;
if (kind == 1)opposite = 2;
if (kind == 2)opposite = 1;
for (int i = 0; i < 4; i++)
{ } }*/ //轮到AI的回合
/*void IsTimeToAI()
{
Point bestAttack; //最佳进攻点
Point bestDefend; //最佳防守点 int max1 = 0;
//循环遍历整个棋盘
for (int i = 1; i <= line_number; i++)
{
for (int j = 1; j <= line_number; j++)
{
if (maps[i][j].kind != 0) continue;
//当前点
Point c;
c.x = i;
c.y = j;
int value = envaluate(c, 2);
//int value = Evaluate(c);
if (max1 < value)
{
max1 = value;
bestAttack = c;
}
}
}
int max2 = 0;
for (int i = 1; i <= line_number; i++)
{
for (int j = 1; j <= line_number; j++)
{
if (maps[i][j].kind != 0) continue;
Point c;
c.x = i;
c.y = j;
int value = envaluate(c, 1);
//int value = Evaluate(c);
if (max2 < value)
{
max2 = value;
bestDefend = c;
}
}
} if (max1 >= max2)
{
dropChessAt(bestAttack);
}
else {
dropChessAt(bestDefend);
}
}*/ //游戏开始
void ConsoleGame()
{
L1:
//初始化
Startup();
//主循环
while ()
{
if (MouseHit())
{
m = GetMouseMsg();
if (m.mkLButton == true ) //按下鼠标左键时
{
flag_leftmouse = ;
}
if (m.mkLButton == false && flag_leftmouse==) //当松开鼠标左键后开
{
//鼠标按键范围在棋盘内时
if (m.x >= step - radius && m.x <= (width - (step - radius)) && m.y >= step - radius && m.y <= (width - (step - radius)))
{
if (m.x % step < step / )
{
point_x = m.x - m.x % step;
}
if (m.x % step > step / )
{
point_x = m.x + (step - m.x % (step));
}
if (m.y % step < step / )
{
point_y = m.y - m.y % step;
}
if (m.y % step > step / )
{
point_y = m.y + (step - m.y % step);
}
if (kind_chess == && maps[point_y / (step)][point_x / step].kind == )
{
number++;
records[number].x = point_y / step;
records[number].y = point_x / step;
records[number].kind = ; setfillcolor(BLACK);
solidcircle(point_x, point_y, radius);
maps[point_y / step][point_x / step].kind = ;
kind_chess = ;
if (IsVictory(point_y / step, point_x / step, ) == )
{ settextcolor(BLACK);
settextstyle(, , _T("宋体"));
outtextxy(width / - , heigh / , _T("黑方胜"));
system("pause");
goto L1;
}
}
//人人对战时的后手方落子
else if (kind_chess == && maps[point_y / step][point_x / step].kind == )
{ number++;
records[number].x = point_y / step;
records[number].y = point_x / step;
records[number].kind = ; setfillcolor(WHITE);
solidcircle(point_x, point_y, radius);
maps[point_y / step][point_x / step].kind = ;
kind_chess = ;
if (IsVictory(point_y / step, point_x / step, ) == )
{
settextcolor(WHITE);
settextstyle(, , _T("宋体"));
outtextxy(width / - , heigh / , _T("白方胜"));
system("pause");
goto L1;
}
}
}
//鼠标按键范围在悔棋键范围内时
if (m.x >= button_left && m.x <=button_right &&m.y >=button_top &&m.y <=button_bottom)
{
if (number >= )
{
int x = records[number].x;
int y = records[number].y;
kind_chess = records[number].kind;
setfillcolor(RGB(, , ));
solidcircle(y * step, x * step, radius);
setlinecolor(BLACK);
if (x == && y ==)
{
line(y*step, x*step , y*step, x*step + radius);
line(y*step , x*step, y*step + radius, x*step);
}
else if (y == && (x > && x < line_number))
{
line(y*step, x*step-radius, y*step, x*step + radius);
line(y*step, x*step, y*step + radius, x*step);
}
else if (y == && x == line_number)
{
line(y*step, x*step - radius, y*step, x*step);
line(y*step, x*step, y*step + radius, x*step);
}
else if (x == && y > && y < line_number)
{
line(y*step, x*step, y*step, x*step+radius);
line(y*step-radius, x*step, y*step+radius , x*step);
}
else if (x == && y == line_number)
{
line(y*step, x*step , y*step, x*step+radius);
line(y*step - radius, x*step , y*step, x*step);
}
else if (y == line_number && x > && x < line_number)
{
line(y*step, x*step - radius, y*step, x*step+radius);
line(y*step-radius, x*step, y*step , x*step);
}
else if (y == line_number && x == line_number)
{
line(y*step, x*step - radius, y*step, x*step);
line(y*step - radius, x*step, y*step, x*step);
}
else if (x == line_number && y > && y < line_number)
{
line(y*step, x*step - radius, y*step, x*step );
line(y*step - radius, x*step, y*step+radius, x*step);
}
else
{
line(y*step, x*step - radius, y*step, x*step + radius);
line(y*step - radius, x*step, y*step + radius, x*step);
}
maps[x][y].kind = ;
number--;
}
}
//鼠标按键范围在认输键范围内时
else if (m.x >= button_left + * step && m.x <= button_right + * step && m.y >= button_top && m.y <= button_bottom)
{
if (kind_chess == )
{
settextcolor(BLACK);
settextstyle(, , _T("宋体"));
outtextxy(width / - , heigh / , _T("白方胜"));
system("pause");
goto L1;
}
else
{
settextcolor(BLACK);
settextstyle(, , _T("宋体"));
outtextxy(width / - , heigh / , _T("黑方胜"));
system("pause");
goto L1;
}
}
flag_leftmouse = ;
}
}
/*if (kind_chess == 2)
{
//Sleep(40);
//IsTimeToAI();
}*/
}
_getch();
} int main()
{
ConsoleGame();
}

源代码

最新文章

  1. Flexible 弹性盒子模型之flex
  2. scrollHeight、scrollTop等的比较
  3. 十一个行为模式之责任链模式(Responsible Chain Pattern)
  4. Android测试之Monkey
  5. Git可视化极简易教程 —— Git GUI使用方法
  6. STM32F0xx_FLASH编程(片内)配置详细过程
  7. android 触摸事件、点击事件的区别
  8. 用java程序模拟网站的登录以及文件批量上传
  9. news总结
  10. MySQL----information-schema数据库相关权限的说明。
  11. JavaMail学习笔记
  12. return和break的区别
  13. ZXing工具类v1.0
  14. 一文读懂 HTTP/2 特性
  15. PAT 1132 Cut Integer
  16. 把excel每一行中的数据输出为一个txt文档的VBA函数
  17. [luogu1337][bzoj3680][JSOI2004]平衡点 / 吊打XXX【模拟退火】
  18. django项目一 分页器(前端分页和后端分页区别)
  19. 很不错的python 机器学习博客
  20. 查找被占用的端口的服务并kill掉

热门文章

  1. SDUT-3346_数据结构实验之二叉树七:叶子问题
  2. 8.5打包libgdx为一个桌面程序(jar包)
  3. 使用jQuery的 autocomplete 实现输入框 自动提示补全
  4. A - Archery Tournament 动态开点+vecotor 神仙题
  5. div 禁止点击
  6. Eclipse(Maven) web项目更改项目名称
  7. 读取hive的表结构,生成带comment的视图建表语句
  8. H3C 传输层
  9. Spring的注解@Qualifier注解
  10. JS中数组声明