自己重构了游戏《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. Python3.7+Robot Framework+RIDE1.7.4.1安装使用教程

    一.解惑:Robot Framewprk今天我们聊一聊,Robot Framework被众多测试工程师误会多年的秘密.今天我们一起来揭秘一下,最近经常在各大群里听到许多同行,在拿Robot Frame ...

  2. Docker入门系列之三:十二个Dockerfile指令

    本篇文章是关于Dockerfiles的,这是Docker系列文章的第三部分.如果您还没有读过第一部分,请先阅读它,您可以从全新的角度了解Docker容器概念. 第二部分是Docker生态系统的简要介绍 ...

  3. 【前端求助帖】关于使用element-plus select 模板嵌套popover中使用select选择后,上一个select自动关闭的问题

    主页代码如下 项目使用的是Vue3+vite, 下载后,直接pnpm  i安装依赖,  pnpm dev 就是可以跑起来 <el-button type="warning" ...

  4. UIButton选择状态下长按时会变回原始状态

    问题大概就像这样 (请无视那红字) 一般而言这是高亮状态的设置有所缺乏.完善代码如下: [_pupilBtn setImage:[UIImage imageNamed:@"a1"] ...

  5. 2019 南昌区域赛 CEGLM 题解 & lagrange 插值

    B. A Funny Bipartite Graph 状压 dp ,利用了原题中选完左边点集,那么右边在 左边编号最大的那个数 之前的所有点都要选的性质,可以优化到 \(O(n \cdot 2^n)\ ...

  6. QT学习:01 工程文件详解

    --- title: framework-cpp-qt-01-工程文件详解 EntryName: framework-cpp-qt-01-project-file date: 2020-04-08 1 ...

  7. 创建docker

    创建docker 准备实验环境 1. 安装前准备 Centos7 Linux 内核:官方建议 3.10 以上,3.8以上貌似也可. 1.1 查看当前的内核版本 uname -r 1.2 使用 root ...

  8. 在C#中使用RabbitMQ做个简单的发送邮件小项目

    在C#中使用RabbitMQ做个简单的发送邮件小项目 前言 好久没有做项目了,这次做一个发送邮件的小项目.发邮件是一个比较耗时的操作,之前在我的个人博客里面回复评论和友链申请是会通过发送邮件来通知对方 ...

  9. P5494 题解

    来一发 \(O(\log n)\) 线性空间的解法. 考虑通过只维护线段树叶子节点的虚树的方法压缩空间,考虑记录下每个节点的编号,然后通过异或完求最低位的 \(1\) 的方式求出 LCA 的深度,然后 ...

  10. 洛谷P1020

    又是一道做的很麻的题,准确来说感觉这不是一道很好的dfs题,没有体现dfs的一些特点 反而感觉是在考察dp,刚开始也是按照我的思路交了3次都没过 原本以为所选的数应该都是由上一次的最大值推出来的,后面 ...