· 5 years ago · May 10, 2020, 01:22 PM
1#include <vector>
2#include <iostream>
3#include <conio.h>
4#include <cmath>
5#include <windows.h>
6#include <cstdlib>
7#include <ctime>
8#include <string>
9
10const int WIDTH = 40;
11const int HEIGHT = 20;
12const size_t MAX_SIZE = 1000;
13
14const int DELAY_MS = 800;
15enum MoveResult
16{
17 GotCollision = 2,
18 GotFruit = 1,
19 NothingHappens = 0
20};
21
22struct Point
23{
24 int x;
25 int y;
26};
27
28
29std::vector<Point> snake(MAX_SIZE);
30size_t head;
31size_t tail;
32
33Point direction;
34Point fruit;
35
36void GotoXY(const int y, const int x);
37void GotoXY(const Point& p);
38void PutCharAt(const int y, const int x, const int c);
39void PutCharAt(const Point& p, const int c);
40void Delay(const int t);
41int GetKey();
42void DrawBorders();
43bool PointOnSnake(const Point& p);
44void NextInSnake(size_t& idx);
45int Move(Point& p);
46void GenerateFruit(Point& fruit);
47void SetupDirectionFromKeyboard(Point& dir);
48void Init();
49void PlayGame();
50void GotoXY(const int y, const int x)
51{
52
53 COORD position{static_cast<short int>(x), static_cast<short int>(y)};
54 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
55 SetConsoleCursorPosition(hConsole, position);
56}
57
58void GotoXY(const Point& p)
59{
60 GotoXY(p.y, p.x);
61}
62
63void PutCharAt(const int y, const int x, const int c)
64{
65 GotoXY(y, x);
66 putch(c);
67}
68
69void PutCharAt(const Point& p, const int c)
70{
71 PutCharAt(p.y, p.x, c);
72}
73
74void Delay(int t)
75{
76 // тоже windows API
77 Sleep(100);
78}
79
80int GetKey()
81{
82
83 if (kbhit())
84 return getch();
85 return 0;
86}
87
88void DrawBorders()
89{
90
91 for (int i = 0; i < WIDTH; ++i)
92 {
93 PutCharAt(0, i, '#');
94 PutCharAt(HEIGHT - 1, i, '#');
95 }
96
97 for (int i = 0; i < HEIGHT; ++i)
98 {
99 PutCharAt(i, 0, '#');
100 PutCharAt(i, WIDTH - 1, '#');
101 }
102}
103
104void NextInSnake(size_t& idx)
105{
106
107 idx = (idx + 1) % snake.size();
108}
109
110bool PointOnSnake(const Point& p)
111{
112
113
114 size_t e = head;
115 NextInSnake(e);
116
117 for (size_t t = tail; t != e; NextInSnake(t))
118 {
119 if (snake[t].x == p.x && snake[t].y == p.y)
120 return true;
121 }
122 return false;
123}
124
125int Move(Point& p)
126{
127
128 p.x += direction.x;
129 p.y += direction.y;
130
131 p.x = (p.x - 1 + (WIDTH - 2)) % (WIDTH - 2) + 1;
132 p.y = (p.y - 1 + (HEIGHT - 2)) % (HEIGHT - 2) + 1;
133 if (fruit.x == p.x && fruit.y == p.y)
134 return MoveResult::GotFruit;
135 if (PointOnSnake(p))
136 return MoveResult::GotCollision;
137 if (p.x == 0 || p.x == WIDTH - 1 || p.y == 0 || p.y == HEIGHT - 1)
138 return MoveResult::GotCollision;
139 return MoveResult::NothingHappens;
140}
141
142void GenerateFruit(Point& fruit)
143{
144 fruit.x = 1 + rand() % (WIDTH - 2);
145 fruit.y = 1 + rand() % (HEIGHT - 2);
146 PutCharAt(fruit, '$');
147}
148
149void SetupDirectionFromKeyboard(Point& dir)
150{
151 switch (GetKey())
152 {
153 case 'w':
154 case 'W':
155 dir = Point{0, -1};
156 break;
157 case 's':
158 case 'S':
159 dir = Point{0, 1};
160 break;
161 case 'd':
162 case 'D':
163 dir = Point{1, 0};
164 break;
165 case 'a':
166 case 'A':
167 dir = Point{-1, 0};
168 break;
169 }
170}
171
172
173void TextGameOver()
174{
175 system("cls");
176 int HEIGHT = 30;
177 int WIDH = 60;
178 GotoXY(HEIGHT / 2, (WIDTH - 10) / 2);
179 std::cout << "Game Over";
180}
181
182
183
184void INTRO()
185{
186 system("cls");
187 int HEIGHT = 30;
188 int WIDH = 60;
189 GotoXY(HEIGHT / 2, (WIDTH - 6) / 2);
190 std::cout << "SNAKE";
191}
192
193
194
195void Init()
196{
197 tail = head = 0;
198 snake[head] = Point{5, 5};
199 direction = Point{1, 0};
200 GenerateFruit(fruit);
201 DrawBorders();
202}
203
204void PlayGame()
205{
206
207 while (true)
208 {
209 SetupDirectionFromKeyboard(direction);
210 Delay(DELAY_MS);
211 Point p = snake[head];
212 PutCharAt(p, 'o');
213
214 int moveResult = Move(p);
215 if (moveResult == MoveResult::GotCollision)
216 {
217 TextGameOver();
218 break;
219 }
220 NextInSnake(head);
221 snake[head] = p;
222 PutCharAt(p, 'O');
223 if (moveResult == MoveResult::NothingHappens)
224 {
225 PutCharAt(snake[tail], ' ');
226 NextInSnake(tail);
227 }
228 if (moveResult == MoveResult::GotFruit)
229 {
230 GenerateFruit(fruit);
231 }
232 }
233}
234
235
236void Test()
237{
238 int count = 100;
239 for (int second = 0; second < count; second++){
240 Delay(100);
241 GotoXY(0, 0);
242 puts(" ");
243 GotoXY(0, 0);
244 std::cout << second;
245 GotoXY(1, 0);
246 int key = GetKey();
247 if (key > 0)
248 {
249 GotoXY(2, 0);
250 std::cout << "Key code " << key << "was pressed. ";
251 }
252 else
253 {
254 std::cout << "No key was pressed ";
255 }
256 }
257}
258
259
260int main()
261{
262 Init();
263 PlayGame();
264 return 0;
265}