编程小白(暂时还没有自动判断输赢功能)
手动设置:
首先把系统屏幕分辨率改为1024*768的分辨率
代码部分:
1、调用系统IO打开设备文件:/dev/fb0
2、调用ioctl函数控制屏幕设备
3、调用mmap把屏幕文件映射到内存当中
4、用系统IO打开键盘设备文件:/dev/input/event1
5、调用tcgetattar、tcsetattar函数来获得、修改终端信息(通过上下左右键控制光标移动,按下回车键下棋)
6、代码实现
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <linux/input.h>
#include <termios.h>
int fb,ret,byte;
struct fb_var_screeninfo var;//定义了可变屏幕信息的结构体类型变量
struct fb_fix_screeninfo fix;//定义了固定屏幕信息的结构体类型变量
void *pv = NULL;//用于保存映射内存空间的地址
char *pc = NULL;//用于操作一个字节的指针
int *pi = NULL;//用于32位色的指针
unsigned long offset = 0;//用于存储文件偏移量
int x = 0,y = 0;
int a=380,b=380;
int k = -1;
int winer = 0;
int arr[1024][768] = {{0},{0}};
void display()//展示棋盘
{
int color = 0xFFFFFF;//颜色为白色
for(x = 100;x <= 660;x+=40)
{
for(y = 100;y <= 660;y++)
{
offset = byte * x + y * fix.line_length;//计算偏移量
pi = (unsigned int *)(pc + offset);
*(pi) = color;
}
}
for(x = 100;x <= 660;x++)
{
for(y = 100;y <= 660;y+=40)
{
offset = byte * x + y * fix.line_length;//计算偏移量
pi = (unsigned int *)(pc + offset);
*(pi) = color;
}
}
}
void draw_flag(int x0,int y0,int r,int color)//画正方形的函数
{
int x = 0;
int y = 0;
for(x = x0-r;x <= x0+r;x++)
{
for(y = y0-r;y <= y0+r;y++)
{
offset = byte * x + y * fix.line_length;//计算偏移量
pi = (unsigned int *)(pc + offset);
*(pi) = color;
}
}
}
void draw_cir(int x0,int y0,int r,int color)//画圆的函数
{
int x = 0;
int y = 0;
for(x = x0-r;x <= x0+r;x++)
{
for(y = y0-r;y <= y0+r;y++)
{
if((x-x0)*(x-x0)+(y-y0)*(y-y0) <= r*r)
{
offset = byte * x + y * fix.line_length;//计算偏移量
pi = (unsigned int *)(pc + offset);
*(pi) = color;
}
}
}
}
int main()
{
int i,j;
fb = open("/dev/fb0",O_RDWR);
if(fb < 0)
{
perror("open()");
exit(-1);
}
ret = ioctl(fb,FBIOGET_VSCREENINFO,&var);
if(ret < 0)
{
perror("ioctl()");
close(fb);
exit(-2);
}
byte = var.bits_per_pixel >> 3;//计算一个像素点所占的字节数
ret = ioctl(fb,FBIOGET_FSCREENINFO,&fix);
if(ret < 0)
{
perror("ioctl()");
close(fb);
exit(-2);
}
pc = mmap(0,fix.smem_len,PROT_READ | PROT_WRITE,MAP_SHARED,fb,offset);
if(pv == (void *)-1)//判断是否映射失败
{
perror("mmap()");
close(fb);
exit(0);
}
//画棋盘
display();
//控制键盘
int fd;
struct input_event ev;//用于存储读取到的内容
struct termios old;//用于存储原始的终端信息
struct termios new;//用于存储修改之后的终端信息
tcgetattr(0,&old);//获取原始终端信息
new = old;//把获取到的终端信息另存到new变量中
new.c_lflag &= ~ICANON; //关闭立即回显
new.c_lflag &= ~ECHO; //关闭回显功能
tcsetattr(0,TCSANOW,&new);//把修改之后的终端配置进行设置
fd = open("/dev/input/event1",O_RDONLY);//通过open函数以只读的方式打开键盘设备文件
if(fd < 0)
{
perror("open()");
close(fb);
exit(0);
}
while(1)
{
if(k % 2 == 0)
{
draw_cir(740,600,20,0x0);
draw_cir(700,600,20,0xFFFFFF);
}
else if(k % 2 == 1)
{
draw_cir(700,600,20,0x0);
draw_cir(740,600,20,0xFF);
}
draw_flag(a,b,10,0xFF00);//光标
draw_flag(a,b,8,0x0);//光标
display();//画棋盘
for(i = 0;i < 1024;i++)
{
for(j = 0;j < 768; j++)
{
if(arr[i][j] == 1)
{
draw_cir(i,j,20,0xFFFFFF);
}
if(arr[i][j] == 2)
{
draw_cir(i,j,20,0xFF);
}
}
}
read(fd,&ev,sizeof(ev));//读取键盘上的数据
if(ev.type == EV_KEY)//判断0是否是按键
{
if(ev.value == SYN_REPORT)//判断是否是事件
{
switch(ev.code)
{ //上、下、左、右、ESC、回车
case 103:
draw_flag(a,b,10,0x0);
b = b - 40;
if(b < 100)
{
b = b + 40;
continue;
}
draw_flag(a,b,10,0xFF00);//光标
draw_flag(a,b,8,0x0);//光标
break;
case 108:
draw_flag(a,b,10,0x0);
b = b + 40;
if(b > 660)
{
b = b - 40;
continue;
}
draw_flag(a,b,10,0xFF00);//光标
draw_flag(a,b,8,0x0);//光标
break;
case 105:
draw_flag(a,b,10,0x0);
a = a - 40;
if(a < 100)
{
a = a + 40;
continue;
}
draw_flag(a,b,10,0xFF00);//光标
draw_flag(a,b,8,0x0);//光标
break;
case 106:
draw_flag(a,b,10,0x0);
a = a + 40;
if(a > 660)
{
a = a - 40;
continue;
}
draw_flag(a,b,10,0xFF00);//光标
draw_flag(a,b,8,0x0);
break;
case 1:
tcsetattr(0,TCSANOW,&old);
close(fd);
close(fb);
exit(0);
case 28:
if(k % 2 == 0)
{
if(arr[a-1][b-1] == 1 || arr[a-1][b-1] == 2)
break;
else
{
draw_cir(a,b,20,0xFFFFFF);
arr[a-1][b-1]=1;
}
}
else if(k % 2 == 1)
{
if(arr[a-1][b-1] == 1 || arr[a-1][b-1] == 2)
break;
else
{
draw_cir(a,b,20,0xFF);
arr[a-1][b-1] = 2;
}
}
k++;
break;
}
}
}
}
munmap(pc,fix.smem_len);//解除内存映射
close(fd);//关闭打开的键盘输入设备文件
close(fb);//关闭打开的framebuffer设备文件
exit(0);
}