实战项目教你一步步写完五子棋

开发工具

VS2013
easyx图形库 官网下载

效果展示

在这里插入图片描述

流程图

在这里插入图片描述

构建框架

#include<easyx.h>
#include<stdio.h>
void drawMenu()//菜单
{
}
void init()//初始化
{
}
void draw()//绘制
{
}
bool is_win()//游戏是否结束
{
}
void play_game()//玩家交互
{
}
void run_game()//开始游戏
{
	init();//初始化
	while (true)
	{
		play_game();//玩游戏
		draw();//绘制
		if (is_win())//判断一下是否结束
		{
			//重新开始或者跳出
		}
	}
}
int main()
{
    drawMenu();//菜单
	run_game();
	system("pause");
	return 0;
}

逻辑关系

先绘制菜单,然后绘制棋盘
画棋子
使用循环语句结合判断语句实现五子棋效果

for (int i = 0; i < N; i++)//N行
for (int j = 0; j < N; j++)//N列
if (chess[i][j] == 0)
	continue;
if (chess[i][j] == 1)//画黑棋
	setfillcolor(BLACK);
if (chess[i][j] == 2)//画白棋
	setfillcolor(WHITE);
solidcircle(size*(j+1), size*(i+1), size / 4);//棋子大小

获取鼠标点击事件

MOUSEMSG msg = GetMouseMsg();
msg.uMsg == WM_LBUTTONDOWN//鼠标操作左键按下

计算鼠标点击的位置
设置棋盘数据
胜利判断:黑棋或者白棋,出现五个棋子连在一起即胜利。
在这里插入图片描述
从玩家点击事件上确定点击的位置
从每次的点击位置进行判断
胜利后重新开始游戏
x轴是左向右的,y轴是从上往下的。在数学中(x,y)
在这里插入图片描述
而在计算机中数组arr[i][j] i的值放在第一位。
在这里插入图片描述
在这里插入图片描述

源代码

#include<stdio.h>
#include<stdlib.h>
#include<easyx.h>//图形库头文件
#include<mciapi.h>//音乐播放头文件
#pragma comment(lib,"winmm.lib")
#define N 15 //格子数目15*15
int length = 500;//棋盘大小
float size;//每一个格子大小
int chess[N][N];//棋位置
bool is_init;//是否初始化
bool is_black;//是否黑棋
bool is_gameover;//是否游戏结束
void drawMenu()//菜单
{
	initgraph(500, 500);//菜单窗口大小 500 500
	setbkcolor(WHITE);//背景颜色
	cleardevice();//屏幕填充成背景色
	setfillcolor(BLUE);//填充颜色
	settextstyle(25, 0, L"宋体");//字体样式
	setbkmode(TRANSPARENT);//样式
	fillrectangle(190, 100, 310, 150);//在指定位置画矩形
	fillrectangle(190, 100 + 60, 310, 150 + 60);
	outtextxy(190+ 10, 100 + 13, L"开始游戏");//在指定位置输出文字
	outtextxy(190 + 10, 100 + 13 + 60, L"退出游戏");
	settextcolor(RED);//字体颜色
	outtextxy(130, 280, L"追梦五子棋游戏v1.2.0版本");
	MOUSEMSG m;//鼠标事件
	while (1)
	{
		m = GetMouseMsg();
		if (m.x >= 190 && m.x <= 310 && m.y >= 100 && m.y <= 150)
		{
			setlinecolor(BLACK);
			rectangle(190 - 5, 100 - 5, 310 + 5, 150 + 5);
			if (m.uMsg == WM_LBUTTONDOWN)//鼠标左键按下
			{
				break;
			}
		}
		else if (m.x >= 190 && m.x <= 310 && m.y >= 160 && m.y <= 210)
		{
			setlinecolor(BLACK);
			rectangle(190 - 5, 160 - 5, 310 + 5, 210 + 5);
			if (m.uMsg == WM_LBUTTONDOWN)
			{
				exit(0);
			}
		}
		else
		{
			setlinecolor(WHITE);
			rectangle(190 - 5, 100 - 5, 310 + 5, 150 + 5);
			rectangle(190 - 5, 160 - 5, 310 + 5, 210 + 5);
		}
	}
	closegraph();
}
void init()//初始化
{
	initgraph(length, length);
	if (!is_init)//是否初始化
	{
		memset(chess, 0, sizeof(chess));
	}
	is_init= true;
	memset(chess, 0, sizeof(chess));
	size = (float)length / (N + 1);
	is_black = true;
	is_gameover = false;
}
void draw_chess()//画棋子
{
	for (int i = 0; i < N; i++)//N行
	{
		for (int j = 0; j < N; j++)//N列
		{
			if (chess[i][j] == 0)
			{
				continue;
			}
			if (chess[i][j] == 1)//黑棋
			{
				setfillcolor(BLACK);
			}
			if (chess[i][j] == 2)//白棋
			{
				setfillcolor(WHITE);
			}
			solidcircle(size*(j+1), size*(i+1), size / 4);//棋子大小
		}
	}
}
void draw_background()//画棋盘
{
	setbkcolor(BLUE);//棋子颜色
	cleardevice();//屏幕填充成背景色
	setlinecolor(BLACK);//线条颜色
	settextcolor(RED);//数字颜色
	for (int i = 1; i <= N; i++)//画线
	{
		line(size, size*i, length - size, size*i);//横线
		line(size*i, size, size*i, length - size);//竖线
		TCHAR nums[3];
		wsprintf(nums, _T("%d"), i);
		outtextxy(size - size / 2, size*i - size / 8, nums);
		outtextxy(size*i - size / 8, size - size / 2, nums);
	}
	//绘制圆点
	setfillcolor(0x0);
	int m = 3;
	fillcircle(size*m, size*m, size / 8);
	fillcircle(size*m, size*(N - m + 1), size / 8);
	fillcircle(size*(N - m + 1), size*m, size / 8);
	fillcircle(size*(N - m + 1), size*(N - m + 1), size / 8);
	fillcircle(size*(N / 2 + 1), size*(N / 2 + 1), size / 8);
}
void draw()//批量加载绘制
{
	BeginBatchDraw();
	draw_background();
	draw_chess();
	EndBatchDraw();
}
bool is_win(int x,int y)//是否胜利
{
	if (chess[y][x] == 0)
	{
		return false;
	}
	int dir[][2] = { { 0, 1 }, { 1, 0 }, { 1, 1 }, { 1, -1 } };
	for (int i = 0; i < 4; i++)
	{
		int contion = 1;
		bool f1 = true, f2 = true;
		for (int j = 1; j < 5; j++)
		{
			int dx = x + dir[i][1] * j;
			int dy = y + dir[i][0] * j;
			int rx = x - dir[i][1] * j;
			int ry = y - dir[i][0] * j;
			if (dx >= 0 && dx < N&&dy >= 0 && dy < N&&chess[dy][dx] == chess[y][x])
			{
				contion++;
			}
			else
			{
			    f1=false;
			}
			if (rx >= 0 && ry < N&&rx < N&&ry >= 0 && chess[y][x] == chess[ry][rx])
			{
				contion++;
			}
			else
			{
				f2=false;
			}
		}
		if (contion >= 5)
		{
			return true;
		}
	}
	return false;
}
void play_game()//游戏过程 玩家交互
{
	MOUSEMSG msg = GetMouseMsg();
	if (msg.uMsg == WM_LBUTTONDOWN)//鼠标操作左键按下
	{
		int x = (msg.x-size/2) / size;
		int y = (msg.y-size/2) / size;
		if (chess[y][x] == 0 && x >= 0 && x < N&&y >= 0 && y < N)
		{
			chess[y][x]=is_black ? 1 : 2;
			if (is_win(x, y))
			{
				is_gameover = true;
				return;
			}
			is_black = !is_black;
		}
	}
}
void run_game()//开始游戏
{
	init();
	while (true)
	{
		play_game();
		draw();
		if (is_gameover)
		{
			if (is_black)//黑棋胜利
			{
				MessageBox(GetHWnd(), _T("黑棋胜利"), _T("游戏结束"), 0);
			}
			else
			{
				MessageBox(GetHWnd(), _T("白棋胜利"), _T("游戏结束"), 0);
			}
			init();
		}
	}
}
int main()//主函数
{
	mciSendString(L"open txz.mp3", 0, 0, 0);//打开音乐
	mciSendString(L"play txz.mp3", 0, 0, 0);//播放音乐
	drawMenu();//菜单
	run_game();//游戏过程
	system("pause");
	return 0;
}

