【c++】五子棋源码
之前发过这个帖子,不过当时是用来申请账号的,不过因为申请用户名是qq号所以没有申请成功,在那个区里没人看,现在开放注册了就在这里再发一遍吧,就当记录下自己的足迹本人是一名学生,正好最近在做课程设计,使用c语言配合easyx图形库(想下载图形库的话百度搜索easyx就能找到了)编写了一个五子棋的小游戏
去年做课程设计,使用c语言配合easyx图形库(想下载的话百度搜索就能找到了)编写了一个五子棋的小游戏,由于是第一次发帖,做的有什
么不对的地方希望大家提下建议,源码我会放在链接内,有需要的可以下载
废话不说了,先上几张效果图
游戏进入界面
游戏的双人模式
单人模式(也就是人机,这里算是比较核心的了,因为比较懒,所以机器人的算法写的不太聪明{:1_905:},只判断了棋子个数,像相同的棋子个数不同的优先级,就没有判断,)
自己做的游戏大概流程图(有点难看,凑合着看吧:lol )
代码的话我就不讲解了,里面都有注释的,如果函数不知道是什么意思,可以百度查一下,都能搜到的
最后补充一下 ,我是用的vc++6.0编写的,如果用vs的话,字符串前好像要加“L”当做宽字符。
举个栗子:
vc++6.0中可以这样写:
MessageBox(h, "请游戏结束后重试", "提示信息", MB_OK);//弹出提示框
但在vs中需要这样写:
MessageBox(h, L"请游戏结束后重试", L"提示信息", MB_OK);//弹出提示框
下面上代码
#include<graphics.h>
#include<Windows.h>
#include<conio.h>
#include<stdio.h>
#definecolumn 19
#definerow 19
//函数声明
int judgement(int x, int y);
void drawchessboard();
void XiaQi();
int caculateValue(int r, int c, int who);
int MaxOfQuan(int r, int c);
void AIReboot();
int caculateValue(int r,int c,int who);
int MaxOfQuan(int r,int c);
//全局变量
IMAGE black, white, background, renren, surrender, renji,mainpicture;//图片全局变量
HWND h;//之后用来接受当前绘图窗口句柄
int turn = 0;//控制下棋 0都不能下1黑棋下2白棋下
int map = { 0 };//存储棋盘信息0没有棋子1黑棋2白棋
int chooseType = 0;//1为人人 2为人机
int gif = 0;//控制菜单处的贴图
struct quanzhi
{
int hang, lie, yuoxie, zouxie;//存储四个方向相邻棋子数\ /
};
quanzhi quan;//记录最优位置
void AIReboot()//机器人下棋
{
memset(quan, 0, sizeof(quan));//数组置零
int i, j,tmp,max1=0,a1=0,b1=0;
for (i = 0; i < row; i++)//遍历棋盘
{
for (j = 0; j < column; j++)
{
if (map != 0)
continue;
caculateValue(i,j,1);//计算敌方最优位置防御
tmp = MaxOfQuan(i, j);
if (max1 <tmp )
{
max1 = tmp;
a1 = i;
b1 = j;
}
}
}
memset(quan, 0, sizeof(quan));
int max2=0,a2=0,b2=0;
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
if (map != 0)
continue;
caculateValue(i,j,2);//计算己方最优位置进攻
tmp = MaxOfQuan(i, j);
if (max2 <tmp )
{
max2 = tmp;
a2 = i;
b2 = j;
}
}
}
if(max2!=0&&max2>=max1)//攻击当己方与敌方最多相连棋子相同时 己方的优先级更大
{
putimage(b2*40, a2*40, &white);
map=2;
if (judgement(b2, a2) != 2)
turn = 1;
}
else//防御
{
putimage(b1*40, a1*40, &white);
map=2;
if (judgement(b1, a1) != 2)
turn = 1;
}
}
int caculateValue(int r,int c,int who)//计算权值
{
//计算行
int sum = 0,i;
for (i = 1; i < 5; i++)
{
if (c - i >= 0 && map == who)
sum++;
if(map!=who)
break;
}
for (i = 1; i < 5; i++)
{
if (c + i < 19 && map == who)
sum++;
if(map!=who)
break;
}
quan.hang = sum;
//列
sum = 0;
for (i = 1; i < 5; i++)
{
if (r - i >= 0 && map == who)
sum++;
if(map!=who)
break;
}
for (i = 1; i < 5; i++)
{
if (r + i < 19 && map == who)
sum++;
if(map!=who)
break;
}
quan.lie = sum;
//左斜
sum = 0;
for (i = 1; i < 5; i++)
{
if (r + i < 19 && c - i >= 0 && map == who)
sum++;
if(map!=who)
break;
}
for (i = 1; i < 5; i++)
{
if (r - i >= 0 && c + i < 19 && map == who)
sum++;
if(map!=who)
break;
}
quan.zouxie = sum;
//右斜
sum = 0;
for (i = 1; i < 5; i++)
{
if (r - i >= 0 && c - i >= 0 && map == who)
sum++;
if(map!=who)
break;
}
for (i = 1; i < 5; i++)
{
if (r + i < 19 && c + i < 19 && map == who)
sum++;
if(map!=who)
break;
}
quan.yuoxie = sum;
return 0;
}
int MaxOfQuan(int r,int c)
{
int max = max(quan.hang, max(quan.lie, max(quan.yuoxie, quan.zouxie)));
return max;
}
void drawchessboard()//绘制棋盘
{
int i, j;
cleardevice();//清屏
putimage(0, 0, &background);//贴背景图、菜单图
putimage(780, 100, 200, 55, &renren, 298, 85);
putimage(780, 200, 200, 55, &renji, 298, 85);
putimage(780, 300, 200, 55, &surrender, 298, 85);
setlinecolor(BLACK);//设置线的颜色为黑色
for (i = 1, j = 1; j < 20; i += 2, j++)//绘制19x19棋盘
{
line(20, 20 * i, 40 * column - 20, 20 * i);
line(20 * i, 20, 20 * i, 40 * row - 20);
}
}
void XiaQi()
{
MOUSEMSG m;//鼠标
while (1)
{
m = GetMouseMsg();//获取鼠标信息
switch (m.uMsg)
{
case WM_LBUTTONDOWN://鼠标左键按下
if (m.x >= 780 && m.x <= 980 && m.y >= 100 && m.y <= 155)//点击开始人人,游戏开始,黑棋先下
{
if (turn == 0)//开始游戏
{
turn = 1;//黑棋先手
chooseType = 1;
drawchessboard();
memset(map, 0, sizeof(map));
MessageBox(h, "游戏开始请下棋", "提示信息", MB_OK);//弹出提示框
outtextxy(800, 50, "当前模式:双人模式");
outtextxy(800,455,"当前执子:");
putimage(900,440,&black);
break;
}
else
MessageBox(h, "请游戏结束后重试", "提示信息", MB_OK);//弹出提示框
}
else if (m.x >= 780 && m.x <= 980 && m.y >= 200 && m.y <= 255)//人机模式
{
if (turn == 0)//开始游戏
{
turn = 1;
chooseType = 2;
drawchessboard();
memset(map, 0, sizeof(map));
MessageBox(h, "游戏开始请下棋", "提示信息", MB_OK);//弹出提示框
outtextxy(800, 50, "当前模式:单人模式");
outtextxy(800,455,"你所执子:");
putimage(900,440,&black);
break;
}
else
MessageBox(h, "请游戏结束后重试", "提示信息", MB_OK);//弹出提示框
}
else if (m.x >= 780 && m.x <= 980 && m.y >= 300 && m.y <= 355)//认输当前轮到谁谁输
{
if (turn == 1)
{
MessageBox(h, "黑方认输 白方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
}
else if (turn == 2)
{
MessageBox(h, "白方认输 黑方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
}
else
MessageBox(h, "游戏未开始 不能认输!!!", "提示信息", MB_OK);//弹出提示框
}
else if(turn==0)
MessageBox(h, "请开始游戏!!!", "提示信息", MB_OK);
if (chooseType == 1)//人人大战
{
if (turn == 1)//黑棋下子
{
putimage(900,440,&white);
int x = m.x, y = m.y;//计算鼠标点击处最近的棋盘空格
int true_x = x / 40 * 40 + 20, true_y = y / 40 * 40 + 20;
if (true_x>760 || true_y>760)
{
MessageBox(h, "这里不是棋盘!!!", "提示信息", MB_OK);//弹出提示框
}
else
{
int locate_x = (true_x - 20) / 40, locate_y = (true_y - 20) / 40;//计算map数组的下标
if (map == 0)
{
putimage(true_x - 20, true_y - 20, &black);
map = 1;
if(judgement(locate_x,locate_y)!=1)
turn = 2;
}
else
MessageBox(h, "这里已经有棋子了,不能下!!!", "提示信息", MB_OK);//弹出提示框
}
}
else if (turn == 2)//白棋下子
{
putimage(900,440,&black);
int x = m.x, y = m.y;
int true_x = x / 40 * 40 + 20, true_y = y / 40 * 40 + 20;
if (true_x>760 || true_y>760)
MessageBox(h, "这里不是棋盘!!!", "提示信息", MB_OK);//弹出提示框
else
{
int locate_x = (true_x - 20) / 40, locate_y = (true_y - 20) / 40;
if (map == 0)
{
putimage(true_x - 20, true_y - 20, &white);
map = 2;
if (judgement(locate_x, locate_y) != 2)
turn = 1;
}
else
MessageBox(h, "这里已经有棋子了,不能下!!!", "提示信息", MB_OK);//弹出提示框
}
}
}
else if (chooseType == 2)//人机模式
{
if(turn==0)
continue;
else
{
int x = m.x, y = m.y;
int true_x = x / 40 * 40 + 20, true_y = y / 40 * 40 + 20;
if (true_x>760 || true_y>760)
{
MessageBox(h, "这里不是棋盘!!!", "提示信息", MB_OK);//弹出提示框
continue;
}
else
{
int locate_x = (true_x - 20) / 40, locate_y = (true_y - 20) / 40;
if (map == 0)
{
putimage(true_x - 20, true_y - 20, &black);
map = 1;
if (judgement(locate_x, locate_y) != 1)
turn = 2;
else
continue;
}
else
{
MessageBox(h, "这里已经有棋子了,不能下!!!", "提示信息", MB_OK);//弹出提示框
continue;
}
}
AIReboot();//机器人
}
}
case WM_MOUSEMOVE:
if (m.x >= 780 && m.x <= 980 && m.y >= 100 && m.y <= 155 && gif == 0)
{
fillrectangle(780, 100, 980, 155);
outtextxy(830, 110, "双人模式");
gif = 1;
}
else if (m.x >= 780 && m.x <= 980 && m.y >= 200 && m.y <= 255 && gif == 0)
{
fillrectangle(780, 200, 980, 255);
outtextxy(830, 210, "单人模式");
gif = 2;
}
else if (m.x >= 780 && m.x <= 980 && m.y >= 300 && m.y <= 355 && gif == 0)
{
fillrectangle(780, 300, 980, 355);
outtextxy(840, 310, " 认输");
gif = 3;
}
else if ((m.x < 780 || m.x > 980) || ((m.x>=780&&m.x<=980)&&((m.y<100)||(m.y>155&&m.y<200)||(m.y>255&&m.y<300)||m.y>355))&& gif != 0)
{
putimage(780, 100, 200, 55, &renren, 298, 85);
putimage(780, 200, 200, 55, &renji, 298, 85);
putimage(780, 300, 200, 55, &surrender, 298, 85);
gif = 0;
}
}
}
}
int judgement(int x,int y)//判断是否胜利
{
//行
int r1 = x - 4, r2 = x + 4,i, j, rsum = 0;
if (r1<0)r1 = 0;
if (r2>18) r2 = 18;
if (turn == 1) //黑棋
{
for (i = r1; i <= r2; i++)
{
if (map == 1)
{
rsum++;
if (rsum == 5)
{
outtextxy(800,510,"获胜者:");
putimage(900,500,&black);
MessageBox(h, "游戏结束 黑方胜!!!", "提示信息", MB_OK);//弹出提示框
//outtextxy(750,525,"游戏结束 黑方行满5子胜!!!");
turn = 0;
chooseType = 0;
return 1;//连续五个黑子,黑方胜返回1
}
}
else
rsum = 0;
}
}
else if (turn == 2) {//白棋
for (i = r1; i <= r2; i++) {
if (map == 2) {
rsum++;
if (rsum == 5) {
outtextxy(800,510,"获胜者:");
putimage(900,500,&white);
MessageBox(h, "游戏结束 白方行满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
return 2;//连续五个白子,白方胜返回2
}
}
else
rsum = 0;
}
}
//列
int c1 = y - 4, c2 = y + 4,csum = 0;
if (c1<0)
c1 = 0;
if (c2>18)
c2 = 18;
if (turn == 1) {//黑棋
for (i = c1; i <= c2; i++) {
if (map == 1) {
csum++;
if (csum == 5) {
outtextxy(800,510,"获胜者:");
putimage(900,500,&black);
MessageBox(h, "游戏结束 黑方列满5子黑方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
return 1;//连续五个黑子,黑方胜返回1
}
}
else
csum = 0;
}
}
else if (turn == 2) {//白棋
for (i = c1; i <= c2; i++) {
if (map == 2) {
csum++;
if (csum == 5) {
outtextxy(800,510,"获胜者:");
putimage(900,500,&white);
MessageBox(h, "游戏结束 白方列满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
return 2;//连续五个白子,白方胜返回1
}
}
else
csum = 0;
}
}
//判断\ 方向
int a1 = y - 4, a2 = x - 4, b1 = y + 4, b2 = x + 4,asum = 0;//a1行 a2列
if (a1<0) a1 = 0;
if (a2<0) a2 = 0;
if (b1>18) b1 = 18;
if (b2>18) b2 = 18;
if (turn == 1) {//黑棋
for (i = a1, j = a2; i <= b1&&j <= b2; i++, j++) {
if (map == 1) {
asum++;
if (asum == 5) {
outtextxy(800,510,"获胜者:");
putimage(900,500,&black);
MessageBox(h, "游戏结束 黑方右斜满5子黑方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
return 1;//连续五个黑子,黑方胜返回1
}
}
else
asum = 0;
}
}
else if (turn == 2) {//白棋
for (i = a1, j = a2; i <= b1&&j <= b2; i++, j++) {
if (map == 2) {
asum++;
if (asum == 5) {
outtextxy(800,510,"获胜者:");
putimage(900,500,&white);
MessageBox(h, "游戏结束 白方右斜满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
return 2;//连续五个白子,白方胜返回2
}
}
else
asum = 0;
}
}
//判断/ 方向
int m1 = y + 4, m2 = x - 4, n1 = y - 4, n2 = x + 4,msum = 0;//a1行 a2列
if (m1>18) a1 = 18;
if (m2<0) m2 = 0;
if (n1<0) n1 = 0;
if (n2>18) n2 = 18;
if (turn == 1) {//黑棋
for (i = m1, j = m2; i >= n1&&j <= n2; i--, j++) {
if (map == 1) {
msum++;
if (msum == 5) {
outtextxy(800,510,"获胜者:");
putimage(900,500,&black);
MessageBox(h, "游戏结束 黑方左斜满5子黑方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
return 1;//连续五个黑子,黑方胜返回1
}
}
else
msum = 0;
}
}
else if (turn == 2) {//白棋
for (i = m1, j = m2; i >= n1&&j <= n2; i--, j++) {
if (map == 2) {
msum++;
if (msum == 5) {
outtextxy(800,510,"获胜者:");
putimage(900,500,&white);
MessageBox(h, "游戏结束 白方左斜满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
turn = 0;
chooseType = 0;
return 2;//连续五个白子,白方胜返回2
}
}
else
msum = 0;
}
}
return 0;
}
int main()
{
loadimage(&mainpicture, ("2.jpg"));
loadimage(&background, ("1.jpg"));
loadimage(&renren, ("人人.png"));
loadimage(&renji, ("人机.png"));
loadimage(&surrender, ("认输.png"));
loadimage(&black, "black.png");
loadimage(&white, "white.png");
initgraph(1030, 750);
h = GetHWnd();//获取绘图窗口句柄
//SetWindowLong(h , GWL_STYLE , GetWindowLong(h,GWL_STYLE)-WS_CAPTION);//去掉标题栏
//SetWindowPos(h , HWND_TOP , 0 , 0 , GetSystemMetrics(SM_CXSCREEN) , GetSystemMetrics(SM_CXSCREEN) , SWP_SHOWWINDOW);//窗口全屏
settextcolor(BLACK);
setbkmode(TRANSPARENT);
setfillcolor(RGB(255,0,0));
putimage(-20,0,&mainpicture);
//drawchessboard();
XiaQi();
_getch();
closegraph();
return 0;
}源码链接在这
链接: https://pan.baidu.com/s/1uJM1deIpMj4M1V3szzAhWw 提取码: 8bzk 复制这段内容后打开百度网盘手机App,操作更方便哦
链接: https://pan.baidu.com/s/1uJM1deIpMj4M1V3szzAhWw 提取码: 8bzk 复制这段内容后打开百度网盘手机App,操作更方便哦
页:
[1]