這學期課程設計用c語言編寫了windows環境下的貪喫蛇,多次修改後形成了暫時性的最終版,功能有等級選擇,遊戲說明,排行榜等等,以下是截圖和部分源代碼。
使用到的頭文件、變量和函數
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 100
#define ESC 27
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define ENTER 13
#define BRICK "■"
enum direction//蛇頭方向
{
left,
right,
up,
down
};
typedef struct food//食物
{
int x;
int y;
}Food;
typedef struct Node//蛇身的節點
{
int x;
int y;
}Sna;
typedef struct SnakeBody//蛇的身體
{
Sna snakenode;
struct SnakeBody *next;
}SnakeNode, *SnakeList;
typedef struct SnakeData//蛇本身數據,體長和頭的方向
{
int snakelen;
enum direction dir;
}SnaData;
int SPEECH=150;//速度
int len; //地圖長
int wide; //地圖寬
int map[N][N]; //地圖數組
int map2[N][N];//真實地圖數組
int Score=0;//分數
int mark=0;//判斷要不要清除蛇尾節點
int stop=1;//遊戲停止判斷
int level=1;//等級
int HighScore[10][5];//排行榜分數
SnakeData Sdata;//記錄蛇本身數據
SnakeNode *tail;//記錄蛇尾節點
SnakeList S;//蛇
Food F;//健康的食物
Food B;//腐爛的食物
int q=1; //表示當前菜單指針所在位置
int p=1; //難度指針所在位置
int c;
int start,end,ftime;
int fx,fy;
int temp;
void color(unsigned short c);
void gotoxy(int x,int y);
void HideCursor();
void readmap(int level);//讀取地圖
void drawmap();//畫地圖
void Initfood(SnakeList S,Food *F,Food *B,int a);//建立食物
void DrawFood(Food *F,int a);//畫食物
int JudgeFood(SnakeList S,Food *F,Food *B);//判斷食物座標合法性
void Initsnake(SnakeList *S);//初始化蛇
void Creatsnake(SnakeList S);//建立蛇
void InitNode(SnakeList S,int x,int y);//建立蛇節點
void Drawsnake(SnakeList S,Food *F,Food *B);//畫蛇和判斷蛇喫食物和判斷蛇過草地
void movesnake(SnakeList S);//蛇的移動
void move(SnakeList S);//清理蛇尾節點
void keyboard();//獲取鍵盤輸入
void paly(SnakeList S,Food *F,Food *B);//玩遊戲函數
unsigned char getkey();
void textout(int y,int x,int ch,char s[]);
void DrawMenu();//畫主界面
void drawtext();//畫主菜單
void Choose();//主菜單各個選項的進入
void DrawInfo();//畫遊戲信息
void DrawHelp();//畫幫助信息
void DrawHelp2();//畫操作說明
void DrawBox1();//難度菜單的邊框
void DrawBox2();//遊戲信息的邊框
void DrawBox3();//遊戲結束信息的邊框
void DrawLevel();//畫難度選擇界面
void DrawLevel2();
void StopMenu();//畫遊戲結束界面
void select(int c);//主菜單上下選擇
void LevelChoose();//難度菜單上下選擇
void LevelChoose2();
void readscore(int level);//讀取一個排行榜數據
void ReadAllScore();//讀取所有排行榜數據
void DrawScore(int level,int x);//畫一個排行榜
void DrawRank();//畫所有排行榜
void DrawRank2();
void JudgeScore(int level);//判斷分數大小是否記錄進排行榜
需要用到的基本函數:
void color(unsigned short c)
{//顏色選擇
HANDLE app=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(app,c);
}
void gotoxy(int x,int y)//光標跳轉
{
COORD cr;
HANDLE app=GetStdHandle(STD_OUTPUT_HANDLE);
cr.X=x;
cr.Y=y;
SetConsoleCursorPosition(app,cr);
}
void HideCursor()//隱藏光標
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
蛇的建立使用鏈表,蛇身移動和加長用到頭插法:
void InitNode(SnakeList S,int x,int y)
{//蛇的節點創建
SnakeNode *q=(SnakeNode *)malloc(sizeof(SnakeNode));
SnakeNode *p=S;
q->next=NULL;
q->snakenode.x=x;
q->snakenode.y=y;
q->next=p->next;
p->next=q;
}
食物座標合法性判斷:
int JudgeFood(SnakeList S,Food *F,Food *B)
{//判斷食物位置是否合法,F爲要建立的食物,B爲已經建立的食物
SnakeNode *p=S->next;
if(F->x%2 != 0) //使得食物座標x一直爲偶數,方便判斷
return 0;
if(F->x==B->x && F->y== B->y)//判斷食物和已建立食物座標是否一樣
return 0;
if(F->x < 8 || F->x > 90)//判斷食物座標是否在外牆上
return 0;
if(F->y < 2 || F->y > 16)
return 0;
if(map2[F->y+1][F->x+1] == 1)//判斷食物座標是否在障礙物(內牆)上
return 0;
while(p!=NULL)//判斷食物座標是否在蛇上
{
if(F->x == p->snakenode.x && F->y == p->snakenode.y)
{
return 0;
}
p=p->next;
}
return 1;
}
蛇穿草地部分代碼:
if((level == 2 || level == 3 || level == 4 || level == 5) && (tail->snakenode.x == 92 || tail->snakenode.x == 4)) //如果蛇穿牆而過,在蛇尾過牆後重新輸出該位置的牆體
{
gotoxy(tail->snakenode.x,tail->snakenode.y);
color(2);
printf("▲");
}
if((level == 3 || level == 4) && (tail->snakenode.y ==17 || tail->snakenode.y ==1))
{
gotoxy(tail->snakenode.x,tail->snakenode.y);
color(2);
printf("▲");
}
藍色食物每10秒換位置:
//每10秒藍色Food變換一次位置
ftime=(end-start) /1000;
if(ftime % 10 == 0 && map2[B->y][B->x] == 5 && ftime != temp)
{
gotoxy(B->x,B->y);
printf(" ");
map2[B->y][B->x]=0;
Initfood(S,B,F,5);
temp=ftime;
}
運行程序: