当前只完成了单机人人对战  后续会完成联机和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. 2019-6-11-WPF-如何在应用程序调试启动

    title author date CreateTime categories WPF 如何在应用程序调试启动 lindexi 2019-06-11 09:32:35 +0800 2018-2-13 ...

  2. python for 循环结构

  3. HDU-1257_最少拦截系统

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Desc ...

  4. OpenKruise - 云原生应用自动化引擎正式开源

    2019 年 6 月 24 日至 26 日, 由 Cloud Native Computing Foundation (CNCF) 主办的云原生技术大会 KubeCon + CloudNativeCo ...

  5. LeetCode73 Set Matrix Zeroes

    题目: Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.(Me ...

  6. thinkphp3.2配置redis缓存和文件缓存

    如果把一些常用但又不容易变的数据存缓存,而不是每次查数据库,这样能很大减轻数据库压力 最近由于项目需要,就尝试了一把redis,但是后面又用了tp3.2的文件缓存,直接进入主题: 在config.ph ...

  7. Mac 安装homebrew,pkgutil --pkgs列出安装包

    Mac 安装homebrew Homebrew官网 http://brew.sh/index_zh-cn.html Homebrew是神马 Linux系统有个让人蛋疼的通病,软件包依赖,好在当前主流的 ...

  8. Python字节码介绍

    了解 Python 字节码是什么,Python 如何使用它来执行你的代码,以及知道它是如何帮到你的.如果你曾经编写过 Python,或者只是使用过 Python,你或许经常会看到 Python 源代码 ...

  9. Keras框架下的保存模型和加载模型

    在Keras框架下训练深度学习模型时,一般思路是在训练环境下训练出模型,然后拿训练好的模型(即保存模型相应信息的文件)到生产环境下去部署.在训练过程中我们可能会遇到以下情况: 需要运行很长时间的程序在 ...

  10. 2002年NOIP普及组复赛题解

    题目涉及算法: 级数求和:入门题: 选数:搜索: 产生数:搜索.高精度: 过河卒:动态规划. 级数求和 题目链接:https://www.luogu.org/problemnew/show/P1035 ...