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

前言

首先感谢您能打开我的文章,希望您能看完,有不对或者可以改进的地方,留言在下面,再次感谢。把之前写的的一个五子棋游戏共享出来,希望大家喜欢。自己把学习过程的一些方法和笔记,以及针对出现的各种错误解决方法共享在博客里面。虽然自己很菜,但我还是会一如既往的分享,努力变的优秀,会一直努力不断地改进。希望对您有帮助。

开发工具

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格式的,看代码的时候横屏看效果好点。

猜你喜欢

转载自blog.csdn.net/qq_45893999/article/details/106479602