某方块。。。

  1 using System;
  2 using System.Drawing;
  3 using System.Windows.Forms;
  4 
  5 internal class tetris : Form
  6 {
  7     private static void Main()
  8     {
  9         Application.EnableVisualStyles();
 10         Application.Run(new tetris());
 11     }
 12 
 13     private const int dimension = 8;
 14     private const int maxwidth = 16;
 15     private const int maxheight = 32;
 16     private const int boardwidth = 8;
 17     private const int nextwidth = boardwidth - 2;
 18     private const int invalid = 255;
 19 
 20     private Timer timer;
 21 
 22     private byte[,] matrix;
 23 
 24     private tetris_object item;
 25     private tetris_object next;
 26 
 27     private bool start;
 28     private bool pause;
 29     private string message;
 30     private int score;
 31     private int ox;
 32     private int oy;
 33 
 34     private int offsetx
 35     {
 36         get
 37         {
 38             return ox;
 39         }
 40         set
 41         {
 42             if (0 != item.check(value, oy, matrix))
 43                 ox = value;
 44         }
 45     }
 46 
 47     private int offsety
 48     {
 49         get
 50         {
 51             return oy;
 52         }
 53         set
 54         {
 55             int result = item.check(ox, value, matrix);
 56 
 57             if (0 == result)
 58             {
 59                 item.shift(ox, oy, matrix);
 60 
 61                 check();
 62 
 63                 item = next;
 64                 next = generate();
 65 
 66                 ox = (maxwidth - 4) / 2;
 67                 oy = -item.bottom;
 68             }
 69             else if (-1 == result)
 70             {
 71                 lost("game over");
 72             }
 73             else
 74             {
 75                 oy = value;
 76             }
 77         }
 78     }
 79 
 80     private tetris()
 81     {
 82         timer = new Timer();
 83 
 84         timer.Interval = 500;
 85 
 86         timer.Tick += timer_tick;
 87 
 88         DoubleBuffered = true;
 89         MaximizeBox = false;
 90         FormBorderStyle = FormBorderStyle.FixedDialog;
 91         StartPosition = FormStartPosition.CenterScreen;
 92         ClientSize = new Size(dimension * (maxwidth + boardwidth), dimension * maxheight);
 93         Font = new Font("Consolas", dimension);
 94 
 95         KeyPress += key_press;
 96         Paint += paint;
 97 
 98         pause = true;
 99     }
100 
101     private void timer_tick(object o, EventArgs e)
102     {
103         ++offsety;
104 
105         Refresh();
106     }
107 
108     private void key_press(object o, KeyPressEventArgs e)
109     {
110         if (!pause)
111             switch (e.KeyChar)
112             {
113                 case 'a':
114                 case 'A': --offsetx; break;
115 
116                 case 'd':
117                 case 'D': ++offsetx; break;
118 
119                 case 's':
120                 case 'S': ++offsety; break;
121 
122                 case 'w':
123                 case 'W': item.rotate(ox, oy, matrix); break;
124             }
125 
126         if ('e' == e.KeyChar || 'E' == e.KeyChar)
127         {
128             if (!start)
129                 init();
130 
131             timer.Enabled = pause;
132 
133             pause = !pause;
134         }
135         else if ('r' == e.KeyChar || 'R' == e.KeyChar)
136         {
137             lost("");
138         }
139 
140         Refresh();
141     }
142 
143     private void paint(object o, PaintEventArgs e)
144     {
145         e.Graphics.FillRectangle(Brushes.WhiteSmoke, 0, 0, dimension * maxwidth, dimension * maxheight);
146         e.Graphics.FillRectangle(Brushes.Gray, dimension * maxwidth, 0, dimension * boardwidth, dimension * maxheight);
147         e.Graphics.FillRectangle(Brushes.LightGray, dimension * (maxwidth + (boardwidth - nextwidth) / 2), dimension * 1, dimension * nextwidth, dimension * nextwidth);
148 
149         e.Graphics.DrawString(string.Format("a:left
d:right
s:down
w:rotate
e:pause
r:reset"), Font, Brushes.Black, dimension * (maxwidth + (boardwidth - nextwidth) / 2), dimension * (nextwidth + 4));
150 
151         if (start)
152         {
153             if (pause)
154                 e.Graphics.DrawString("pause", Font, Brushes.Black, dimension * 1, dimension * (maxheight / 2));
155 
156             e.Graphics.DrawString(string.Format("{0:d7}", score), Font, Brushes.Black, dimension * (maxwidth + (boardwidth - nextwidth) / 2), dimension * (nextwidth + 2));
157 
158             for (int y = 0; y < maxheight; ++y)
159                 for (int x = 0; x < maxwidth; ++x)
160                     if (invalid != matrix[x, y])
161                         e.Graphics.FillRectangle(tetris_object.colors[matrix[x, y]], dimension * x, dimension * y, dimension - 1, dimension - 1);
162 
163             item.draw(ox, oy, e.Graphics);
164             next.draw(maxwidth + (boardwidth - 4) / 2, 2, e.Graphics);
165         }
166         else
167         {
168             e.Graphics.DrawString(message, Font, Brushes.Black, dimension * 1, dimension * (maxheight / 2 - 2));
169             e.Graphics.DrawString("press "e" to start", Font, Brushes.Black, dimension * 1, dimension * (maxheight / 2));
170         }
171     }
172 
173     private void init()
174     {
175         matrix = new byte[maxwidth, maxheight];
176 
177         for (int y = 0; y < maxheight; ++y)
178             for (int x = 0; x < maxwidth; ++x)
179                 matrix[x, y] = invalid;
180 
181         item = generate();
182         next = generate();
183 
184         start = true;
185         pause = true;
186         message = "";
187         score = 0;
188         ox = (maxwidth - 4) / 2;
189         oy = -item.bottom;
190     }
191 
192     private void lost(string text)
193     {
194         timer.Enabled = false;
195 
196         start = false;
197         message = text;
198     }
199 
200     private tetris_object generate()
201     {
202         tetris_object current = new tetris_object();
203 
204         return current;
205     }
206 
207     private void check()
208     {
209         byte[,] target = new byte[maxwidth, maxheight];
210 
211         for (int y = 0; y < maxheight; ++y)
212             for (int x = 0; x < maxwidth; ++x)
213                 target[x, y] = invalid;
214 
215         for (int y = maxheight, ty = maxheight; y-- > 0; )
216             if (!check(y))
217             {
218                 --ty;
219 
220                 for (int x = 0; x < maxwidth; ++x)
221                     target[x, ty] = matrix[x, y];
222             }
223 
224         matrix = target;
225     }
226 
227     private bool check(int y)
228     {
229         for (int x = 0; x < maxwidth; ++x)
230             if (invalid == matrix[x, y])
231                 return false;
232 
233         score = score + 100;
234 
235         if (0 == score % 1000)
236             if (100 < timer.Interval)
237                 timer.Interval = timer.Interval - 50;
238 
239         return true;
240     }
241 
242     private void remove(int y)
243     {
244     }
245 
246     private class tetris_object
247     {
248         private static readonly byte[][][] objects =
249         {
250             new byte[][]
251             {
252                 new byte[] { 8, 9, 10, 11, },
253                 new byte[] { 1, 5, 9, 13, },
254             },
255             new byte[][]
256             {
257                 new byte[] { 9, 10, 13, 14, },
258             },
259             new byte[][]
260             {
261                 new byte[] { 5, 8, 9, 10, },
262                 new byte[] { 5, 9, 10, 13, },
263                 new byte[] { 8, 9, 10, 13, },
264                 new byte[] { 5, 8, 9, 13, },
265             },
266             new byte[][]
267             {
268                 new byte[] { 4, 8, 9, 10, },
269                 new byte[] { 5, 6, 9, 13, },
270                 new byte[] { 8, 9, 10, 14, },
271                 new byte[] { 5, 9, 12, 13, },
272             },
273             new byte[][]
274             {
275                 new byte[] { 6, 8, 9, 10, },
276                 new byte[] { 5, 9, 13, 14, },
277                 new byte[] { 8, 9, 10, 12, },
278                 new byte[] { 4, 5, 9, 13, },
279             },
280             new byte[][]
281             {
282                 new byte[] { 4, 5, 9, 10, },
283                 new byte[] { 6, 9, 10, 13, },
284             },
285             new byte[][]
286             {
287                 new byte[] { 5, 6, 8, 9, },
288                 new byte[] { 5, 9, 10, 14, },
289             },
290         };
291         private static readonly Brush[] brushes =
292         {
293             Brushes.Salmon,
294             Brushes.Peru,
295             Brushes.Teal,
296             Brushes.Purple,
297             Brushes.Indigo,
298             Brushes.Olive,
299             Brushes.Green,
300         };
301 
302         private int column;
303         private int row;
304 
305         internal static Brush[] colors
306         {
307             get
308             {
309                 return brushes;
310             }
311         }
312 
313         internal int bottom
314         {
315             get
316             {
317                 return objects[column][row][3] / 4 + 1;
318             }
319         }
320 
321         internal tetris_object()
322         {
323             Random random = new Random();
324 
325             column = random.Next() % objects.Length;
326             row = random.Next() % objects[column].Length;
327         }
328 
329         internal void rotate(int x, int y, byte[,] matrix)
330         {
331             int original = row;
332 
333             while (++original < objects[column].Length)
334                 if (0 != check(objects[column][original], x, y, matrix))
335                     goto _rotate;
336 
337             for (original = 0; original < row; ++original)
338                 if (0 != check(objects[column][original], x, y, matrix))
339                     goto _rotate;
340 
341             return;
342 
343         _rotate:
344             row = original;
345         }
346 
347         private int check(byte[] cubes, int x, int y, byte[,] matrix)
348         {
349             int minx = Math.Min(Math.Min(cubes[0] % 4, cubes[1] % 4), Math.Min(cubes[2] % 4, cubes[3] % 4));
350             int maxx = Math.Max(Math.Max(cubes[0] % 4, cubes[1] % 4), Math.Max(cubes[2] % 4, cubes[3] % 4));
351 
352             if (-minx > x || maxwidth - maxx <= x)
353                 return 0;
354 
355             if (maxheight <= y + cubes[3] / 4)
356                 return 0;
357 
358             foreach (byte cube in cubes)
359             {
360                 int l = x + cube % 4;
361                 int t = y + cube / 4;
362 
363                 if (0 <= l && maxwidth > l && 0 <= t && maxheight > t)
364                     if (invalid != matrix[l, t])
365                         if (1 > y + cubes[0] / 4)
366                             return -1;
367                         else
368                             return 0;
369             }
370 
371             return 1;
372         }
373 
374         internal int check(int x, int y, byte[,] matrix)
375         {
376             return check(objects[column][row], x, y, matrix);
377         }
378 
379         internal void shift(int x, int y, byte[,] matrix)
380         {
381             foreach (byte cube in objects[column][row])
382                 matrix[x + cube % 4, y + cube / 4] = (byte)column;
383         }
384 
385         internal void draw(int x, int y, Graphics graphics)
386         {
387             foreach (byte cube in objects[column][row])
388                 graphics.FillRectangle(brushes[column], dimension * (x + cube % 4), dimension * (y + cube / 4), dimension - 1, dimension - 1);
389         }
390     }
391 }
原文地址:https://www.cnblogs.com/sunnymilk/p/3279271.html