0 Star 1 Fork 0

鬼&泣 / 2048-heuristic

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
keyboard_run_app.cpp 6.10 KB
一键复制 编辑 原始数据 按行查看 历史
鬼&泣 提交于 2022-07-16 13:36 . big changed
#include <string.h>
#include <termio.h> // up down right left, button
#include <signal.h>
#include "2048_environment.h"
/* ---------------------- keyboard setting, begin ---------------------- */
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 setting, finished ---------------------- */
#define KEYCODE_R 185
#define KEYCODE_L 186
#define KEYCODE_U 183
#define KEYCODE_D 184
/* ---------------------- ask for move, begin ---------------------- */
int get_keyInput(std::string hint, bool avalible[4], int score, int moveno, bool game_over)
{
std::string _info = "";
int kfd = 0;
char c[4] = "";
int all_sum = 0;
PRINT_FONT_BLU
puts("-----------------------------------------");
PRINT_FONT_RED
printf("Current Move Number: %d, Current Score: %d\n", moveno, score);
PRINT_FONT_BLU
puts("-----------------------------------------\n");
if(game_over)
return -1;
PRINT_FONT_CYA
std::cout << "Please use arrow keys, " + hint << std::endl;
for(int i=1;;i++)
{
int move = -1;
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);
}
if(c[0]==10) // 对于回车键,enter,需要再多回退一行
{
printf("\033[A"); // "\033[nA" 光标向上移动n行,n为具体数值,不写n则默认为1
printf("\033[2K"); // ANSI 转义字符, 擦除整行
}
c[0] = '\0';
c[1] = '\0';
c[2] = '\0';
c[3] = '\0';
if(move != -1)
{
if(avalible[move])
return move;
else
{
std::cout << "[******] Wrong input, "+_info << std::endl;
}
}
printf("\033[A"); // "\033[nA" 光标向上移动n行,n为具体数值,不写n则默认为1
printf("\033[2K"); // ANSI 转义字符, 擦除整行
}
}
int ask_for_move(board_t board, int scorepenalty, int moveno) {
bool game_over = false;
bool avalible[4];
std::string validstr[4] = {"Up", "Down", "Left", "Right"};
std::string hint = "[Move]: ";
int sum_val = 0;
for(int move=0; move<4; move++)
{
if(execute_move(move, board) != board)
{
avalible[move] = true;
sum_val++;
}
else
{
avalible[move] = false;
}
}
if(sum_val==0)
{
game_over = true;
}
for(int move=0; move<4; move++)
{
if(avalible[move]==true)
{
hint += validstr[move];
sum_val--;
if(sum_val!=0)
{
hint += ", ";
}
}
}
return get_keyInput(hint, avalible, get_score(board, scorepenalty), moveno, game_over);
}
/* ---------------------- ask for move, finished ---------------------- */
void play_game() {
int moveno = 0; // 共执行的下棋步数, 全局变量
int scorepenalty=0;
board_t board = initial_board(scorepenalty); // 注意:这里是C++引用传递,不是值传递
while(1) {
system("clear"); // 清空屏幕
print_board(board);
int move = ask_for_move(board, scorepenalty, moveno);
if(move < 0)
break;
board = execute_move(move, board);
moveno++;
board = insert_penalty(board, scorepenalty);
}
PRINT_FONT_YEL
puts("-----------------------------------------");
PRINT_FONT_RED
printf("Game over. Your score is %d. The highest rank you achieved was %d.\n", get_score(board, scorepenalty), get_max_rank(board));
PRINT_FONT_YEL
puts("-----------------------------------------\n\n");
}
void run_app()
{
keyboard_open(); // 设置键盘输入,设置终端无缓存输入
init_tables();
play_game();
keyboard_close(); // 恢复之前的键盘输入和终端缓存的设置
}
C++
1
https://gitee.com/devilmaycry812839668/heuristic-2048.git
git@gitee.com:devilmaycry812839668/heuristic-2048.git
devilmaycry812839668
heuristic-2048
2048-heuristic
devilmaycry

搜索帮助