当前只完成了单机人人对战  后续会完成联机和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();
}

源代码

五子棋C++版的更多相关文章

  1. 五子棋Web版的开发(一)---搭建IDEA SSH环境

    最近公司都没啥事,我在完成了控制台版的本地五子棋后(github地址:https://github.com/lkq51/wuziqi_console2),想将他升级成为一个web版的五子棋游戏.因为公 ...

  2. JavaScript五子棋第二版

      这是博主做的一个移动端五子棋小游戏,请使用手机体验.由于希望能有迭代开发的感觉,所以暂时只支持双人对战且无其他提示及对战界面,只有胜利提示,悔棋.对战双方显示.人机对战.集成TS(用于学习).和局 ...

  3. 五子棋Web版的开发(三)

    最近在这个上面花费的时间不多,进展不大,而且遇到了一个问题好久也没有解决..我将struct2 改为Spring MVC.但是ziRUL的自动映射却无法起作用.   一直不知道为什么会出现这个问题.. ...

  4. 五子棋Web版的开发(二)--整合Spring4.3+hibernate4+Struts2.3

    拖了这么久才把ssh框架给整合完毕,期间发现自己对SSH的知识真的是知之甚少.在整合期间遇到了无数的坑,我还是先把项目地址发一下吧 首先我遇到的第一个问题是 CreateQuery is not va ...

  5. 五子棋——C++

    最近在学C++,这个是照葫芦画瓢的五子棋C++版- - 依赖SDL_PingGe_1.3,很多实用的函数,类我都封装成DLL了调用起来真是舒服啊.. 不过一方面要对DLL做测试,一方面要开发,一个人还 ...

  6. JAVA小项目之五子棋

    五子棋V1.0 功能: 人人对战,人机对战(初级) 记录双方分数: 主要知识点: 二维坐标系中,各方向坐标的关系及规律. 效果图: 主框架类: package com.gxlee.wzq; /** * ...

  7. 五子棋的斜对角方向上的规则 -- java编程(简单粗暴版)

    五子棋判断输赢规则 --- 斜对角线方向上 一.左上右下方向上 1.分析图 2.代码 /**判断左上右下方向上是否有连续五颗相同颜色的棋子 * 全部遍历法 */ int loop = 0; boole ...

  8. Javascript版五子棋

    Javascript版五子棋,无禁手.欢迎提出算法的改进意见.2. [代码]HTML     <!DOCTYPE html><html>    <head>    ...

  9. Web版简易五子棋

    前些时候把大三写的C++版五子棋改成Web板挂到了网上,具有一定傻瓜式智能,欢迎体验使用拍砖:http://www.zhentiyuan.com/Games/QuickFiveChess.aspx 现 ...

随机推荐

  1. poj 3225 【线段树】

    poj 3225 这题是用线段树解决区间问题,看了两天多,算是理解一点了. Description LogLoader, Inc. is a company specialized in provid ...

  2. 在WPF中绘制多维数据集

    原文 https://stuff.seans.com/2008/08/13/drawing-a-cube-in-wpf/ 是时候使用WPF绘制一个简单的3D对象了.作为WPF中3D图形的快速介绍,让我 ...

  3. python if 选择结构

  4. Android 整合实现简单易用、功能强大的RecyclerView

    之前总是会有人在一些开发群里问,有木有比较好使且功能强大些的RecyclerVew,比如支持下来刷新,加载更多等,还有人在问,如何为RecyclerView添加分割线,尤其是如何为网格布局添加分割线? ...

  5. Transformer的PyTorch实现

    Google 2017年的论文 Attention is all you need 阐释了什么叫做大道至简!该论文提出了Transformer模型,完全基于Attention mechanism,抛弃 ...

  6. 安装visualStudio 出现 cant install Microsoft.TeamFoundation.OfficeIntegration.Resources

    本文告诉大家在安装 VisualStudio 时出现cant install Microsoft.TeamFoundation.OfficeIntegration.Resources如何安装 如果在安 ...

  7. 让 AE 输出 MPEG

    最近在做视频后期处理,但是我发现 AE 的文件都很大,大概一个 10 分钟视频 10G ,所以有什么办法让他输出的文件变小?一个方法是使用 MPEG 输出. 本文告诉大家如何让 AE 输出 MPEG ...

  8. H3C 网络号和主机号

  9. 【codeforces 777E】Hanoi Factory

    [题目链接]:http://codeforces.com/problemset/problem/777/E [题意] 让你摆汉诺塔片; 要求在上面的片的外圈大于在下面的片的内圈,且小于下面的片的外圈; ...

  10. Handler用法总结

    一.线程通讯问题 1.1 Message.Handler.Looper 在Android中提供了一种异步回调机制Handler,我们可以它来完成一个很长时间的任务. Handler基本使用: 在主线程 ...