ubutun操作系统《五子棋》

  编程小白(暂时还没有自动判断输赢功能)

手动设置: 

                首先把系统屏幕分辨率改为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);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值