#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#define FrameX 4
#define FrameY 4
#define Frame_width 20
#define Frame_height 20
struct Snack
{
int x[100];
int y[100];
int length;
int speed;
};
struct Food
{
int x;
int y;
};
int islong;
int pos[2];
void MakeFrame();
void PrintSnack(struct Snack *snack);
void Gotoxy(int x,int y);
void NewFood(struct Snack *snack,struct Food *food);
///随機生成食物
void NewFood(struct Snack *snack,struct Food *food)
{
while(1)
{
srand((unsigned)time(NULL));
food->x = rand()%(Frame_width-1);
food->y = rand()%(Frame_height);
if(food->x == 0||food->y == 0)
continue;
food->x = 2*food->x+FrameX;
food->y = food->y+FrameY;
int i;
for(i = 0;i < snack->length;i++)
{
if(food->x == snack->x[i]&&food->y == snack->y[i])
break;
}
if(i == snack->length)
{
Gotoxy(food->x,food->y);
printf("◎");
break;
}
}
}
///設定視窗大小
void setWindowsSize(int w,int h)
{
///聲明一個句柄
HANDLE hout;
///獲得标準輸出句柄
hout = GetStdHandle(STD_OUTPUT_HANDLE);
///定義了一個矩形 結構體
SMALL_RECT rc = {0,0,w-1,h-1};
///定義一個等高 機構體
COORD size = {w,h};
SetConsoleWindowInfo(hout,TRUE,&rc);
SetConsoleScreenBufferSize(hout,size);
}
///移動光标到指定位置
void Gotoxy(int x,int y)
{
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos; pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(hout,pos);
}
///隐藏光标
void Hide()
{
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursor_info = {1,0};
SetConsoleCursorInfo(hout,&cursor_info);
}
///開始界面
void MainMenu()
{
unsigned char ch;
printf("\n\n\n");
printf("\t\t+----------------------------------+\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 貪吃蛇遊戲 |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 按任意鍵開始遊戲 |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t+----------------------------------+\n");
ch = getch();
}
///結束界面
void OverGame()
{
system("cls");
unsigned char ch;
printf("\n\n\n");
printf("\t\t+----------------------------------+\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 貪吃蛇遊戲 |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| 遊戲結束 |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t+----------------------------------+\n");
Sleep(2000);
ch = getch();
}
void SetColor()
{
HANDLE hout;
hout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hout,BACKGROUND_INTENSITY|BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|FOREGROUND_RED);
}
///初始化蛇的資料
void InitSnack(struct Snack *snack)
{
snack->x[0] = FrameX+2;
snack->y[0] = FrameY+Frame_height/2;
snack->length = 3;
snack->speed = 300;
for(int i = 1;i < snack->length;i++)
{
snack->x[i] = snack->x[i-1]+2;
snack->y[i] = snack->y[i-1];
}
}
///顯示遊戲資訊
void ShowInfo(struct Snack *snack)
{
Gotoxy(FrameX+2*Frame_width+3,FrameY+2);
printf("目前等級: %d",(snack->length-3)/5+1);
Gotoxy(FrameX+2*Frame_width+3,FrameY+4);
printf("目前速度(移動間隔): %d",snack->speed);
Gotoxy(FrameX+2*Frame_width+3,FrameY+6);
printf("目前分數: %d",(snack->length-3)*50);
}
///列印蛇
void PrintSnack(struct Snack *snack)
{
for(int i = 0;i < snack->length;i++)
{
Gotoxy(snack->x[i],snack->y[i]);
if(i == 0)
printf("◆");
else if(i == snack->length-1)
printf("◇");
else printf("◎");
}
}
/// 蛇的移動
void MoveSnack(struct Snack *snack)
{
Gotoxy(snack->x[0],snack->y[0]);
printf(" ");
for(int i = 1;i < snack->length;i++)
{
snack->x[i-1] = snack->x[i];
snack->y[i-1] = snack->y[i];
}
}
///蛇吃食物
void EatFood(struct Snack *snack,struct Food *food)
{
if(snack->x[snack->length-1] == food->x&&snack->y[snack->length-1] == food->y)
{
snack->length++;
for(int i = snack->length-1;i >= 1;i--)
{
snack->x[i] = snack->x[i-1];
snack->y[i] = snack->y[i-1];
}
snack->x[0] = pos[0];
snack->y[0] = pos[1];
NewFood(snack,food);
if((snack->length-3)%5 == 0)
snack->speed-=50;
ShowInfo(snack);
}
}
///判斷是否死亡,0表示死亡,1表示未死亡
int IsDie(struct Snack *snack)
{
for(int i = 0;i < snack->length-1;i++)
if(snack->x[snack->length-1] == snack->x[i]&&snack->y[snack->length-1] == snack->y[i])
return 0;
if(snack->x[snack->length-1] == FrameX||snack->x[snack->length-1] == FrameX+2*Frame_width-2
||snack->y[snack->length-1] == FrameY||snack->y[snack->length-1] == FrameY+Frame_height)
return 0;
return 1;
}
void StartGame()
{
system("cls");
struct Snack *snack,s;
snack = &s;
struct Food *food,f;
food = &f;
MakeFrame();
InitSnack(snack);
PrintSnack(snack);
ShowInfo(snack);
NewFood(snack,food);
unsigned ch;
while(1)
{
islong = 0;
pos[0] = snack->x[0];
pos[1] = snack->y[0];
if(kbhit())
{
ch = getch();
if((int)ch == 27)
{
OverGame();
break;
}
if(kbhit())
{
Sleep(20);
islong = 1;
}
}
switch(ch)
{
case 72:///向上
MoveSnack(snack);
snack->y[snack->length-1]-=1;
break;
case 80:///向下
MoveSnack(snack);
snack->y[snack->length-1]+=1;
break;
case 75:///向左
MoveSnack(snack);
snack->x[snack->length-1]-=2;
break;
case 77:///向右
MoveSnack(snack);
snack->x[snack->length-1]+=2;
break;
}
PrintSnack(snack);
EatFood(snack,food);
if(IsDie(snack) == 0)
{
Gotoxy(FrameX+Frame_width-2,FrameY+Frame_height/2-1);
printf("Game Over!");
Sleep(2000);
break;
}
if(islong == 0)
Sleep(snack->speed);
else
Sleep(10);
}
}
///顯示遊戲視窗和提示資訊
void MakeFrame()
{
Gotoxy(FrameX,FrameY);
printf("╔");
Gotoxy(FrameX+2*Frame_width-2,FrameY);
printf("╗");
Gotoxy(FrameX,FrameY+Frame_height);
printf("╚");
Gotoxy(FrameX+2*Frame_width-2,FrameY+Frame_height);
printf("╝");
for(int i = 1;i < Frame_width-1;i++)
{
Gotoxy(FrameX+2*i,FrameY);
printf("═");
}
for(int i = 1;i < Frame_width-1;i++)
{
Gotoxy(FrameX+2*i,FrameY+Frame_height);
printf("═");
}
for(int i = 1;i < Frame_height;i++)
{
Gotoxy(FrameX,FrameY+i);
printf("║");
}
for(int i = 1;i < Frame_height;i++)
{
Gotoxy(FrameX+2*Frame_width-2,FrameY+i);
printf("║");
}
Gotoxy(FrameX+2*Frame_width+3,FrameY+Frame_height-5);
printf("操作: 用上下左右方向鍵控制方向");
Gotoxy(FrameX+2*Frame_width+3,FrameY+Frame_height-3);
printf("長按方向鍵加速");
Gotoxy(FrameX+2*Frame_width+3,FrameY+Frame_height-1);
printf("按ESC退出遊戲");
SetColor();
Gotoxy(FrameX+Frame_width-5,FrameY-2);
printf("貪吃蛇遊戲");
}
int main()
{
system("color f3");
setWindowsSize(80,30);
MainMenu();
Hide();
StartGame();
OverGame();
//Gotoxy(10,10);
//Hide();
return 0;
}