main.c
#include <stdio.h>
#include "snake.h"
char * s_gets(char *st, int n);
void start(snake *ps, food *pd, score *ft); //开始游戏
void open(FILE *pf,score *ps,score *pt); // 打开记录文件
void show(FILE *sp,score *ps); //打印排行
void Interface(void); //游戏界面
int number(void); //游戏选项
int wasd = 'a'; //控制方向
int flag = 1; //控制食物生成
int main(int argc, char *argv[]) {
FILE *sp; // 指向保存数据的二进制文本
int i;
snake snakes; //蛇 分数
score scores[SCORE]; //记录分数,姓名
score ft; //单局的分数,姓名
food pd; //食物
srand((unsigned int) time(0));
Interface();//游戏界面
i = number();//游戏选项
while(i != '3')
{
switch(i)
{
case '1':
start(&snakes,&pd,&ft); //开始游戏
open(sp,scores,&ft); //记录分数
break;
case '2':
show(sp,scores); //查看记录的分数
break;
}
Interface();//游戏界面
i = number();
}
gotoxy(0,0);
printf("帅哥在来玩啊!");
return 0;
}
void show(FILE *sp,score *ps) //打印排行
{
int i,m;
space();
int x, y;
sp = fopen("123.txt","rb");
rewind(sp);
i=0;
while(fread(&ps[i],sizeof(score),1,sp)>0)
i++;
fclose(sp);
for(x=MOVE;x<WRID+MOVE;x+=2)
{
gotoxy(x, 0);
printf(WALL);
gotoxy(x,HIGH);
printf(WALL);
}
for(y=1;y<HIGH;++y)
{
gotoxy(MOVE,y);
printf(WALL);
gotoxy(WRID+MOVE-2,y);
printf(WALL);
}
if(i == SCORE)
{
for(m=0;m<i;m++)
{
gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
printf("%d:姓名:%-6s 分数: %d ",m+1,ps[m].name,ps[m].count);
}
}
else if(i < SCORE && i >0)
{
for(m=0;m<i;m++)
{
gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
printf("%d:姓名:%-6s 分数: %d ",m+1,ps[m].name,ps[m].count);
}
for(m=i;m<SCORE;++m)
{
gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
printf("%d:姓名:---- 分数:---- ",m+1);
}
}
else
{
for(m=0;m<SCORE;++m)
{
gotoxy((WRID+MOVE)/2-6,HIGH/2-2+m);
printf("%d:姓名:---- 分数:---- ",m+1);
}
}
gotoxy((WRID+MOVE)/2-2,HIGH/2-2+m+3);
printf("按任意键继续");
getch();
space(); //清屏
}
void open(FILE *pf,score *ps,score *pt) // 打开记录文件
{
int i=0;
int n, m;
bool fun = false;
score temp;
pf=fopen("123.txt","a+b"); //读打开
rewind(pf);
while(fread(&ps[i],sizeof(score),1,pf) > 0)
i++;
fclose(pf);
if(i==0)
{
ps[i++] = *pt;
}
else
{
for(n=0;n<i;n++) //排序
{
if(ps[n].count <= pt->count)
break;
}
if(n <= i-1)
{
if(i==SCORE)
{
if(n == i-1)
ps[n] = *pt;
if(n < i-1)
{
for(m=i-2;m>=n;m--)
ps[m+1] = ps[m];
ps[n] = *pt;
}
}
if(i < SCORE)
{
for(m=i-1;m>=n;m--)
ps[m+1] = ps[m];
ps[n] = *pt;
i++;
}
}
}
pf = fopen("123.txt","wb");
rewind(pf);
n=0;
while(n<i)
{
fwrite(&ps[n],sizeof(score),1,pf);
n++;
}
fclose(pf);
}
void start(snake *ps, food *pd, score *ft) //开始游戏
{
int i=1;
char name[NAME];
int fast = 300;
wall(ps);
gotoxy((MOVE+WRID)/2-8,3);
printf("输入姓名:");
s_gets(name,NAME);
strcpy(ft->name,name);
gotoxy((MOVE+WRID)/2-8,3);
printf(" ");
while(i)
{
Sleep(fast);//在标准C中是sleep(S不要大写),下面使用大写的来说明,具体
//用什么看你用什么编译器。简单的说VC用Sleep,别的一律使用sleep
if(flag)
{
foods(pd,ps); //生成随机食物
if(fast > 100)
fast -=2;
}
snakemove(ps,pd,ft); //移动蛇
gotoxy(MOVE+WRID+4,7);
printf("玩家: %s", ft->name);
gotoxy(MOVE+WRID+4,9);
printf("得分: %d", ft->count);
gotoxy(MOVE+WRID+4,21);
printf("游戏规则: wsad移动蛇.吃方块得1分.");
gotoxy(MOVE+WRID+4,22);
printf(" 撞墙或吃到身体游戏结束.");
if(gameover(ps)) //判断游戏是否结束
{
gotoxy((MOVE+WRID)/2-6,HIGH/2);
printf("玩家:%s 得分:%d",ft->name,ft->count);
gotoxy((MOVE+WRID)/2-6,HIGH/2+1);
printf("按任意键返回主菜单");
if(getch());
space(); //清屏
i = 0;
}
}
}
int number(void) //游戏选项
{
int i;
i = getch();
while(strchr("123", i) == NULL)
i = getch();
space();
return i;
}
void Interface(void)
{
int x, y;
for(x=MOVE;x<WRID+MOVE;x+=2)
{
gotoxy(x, 0);
printf(WALL);
gotoxy(x,HIGH);
printf(WALL);
}
for(y=1;y<HIGH;++y)
{
gotoxy(MOVE,y);
printf(WALL);
gotoxy(WRID+MOVE-2,y);
printf(WALL);
}
gotoxy((WRID+MOVE)/2-2, HIGH/2-5);
fputs("贪 吃 蛇",stdout);
gotoxy(MOVE+20, HIGH-3);
printf("[1]开始 [2]排行榜 [3]退出");
}
char* s_gets(char *st, int n)
{
char *val;
char *find;
val = fgets(st,n,stdin);
if(val)
{
find = strchr(st, '\n');
if(find)
*find = '\0';
else
while(getchar() != '\n')
continue;
}
return val;
}
snake.c
#include <stdio.h>
#include "snake.h"
static void insnake(snake *head); //初始化蛇
static void eatfood(snake *ph,food *pd, score *ft); //吃食物
void gotoxy(int x, int y)
{
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
bool gameover(snake *ph)
{
node *temp = ph->front->next;
node *pf = ph->front;
if(ph->front->x == MOVE || ph->front->x == (WRID+MOVE)-2 || //判断蛇头是否撞墙
ph->front->y == 0 ||ph->front->y == HIGH)
{
while(pf != NULL) //释放动态内存
{
ph->front = ph->front->next;
free(pf);
pf = ph->front;
}
ph->rear = NULL;
flag = 1;
wasd = 'a';
return true;
}
while(temp != NULL)
{
if(ph->front->x == temp->x && ph->front->y == temp->y) //判断蛇头是否吃到蛇身
{
while(pf != NULL) //释放动态内存
{
ph->front = ph->front->next;
free(pf);
pf = ph->front;
}
ph->rear = NULL;
flag = 1;
wasd = 'a';
return true;
}
temp = temp->next;
}
return false;
}
void snakemove(snake *ph,food *pd,score *ft)
{
node * temp;
if(kbhit())
wasd = tolower(getch());
temp = ph->rear;
gotoxy(ph->rear->x, ph->rear->y); // 消除蛇尾
printf(" ");
while(temp != ph->front) //打印移动中的 蛇身
{
temp->x = temp->upper->x;
temp->y = temp->upper->y;
gotoxy(temp->x, temp->y);
printf(SE);
temp = temp->upper;
}
switch(wasd)
{
case 'w':
(ph->front->y)--;
break;
case 's':
(ph->front->y)++;
break;
case 'a':
ph->front->x -= 2;
break;
case 'd':
ph->front->x += 2;
break;
}
gotoxy(ph->front->x, ph->front->y); // 打印蛇头
printf(TU);
eatfood(ph,pd,ft);
gotoxy(100,0);
}
static void eatfood(snake *ph,food *pd, score *ft) //吃食物
{
node *pnew;
if(ph->front->x==pd->x && ph->front->y==pd->y)
{
pnew = (node *)malloc(sizeof(node));
pnew->next = pnew->upper = NULL;
ph->rear->next = pnew;
pnew->upper = ph->rear;
ph->rear = pnew;
ph->item++;
flag = 1;
}
ft->count = ph->item-LEN;
}
void wall(snake *head) //墙体
{
int x, y;
for(x=MOVE;x<WRID+MOVE;x+=2)
{
gotoxy(x, 0);
printf(WALL);
gotoxy(x,HIGH);
printf(WALL);
}
for(y=1;y<HIGH;++y)
{
gotoxy(MOVE,y);
printf(WALL);
gotoxy(WRID+MOVE-2,y);
printf(WALL);
}
gotoxy(100,0);
insnake(head);
}
void foods(food *pd, snake *head ) //生成食物
{
int xy=1;
node * ps = head->front;
pd->x = rand() %(WRID-4)+1+MOVE;
pd->y = rand() %(HIGH-1) +1;
if(pd->x %2 == 0)
{
while(ps != NULL)
{
if(ps->x == pd->x && ps->y == pd->y)
xy = 0;
ps = ps->next;
}
if(xy)
{
gotoxy(pd->x,pd->y);
printf(WALL);
flag = 0;
}
}
}
static void insnake(snake *head) //初始化蛇
{
int i = 0;
int x, y;
head->item = LEN;
node *ps;
for(i=0;i< head->item;i++) //生成双向链表
{
ps = (node *)malloc(sizeof(node));
ps->next = NULL;
ps->upper = NULL;
if(i==0)
head->front = head->rear = ps;
else
{
ps->upper = head->rear;
head->rear->next = ps;
head->rear = ps;
}
}
head->front->x = (MOVE+WRID) / 2;
if(head->front->x%2 != 0)
(head->front->x)++;
head->front->y = HIGH / 2;
gotoxy(head->front->x, head->front->y); //打印蛇头
printf(TU);
ps = head->front->next;
while(ps != NULL) // 打印蛇身
{
ps->x = ps->upper->x + 2;
ps->y = ps->upper->y;
gotoxy(ps->x, ps->y);
printf(SE);
ps = ps->next;
}
gotoxy(100,0);
}
void space(void)
{
int y,i;
y = HIGH;
for(i=0;i<=y;++i)
{
gotoxy(MOVE,i);
printf(" "
" "
" "
" ");
}
}
snake.h
#ifndef __SNAKE_H
#define __SNAKE_H
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <windows.h> // ■⊙●
#include <time.h>
#include <stdbool.h>
#define SCORE 5 //记录长度
#define NAME 30 //名字长度
#define WALL "■" //墙
#define TU "⊙"
#define SE "●"
#define WRID 70 //墙宽
#define HIGH 26 //墙高
#define MOVE 10 //墙体平移
#define LEN 3 //初始化长度
typedef struct Score{ //记录分数
char name[NAME]; //姓名
int count; //分数
}score;
typedef struct Node{ //蛇
int x;
int y;
struct Node *next;
struct Node *upper;
}node;
typedef struct Snake{ //蛇的头指针 和 分数
node * front; //头指针
node * rear; //尾指针
int item; //分数
}snake;
typedef struct Food{ //食物
int x;
int y;
}food;
extern int wasd; //控制方向
extern int flag; //控制食物生成
void gotoxy(int x, int y); //光标坐标
void wall(snake *head); //初始化墙 和 蛇身
void snakemove(snake *ph,food *pd,score *ft); //移动蛇
void foods(food *pd, snake *head); //生成食物
bool gameover(snake *ph); //结束游戏
void space(void); //清除
#endif