相信对很多人来说,学完C语言以后,都会找一些小程序来练练手。例如贪吃蛇、五子棋、俄罗斯方块等等。
今天给大家分享一个基于控制台的C语言贪吃蛇小程序。
基础知识要求:C语言基础。
知识点补充
这里写一些你可能没学到的知识点
- system("cls"):清屏函数
- Sleep(300):等待函数,其中括号内的为毫秒。
- _getch():获取一个键盘字符,不显示该字符就返回
- kbhit():判断是否有键按下,是返回1,否返回0.
代码部分
- 废话不多说,直接贴代码
#include <conio.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <windows.h>
struct node
{
int x;
int y;
struct node *next;
};
node *init(int length); //初始化蛇
void print(int a[15][30],node *head); //输出函数
void food(node *head); //食物产生函数
void move(node *head); //移动函数
bool dead(node *head); //判断死亡函数
int food_x=0,food_y=0;
int food_flag = 0;
int target = 2;
void main(){
int a[15][30];
node *head;
head = init(2);
while(1)
{
system("cls");
move(head);
if(dead(head))
break;
print(a,head);
Sleep(300);
}
system("cls");
printf("Game Over!!!\n");
}
node *init(int length)
{
int i = 2;
node *head;
head = (node*)malloc(sizeof(node));//分配地址
node *p = head;
head->x = 1;
head->y = 1;
while(i <= length)
{
node *s;
s = (node*)malloc(sizeof(node));
s->x = 1;
s->y = i;
s->next = NULL;
p->next = s;
p = p->next;
i++;
}
food(head);
return head;
}
void print(int a[15][30],node *head)
{
//0为空格,-1为墙壁#,1为蛇身*,2为蛇头@,3为食物$
int i,j;
node *p = head;
for(i = 0; i < 15; i++)
{
for(j = 0; j < 30; j++)
{
if(i == 0 || j == 0 || i == 14 || j == 29)
a[i][j] = -1;
else
a[i][j] = 0;
}
}
while(p != NULL)
{
if(p->next == NULL)
a[p->x][p->y] = 2;
else
a[p->x][p->y] = 1;
p = p->next;
}
a[food_x][food_y] = 3;
for(i = 0; i < 15; i++)
{
for(j = 0; j < 30; j++)
{
if(a[i][j] == -1)
printf("#");
if(a[i][j] == 0)
printf(" ");
if(a[i][j] == 1)
printf("*");
if(a[i][j] == 2)
printf("@");
if(a[i][j] == 3)
printf("$");
}
printf("\n");
}
}
void food(node *head)
{
node *p = head;
srand((unsigned)time(NULL));
food_x = rand()%12 + 1;
food_y = rand()%27 + 1;
while(p != NULL)
{
if(p->x == food_x && p->y == food_y)
{
food_x = rand()%12 + 1;
food_y = rand()%27 + 1;
p = head;
}
p = p->next;
}
}
void move(node *head)
{
char ch;
if(kbhit())
{
ch = _getch(); //VS中getch()用_getch()代替。
switch (ch)
{
case -32: //上下左右占两个字节,低八位存ASCII码,高八位存按键扫描码
ch = _getch(); //其中-32为我的电脑的按键扫描码
switch (ch)
{
case 72:if(target != 1)target = 0; break; //72为上的ASCII码
case 80:if(target != 0)target = 1; break; //80为下的ASCII码
case 77:if(target != 3)target = 2; break; //77为右的ASCII码
case 75:if(target != 2)target = 3; break; //75位左的ASCII码
default:break;
}
}
}
node *p;
node *q = head->next;
while(q->next != NULL)
q = q->next;
switch(target)
{
case 0:if(q->x - 1 == food_x && q->y == food_y)food_flag = 1;break;
case 1:if(q->x + 1 == food_x && q->y == food_y)food_flag = 1;break;
case 2:if(q->x == food_x && q->y + 1 == food_y)food_flag = 1;break;
case 3:if(q->x == food_x && q->y - 1 == food_y)food_flag = 1;break;
}
if(food_flag == 1)
{
node *s;
s = (node*)malloc(sizeof(node));
s->x = food_x;
s->y = food_y;
s->next = NULL;
q->next = s;
food(head);
food_flag = 0;
}
else
{
p = head;
q = head->next;
while(q != NULL)
{
p->x = q->x;
p->y = q->y;
if(q->next == NULL)
{
switch(target)
{
case 0:q->x = q->x - 1;break;
case 1:q->x = q->x + 1;break;
case 2:q->y = q->y + 1;break;
case 3:q->y = q->y - 1;break;
}
}
p = p->next;
q = q->next;
}
}
}
bool dead(node *head)
{
node *p = head;
while(p->next != NULL)
p = p->next;
if(p->x >= 14 || p->x <= 0 || p->y >= 29 || p->y <= 0)
return true;
node *q = head;
while(q->next != NULL)
{
if(q->x == p->x && q->y == p->y)
return true;
q = q->next;
}
return false;
}
以上就是全部内容。