失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C语言实现贪吃蛇(双人版本)

C语言实现贪吃蛇(双人版本)

时间:2022-10-05 02:20:11

相关推荐

C语言实现贪吃蛇(双人版本)

项目实战合集

本专栏系列都是实战源码,可直接下载编译使用;

上一篇: C语言实现学生管理系统

文章目录

前言一、项目介绍二、项目源码总结新壁纸

前言

相信很多小伙伴还不知道贪吃蛇是怎么诞生的,贪吃蛇由来介绍:

1976年,Gremlin平台推出了一款经典街机游戏Blockade。游戏中,两名玩家分别控制一个角色在屏幕上移动,所经之处砌起围栏。角色只能向左、右方向90度转弯,游戏目标保证让对方先撞上屏幕或围栏。

Blockade 很受欢迎,类似的游戏先后出现在 Atari 2600、TRS-80、苹果 2 等早期游戏机、计算机上。但真正让这种游戏形式红遍全球的还是后随诺基亚手机走向世界的贪吃蛇游戏——Snake

一、项目介绍

该项目由C语言实现,保留了传统贪吃蛇玩法的特色,增加了双人对战趣味性,代码注释详细,请仔细阅读;

二、项目源码

/*-----------------------------------【程序说明】----------------------------* 项目命题: 贪吃蛇之双人版本(C语言)* 代码所属: 枫之剑客*作者: 阿甘*开发时间: /10/02*IDE 版 本: Visual Studio *项目版本: 1.0.0.1*---------------------------------------------------------------------------*/#include <stdio.h> #include <Windows.h> #include <time.h> #include <stdlib.h> #include <conio.h> typedef struct snake {int x, y;//坐标 int direction;//移动方向 上1 左2 下3 右4 snake * next; }*Msnake; struct food {int x, y; }F;struct food2 {int x, y; }F2; struct food1 {int x, y; }F1[800]; struct food3 {int x, y; }F12[800]; int ai=0,k=0,ai2=0,k2=0,a=1,b=1;int level; //等级 int lengt = 4;//蛇长度int lengt2 = 4;//蛇2长度 int t;//用于计时 int score = 0; //获得成绩 int score2 = 0; //2获得成绩 int l;// 用于记录不同等级的速度 int n = 0;//吃到食物个数int n2 = 0;//2吃到食物个数 snake * creat();//初始话蛇的位置及长度snake * creat2();//初始话蛇2的位置及长度 void showMain();//画出终端的大小及命名 画出游戏界面(边框,提示,基本成绩etc) void gotoxy(int x, int y); //光标的移动 void c(int k); //颜色选择 int time(); //用来计时 void ycgb(int k); //隐藏光标 void game(); //具体游戏运行 void draw(snake * head); //真正画蛇 void newfood(snake * head);// //随机产生食物并保证食物不与蛇的坐标重合 void newfood2(snake * head);// //随机产生食物并保证食物不与蛇2的坐标重合 void newfood1(snake * head); //随机产生障碍并保证障碍不与蛇的坐标重合void newfood3(snake * head); //随机产生障碍并保证障碍不与蛇2的坐标重合 int random(); //用来输出随机值 int direc(char ch);//方向键设置 int direc2(char ch);//方向键设置 void key(snake * head,snake*head1, snake * p,char ch); //改变蛇的方向功能的实现void key2(snake * head,snake*head1, snake * p2,char ch); //改变蛇2的方向功能的实现void pause(snake * head,snake*head1, snake * p,char ch); //暂停功能的实现void cls();//清屏 void cls2();//清屏 2int judge(int a,int b);//进行哪一方失败判断 int main() {ycgb(0); showMain(); game(); while (1) {cls();gotoxy(32,10);c(10); printf("按回车可重新开始游戏!"); gotoxy(34,11); printf("按Esc可离开游戏!");cls2();gotoxy(114,10); printf("按回车可重新开始游戏!"); gotoxy(116,11); printf("按Esc可离开游戏!"); char ch; ch = getch(); while (ch != 13 && ch != 27) {ch = getch(); } if (ch == 13) {showMain(); game(); } else break; } return 0; } int direc(char ch)//方向键设置 {if (ch == 119) return 1;if (ch == 97) return 2; if (ch == 115) return 3; if (ch == 100) return 4; return 0; }int direc2(char ch)//2方向键设置 {ch = getch(); if (ch == 72) return 1; if (ch == 80) return 3; if (ch == 75) return 2; if (ch == 77) return 4; return 0; } snake * creat() // 初始话蛇的位置及长度 {snake *head, *p, *q; head = (snake *) malloc (sizeof(snake)); head->x = 28; head->y = 10; head->direction = 4; head->next = NULL; p = head; for (int i = 0; i < 3; i++) {q = (snake *) malloc (sizeof(snake)); p->next = q; q->next = NULL; q->x = p->x + 2; q->y = p->y; q->direction = p->direction; p = q; } return head; } snake * creat2() // 初始话蛇2的位置及长度 {snake *head2, *p, *q; head2 = (snake *) malloc (sizeof(snake)); head2->x = 110; head2->y = 10; head2->direction = 4; head2->next = NULL; p = head2; for (int i = 0; i < 3; i++) {q = (snake *) malloc (sizeof(snake)); p->next = q; q->next = NULL; q->x = p->x + 2; q->y = p->y; q->direction = p->direction; p = q; } return head2; } void showMain()//画出终端的大小及命名 画出游戏界面(边框,提示,基本成绩etc) {int i; system("title 贪吃蛇.生死局双人"); system("mode con cols=162 lines=35"); gotoxy(28, 10); c(10); printf("欢迎进入贪吃蛇的世界!!");gotoxy(108, 10); c(10); printf("欢迎进入贪吃蛇的世界!!"); gotoxy(0, 0); c(3); for (i = 0; i < 40; i++) {printf("▇"); Sleep(30); } for (i = 1; i < 25; i++) {gotoxy(78, i); printf("▇"); Sleep(30); } for (i = 39; i >= 0; i--) {gotoxy(2*i, 25); printf("▇"); Sleep(30); } for (i = 24; i >= 1; i--) {gotoxy(0, i); printf("▇"); Sleep(30); }gotoxy(82, 0); c(3); for (i = 0; i < 40; i++) {printf("▇"); Sleep(30); } for (i = 1; i < 25; i++) {gotoxy(160, i); printf("▇"); Sleep(30); } for (i = 39; i >= 0; i--) {gotoxy(2*i+82, 25); printf("▇"); Sleep(30); } for (i = 24; i >= 1; i--) {gotoxy(82, i); printf("▇"); Sleep(30); } c(10); gotoxy(30, 11); printf("请选择难度(0~6):"); scanf("%d", &level); switch(level){case 1: l = 600;break; case 2: l = 400;break; case 3: l = 200;break; case 4: l = 150;break; case 5: l = 100;break; case 6: l = 60;break; default: l = 2333; break;} cls();cls2(); c(15); gotoxy(4, 26); printf("等级: %d", level); gotoxy(20, 26); printf("分数: %d", score); gotoxy(4, 27); printf("当前长度: %d", lengt); gotoxy(20, 27); printf("已吃食物个数: %d", n); gotoxy(45, 26); printf("移动:↑↓←→"); gotoxy(45, 27); printf("暂停or继续:空格"); c(13); gotoxy(86, 26); printf("等级: %d", level); gotoxy(106, 26); printf("分数: %d", score); gotoxy(86, 27); printf("当前长度: %d", lengt); gotoxy(106, 27); printf("已吃食物个数: %d", n); gotoxy(127, 26); printf("移动:↑↓←→"); gotoxy(127, 27); printf("暂停or继续:空格"); gotoxy(64,30);c(10); printf("触碰绿色球游戏结束!黄色球能让你的小可爱生长!");gotoxy(74,31); printf("生长到一定长度会升级哦!"); gotoxy(150, 33); printf("制作:秋志");} void key(snake * head,snake* head1, snake * p,char ch)//改变蛇1的方向的实现 {int i, j;i = direc(ch); j = p->direction; if ((i==1&&j==3)||(i==2&&j==4)||(i==3&&j==1)||(i==4&&j==2));//判断是否与原有方向相冲突 else p->direction = i; } void pause(snake * head,snake*head1, snake * p2,char ch)//暂停功能的实现 {int i;if(a==1){cls(); gotoxy(36,10); printf("暂停中");}if(b==1){cls2(); gotoxy(118,10); printf("暂停中");}while (1) {if (kbhit() && getch() == 32) {if(a==1){gotoxy(36,10); printf(""); draw(head);gotoxy(F.x, F.y); c(12); printf("●");for(i=0;i<ai;i++){gotoxy(F1[i].x,F1[i].y);c(10);printf("●");}}if(b==1){gotoxy(118,10); printf("");draw(head1);gotoxy(F2.x, F2.y); c(12); printf("●");for(i=0;i<ai2;i++){gotoxy(F12[i].x,F12[i].y);c(10);printf("●");} }break;} } } void key2(snake * head,snake*head1, snake * p2,char ch)//改变蛇2的方向与暂停功能的实现 {int i,j;i = direc2(ch); j = p2->direction; if ((i==1&&j==3)||(i==2&&j==4)||(i==3&&j==1)||(i==4&&j==2));//判断是否与原有方向相冲突 else p2->direction = i; } void cls() //清屏 {gotoxy(2, 1); for (int i = 1; i < 26; i++) {for (int j = 2; j < 78; j++) printf(" "); gotoxy(2, i); } }void cls2() //清屏2 {gotoxy(84, 1); for (int i = 1; i < 26; i++) {for (int j = 2; j < 78; j++) printf(" "); gotoxy(84, i); } } int random()//用来输出随机值 {srand(time()+rand());//将随机数种子初始化 return rand();//返回随机数 } void newfood(snake * head) //随机产生食物并保证食物不与蛇的坐标重合 {int j; snake *p; p = head; int f = 1; F.x = random() % 76 + 1; if (F.x&1) F.x++; F.y = random() % 24 + 1; while (p) {if (p->x == F.x && p->y == F.y) {f = 0; break; }for(j=0;j<ai;j++){if (F1[j].x == F.x && F1[j].y == F.y) {f = 0; break; } } p = p->next; } if (f) {c(12); gotoxy(F.x, F.y); printf("●"); } else newfood(head); } void newfood2(snake * head) //随机产生食物并保证食物不与蛇2的坐标重合 {int j; snake *p; p = head; int f = 1; F2.x = random() % 76+ 83;if(F2.x&1) F2.x++; F2.y = random() % 24 + 1; while (p) {if (p->x == F2.x && p->y == F2.y) {f = 0; break; }for(j=0;j<ai2;j++){if (F12[j].x == F2.x && F12[j].y == F2.y) {f = 0; break; } } p = p->next; } if (f) {c(12); gotoxy(F2.x, F2.y); printf("●"); } else newfood2(head); } void newfood1(snake * head) //随机产生障碍并保证障碍不与蛇的坐标重合 {snake *p; p = head; int f = 1; F1[ai].x = random() % 76 + 1; if (F1[ai].x&1) F1[ai].x++; F1[ai].y = random() % 24 + 1; while (p) {if (p->x == F1[ai].x && p->y == F1[ai].y) {f = 0; break; } p = p->next; }if (F.x == F1[ai].x && F.y == F1[ai].y) {f = 0; } if (f) {c(10); gotoxy(F1[ai].x, F1[ai].y); printf("●"); ai++; } else newfood1(head);} void newfood3(snake * head2) //随机产生障碍并保证障碍不与蛇2的坐标重合 {snake *p; p = head2; int f = 1; F12[ai2].x = random() % 76 + 83; if (F12[ai2].x&1)F12[ai2].x++; F12[ai2].y = random() % 24 + 1; while (p) {if (p->x == F12[ai2].x && p->y == F12[ai2].y) {f = 0; break; } p = p->next; }if (F2.x == F12[ai2].x && F2.y == F12[ai2].y) {f = 0; } if (f) {c(10); gotoxy(F12[ai2].x, F12[ai2].y); printf("●"); ai2++; } else newfood3(head2);} void draw(snake * head) //画蛇 {gotoxy(head->x, head->y); c(12); printf("●"); c(13); head = head->next; while (head->next) {gotoxy(head->x, head->y); printf("●"); head = head->next; } c(12); gotoxy(head->x, head->y); printf("◆"); } void c(int k)//改变颜色输出 {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), k); } int time()//用来计时 {clock_t t=clock()/CLOCKS_PER_SEC; return t; } void gotoxy(int x,int y) //移动光标 {COORD coord; coord.X=x; coord.Y=y; SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord ); } void ycgb(int k)//隐藏光标 {HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(hOut,&cci); cci.bVisible=k;//赋1为显示,赋0为隐藏 SetConsoleCursorInfo(hOut,&cci); }int judge(int a,int b)//判断失败一方 {if(a+b==0){cls(); gotoxy(30, 10); printf("您的分数为%d", score);cls2(); gotoxy(112, 10); printf("您的分数为%d", score2);if(score>score2){gotoxy(28,11);printf("恭喜白蛇获胜!");gotoxy(110,11);printf("恭喜白蛇获胜!");}if(score<score2){gotoxy(28,11);printf("恭喜粉蛇获胜!");gotoxy(110,11);printf("恭喜粉蛇获胜!");}if(score==score2){gotoxy(34,11); printf("平局!");gotoxy(116,11); printf("平局!");} Sleep(2500); score = 0; n = 0;k=0; lengt = 4;score2 = 0; n2 = 0;k2=0; lengt2 = 4;return 1; }elsereturn 0; } void game() //具体游戏运行 {ai=0;ai2=0;a=b=1;int j,c1=0;char ch;snake *head, *p, *q, *s,*head2, *p2, *q2, *s2; head = creat();head2 = creat2(); s=p = head;s2=p2 = head2; while (p->next) p = p->next;while (p2->next) p2 = p2->next; draw(head);draw(head2); newfood(head);newfood2(head2); while (1) {if(a==1){q = (snake *) malloc (sizeof(snake)); p->next = q; q->direction = p->direction; q->next = NULL; switch(p->direction) {case 1: q->x = p->x; q->y = p->y - 1; break; case 2: q->x = p->x - 2; q->y = p->y; break; case 3: q->x = p->x; q->y = p->y + 1; break; case 4: q->x = p->x + 2; q->y = p->y; break; }} if(b==1){q2 = (snake *) malloc (sizeof(snake)); p2->next = q2; q2->direction = p2->direction; q2->next = NULL;switch(p2->direction) {case 1: q2->x = p2->x; q2->y = p2->y - 1; break; case 2: q2->x = p2->x - 2; q2->y = p2->y; break; case 3: q2->x = p2->x; q2->y = p2->y + 1; break; case 4: q2->x = p2->x + 2; q2->y = p2->y; break; } } if(a==1){if (q->x == F.x && q->y == F.y) //吃到食物(蛇变长并更新数据) {gotoxy(p->x, p->y); c(15); printf("●"); gotoxy(q->x, q->y); c(12); printf("◆"); p = q; score = score +level; lengt++; n++;k++;c(15); gotoxy(20, 26); printf("分数: %d", score); gotoxy(4, 27); printf("当前长度: %d", lengt); gotoxy(20, 27); printf("已吃食物个数: %d", n); if(k==8-level) {cls(); c(10); gotoxy(30, 10); printf("您的分数为%d", score);cls2(); gotoxy(112, 10); printf("您的分数为%d", score2);gotoxy(28,11);printf("恭喜白蛇获胜!");gotoxy(110,11);printf("恭喜白蛇获胜!");Sleep(2500);score = 0; n = 0;k=0; lengt = 4;score2 = 0; n2 = 0;k2=0; lengt2 = 4;return ;} newfood(head); }else {for(j=0;j<ai;j++)//是否撞到了障碍物 {if(F1[j].x==q->x && F1[j].y==q->y){cls(); gotoxy(30, 10); printf("您的分数为%d", score);a=0;c1=judge(a,b);if(c1)return ; }} if(a==1){gotoxy(head->x, head->y); printf(" "); head = head->next; free(s); gotoxy(head->x, head->y); c(12); printf("●"); gotoxy(p->x, p->y); c(15); printf("●"); gotoxy(q->x, q->y); c(12); printf("◆"); p = q; } }}if(b==1){if (q2->x == F2.x && q2->y == F2.y) //2吃到食物(蛇变长并更新数据) {gotoxy(p2->x, p2->y); c(13); printf("●"); gotoxy(q2->x, q2->y); c(12); printf("◆"); p2 = q2; score2 = score2 +level; lengt2++; n2++;k2++;c(13); gotoxy(106, 26); printf("分数: %d", score2); gotoxy(86, 27); printf("当前长度: %d", lengt2); gotoxy(106, 27); printf("已吃食物个数: %d", n2);if(k2==8-level) {cls();c(13); gotoxy(30, 10); printf("您的分数为%d", score);cls2(); gotoxy(112, 10); printf("您的分数为%d", score2);gotoxy(28,11);printf("恭喜粉蛇获胜!");gotoxy(110,11);printf("恭喜粉蛇获胜!");Sleep(2500);score = 0; n = 0;k=0; lengt = 4;score2 = 0; n2 = 0;k2=0; lengt2 = 4; return ;} newfood2(head2); }else{for(j=0;j<ai2;j++)//2是否撞到了障碍物 {if(F12[j].x==q2->x && F12[j].y==q2->y){cls2(); gotoxy(112, 10);c(13); printf("您的分数为%d", score2);b=0; c1=judge(a,b);if(c1==1)return ;}}if(b==1){gotoxy(head2->x, head2->y); printf(" "); head2 = head2->next; free(s2); gotoxy(head2->x, head2->y); c(12); printf("●"); gotoxy(p2->x, p2->y); c(13); printf("●"); gotoxy(q2->x, q2->y); c(12); printf("◆"); p2 = q2;} }}if(a==1)newfood1(head); if(b==1)newfood3(head2); Sleep(l); if(kbhit()){ch=getch();if(ch==-32){if(b==1)key2(head2,head, q2,ch);} if(ch==115||ch==97||ch==119||ch==100){if(a==1)key(head,head2, q,ch); }if(ch==32){pause(head,head2,q,ch);}} if(a==1){if (q->x==0||q->x==78||q->y==0||q->y==25)//碰墙结束 {cls(); gotoxy(30, 10); printf("您的分数为%d", score);a=0;c1=judge(a,b);if(c1==1)return ; }}if(a==1){s=head; while (s->next) {if (q->x == s->x && q->y == s->y)//碰自己结束 {cls(); gotoxy(30, 10); printf("您的分数为%d", score);a=0;c1=judge(a,b);if(c1==1)return ; } s = s->next; } s = head; } if(b==1){if (q2->x==82||q2->x==160||q2->y==0||q2->y==25)//2碰墙结束 {cls2(); gotoxy(112, 10); c(13); printf("您的分数为%d", score2);b=0;c1=judge(a,b);if(c1==1)return;}}if(b==1){s2=head2; while (s2->next) {if (q2->x == s2->x && q2->y == s2->y)//2碰自己结束 {cls2(); gotoxy(112, 10);c(13); printf("您的分数为%d", score2);b=0;c1=judge(a,b);if(c1==1)return ; } s2 = s2->next; } s2 = head2;} } }

总结

和别的游戏不同,贪食蛇是一个悲剧性的游戏。许多电子游戏都是以操作者的胜利而告终,而贪食蛇的结局却是死亡。不管玩得多么纯熟,技术多么高超,你最终听到的都是贪食蛇的一声惨叫。当手机上的小蛇越长越长,积分越来越高的时候,死亡也就越来越近。那时候忙的不是为了吃豆子长身体,而是为了避免撞墙。你会发现你穷于应付,四处奔忙。贪食蛇最要命的就在一个“贪”字上。

在学习编程的过程中无疑实战才是学习成果最好的验证,所以要不断的进行代码练习以及项目实战,本博客《项目实战合集》专栏为各位提供了各类项目的实战源码,希望各位有所受益,喜欢的小伙伴记得点波关注和赞,谢谢!

新壁纸

如果觉得《C语言实现贪吃蛇(双人版本)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。