自己重构了游戏《2048》并且重构了它的最好启发式AI解法,并上传到了Gitee中的 鬼&泣 / 2048-heuristic的devilmaycry分支,在这个过程中编写了一个C语言版的“无缓冲键盘输入 ,并识别上下左右光标键”的代码,这里记录一下以备以后使用时查看。

代码地址:

cpp_source/environment/keyboard_run_app.cpp

 
 
 
 
 第一部分代码:
struct termios cooked, raw;

// 恢复之前的键盘输入和终端缓存的设置
void keyboard_close(int sig=0)
{
int kfd = 0;
(void)sig;
PRINT_ATTR_REC // 终端字体颜色恢复
// system("clear"); // 情况屏幕
tcsetattr(kfd, TCSANOW, &cooked);//在程序结束时在恢复原来的配置
exit(0);
} // 设置键盘输入,设置终端无缓存输入
void keyboard_open()
{
signal(SIGINT, keyboard_close); // 捕获Ctrl+C, 中断退出 int kfd = 0; // get the console in raw mode
tcgetattr(kfd, &cooked); // 得到 termios 结构体保存,然后重新配置终端
memcpy(&raw, &cooked, sizeof(struct termios));
raw.c_lflag &=~ (ICANON | ECHO);
// Setting a new line, then end of file
raw.c_cc[VEOL] = 1;
raw.c_cc[VEOF] = 2;
tcsetattr(kfd, TCSANOW, &raw);
}

keyboard_open函数设置无缓冲的键盘输入模式并保存原始的终端设置。在signal函数中设置对ctrl+c的捕获并进行终端设置的恢复操作及程序退出操作。

第二部分,对光标键的处理

#define KEYCODE_R 185
#define KEYCODE_L 186
#define KEYCODE_U 183
#define KEYCODE_D 184
相关资料参考:
 
 
相关代码:
        fflush(stdin);
// get the next event from the keyboard
if(read(kfd, &c, 3) < 0)
{
perror("read(): Error!!! ");
exit(-1);
} all_sum = c[0]+c[1]+c[2];
// printf("sum: %d \n", s); switch(all_sum)
{
case KEYCODE_L:
_info = "Left Button Pressed, Numbers of attempt: "+std::to_string(i);
// printf("[******] Wrong input, Left Button Pressed, Numbers of attempt: %d\n", i);
move = 2;
break;
case KEYCODE_R:
_info = "Right Button Pressed, Numbers of attempt: "+std::to_string(i);
// printf("[******] Wrong input, Right Button Pressed, Numbers of attempt: %d\n", i);
move = 3;
break;
case KEYCODE_U:
_info = "Up Button Pressed, Numbers of attempt: "+std::to_string(i);
// printf("[******] Wrong input, Up Button Pressed, Numbers of attempt: %d\n", i);
move = 0;
break;
case KEYCODE_D:
_info = "Down Button Pressed, Numbers of attempt: "+std::to_string(i);
// printf("[******] Wrong input, Down Button Pressed, Numbers of attempt: %d\n", i);
move = 1;
break;
default:
printf("[******] Wrong input, value: %c = 0x%02X = %d, Numbers of attempt: %d\n", c[0], c[0], c[0], i);
}
由于光标键是组合键,因此需要读入三个字符才能判断,这里采用的函数为:read(kfd, &c, 3) ,毕竟神奇的地方是这个函数可以在较短时间(如:0.0001秒)内最多读入三个字符,因此该函数可以识别所有的键盘按键的输入,不仅可以识别组合ASCII码的按键,而且还能识别单ASCII码的按键。这种一次性最多读入N个字符的操作比较少见,这里也不是很懂,也就当记录一下不深入研究了,本想用python语言实现类似的功能最后还是没有成功,或许这种功能还是系统原生的C语言比较好实现一些。
 
 
 
 
 
==============================================
 
 
 
 
提醒一下,这个代码只有片段不能直接运行编译,在Gitee上的该部分代码是作为子模块存在的,并没有编写main函数,如果想编译执行还需要自己手动加上main函数,由于只需要简单的添加入口main函数即可编译执行这里也就不过多给出代码了。
 
 
 
 
----------------------------------
 
 

