随手用C/C++写了一个控制台贪吃蛇,用_kbhit()判断输入缓存区是否有输入字符,{ 72, 77, 80, 75 } 分别表示上右下左的编码,实际上按一下方向键“上”会输入ascii值为-32和72两个字符;方向数组下标+2再模4能得到相反的方向。
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <dos.h>
#include <windows.h>
const int MAXN = 3;
int length = 2;
char cha[][5] = {
" ", //0:空
"※", //1:墙
"◆", //2:头
"●", //3:身体
"●", //4:尾巴
"□", //5:身体被吃
"○" //6:食物
};
int dir[4][2] = {
{ -1, 0 }, //上
{ 0, 1 }, //右
{ 1, 0 }, //下
{ 0, -1 } //左
};
int keyCode[4] = { 72, 77, 80, 75 };
int map[MAXN][MAXN] = { 0 };
int body[MAXN][MAXN];
int headX, headY;
int tailX, tailY;
bool createFood() {
bool OK = false;
for (int i = 0; i < MAXN; i++) {
for (int j = 0; j < MAXN; j++) {
if (map[i][j] == 0) {
OK = true;
break;
}
}
}
if (!OK) return false;
int x, y;
do {
x = rand() % MAXN;
y = rand() % MAXN;
} while (map[x][y] != 0);
map[x][y] = 6;
return true;
}
bool init() {
srand((unsigned)time(NULL));
memset(body, -1, sizeof(body));
tailX = -1; tailY = -1;
if (length < 2) {
printf("蛇初始长度过短");
return false;
}
if (MAXN < 3 || MAXN < length) {
printf("地图宽度过小");
return false;
}
for (int i = 0; i <= length - 2; i++) {
if (i == 0) {
tailX = MAXN / 2; tailY = (MAXN - length) / 2;
map[tailX][tailY] = 4;
body[tailX][tailY] = 1;
} else {
map[MAXN / 2][(MAXN - length) / 2 + i] = 3;
body[MAXN / 2][(MAXN - length) / 2 + i] = 1;
}
}
headX = MAXN / 2; headY = (MAXN - length) / 2 + length - 1;
map[headX][headY] = 2;
body[headX][headY] = -1;
createFood();
return true;
}
void print() {
system("CLS");
for (int i = 0; i < MAXN + 2; i++) {
printf("%s", cha[1]);
}
printf("\n");
for (int i = 0; i < MAXN; i++) {
printf("%s", cha[1]);
for (int j = 0; j < MAXN; j++) {
printf("%s", cha[map[i][j]]);
}
printf("%s\n", cha[1]);
}
for (int i = 0; i < MAXN + 2; i++) {
printf("%s", cha[1]);
}
printf("\n");
}
int move(char ch) {
for (int i = 0; i < 4; i++) {
if (int(ch) == keyCode[i]) {
int nextX = (MAXN + headX + dir[i][0]) % MAXN;
int nextY = (MAXN + headY + dir[i][1]) % MAXN;
if (map[nextX][nextY] == 3) {
if ((body[nextX][nextY] + 2) % 4 == i) {
return 2;
}
map[nextX][nextY] = 5;
return 0;
}
if (tailX >= 0 && tailY >= 0 && map[nextX][nextY] != 6) {
int x = (MAXN + tailX + dir[ body[tailX][tailY] ][0]) % MAXN;
int y = (MAXN + tailY + dir[ body[tailX][tailY] ][1]) % MAXN;
map[x][y] = 4;
map[tailX][tailY] = 0;
body[tailX][tailY] = -1;
tailX = x; tailY = y;
}
if (map[nextX][nextY] == 6 && !createFood()) {
map[nextX][nextY] = 2;
map[headX][headY] = 3;
return 1;
}
map[nextX][nextY] = 2;
map[headX][headY] = 3;
body[headX][headY] = i;
body[nextX][nextY] = -1;
headX = nextX; headY = nextY;
break;
}
}
return -1;
}
int main() {
if (!init()) {
return 0;
}
print();
Sleep(1000);
char ch = keyCode[1];
char temp = ch;
while(true) {
if(_kbhit()) {
do {
ch = _getch();
} while ((ch == -32 && _kbhit()) ||
(ch == temp && _kbhit()));
}
int r;
do {
r = move(ch);
if (r == 0) {
print();
printf("You Lose!\n");
return 0;
} else if (r == 1) {
print();
printf("You Win!\n");
return 0;
} else if (r == 2){
ch = temp;
}
} while (r == 2);
temp = ch;
print();
Sleep(500);
}
return 0;
}