C++之貪吃蛇,貪吃蛇
1 #include<iostream>
2 #include<cstdio>
3 #include<cstdlib>
4 #include<ctime>
5 #include<conio.h>
6 using namespace std;
7
8 typedef struct{ int x, y; }Point;
9
10 char map[22][22]; //定義一個22*22的地圖(含邊界)
11 Point snake[400], food, Next; //定義蛇、食物、下一步蛇頭的位置
12 int head, tail; //用於儲存蛇頭和蛇尾的下標
13 int grade, length, autotime; //游戲等級、蛇長、自動前進所需時間
14 char direction; //前進方向
15
16 //用inline定義內聯函數節省程序運行時的調用開銷
17 //刷新地圖
18 inline void Update(char map[][22], int grade, int length, int autotime)
19 {
20 system("cls"); //清屏
21 int i, j;
22 printf("\n");
23 for (i = 0; i < 22; i++)
24 {
25 printf("\t");
26 for (j = 0; j < 22; j++)
27 printf("%c ", map[i][j]);
28 if (i == 0)
29 printf("\t等級為:%d", grade);
30 if (i == 2)
31 printf("\t長度為:%d", length);
32 if (i == 6)
33 printf("\t自動前進時間");
34 if (i == 8)
35 printf("\t間隔為:%d ms", autotime);
36 printf("\n");
37 }
38 }
39
40 //歡迎界面
41 inline void hello()
42 {
43 puts("\n\n\n\t\t\t貪吃蛇游戲即將開始!"); //准備開始
44 double start;
45 for (int i = 3; i >= 0; i--)
46 {
47 start = (double)clock() / CLOCKS_PER_SEC; //得到程序目前為止運行的時間
48 while ((double)clock() / CLOCKS_PER_SEC - start <= 1); //經過1秒之後
49 if (i > 0)
50 {
51 system("cls"); //清屏
52 printf("\n\n\n\t\t\t進入倒計時:%d\n", i); //倒計時
53 }
54 else
55 Update(map, grade, length, autotime); //刷新地圖
56 }
57 }
58
59 //隨機生成食物位置
60 inline void f()
61 {
62 srand(int(time(0))); //調用種子函數
63 do{
64 food.x = rand() % 20 + 1;
65 food.y = rand() % 20 + 1;
66 } while (map[food.x][food.y] != ' ');
67 map[food.x][food.y] = '!'; //食物為“!”
68 }
69
70 //初始化
71 inline void init()
72 {
73 int i, j;
74 for (i = 1; i <= 20; i++)
75 for (j = 1; j <= 20; j++)
76 map[i][j] = ' ';
77 for (i = 0; i <= 21; i++)
78 map[0][i] = map[21][i] = map[i][0] = map[i][21] = '*'; //邊界
79 map[1][1] = map[1][2] = 'O'; //蛇身(含蛇尾)
80 map[1][3] = '@'; //蛇頭
81 head = 2; tail = 0; //開始時頭和尾的下標
82 snake[head].x = 1; snake[head].y = 3; //開始時蛇頭在地圖上的下標
83 snake[tail].x = 1; snake[tail].y = 1; //開始時蛇尾在地圖上的下標
84 snake[1].x = 1; snake[1].y = 2; //開始時蛇身在地圖上的下標
85 f(); //隨機生成食物位置
86 grade = 1; length = 3; autotime = 500; //開始的等級、長度、自動前進時間
87 direction = 77; //初始的運動方向向右
88 }
89
90 //預前進
91 inline int GO()
92 {
93 bool timeover = true;
94 double start = (double)clock() / CLOCKS_PER_SEC; //得到程序目前為止運行的時間
95
96 //自動經過1秒或者等待1秒內的鍵盤輸入
97 while ((timeover = ((double)clock() / CLOCKS_PER_SEC - start <= autotime / 1000.0)) && !_kbhit());
98 //鍵盤輸入
99 if (timeover)
100 {
101 _getch();
102 direction = _getch(); //獲取方向
103 }
104 switch (direction)
105 {
106 case 72:
107 Next.x = snake[head].x - 1; Next.y = snake[head].y; //向上
108 break;
109 case 80:
110 Next.x = snake[head].x + 1; Next.y = snake[head].y; //向下
111 break;
112 case 75:
113 Next.x = snake[head].x; Next.y = snake[head].y - 1; //向左
114 break;
115 case 77:
116 Next.x = snake[head].x; Next.y = snake[head].y + 1; //向右
117 break;
118 default:
119 puts("\tGame over!"); //按下非方向鍵游戲失敗
120 return 0;
121 }
122 if (Next.x == 0 || Next.x == 21 || Next.y == 0 || Next.y == 21) //撞到邊界
123 {
124 puts("\tGame over!");
125 return 0;
126 }
127 if (map[Next.x][Next.y] != ' '&&!(Next.x == food.x&&Next.y == food.y)) //吃到自己
128 {
129 puts("\tGame over!");
130 return 0;
131 }
132 if (length == 400) //最長蛇長
133 {
134 puts("\tGood game!");
135 return 0;
136 }
137 return 1;
138 }
139
140 //吃到食物
141 inline void EAT()
142 {
143 length++; //長度增加1
144 int _grade = length / 10 + 1; //計算等級
145 if (_grade != grade)
146 {
147 grade = _grade;
148 if (autotime >= 100)
149 autotime = 550 - grade * 50; //增加一級自動時間減短50毫秒
150 }
151 map[Next.x][Next.y] = '@'; //蛇頭位置變化
152 map[snake[head].x][snake[head].y] = 'O'; //原蛇頭位置變化為蛇身
153 head = (head + 1) % 400; //蛇頭下標加1
154 snake[head].x = Next.x; snake[head].y = Next.y; //蛇頭下標變化
155 f(); //隨機生成食物位置
156 Update(map, grade, length, autotime); //刷新地圖
157 }
158
159 //沒吃到食物
160 inline void FAILURE()
161 {
162 map[snake[tail].x][snake[tail].y] = ' '; //蛇尾原來的位置變成“ ”
163 tail = (tail + 1) % 400; //蛇尾下標加1
164 map[Next.x][Next.y] = '@'; //蛇頭位置變化
165 map[snake[head].x][snake[head].y] = 'O'; //原蛇頭位置變化為蛇身
166 head = (head + 1) % 400; //蛇頭下標加1
167 snake[head].x = Next.x; //蛇頭下標變化
168 snake[head].y = Next.y;
169 Update(map, grade, length, autotime); //刷新地圖
170 }
171
172 //main函數
173 int main()
174 {
175 init(); //初始化
176 hello(); //歡迎界面
177 while (1)
178 {
179 if (GO()) //預前進
180 {
181 if (Next.x == food.x&&Next.y == food.y)
182 EAT(); //吃到食物
183 else
184 FAILURE(); //沒吃到食物
185 }
186 else
187 return 0; //失敗或者勝利,游戲結束
188 }
189 return 0;
190 }
191 //
