SHOW:
|
|
- or go back to the newest paste.
1 | using System; | |
2 | using System.Linq; | |
3 | using System.Threading; | |
4 | using System.Text; | |
5 | ||
6 | namespace Tetris | |
7 | { | |
8 | class Tetris | |
9 | { | |
10 | class Piece | |
11 | { | |
12 | private int[] x = new int[4]; | |
13 | private int[] y = new int[4]; | |
14 | private char c; | |
15 | private ConsoleColor color; | |
16 | private int formIndex; | |
17 | private int rotationCount; | |
18 | public bool isFinal; | |
19 | ||
20 | public Piece(int offset) | |
21 | { | |
22 | Random ranGen = new Random(); | |
23 | int currFormIndex = ranGen.Next(0, forms.GetLength(0)); | |
24 | this.c = (char)forms[currFormIndex, 8]; | |
25 | this.color = formColors[forms[currFormIndex, 9]]; | |
26 | for (int i = 0; i < 4; i++) | |
27 | { | |
28 | this.x[i] = forms[currFormIndex, i] + offset; | |
29 | this.y[i] = forms[currFormIndex, i + 4] + 1; | |
30 | } | |
31 | this.isFinal = false; | |
32 | this.formIndex = currFormIndex; | |
33 | this.rotationCount = 0; | |
34 | } | |
35 | ||
36 | public void Rotate() | |
37 | { | |
38 | for (int i = 0; i < 4; i++) | |
39 | { | |
40 | this.x[i] += rotation[this.formIndex, this.rotationCount % 4, i]; | |
41 | this.y[i] += rotation[this.formIndex, this.rotationCount % 4, i + 4]; | |
42 | } | |
43 | this.rotationCount++; | |
44 | } | |
45 | ||
46 | public void Move(ConsoleKeyInfo pressedKey) | |
47 | { | |
48 | if (pressedKey.Key == ConsoleKey.RightArrow) | |
49 | { | |
50 | if (isPossible('R')) | |
51 | { | |
52 | for (int i = 0; i < 4; i++) | |
53 | { | |
54 | this.x[i]++; | |
55 | } | |
56 | } | |
57 | } | |
58 | else if (pressedKey.Key == ConsoleKey.LeftArrow) | |
59 | { | |
60 | if (isPossible('L')) | |
61 | { | |
62 | for (int i = 0; i < 4; i++) | |
63 | { | |
64 | this.x[i]--; | |
65 | } | |
66 | } | |
67 | } | |
68 | else if (pressedKey.Key == ConsoleKey.R) | |
69 | { | |
70 | if(isPossible('T')) | |
71 | { | |
72 | Rotate(); | |
73 | } | |
74 | } | |
75 | else if(pressedKey.Key == ConsoleKey.DownArrow) | |
76 | while (!isStopped()) | |
77 | { | |
78 | for (int i = 0; i < 4; i++) | |
79 | { | |
80 | this.y[i]++; | |
81 | } | |
82 | } | |
83 | } | |
84 | ||
85 | private bool isStopped() | |
86 | { | |
87 | for (int i = 0; i < 4; i++) | |
88 | { | |
89 | if (this.y[i] + 1 == field.GetLength(0) - 1 || field[this.y[i] + 1, this.x[i], 0] != 0) | |
90 | { | |
91 | this.isFinal = true; | |
92 | return true; | |
93 | } | |
94 | } | |
95 | return false; | |
96 | } | |
97 | ||
98 | private bool isPossible(char c) | |
99 | { | |
100 | switch (c) | |
101 | { | |
102 | case 'L': | |
103 | { | |
104 | for (int i = 0; i < 4; i++) | |
105 | { | |
106 | if (this.x[i] - 1 < 1 || field[this.y[i], this.x[i] - 1, 0] != 0) | |
107 | { | |
108 | return false; | |
109 | } | |
110 | } | |
111 | return true; | |
112 | } | |
113 | case 'R': | |
114 | { | |
115 | for (int i = 0; i < 4; i++) | |
116 | { | |
117 | if (this.x[i] + 1 > field.GetLength(1) - 2 || field[this.y[i], this.x[i] + 1, 0] != 0) | |
118 | { | |
119 | return false; | |
120 | } | |
121 | } | |
122 | return true; | |
123 | } | |
124 | default: | |
125 | { | |
126 | for (int i = 0; i < 4; i++) | |
127 | { | |
128 | if (this.y[i] - 2 < 1 || this.y[i] + 2 > field.GetLength(0) - 1 || this.x[i] - 2 < 1 || this.x[i] + 2 > field.GetLength(1) - 1 || field[this.y[i] + rotation[this.formIndex, this.rotationCount % 4, i + 4], this.x[i] + rotation[this.formIndex, this.rotationCount % 4, i], 0] != 0) | |
129 | { | |
130 | return false; | |
131 | } | |
132 | } | |
133 | return true; | |
134 | } | |
135 | } | |
136 | } | |
137 | ||
138 | public void Move() | |
139 | { | |
140 | if (!isStopped()) | |
141 | { | |
142 | for (int i = 0; i < 4; i++) | |
143 | { | |
144 | this.y[i]++; | |
145 | } | |
146 | } | |
147 | else | |
148 | { | |
149 | for (int i = 0; i < 4; i++) | |
150 | { | |
151 | field[this.y[i], this.x[i],0] = 1; | |
152 | field[this.y[i], this.x[i], 1] = (byte)Array.IndexOf(formColors,this.color); | |
153 | } | |
154 | } | |
155 | } | |
156 | ||
157 | public void Draw() | |
158 | { | |
159 | for (int i = 0; i < 4; i++) | |
160 | { | |
161 | DrawCharOnPosition(this.x[i], this.y[i], this.c, this.color); | |
162 | } | |
163 | } | |
164 | ||
165 | public void Clean() | |
166 | { | |
167 | for (int i = 0; i < 4; i++) | |
168 | { | |
169 | DrawCharOnPosition(this.x[i], this.y[i], this.c, ConsoleColor.Black); | |
170 | } | |
171 | } | |
172 | } | |
173 | ||
174 | public static void DrawCharOnPosition(int x, int y, char c, ConsoleColor color) | |
175 | { | |
176 | Console.SetCursorPosition(x, y); | |
177 | Console.ForegroundColor = color; | |
178 | Console.Write(c); | |
179 | } | |
180 | ||
181 | public static void RemoveScrollBars(int width, int heigth) | |
182 | { | |
183 | Console.BufferHeight = Console.WindowHeight = heigth; //clear the left scroll bar | |
184 | Console.BufferHeight = Console.WindowWidth = width; //clear the down scroll bar | |
185 | } | |
186 | ||
187 | static void DrawField() | |
188 | { | |
189 | for (int i = 0; i < field.GetLength(0); i++) | |
190 | { | |
191 | DrawCharOnPosition(0, i, '|', ConsoleColor.White); | |
192 | DrawCharOnPosition(field.GetLength(1) - 1, i, '|', ConsoleColor.White); | |
193 | } | |
194 | for (int i = 1; i < field.GetLength(1) - 1; i++) | |
195 | { | |
196 | DrawCharOnPosition(i, 0, '=', ConsoleColor.White); | |
197 | DrawCharOnPosition(i, field.GetLength(0) - 1, '=', ConsoleColor.White); | |
198 | } | |
199 | for (int i = 0; i < field.GetLength(1); i++) | |
200 | { | |
201 | for (int j = 0; j < field.GetLength(0); j++) | |
202 | { | |
203 | if (field[j, i, 0] != 0) | |
204 | { | |
205 | DrawCharOnPosition(i, j, '#', formColors[field[j, i, 1]]); | |
206 | } | |
207 | } | |
208 | } | |
209 | } | |
210 | ||
211 | ||
212 | ||
213 | static bool GameOver() | |
214 | { | |
215 | for (int i = 0; i < field.GetLength(1); i++) | |
216 | { | |
217 | if (field[1, i, 0] != 0) | |
218 | { | |
219 | return true; | |
220 | } | |
221 | } | |
222 | return false; | |
223 | } | |
224 | ||
225 | public static void DrawStringOnPosition(int x, int y, string s, ConsoleColor color) | |
226 | { | |
227 | Console.SetCursorPosition(x, y); | |
228 | Console.ForegroundColor = color; | |
229 | Console.Write(s); | |
230 | } | |
231 | ||
232 | ||
233 | static void DrawInfo(int level, int score, int lines) | |
234 | { | |
235 | DrawStringOnPosition(field.GetLength(1) + 3, 10, "Level: " + level, ConsoleColor.White);//Draw info; | |
236 | DrawStringOnPosition(field.GetLength(1) + 3, 11, "Score: " + score, ConsoleColor.White); | |
237 | DrawStringOnPosition(field.GetLength(1) + 3, 12, "Lines: " + lines, ConsoleColor.White); | |
238 | } | |
239 | ||
240 | static public byte[,,] field; | |
241 | ||
242 | static public ConsoleColor[] formColors = { ConsoleColor.Black, ConsoleColor.Green, ConsoleColor.Red, ConsoleColor.Yellow, ConsoleColor.Magenta }; | |
243 | ||
244 | static int[,] forms = { { 0, 1, 1, 2, 0, 0, 1, 1, 35, 1}, { 0, 1, 1, 2, 1, 1, 0, 0, 35, 1}, | |
245 | { 0, 1, 2, 3, 0, 0, 0, 0, 35, 2}, { 0, 1, 1, 2, 0, 1, 0, 0, 35, 3}, | |
246 | { 0, 1, 2, 2, 0, 0, 0, 1, 35, 4}, { 0, 0, 1, 2, 1, 0, 0, 0, 35, 4}, | |
247 | }; | |
248 | ||
249 | static int[, ,] rotation = {{{ 0, -1, 0, -1, 2, 1, 0, -1 },{ 0, 1, 0, 1, -2, -1, 0, 1 },{ 0, -1, 0, -1, 2, 1, 0, -1 },{ 0, 1, 0, 1, -2, -1, 0, 1 }}, | |
250 | {{ 1, 0, -1, -2, 1, 0, 1, 0 },{ -1, 0, 1, 2, -1, 0, -1, 0 },{ 1, 0, -1, -2, 1, 0, 1, 0},{ -1, 0, 1, 2, -1, 0, -1, 0}}, | |
251 | {{ 2, 1, 0, -1, -2, -1, 0, 1 },{ -2, -1, 0, 1, 2, 1, 0, -1},{ 2, 1, 0, -1, -2, -1, 0, 1},{ -2, -1, 0, 1, 2, 1, 0, -1}}, | |
252 | {{ 1, -1, 0, -1, -1, -1, 0, 1 },{ 1, 1, 0, -1, 1, -1, 0, -1},{ -1, 1, 0, 1, 1, 1, 0, -1},{ -1, -1, 0, 1, -1, 1, 0, 1}}, | |
253 | {{ 2, 1, 0, -1, -2, -1, 0, -1},{ 2, 1, 0, 1, 2, 1, 0, -1},{-2, -1, 0, 1, 2, 1, 0, 1},{ -2, -1, 0, -1, -2, -1, 0, 1}}, | |
254 | {{ -1, 0, -1, -2, -1, 0, 1, 2 },{ 1, 0, -1, -2, -1, 0, -1, -2 },{ 1, 0, 1, 2, 1, 0, -1, -2},{ -1, 0, 1, 2, 1, 0, 1, 2}}}; | |
255 | ||
256 | static void Main() | |
257 | { | |
258 | int level = 0; | |
259 | int linesCount = 0; | |
260 | int score = 0; | |
261 | int playfieldWidth = 16; | |
262 | int playfieldHeigth = 30; | |
263 | field = new byte[playfieldHeigth, playfieldWidth, 2]; | |
264 | RemoveScrollBars(playfieldWidth * 2, playfieldHeigth); //Remove the scroll bars | |
265 | Console.Title = "Tetris"; | |
266 | Piece currentPiece = new Piece(playfieldWidth / 2 - 2); //Create the first piece | |
267 | while (true) | |
268 | { | |
269 | Console.Clear(); //Clear the field | |
270 | DrawField(); //Redraw the field; | |
271 | currentPiece.Draw(); //Draw the piece | |
272 | while (Console.KeyAvailable) //Move if possible the piece left/right or rotate if a proper key is pressed | |
273 | { | |
274 | ConsoleKeyInfo pressedKey = Console.ReadKey(true); | |
275 | currentPiece.Clean(); | |
276 | currentPiece.Move(pressedKey); | |
277 | currentPiece.Draw(); | |
278 | }; | |
279 | currentPiece.Move(); //Check if possible and move down or stop moving | |
280 | if (currentPiece.isFinal) //If stop moving check lines and score | |
281 | { | |
282 | score += 4; | |
283 | for ( int i = 0; i < field.GetLength(0); i++) | |
284 | { | |
285 | int line = 1; | |
286 | for (int j = 1; j < field.GetLength(1) - 1; j++) | |
287 | { | |
288 | line *= field[i, j, 0]; | |
289 | } | |
290 | if (line != 0) | |
291 | { | |
292 | linesCount++; | |
293 | level = level < 5 ? linesCount / 20 : 5; | |
294 | score += 40; | |
295 | for (int c = 0; c < field.GetLength(1); c++) | |
296 | { | |
297 | for (int r = i; r > 0; r--) | |
298 | { | |
299 | field[r, c, 0] = field[r - 1, c, 0]; | |
300 | field[r, c, 1] = field[r - 1, c, 1]; | |
301 | } | |
302 | field[0, c, 0] = 0; | |
303 | field[0, c, 1] = 0; | |
304 | } | |
305 | } | |
306 | } | |
307 | currentPiece = new Piece(playfieldWidth / 2 - 2); | |
308 | } | |
309 | DrawInfo(level, score, linesCount); //Draw info | |
310 | if (GameOver()) //Check if game over | |
311 | { | |
312 | DrawStringOnPosition(field.GetLength(1) - 6, field.GetLength(0) / 2, "!!!GAME OVER!!!", ConsoleColor.Red); | |
313 | Console.WriteLine(); | |
314 | break; | |
315 | - | Console.Beep(); |
315 | + | |
316 | Console.Beep(); //Play sound | |
317 | Thread.Sleep(600 - 100 * level); //Slow the program | |
318 | } | |
319 | } | |
320 | } | |
321 | } |