某方块。。。
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\nd:right\ns:down\nw:rotate\ne:pause\nr: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 }