导入图标

导入一下这个图标
在这里插入图片描述
第一步
在这里插入图片描述
第二步
在这里插入图片描述

总结

完成五子棋游戏,需要安装图形库,以及它里面的相关知识,思路理清楚啦,写起来就容易多了。注意最后导入图标是.ico格式的,看代码的时候横屏看效果好点。

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
#include<graphics.h> #include<conio.h> #include <mmsystem.h> #pragma comment(lib,"winmm.lib") void Beginning(); //开始图片 void Background(); //显示背景 void ShowPlate(); //显示棋盘 void PlayGame(); //玩游戏 void Judgewin(int,int); //判断输赢 void Blackwin(); //黑棋赢 void Whitewin(); //白棋赢 bool flag=true; //走棋顺序 int piece[16][16]; //棋子变量 int ti,tj; int f=1; void main() { for(int i=0;i<16;i++) for(int j=0;j<16;j++) piece[i][j]=0; //初始化棋子变量 initgraph(965,642); //设置窗口大小 mciSendString("play 2.mp3",0,0,0);//播放背景音乐 Background(); //显示背景 PlayGame(); //玩游戏 getch(); //保持窗口开着 } void Background() { IMAGE img; getimage(&img, "2.jpg"); putimage(0,0, &img); //设置背景图片 } void ShowPlate() { setfillstyle(RGB(213,176,146)); bar(270,30,730,490); //棋盘大小 for(int x=290,y=50;x<=710,y<=470;x+=30,y+=30) //画棋盘线 { setcolor(BLACK); line(x,50,x,470); line(290,y,710,y); } setfillstyle(BLACK); bar(284,44,286,476); bar(284,44,716,46); bar(714,44,716,476); bar(284,474,716,476);//棋盘线周围的一圈粗线 fillellipse(380,140,4,4); fillellipse(620,140,4,4); fillellipse(380,380,4,4); fillellipse(620,380,4,4); fillellipse(500,260,4,4);//棋盘的五个小黑点 setcolor(BLACK); setfillstyle(RGB(213,176,146)); bar3d(800,100,900,140,0,0); bar3d(800,200,900,240,0,0); bar3d(800,300,900,340,0,0); setfont(24,0,"华文行楷"); outtextxy(805,110,"重新开始");//重新开始 按钮 outtextxy(827,210,"悔棋");//悔棋按钮 outtextxy(827,310,"投降");//投降按钮 setcolor(RGB(213,176,146)); setfillstyle(WHITE); fillellipse(820,28,20,20); setcolor(RGB(213,176,146)); setfillstyle(BLACK); fillellipse(880,28,20,20); for(int i=0;i<15;i++) { for(int j=0;j<15;j++) { if(piece[i][j]==-1) { setcolor(WHITE); setfillstyle(WHITE); fillellipse(290+j*30,50+i*30,12,12); } else if(piece[i][j]==1) { setcolor(BLACK); setfillstyle(BLACK); fillellipse(290+j*30,50+i*30,12,12); } } } } void PlayGame() { int h=0; int y=0; int Y; int ti=0,tj=0; while(f) { MOUSEMSG msg=GetMouseMsg(); //得到鼠标输入 while(msg.uMsg==WM_LBUTTONUP) { h++; if(h==1) { ShowPlate(); } else break; } if(h>2) { int a,b,c,d; a=(msg.x-290)%30; b=(msg.y-50)%30; c=(msg.x-290)/30+a/15;//落子点的横坐标 d=(msg.y-50)/30+b/15;//落子点的纵坐标 if(msg.x>800&&msg.x<840&&msg.y>8&&msg.y<48&&y==0) flag=false; else if(msg.x>860&&msg.x<900&&msg.y>8&&msg.y<48&&y==0) flag=true; if(a==15||b==15) //判断是否在两格中间 continue; if(msg.uMsg==WM_LBUTTONUP&&piece[d][c]==0&&(c>=0&&c<15&&d>=0&&d<15)) //判断是否在棋盘内且无棋子 { mciSendString("play 3.mp3",0,0,0); if(flag==true) { piece[d][c]=1; setcolor(BLACK); setfillstyle(BLACK); fillellipse(290+c*30,50+d*30,12,12); flag=false; ti=d; tj=c; y++; } else { piece[d][c]=-1; setcolor(WHITE); setfillstyle(WHITE); fillellipse(290+c*30,50+d*30,12,12); flag=true; ti=d; tj=c; y++; } } Judgewin(c,d); if(msg.uMsg==WM_LBUTTONUP) if((msg.x>=800&&msg.x<=900)&&(msg.y>=300&&msg.y<=340)) //投降 { if(flag==true) Whitewin(); else Blackwin(); } if(msg.uMsg==WM_LBUTTONUP) if((msg.x>=800&&msg.x<=900)&&(msg.y>=100&&msg.y<=140)) //中途重新开始 { y=0; for (c=0;c<16;c++) { for (d=0;d<16;d++) { piece[c][d]=0; } } ShowPlate(); } if(msg.uMsg==WM_LBUTTONUP) { if ((msg.x>=800&&msg.x<=900)&&(msg.y>=200&&msg.y<=240)&&(Y!=y)) //悔棋 { Y=y; if(flag==true) flag=false; else flag=true; piece[ti][tj]=0; ShowPlate(); } } } while(!f) //结束后重新开始 { MOUSEMSG msg=GetMouseMsg(); if(msg.uMsg==WM_LBUTTONUP) if((msg.x>=800&&msg.x<=900)&&(msg.y>=100&&msg.y<=140)) { for (int c1=0;c1<16;c1++) { for (int d1=0;d1<16;d1++) { piece[c1][d1]=0; } } ShowPlate(); f=1; PlayGame(); } } } } void Judgewin(int c,int d) { for(int i=0;i<15;i++)//判断是否五子连珠——横向 { int s=0; for(int j=i;j<i+5;j++) { s=s+piece[d][j]; if(s==5) Blackwin(); if(s==-5) Whitewin(); } } for(int m=0;m<15;m++)//判断是否五子连珠——纵向 { int s=0; for(int n=m;n<m+5;n++) { s=s+piece[n][c]; if(s==5) Blackwin(); if(s==-5) Whitewin(); } } for(int p=d-5,q=c-5;p<15;p++,q++)//判断是否五子连珠——左上到右下 { int s=0; for(int t=0;t<5;t++) { s=s+piece[p+t][q+t]; if(s==5) Blackwin(); if(s==-5) Whitewin(); } } for(int P=d+5,Q=c-5;Q<15;P--,Q++)//判断是否五子连珠——左下到右上 { int s=0; for(int t=0;t<5;t++) { s=s+piece[P-t][Q+t]; if(s==5) Blackwin(); if(s==-5) Whitewin(); } } } void Blackwin() { setcolor(WHITE); setfillstyle(BLACK); fillellipse(500,260,70,30); outtextxy(470,250,"黑子赢"); f=0; mciSendString("play 4.mp3",0,0,0); } void Whitewin() { setcolor(BLACK); setfillstyle(WHITE); fillellipse(500,260,70,30); outtextxy(470,250,"白子赢"); f=0; mciSendString("play 4.mp3",0,0,0); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘客-追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值