基于GEC6818的五子棋游戏

2023-10-18 15:30
文章标签 游戏 五子棋 gec6818

本文主要是介绍基于GEC6818的五子棋游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基本的五子棋游戏,有UI界面,能悔棋,需要预装驱动和文件才能运行。

设计思路流程图

以下是代码

main.c

#include <stdio.h>
#include "bmp.h"
#include "game.h"
#include "lcd.h"	
#include <stdlib.h>		//	abs 的头文件int main()
{//屏幕初始化unsigned int *plcd = lcd_init();game://开始操作屏幕Display_homepage("gobang.bmp",plcd);    //封面图片//播放背景音乐system("killall -KIll madplay");system("madplay -Q 2.mp3 -a -20 &");//Game_play( plcd);goto game;//关闭屏幕lcd_end( plcd);return 0 ;
}

lcd.c        操作屏幕函数的封装

#include <stdio.h>
#include <sys/types.h>	//	open 头文件
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>		//	read、write、close 头文件
#include <sys/mman.h>	//	mmap 的头文件
#include "lcd.h"		//	用到哪个函数就得 加上 对应的头文件int lcd_fd = -1;		//	全局变量/*lcd_init:	屏幕初始化 打开 + 映射返回值:		第一个像素点的地址
*/
unsigned int *lcd_init()
{//	1、打开屏幕文件lcd_fd = open("/dev/fb0",O_RDWR);	//	读写打开 显示屏if(lcd_fd == -1){perror("open error");		//	显示错误原因return NULL;}//	2、屏幕映射unsigned int *plcd = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,lcd_fd,0);if(plcd == MAP_FAILED){perror("mmap error");		//	显示错误原因return NULL;}return plcd;
}/*lcd_end:	屏幕扫尾 解映射 + 关闭返回值:		第一个像素点的地址
*/
void lcd_end(unsigned int *plcd)
{//	4、解除映射munmap(plcd,800*480*4);//	5、关闭屏幕文件close(lcd_fd);}

lcd.h        

#ifndef __LCD_H__		//	固定格式
#define __LCD_H__		//	固定格式/*lcd_init:	屏幕初始化 打开 + 映射返回值:		第一个像素点的地址
*/
unsigned int *lcd_init();/*lcd_end:	屏幕扫尾 解映射 + 关闭返回值:		第一个像素点的地址
*/
void lcd_end(unsigned int *plcd);#endif		//	固定格式

bmp.c        UI界面及屏幕输入的封装

#include "bmp.h"
#include "game.h"
#include <stdlib.h>		//	abs 的头文件// 居中显示图片
void Display_homepage(char *bmp_name,unsigned int * plcd)  
{//	1、打开图片文件int fd = open(bmp_name,O_RDWR);	//	读写打开 图片if(fd == -1){perror("open error");		//	显示错误原因return ;}//	2、判断图片是不是 BMP char buf[2];read(fd,buf,2);if(!(buf[0] == 'B' && buf[1] == 'M')){printf("你是不是憨批,转换不会\n");return ;}//	3、解析 位宽 位高 色深int width;lseek(fd,0x12,SEEK_SET);	//	定位到指定的位置read(fd,&width,4);		//	读取 4 字节的宽度int height;lseek(fd,0x16,SEEK_SET);	//	定位到指定的位置read(fd,&height,4);		//	读取 4 字节的高度short depth;lseek(fd,0x1c,SEEK_SET);	//	定位到指定的位置read(fd,&depth,2);		//	读取 2 字节的高度printf("%s:%d,%d,%d\n",bmp_name,width,height,depth);//	4、获取像素数组//	一行实际大小:int line_bytes = abs(width) * depth/8;int laizi = 0;		//	可能需要补充的字节数目if(line_bytes % 4){laizi = 4 - line_bytes % 4;}//	一行保存总大小:int linebytes = line_bytes + laizi;//	像素数组总大小:int bytes = linebytes * abs(height);//	读取像素数组:	unsigned char array[bytes];	lseek(fd,0x36,SEEK_SET);	//	定位到指定的位置read(fd,array,bytes);//	5、显示图片unsigned char a,r,g,b;		//	保存每个像素点颜色值分量int i,j,k = 0;for(i = 0;i < abs(height);i++)		//	一行一行的显示{for(j = 0;j < abs(width);j++)	//	一行每个像素点依次显示{b = array[k++];		//	获取当前像素点的 蓝色分量g = array[k++];		//	获取当前像素点的 绿色分量r = array[k++];		//	获取当前像素点的 红色分量if(depth == 32){a = array[k++];	//	获取当前像素点的 透明分量}else{a = 0;}unsigned int color = a << 24 | r << 16 | g << 8 | b;		//	合成当前像素点的颜色int x = width > 0 ? j : (abs(width) - 1 - j);		//	width > 0 从左到右,反之从右到左 0开始的int y = height > 0 ? (abs(height) - 1 - i) : i;		//	height > 0 从下到上,反之从上到下 0开始的int m=(800-abs(width))/2;int n=(480-abs(height))/2;display_point(x+m,y+n,color,plcd);}k += laizi;		//	跳过加上的癞子}//	6、关闭图片文件close(fd);}void Display_qipan()      //生成棋盘页面
{   //打开屏幕文件int fd = open("/dev/fb0",O_RDWR);unsigned int *plcd = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);display_pic("duolah.bmp",plcd,0,0);//黑方display_pic("duolaw.bmp",plcd,600,0);//白方//生成棋盘for(int i = 0;i <= 480;i++){for(int j = 120;j <= 600;j++){if((i%30 -15 == 0||j%30 - 15 == 0)&& i >= 15&&i <= 465&&j >= 135&&j <= 585)display_point(j, i,0x00, plcd);else{display_point(j, i,0xCDAA7D,plcd);}}}munmap(plcd,800*480*4);  close(fd);		
}//设定位置显示图片
void display_pic(char *bmp_name,unsigned int * plcd,int m ,int n) 
{//	1、打开图片文件int fd = open(bmp_name,O_RDWR);	//	读写打开 图片if(fd == -1){perror("open error");		//	显示错误原因return ;}//	2、判断图片是不是 BMP char buf[2];read(fd,buf,2);if(!(buf[0] == 'B' && buf[1] == 'M')){printf("你是不是憨批,转换不会\n");return ;}//	3、解析 位宽 位高 色深int width;lseek(fd,0x12,SEEK_SET);	//	定位到指定的位置read(fd,&width,4);		//	读取 4 字节的宽度int height;lseek(fd,0x16,SEEK_SET);	//	定位到指定的位置read(fd,&height,4);		//	读取 4 字节的高度short depth;lseek(fd,0x1c,SEEK_SET);	//	定位到指定的位置read(fd,&depth,2);		//	读取 2 字节的高度/*printf("%s:%d,%d,%d\n",bmp_name,width,height,depth);*///	4、获取像素数组//	一行实际大小:int line_bytes = abs(width) * depth/8;int laizi = 0;		//	可能需要补充的字节数目if(line_bytes % 4){laizi = 4 - line_bytes % 4;}//	一行保存总大小:int linebytes = line_bytes + laizi;//	像素数组总大小:int bytes = linebytes * abs(height);//	读取像素数组:	unsigned char array[bytes];	lseek(fd,0x36,SEEK_SET);	//	定位到指定的位置read(fd,array,bytes);//	5、显示图片unsigned char a,r,g,b;		//	保存每个像素点颜色值分量int i,j,k = 0;/*printf("请输入起始位置: ");scanf("%d,%d",&m,&n);*/for(i = 0;i < abs(height);i++)		//	一行一行的显示{for(j = 0;j < abs(width);j++)	//	一行每个像素点依次显示{b = array[k++];		//	获取当前像素点的 蓝色分量g = array[k++];		//	获取当前像素点的 绿色分量r = array[k++];		//	获取当前像素点的 红色分量if(depth == 32){a = array[k++];	//	获取当前像素点的 透明分量}else{a = 0;}unsigned int color = a << 24 | r << 16 | g << 8 | b;		//	合成当前像素点的颜色int x = width > 0 ? j : (abs(width) - 1 - j);		//	width > 0 从左到右,反之从右到左 0开始的int y = height > 0 ? (abs(height) - 1 - i) : i;		//	height > 0 从下到上,反之从上到下 0开始的display_point(x+m,y+n,color,plcd);}k += laizi;		//	跳过加上的癞子}//	6、关闭图片文件close(fd);}/*display_point:	在(x,y)显示一个颜色为 color 的点@x:		x 坐标@y:		y 坐标@color:	要显示颜色@plcd:	第一个像素点的地址(mmap 的返回值)
*/
void display_point(int x,int y,unsigned int color,unsigned int *plcd)
{if(x >= 0 && x < 800 && y >= 0 && y < 480)	//	防止憨批{*(plcd + y * 800 + x) = color;}
}//获取触屏坐标
struct point get_point()
{struct point xy = {-1,-1};			//	保存实时坐标//	1、打开文件int fd = open("/dev/input/event0",O_RDWR);	//	读写打开 触摸屏if(fd == -1){perror("open error");		//	显示错误原因return xy;}//	2、操作文件	writestruct input_event ev;		//	保存读取到的输入信息while(1){read(fd,&ev,sizeof(ev));if(ev.type == EV_ABS && ev.code == ABS_X){xy.x = ev.value;		//	保存 x 坐标}else if(ev.type == EV_ABS && ev.code == ABS_Y){xy.y = ev.value;		//	保存 y 坐标}else if(ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0)	//	手离开屏幕{break;}}//	3、关闭文件close(fd);return xy;
}

bmp.h

#ifndef __BMP_H__
#define __BMP_H__
#include <stdio.h>
#include "game.h"
struct point		//	保存触摸屏的坐标 point 对应两个值 point.x point.y
{int x;int y;
};void Display_qipan();
void Display_homepage(char *bmp_name,unsigned int * plcd);
void display_point(int x,int y,unsigned int color,unsigned int *plcd);
void display_pic(char *bmp_name,unsigned int * plcd,int m ,int n) ;
struct point get_point();#endif

gsme.c        游戏的算法

#include "bmp.h"
#include "game.h"
#include <stdlib.h>		//	abs 的头文件int turn = 0;  //回合数
unsigned int Game_buf[16][17]={0};//存储16*16每个点/*答辩结束后发现此处存在bug*/
unsigned int Game_buf2[10][16][17]={0};//存储10局16*16每个点int Game_sta(int x,int y,unsigned int *plcd) //游戏开始 像素点坐标
{//得到棋盘坐标位置 int X = abs(x - 120) / 30;		//	120 = 135-(30/2)int Y = abs(y - 0) / 30;	//	0=15-(30/2);printf("落子位置为%d,%d \n",X,Y);//	将落棋状态写入数组 0/1/2 分别代表 空/黑/白if(Game_buf[X][Y]==0)	//避免重复落子{//轮数加1	for (int i = 0; i < 16; i++){for (int j = 0; j < 16; j++){	Game_buf2[turn][i][j] = Game_buf[i][j];		//保存 落子前所有的棋子位置}}turn++;if(turn	% 2){Game_buf[X][Y]=1; Luozi(X * 30 + 135,Y * 30 + 15,turn,plcd);}else{Game_buf[X][Y]=2;Luozi(X * 30 + 135,Y * 30 + 15,turn,plcd);} }	//提醒下棋if(turn & 1)//黑方下完提示白方{display_pic("baiturn.bmp", plcd,600,175);}else{display_pic("heiturn.bmp", plcd,600,175);} //游戏结束判定turn = Game_Over(X,Y,plcd,turn);return turn ;
}//显示落子
int Luozi(int x,int y,int turn,unsigned int *plcd)
{int i,j;if (turn & 1)//执黑方先落子{for (i = 0; i < 800; i++){for (j = 0; j < 480; j++){if ((i-x)*(i-x)+(j-y)*(j-y)<=100)//生成半径为10的棋子{display_point(i, j, 0X000000,plcd);}}}printf("执白者已落子 \n");}else{for(i=0;i<800;i++){for(j=0;j<480;j++){	if((i-x)*(i-x)+(j-y)*(j-y)<=100){display_point(i,j,0xffffff,plcd);}}}printf("执黑者已落子 \n");}
}//悔棋
int regret(int x,int y,unsigned int *plcd)
{	if(turn){turn--;		//回合数减1	//存储   复位悔棋前的棋子布局for(int i = 0;i < 16;i++){for(int j = 0;j < 16;j++){Game_buf[i][j]=Game_buf2[turn][i][j]; //棋盘复位}}// 显示   复位悔棋前的棋子布局Display_qipan();for(int i = 0;i < 16;i++){for(int j = 0;j < 16;j++){int X = abs(x - 120) / 30;		//	120 = 135-(30/2)int Y = abs(y - 0) / 30;	//	0=15-(30/2);if(Game_buf[i][j] == 1){Luozi(i * 30 + 135,j * 30 + 15,1,plcd);}if(Game_buf[i][j] == 2){Luozi(i * 30 + 135,j * 30 + 15,2,plcd);}}}}else{printf("棋盘中已无棋子 \n");}}//清空棋盘
int clear()
{for(int a=0;a<16;a++){for(int b=0;b <16;b++){Game_buf[a][b]=0;for (int c= 0; c < 10; c++){Game_buf2[c][a][b]=0;}}}turn = 0 ;printf("已清盘 \n");
}//游戏结束条件
int Game_Over(int x,int y,unsigned int * plcd,int turn)  //棋盘落子坐标
{int x1 = 0,y1 = 0,xy1 = 0,xy2 = 0;//四个方向的累计数for(int i = -4;i < 5;i ++){//水平方向判定if(Game_buf[x][y] == Game_buf[x + i][y] )		{   x1++;printf("x1值为 %d\n",x1);if(x1 == 5){break;}}else{x1 = 0;}//竖直方向判定	if(Game_buf[x][y] == Game_buf[x][y + i])		{y1++;printf("y1值为 %d\n",y1);if(y1 == 5){break;}}else{y1 = 0;}//Y=X方向判定if(Game_buf[x][y] == Game_buf[x + i][y + i])		{xy1++;printf("xy1值为 %d\n",xy1);if(xy1 == 5){break;}}else{xy1 = 0;}//Y=-X方向判定if(Game_buf[x][y] == Game_buf[x - i][y+i])		{xy2++;printf("xy2值为 %d\n",xy2);if(xy2 == 5){break;}}else{xy2 = 0;}}if( x1 == 5||y1 == 5||xy1 == 5||xy2 == 5)//结束条件{if(turn & 1){Display_homepage("heiwin.bmp", plcd);/*system("killall -KIll madplay");system("madplay -Q 3.mp3 &");*/}else{Display_homepage("baiwin.bmp", plcd);/*system("killall -KIll madplay");system("madplay -Q 4.mp3 &");*/}clear();	//清理棋盘sleep(3);	//复盘时间Display_qipan();//播放背景音乐system("killall -KIll madplay");system("madplay -Q 2.mp3 -a -20 &");return 0;}else{return turn;}}int Game_play(unsigned int *plcd)
{while(1){struct point p = get_point();printf("%d,%d\n",p.x,p.y);if (p.x>370&&p.x<625&&p.y>520&&p.y<600)  //进入游戏,生成棋盘{Display_qipan();					clear();system("killall -KIll madplay");system("madplay -Q 2.mp3 -a -20 &");printf("开始下棋 \n");break;}else{printf("请点击指定区域 \n");}}while(1){struct point p = get_point();printf("%d,%d\n",p.x,p.y);int x1 = p.x * 800 / 1024,y1 = p.y * 480 / 600; 	//触屏坐标转化为像素点坐标			if (x1>120&&x1<600&&y1>0&&y1<480)  // 在范围内落子{//开始游戏Game_sta(x1,y1,plcd);}else if(x1>600&&x1<800&&y1>0&&y1<75||x1>0&&x1<120&&y1>0&&y1<80)//		悔棋{	regret(x1,y1,plcd);}else if (y1>400&&y1<480&&x1>600&&x1<800){printf("返回主界面 \n");break ;}} }

game.h

#ifndef __GAME_H__
#define __GAME_H__#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <math.h>
#include <linux/input.h>struct point get_point();
int Game_sta(int x,int y,unsigned int *plcd);
int save(int turn);int Luozi(int x,int y,int turn,unsigned int *plcd);
int clear();
int regret(int x,int y,unsigned int *plcd);int Game_Over(int x,int y,unsigned int * plcd,int turn);
int Game_play(unsigned int *plcd);#endif

项目展示

项目讲解

这篇关于基于GEC6818的五子棋游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/233454

相关文章

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

第四次北漂----挣个独立游戏的素材钱

第四次北漂,在智联招聘上,有个小公司主动和我联系。面试了下,决定入职了,osg/osgearth的。月薪两万一。 大跌眼镜的是,我入职后,第一天的工作内容就是接手他的工作,三天后他就离职了。 我之所以考虑入职,是因为 1,该公司有恒歌科技的freex平台源码,可以学学,对以前不懂的解解惑。 2,挣点素材钱,看看张亮002的视频,他用了6000多,在虚幻商城买的吸血鬼游戏相关的素材,可以玩两年。我

nyoj 1038 纸牌游戏

poj 的一道改编题,说是翻译题更恰当,因为只是小幅度改动。 一道模拟题,代码掌控能力比较好,思维逻辑清晰的话就能AC。 代码如下: #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{char c[5];int rk;char da[5];int nu

如果出一个名叫白神话悟空的游戏

最近黑神话由于与原著不符引起了原著派的争议。 所以我在摸鱼的时候想到如果游科或者某个别的公司“痛改前非”不夹带私货完全复刻吴承恩百回版剧情制作一个“重走西游路”的游戏,会有一个什么样的销量?(设定为原著派已经多方渠道认证,此游戏的确没有夹带私货,绝大部分复刻了原著剧情) 游戏玩法我想了几类 超长线性有岔路蜈蚣形状地图,蜈蚣的腿部是探索区域和支线,重走西游路线,开篇就是开始取经前唐玄宗御弟cg

8阶段项目:五子棋(附带源码)

8阶段项目:五子棋 8.1-技术实现 1.静态变量 静态变量只能定义在类中,不能定义在方法中。静态变量可以在static修饰的方法中使用,也可以在非静态的方法中访问。主要解决在静态方法中不能访问非静态的变量。 2.静态方法 静态方法就相当于一个箱子,只是这个箱子中装的是代码,需要使用这些代码的时候,就把这个箱子放在指定的位置即可。   /*** 静态变量和静态方法*/public cl

《黑暗之魂2:原罪学者》是什么类型的游戏 《黑暗之魂》可以在苹果Mac电脑上玩吗?

在宏大的世界观游戏中,《黑暗之魂2:原罪学者》脱颖而出,以其探索性和挑战性征服了全球玩家的心灵。下面我们来看看《黑暗之魂2:原罪学者》是什么类型的游戏,《黑暗之魂2:原罪学者》可以在苹果电脑玩吗的相关内容。 一、《黑暗之魂2:原罪学者》是什么类型的游戏 《黑暗之魂2:原罪学者》作为《黑暗之魂2》的增强版和重制版,是一款FromSoftware制作、BANDAI NAMCO和FromSoft

简单取石子游戏~博弈

很坑爹的小游戏,至于怎么坑爹,嘎嘎~自己研究去吧~! #include<stdio.h>#include<windows.h>#include<iostream>#include<string.h>#include<time.h>using namespace std;void Loc(int x,int y);/*定位光标*/void Welcome(); /*创建欢迎界面*/