C语言编写Linux终端环境下无缓冲键盘输入 ,并识别上下左右光标键的更多相关文章

  1. 使用Tmux提高linux终端环境下的效率

    最近转移到linux下开发,同事告诉我一个工具tmux.关于tmux的工具的使用参考以下文章 如何使用Tmux提高终端环境下的效率 tmux的使用和快捷键 tmux简明教程 tmux使用大全

  2. 在 Windows 和 Linux(Gnome) 环境下 从命令界面打开网页的方式

    1.在 Windows 中 通过命令 可以打开网页是很简单的: start http://www.baidu.com 或 start iexplorer http://www.baidu.com 第二 ...

  3. linux网络环境下socket套接字编程(UDP文件传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  4. 如何在Linux桌面环境下自动启动程序?

    大多数Linux桌面环境有各自的图形用户界面(GUI),让用户可以配置针对特定用户的自动启动程序或服务.本文将介绍如何在各种Linux桌面环境下,自动启动某个程序的方法. AD:WOT2014:用户标 ...

  5. Linux centos7环境下安装JDK的步骤详解

    Linux centos7环境下安装JDK的步骤详解 测试root用户下JAVA版本 输入命令:   java –version 1.先到Oracle官网里下载好jdk,网址如下: http://ww ...

  6. Linux单机环境下HDFS伪分布式集群安装操作步骤v1.0

    公司平台的分布式文件系统基于Hadoop HDFS技术构建,为开发人员学习及后续项目中Hadoop HDFS相关操作提供技术参考特编写此文档.本文档描述了Linux单机环境下Hadoop HDFS伪分 ...

  7. Linux/CentOS环境下如何安装和配置PhantomJS工作环境

    PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, C ...

  8. Linux centos7环境下安装MySQL的步骤详解

    Linux centos7环境下安装MySQL的步骤详解 安装MySQL mysql 有两个跟windows不同的地方 1).my.ini 保存到/etc/my.ini 2).用户权限,单独用户执行 ...

  9. Linux centos7环境下安装Nginx

    Linux centos7环境下安装Nginx的步骤详解 1.    首先到Nginx官网下载Nginx安装包 http://nginx.org/download/nginx-1.5.9.tar.gz ...

  10. Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)

    https://blog.csdn.net/shinesun001/article/details/54312402 在centos 7环境下搭建好Lnmp环境之后,发现安装的php有好多扩展都没有安 ...

随机推荐

  1. mongodb QuickStart Demo

    import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.cl ...

  2. Godot中鼠标点击3D对象

    Godot中鼠标点击3D对象 方法一:调用RigidBody3D中的input_event事件 RigidBody3D中有信号input_event可以接受鼠标的输入,用这个信号可以处理点击事件. 具 ...

  3. 高通参考设计中MTP与QRD

    高通参考设计中MTP与QRD 背景 之前在调试设备树的时候,看到设备树带了一个qrd的后缀,一直没搞清楚.上网找资料也好像不是我想要的. 今天查阅lk侧的代码,发现了HW_PLATFORM_HRD这个 ...

  4. 下载 Linux 内核的脚本

    介绍 在 类UNIX 环境下运行比较好(基于wget) 包括了 2.6 ~ 4.x 内核的地址. 5.x 因为 还在更新因此不做记录. 脚本下载地址: https://files.cnblogs.co ...

  5. 聊一聊 C# 弱引用 底层是怎么玩的

    一:背景 1. 讲故事 最近在分析dump时,发现有程序的卡死和WeakReference有关,在以前只知道怎么用,但不清楚底层逻辑走向是什么样的,借着这个dump的契机来简单研究下. 二:弱引用的玩 ...

  6. 三层交换机vlan间路由

    sw1: [Huawei]vlan batch 10 20 [Huawei]int e0/0/1 [Huawei-Ethernet0/0/1]port link-type access [Huawei ...

  7. dot net core使用BackgroundService运行一个后台服务

    不管是在控制台程序还是asp.net core程序中,我们经常会有用到一个需要长时间运行的后台任务的需求.通常最直觉的方式是使用Thread实例来新建一个线程,但是这样需要自行管理线程的启动和停止. ...

  8. AM62x GPMC并口如何实现“小数据-低时延,大数据-高带宽”—ARM+FPGA低成本通信方案

    GPMC并口简介 GPMC(General Purpose Memory Controller)是TI处理器特有的通用存储器控制器接口,支持8/16bit数据位宽,支持128MB访问空间,最高时钟速率 ...

  9. mysql判断两个字符串(以逗号分隔)是否存在交集

    转载:https://blog.csdn.net/username666/article/details/107815331?utm_medium=distribute.pc_relevant.non ...

  10. java 编程思想--个人总结

    从应用开始思考----思考解题思路--将思路分解成一步一步的步骤-----根据每一步的步骤思考如何用代码实现-- -- 不要心急,可以一块一块来完成-- 最后再思考如何用代码实现每两块之间的连接--- ...