贪吃蛇 C语言
开始学C两个多月, 斗胆自制贪吃蛇, 因为没有资源, 所有逻辑码字全靠自身, 如果能给大家带来新的思考和感悟, 将是我最大的荣幸----2020/12/08
不知不觉大一已过去了一半, 今天要考试了, 我也是感慨良多, 那是我失去的青春, 呜呜呜~~ 这次代码是继上次的优化和完善, 若有好的建议或意见随时欢迎交流----2021/1/13
看到有朋友评论, 我有点小激动, 所以又偷偷优化一下代码, 最近开始进攻Java, 希望能在一周之内拿下----2021/1/18
又偷偷优化了一下(模型,颜色,控制台大小,手感),下次优化再加上A*算法,可能以为动用了system系统权限,添加信任即可----2021/4/17
#include<stdio.h>
#include<stdlib.h>//malloc,calloc(),realloc(),free(),system(),atoi(),atol(),rand(),srand(),exit()
#include<windows.h>//Sleep(),gotoxy(),HideCursor()
#include<conio.h>//_getch(),kbhit()
#include<time.h>//time()
#include<stdbool.h>//true=1,false=0
#define MAX 20//地图大小,可改
int sx=4, sy=4, fx=4, fy=4, curLen=0, reaLen=4;//(sx,sy)蛇头,(fx,fy)食物,curLen当前长度,reaLen实际长度
void gotoxy(int x,int y) { //移动光标
COORD pos;
HANDLE hOutput;
pos.X=(SHORT)x;
pos.Y=(SHORT)y;
hOutput =GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput,pos);
}
void HideCursor() { //隐藏光标
CONSOLE_CURSOR_INFO cursor;
cursor.bVisible=FALSE;
cursor.dwSize=sizeof(cursor);
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(handle,&cursor);
}
void modeset(int w,int h) {//控制台大小
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD size = {(short int)w, (short int)h};
SetConsoleScreenBufferSize(hOut,size);
SMALL_RECT rc = {1,1, (short int)w, (short int)h};
SetConsoleWindowInfo(hOut ,true ,&rc);
system("cls");
return;
}
HANDLE hout;//字体颜色
void color(int c) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),(WORD)c);
}
//*****************************************************************
typedef struct linkedlist { //坐标
int x, y;
struct linkedlist *next;
} linkedlist;
linkedlist *head;//蛇头
linkedlist *new1() {
linkedlist *p=(linkedlist*)malloc(sizeof(linkedlist));
p->x=sx;
p->y=sy;
p->next=NULL;
return p;
}
void over() {//结束
int i,j;
for(i=1; i<MAX-1; i++) {
for(j=1; j<MAX-1; j++) {
gotoxy(i, j);
printf(" ");
}
if (i==MAX-2) {
break;
}
printf("\n");
}
gotoxy(10, 10);
color(15);
printf("game over!");
gotoxy(0, 16);
exit(0);
}
void rushWall() {//撞墙
if (sx==0||sy==0||sx==MAX*2-2||sy==MAX-1) {
over();
}
}
void rushBody() {//撞到自身
linkedlist *p;
for(p=head->next; p!=NULL; p = p->next) {
if(p->x==sx && p->y==sy) {
over();
}
}
}
void remove1() {//移除蛇尾
curLen--;
linkedlist *p;
for(p=head; p->next->next!=NULL; p=p->next);
gotoxy(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next=NULL;
}
void add() {//蛇身移动
curLen++;
linkedlist *p=new1();
gotoxy(sx, sy);
color(4);
printf("█ ");
if(head==NULL) {
head=p;
} else {
p->next=head;
head=p;
}
if (curLen>=reaLen) {
remove1();
}
if (curLen == 3) {
gotoxy(4, 4);
printf(" ");
}
}
void wall() {//墙体
system("color f5");
color(15);
int i,j;
for(i=0; i<MAX; i++) {
for(j=0; j<MAX; j++) {
if(i==0||j==0||i==MAX-1||j==MAX-1) {
printf("%s","█ ");
} else {
printf(" ");
}
}
if (i==MAX-1) {
break;
}
printf("\n");
}
}
void food() {//创建食物
srand((unsigned int)time(NULL));
fx=(rand()%(MAX-4)+2)*2;
fy=rand()%(MAX-4)+2;
color(2);
gotoxy(fx, fy);
printf("█ ");
}
bool usefulFood() {//有效食物
linkedlist *p;
for(p=head; p!=NULL; p=p->next) {
if(p->x==fx && p->y==fy) {
return false;
}
}
return true;
}
void eatFood() {//吃食物
if (sx==fx && sy==fy) {
reaLen++;
do {
food();
} while (!usefulFood());
}
}
int main() {
modeset(MAX*2,MAX);
HideCursor();
wall();
food();
int dir;
while(true) {
dir=getch();
while(!kbhit()) {
gotoxy(sx, sy);
color(7);
printf("█ ");
switch(dir) {
case 'a'://left
case 'A':
sx-=2;
break;
case 'd'://right
case 'D':
sx+=2;
break;
case 'w'://up
case 'W':
sy--;
break;
case 's'://down
case 'S':
sy++;
break;
default:
break;
}
add();
Sleep(100);//速度,可改
rushWall();
rushBody();
eatFood();
}
}
return 0;
}