using System; using System.Drawing; using System.Windows.Forms; namespace MyGame { public delegate void KillWoodEventHandler(); public interface IGameBo { int[,] Grids { get; } int XPos { get; } int YPos { get; } } public interface IGameBiz { void Run(); } public interface IGameLogic { void Draw(Graphics e); void KeyDown(KeyEventArgs e); } public interface IGameWood : IGameLogic { event KillWoodEventHandler KillWood; } public interface IWoodBo { int[,] Grids { get; } } public interface IWoodBiz { bool OnAngle(); bool CanLeft(); bool CanRight(); bool CanDown(); } public interface IWood : IWoodBiz, IWoodBo { } public class WoodGame : IGameBo, IGameBiz, IGameLogic, IGameWood { public const int X = 20, Y = 20; public const int StartPos = 7; public const int Dimension = 18; public const int XDimension = XSize * Dimension; public const int YDimension = YSize * Dimension; public const int XSize = 16; public const int YSize = 26; public event KillWoodEventHandler KillWood; int[,] Grids { get; set; } int XPos { get; set; } int YPos { get; set; } int[,] IGameBo.Grids { get { return this.Grids; } } int IGameBo.XPos { get { return this.XPos; } } int IGameBo.YPos { get { return this.YPos; } } Random Random = new Random(); IWood CurrentWood, NextWood; Bitmap bmp; public WoodGame() { Init(); } ~WoodGame() { UnInit(); } public void Draw(Graphics e) { using (Graphics graphics = Graphics.FromImage(bmp)) { graphics.Clear(Color.White); DrawContext(graphics); } e.DrawImage(bmp, X, Y); } public void KeyDown(KeyEventArgs e) { switch (e.KeyCode) { case Keys.Left: if (CurrentWood.CanLeft()) { XPos--; this.OnDraw(); } break; case Keys.Right: if (CurrentWood.CanRight()) { XPos++; this.OnDraw(); } break; case Keys.Down: Run(); break; case Keys.Space: if (CurrentWood.OnAngle()) this.OnDraw(); break; } } public void Run() { if (CurrentWood.CanDown()) { YPos++; } else { FinishWood(); StartWood(); } this.OnDraw(); } void Init() { bmp = new Bitmap(XDimension + 1, YDimension + 1); Grids = new int[XSize, YSize]; NextWood = GetWood(); StartWood(); } void UnInit() { bmp.Dispose(); } void StartWood() { CurrentWood = NextWood; NextWood = GetWood(); XPos = StartPos; YPos = 0; } void FinishWood() { int size = CurrentWood.Grids.GetLength(0); for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { if (CurrentWood.Grids[x, y] != 0) Grids[XPos + x, YPos + y] = 1; } } PriKillWood(); OnDraw(); } void PriKillWood() { int size = CurrentWood.Grids.GetLength(0); int y1 = Math.Min(YPos + size, YSize) - 1; int y2 = y1; while (y1 >= YPos) { int x1 = 0; while (x1 < XSize) { if (Grids[x1, y1] == 0) break; x1++; } if (x1 == XSize) { OnKillWood(); } else { for (int x = 0; x < XSize; x++) Grids[x, y2] = Grids[x, y1]; y2--; } y1--; } while (y1 >= 0) { for (int x = 0; x < XSize; x++) Grids[x, y2] = Grids[x, y1]; y2--; y1--; } } void OnDraw() { if (Form.ActiveForm != null) Form.ActiveForm.Refresh(); } void DrawContext(Graphics e) { for (int x = 0; x <= XDimension; x += Dimension) e.DrawLine(Pens.SlateGray, x, 0, x, YDimension); for (int y = 0; y <= YDimension; y += Dimension) e.DrawLine(Pens.SlateGray, 0, y, XDimension, y); int size = CurrentWood.Grids.GetLength(0); for (int x = 0; x < XSize; x++) { for (int y = 0; y < YSize; y++) { if (Grids[x, y] == 1) e.FillRectangle(Brushes.Black, new Rectangle(x * Dimension + 2, y * Dimension + 2, Dimension - 3, Dimension - 3)); } } for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { if (CurrentWood.Grids[x, y] == 1) e.FillRectangle(Brushes.Black, new Rectangle((XPos + x) * Dimension + 2, (YPos + y) * Dimension + 2, Dimension - 3, Dimension - 3)); } } } private void OnKillWood() { if (KillWood != null) { KillWood(); } } Wood GetWood() { int rnd = Random.Next() % 8; switch (rnd) { case 0: rnd = Random.Next() % 2; return new AngleWood(this, new int[,,] { {{0,0,0,0}, {0,0,0,0}, {1,1,1,1}, {0,0,0,0}}, {{0,0,1,0}, {0,0,1,0}, {0,0,1,0}, {0,0,1,0}}, }, rnd); case 1: rnd = Random.Next() % 4; return new AngleWood(this, new int[,,] { {{1,0,0}, {1,0,0}, {1,1,0}}, {{0,0,0}, {1,1,1}, {1,0,0}}, {{1,1,0}, {0,1,0}, {0,1,0}}, {{0,0,0}, {0,0,1}, {1,1,1}} }, rnd); case 2: rnd = Random.Next() % 2; return new AngleWood(this, new int[,,] { {{1,1,0}, {0,1,1}, {0,0,0}}, {{0,1,0}, {1,1,0}, {1,0,0}}, }, rnd); case 3: rnd = Random.Next() % 2; return new AngleWood(this, new int[,,] { {{0,1,1}, {1,1,0}, {0,0,0}}, {{1,0,0}, {1,1,0}, {0,1,0}}, }, rnd); case 4: rnd = Random.Next() % 4; return new AngleWood(this, new int[,,] { {{0,0,1}, {0,0,1}, {0,1,1}}, {{0,0,0}, {1,0,0}, {1,1,1}}, {{0,1,1}, {0,1,0}, {0,1,0}}, {{0,0,0}, {1,1,1}, {0,0,1}} }, rnd); case 5: return new AngleWood(this, new int[,,] { {{1,1}, {1,1}} }, 0); case 6: rnd = Random.Next() % 4; return new AngleWood(this, new int[,,] { {{0,1,1}, {0,0,1}, {0,1,1}}, {{0,0,0}, {1,0,1}, {1,1,1}}, {{1,1,0}, {1,0,0}, {1,1,0}}, {{1,1,1}, {1,0,1}, {0,0,0}} }, rnd); case 7: rnd = Random.Next() % 4; return new AngleWood(this, new int[,,] { {{1,1,1}, {0,1,0}, {0,0,0}}, {{0,0,1}, {0,1,1}, {0,0,1}}, {{0,0,0}, {0,1,0}, {1,1,1}}, {{1,0,0}, {1,1,0}, {1,0,0}} }, rnd);/* case 8: rnd = Random.Next() % 4; return new AngleWood(this, new int[,,] { {{0,1,0}, {0,1,0}, {1,1,1}}, {{1,0,0}, {1,1,1}, {1,0,0}}, {{1,1,1}, {0,1,0}, {0,1,0}}, {{0,0,1}, {1,1,1}, {0,0,1}} }, rnd); case 9: rnd = Random.Next() % 4; return new AngleWood(this, new int[,,] { {{1,0,0,0}, {1,1,0,0}, {1,1,1,0}, {1,1,1,1}}, {{1,1,1,1}, {1,1,1,0}, {1,1,0,0}, {1,0,0,0}}, {{1,1,1,1}, {0,1,1,1}, {0,0,1,1}, {0,0,0,1}}, {{0,0,0,1}, {0,0,1,1}, {0,1,1,1}, {1,1,1,1}} }, rnd); case 10: rnd = Random.Next() % 2; return new AngleWood(this, new int[,,] { {{1,1,1}, {0,0,0}, {1,1,1}}, {{1,0,1}, {1,0,1}, {1,0,1}} }, rnd);*/ } throw new Exception(); } } public abstract class Wood : IWood { public IGameBo Game; public int[,] Grids { get; set; } public Wood(IGameBo mGame, int[,] mGrids) { this.Game = mGame; this.Grids = mGrids; } public abstract bool OnAngle(); public virtual bool CanLeft() { return Check(Grids, Game.XPos - 1, Game.YPos); } public virtual bool CanRight() { return Check(Grids, Game.XPos + 1, Game.YPos); } public virtual bool CanDown() { return Check(Grids, Game.XPos, Game.YPos + 1); } public virtual int GetSize() { return Grids.GetLength(0); } protected bool Check(int[,] mGrids, int mXPos, int mYPos) { int size = this.GetSize(); for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { if (mGrids[x, y] == 0) continue; if (mXPos + x < 0 || mXPos + x >= WoodGame.XSize || mYPos + y >= WoodGame.YSize || (mXPos + x >= 0 && mYPos + y >= 0 && Game.Grids[mXPos + x, mYPos + y] != 0)) return false; } } return true; } } public class AngleWood : Wood { int Angle; int AngleTime; int[, ,] AngleGrids; public AngleWood(IGameBo mGame, int[, ,] mAngleGrids, int mAngle) : base(mGame, GetAngle(mAngleGrids, mAngle)) { this.Angle = mAngle; this.AngleTime = mAngleGrids.GetLength(0); this.AngleGrids = mAngleGrids; } public override bool OnAngle() { int angle = this.Angle; if (angle == this.AngleTime - 1) angle = 0; else angle++; int[,] newGrids; if (CanAngle(angle, out newGrids)) { Grids = newGrids; this.Angle = angle; return true; } return false; } static int[,] GetAngle(int[, ,] mAngleGrids, int mAngle) { int size = mAngleGrids.GetLength(1); int[,] grids = new int[size, size]; for (int x = 0; x < size; x++) for (int y = 0; y < size; y++) grids[x, y] = mAngleGrids[mAngle, y, x]; return grids; } public virtual bool CanAngle(int mAngle, out int[,] mNewGrids) { int size = this.GetSize(); int[,] newAngle = GetAngle(AngleGrids, mAngle); mNewGrids = null; if (!Check(newAngle, Game.XPos, Game.YPos)) return false; mNewGrids = newAngle; return true; } } static class GameProgram { class GameForm : Form { const string text = "俄罗斯方块,分数:"; IGameWood game; public GameForm() { int cx = WoodGame.XDimension + WoodGame.X * 2 + SystemInformation.Border3DSize.Width * 2 + 3; int cy = WoodGame.YDimension + WoodGame.Y * 2 + SystemInformation.Border3DSize.Height * 2 + SystemInformation.CaptionHeight + 3; this.Size = new Size(cx, cy); this.DoubleBuffered = true; this.MaximizeBox = false; this.FormBorderStyle = FormBorderStyle.FixedSingle; this.Text = text + "0"; game = new WoodGame(); game.KillWood += game_KillWood; } int i = 0; void game_KillWood() { i += 100; this.Text = text + i; } protected override void OnPaint(PaintEventArgs e) { game.Draw(e.Graphics); } protected override void OnKeyDown(KeyEventArgs e) { game.KeyDown(e); } } static void Main() { Application.Run(new GameForm()); } } }