自己重構了遊戲《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函數即可編譯執行這裡也就不過多給出代碼了。