我在dev c++中编写了一段程序,我想实现“不按回车getchar()”,就用了termios.h这个头文件,但是编译的错误是4 22 C:\Users***\Desktop\未命名1.cpp [Error] termios.h: No such file or directory 。删掉#include <termios.h>之后,一些语句就无法使用,请问怎么解决?或者有没有别的方法能实现“不按回车getchar()”?
代码如下:
#include <iostream>
#include <cstring>
#include <iomanip>
#include <termios.h>
#include <list>
#include <unistd.h>
#define clear() cout << "\033c" << flush
using namespace std;
struct node
{
int x, y;
};
int num[15][15];
int x, y;
node head, food;
bool Food = false;
list<node> snake;
char ch = 0;
int score = 0;
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
bool kbhit();
char readch();
void changeNum();
void drawBoard();
void move();
int scanKeyboard();
void init_snake();
void fullFood();
bool getFood();
void longer();
bool gameOver();
void intro();
int getch(); // 不回显函数
//主函数
int main()
{
init_snake(); //初始化蛇
init_keyboard(); //初始化键盘
x = 0, y = 0; //初始化移动方向
intro(); //介绍游戏规则
char a = getch();
fullFood(); //填充食物
drawBoard(); //绘制游戏界面
while(ch != 'n') {
usleep(200000);
if(kbhit()) //如果按下按键
{
ch = readch(); //读取按键值
}
int nx = x, ny = y;
if (ch == 'w') nx = -1,ny = 0; //预设移动方向
if (ch == 's') nx = 1, ny = 0;
if (ch == 'a') nx = 0, ny = -1;
if (ch == 'd') nx = 0, ny = 1;
if (ch == 'n') return 0;
if (nx != -x || ny != -y)
x = nx, y = ny;
if (getFood())
{
score++;
longer();
fullFood();
}
else move();
if (gameOver())
{
drawBoard();
cout << "GameOver!!" << endl;
return 0;
}
drawBoard();
}
close_keyboard();
return 0;
}
bool gameOver()
{
head = snake.front();
if (head.x <= 0 || head.x > 12)
return true;
if (head.y <= 0 || head.y > 12)
return true;
if (num[head.x][head.y] == 1)
return true;
return false;
}
void init_keyboard()
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}
bool kbhit()
{
char ch;
int nread;
if(peek_character != -1)
return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1) {
peek_character = ch;
return 1;
}
return 0;
}
char readch()
{
char ch;
if(peek_character != -1) {
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}
void fullFood() // 填充数据
{
int x[200] = {}, y[200] = {}, cur = 0;
for (int i = 1; i <= 12; i++)
{
for (int j = 1; j <= 12; j++)
{
if (num[i][j] == 0)
{
cur++;
x[cur] = i;
y[cur] = j;
}
}
}
if (cur > 0) // 还有空位
{
srand(time(0));
int cc = rand() % cur + 1; // 随机从空位中取出一个
food.x = x[cc];
food.y = y[cc];
}
}
void changeNum()
{
if(snake.empty()) return;
memset(num, 0, sizeof(num));
for (auto pos = snake.begin(); pos != snake.end(); pos++)
{
num[(*pos).x][(*pos).y] = 1;
}
num[food.x][food.y] = 3;
auto pos = snake.begin();
num[(*pos).x][(*pos).y] = 2;
}
void drawBoard() // 打印当前表格
{
changeNum();
clear();
cout << " ╔";
for (int i = 1; i <= 6; i++) cout << "════";
cout << "═╗\n";
// 输出中间部分
for (int i = 1; i <= 12; i++) // 行
{
cout << " ║";
for (int j = 1; j <= 12; j++) // 列
{
if (num[i][j] == 1)
cout << "\033[41m \033[0m";
else if (num[i][j] == 2)
cout << "\033[42m \033[0m";
else if (num[i][j] == 3)
cout << "\033[43m \033[0m";
else
cout << " ";
}
cout << " ║" << endl;
}
cout << " ╚";
for (int i = 1; i <= 6; i++) cout << "════";
cout << "═╝\n";
cout << "score:" << score << endl;
}
void move()
{
clear();
if (x == 0 && y == 0)
{
drawBoard();
return;
}
node next = snake.front();
next.y += y;
next.x += x;
snake.pop_back();
snake.push_front(next);
}
int scanKeyboard()
{
int in;
struct termios new_settings;
struct termios stored_settings;
tcgetattr(0,&stored_settings);
new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_cc[VTIME] = 0;
tcgetattr(0,&stored_settings);
new_settings.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&new_settings);
in = getchar();
tcsetattr(0,TCSANOW,&stored_settings);
return in;
}
void init_snake()
{
head.x = 1, head.y = 1;
snake.push_back(head);
for (int i = 2; i <= 4; i++)
{
node a;
a.x = 1, a.y = i;
snake.push_back(a);
}
changeNum();
}
bool getFood()
{
head = snake.front();
if(num[head.x + x][head.y + y] == 3) return true;
else return false;
}
void longer()
{
node temp = snake.front();
temp.x += x;
temp.y += y;
snake.push_front(temp);
}
void intro()
{
cout << "欢迎来到贪吃蛇小游戏" << endl;
cout << "游戏规则介绍:" << endl;
cout << "你可以使用w,a,s,d来控制贪吃蛇进行上下左右的移动" << endl;
cout << "在移动过程中,每吃到一个果子,你就能增加1分,同时你也会变长 1 格" << endl;
cout << "但,如果你在移动过程中碰到了自己或者墙壁,那么你就GAMEOVER了!" << endl;
cout << "当然,你也可以按下 n 键提前结束游戏。好了,现在按下任意键开始游戏吧!" << endl;
}
int getch()
{
struct termios nts, ots;
// 得到当前终端(0表示标准输入)的设置
if (tcgetattr(0, &ots) < 0) return EOF;
// 设置终端为Raw原始模式,该模式下所有的输入数据以字节为单位被处理
nts = ots;
cfmakeraw(&nts);
// 设置上更改之后的设置
if (tcsetattr(0, TCSANOW, &nts) < 0) return EOF;
// 设置还原成老的模式
int cr;
cr = getchar();
if (tcsetattr(0, TCSANOW, &ots) < 0) return EOF;
return cr;
}