本文把遊戲區域就行編号,第一行從0到WIDTH-1,…… 到HEIGHT-1 到 WIDTH*HEIGHT-1(二維數組)。并用trace[LEN]數組儲存snake移動的軌迹(儲存的是數值,數值就能表現出所在的行和列),(trace[0]始終為snake的頭部),根據display()函數繪圖,延時,在繪圖,達到重新整理螢幕的效果。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiNyEDOzETN5EDNxQDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#define HEIGHT 10
#define WIDTH 10
#define LEN HEIGHT*WIDTH/2
#define SPEED 800
enum moveState{
UP = -*WIDTH, DOWN = WIDTH, LEFT = -, RIGHT =
};
int x, y; /* rand point */
int trace[LEN] = {}; /* trace the snake */
moveState ms = UP; /* default UP */
int len = ; /* snake length */
void display();
void gotoxy(int x, int y);
void automove();
void randpoint();
void gameover();
void keyinput();
int merge();
int main(void)
{
srand(time());
x = rand()%WIDTH;
while((y = rand()%HEIGHT) == ) // y != 0
;
trace[] = y*WIDTH + x;
display();
randpoint();
while(){
keyinput();
}
return ;
}
/* goto (x, y) point oisition */
void gotoxy(int x, int y)
{
HANDLE hOut;
COORD pos={x, y}; // windows API, 光标位置
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos); // set
//SetConsoleTextAttribute(hOut,0x00|0x05);
}
void display()
{
int i, j;
gotoxy(,);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), |); // API, set color
/* display the bound */
for(i = ; i < HEIGHT+; i++){
for(j = ; j < WIDTH+; j++){
if(i == || i == HEIGHT+ || j == || j == WIDTH+)
printf("□"); /* 2 char */
else
printf(" ");
}
printf("\n");
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), |); // API, set color
gotoxy(WIDTH*+, HEIGHT/);
printf("\t ↑ ← ↓ → space");
gotoxy(WIDTH*+, HEIGHT/*);
printf("\t score: %d", len*);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), |); // API, set color
/* display the rand point */
gotoxy(*x+, y+); // include bound
printf("■"); // 2 char
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), |); // API, set color
/* display the snake */
for(i = ; i < len; i++){
gotoxy(trace[i]%WIDTH*+, trace[i]/WIDTH+);
printf("■");
}
Sleep(SPEED); // delay SPEED ms
}
/* 根據ms的方向進行移位,儲存新的路徑 */
void automove()
{
int i;
/* shift bit */
for(i = len-; i > ; i--){
trace[i] = trace[i-];
}
trace[i] += ms; /* i = 0 */
}
/* 合并新的随機點 */
int merge()
{
int i;
int temp = y*WIDTH + x;
if(temp == trace[]){
/* shift bit */
len++;
for(i = len-; i > ; i--){
trace[i] = trace[i-];
}
trace[i] += ms; /* i = 0 */
return ;
}
return ;
}
/* born randpoint */
void randpoint()
{
int i;
while(){
x = rand()%WIDTH;
y = rand()%HEIGHT;
for(i = ; i < len; i++)
if(y*WIDTH+x == trace[i])
break;
if(i == len)
return;
}
}
void keyinput()
{
int i;
while(!kbhit()){ // no keyboard input
automove();
if(trace[] < || trace[] > HEIGHT*WIDTH || trace[]%WIDTH == WIDTH- && ms == LEFT
|| trace[]%WIDTH == && ms == RIGHT)
gameover();
for(i = ; i < len; i++)
if(trace[] == trace[i])
gameover();
if(merge() == )
randpoint();
display();
}
int key = getch(); //擷取鍵盤輸入
if(key == )
exit();
else if(key == ' '){ // space for Pause
while(getch() != ' ')
;
}
else if(key == ){ //方向鍵會産生2個字元
key = getch();
switch(key){
case : //up
ms = UP;
break;
case : //left
ms = LEFT;
break;
case : //right
ms = RIGHT;
break;
case : //down
ms = DOWN;
break;
}
}
automove();
/* judge out of the bound */
if(trace[] < || trace[] > HEIGHT*WIDTH || trace[]%WIDTH == WIDTH- && ms == LEFT
|| trace[]%WIDTH == && ms == RIGHT)
gameover();
/* judge head touched the body */
for(i = ; i < len; i++)
if(trace[] == trace[i])
gameover();
if(merge() == )
randpoint();
display();
}
void gameover()
{
gotoxy(WIDTH/, HEIGHT/);
printf("you are lost!\n");
gotoxy(, HEIGHT+);
exit();
}