<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      xingd.net

      .net related techonology

      導航

      Minesweeper: GDI+ 初步實現

      Posted on 2008-03-06 18:14  xingd  閱讀(3981)  評論(1)    收藏  舉報
      邏輯代碼部分借鑒木野狐博客中的代碼,參考http://www.rzrgm.cn/RChen/archive/2005/07/07/188107.html,之后我會加入自己的設計調整。

      一些必要的枚舉:

      public enum GameStatus
      {
          NotStarted,
          Playing,
          Win,
          Lose
      }


      public enum MineCellStatus : short
      {
          Covered,
          MarkDoubt,
          MarkMine,
          Uncovered,
          Exploded
      }


      public struct MineCell
      {
          
      public MineCellStatus Status;
          
      public bool IsMine;        
          
      public byte NearbyMines;
      }

      將MineCell聲明為struct或class代表了兩種不同的設計策略,簡單起見,先使用struct。

      邏輯代碼如下:

      namespace xingd.Minesweeper
      {
          
      public class MineBoard
          
      {
              
      private MineCell[,] cells = new MineCell[00];

              
      private int totalMines;
              
      private int makedMines;
              
      private GameStatus status;

              
      public int Columns get return cells.GetLength(1); } }

              
      public int Rows get return cells.GetLength(0); } }

              
      public int TotalMines get return totalMines; } }
              
      public int MarkedMines get return makedMines; } }

              
      public GameStatus Status get return status; } }

              
      public MineCell this[int row, int col] get return cells[row, col]; } }

              
      public void Init(int rows, int columns, int mines)
              
      {
                  
      if (rows <= 0 || columns <= 0 || mines >= columns * rows)
                  
      {
                      
      throw new ArgumentException();
                  }


                  cells 
      = new MineCell[rows, columns];
                  totalMines 
      = mines;
                  makedMines 
      = 0;
                  status 
      = GameStatus.NotStarted;

                  PlaceRandomMines();
                  UpdateNearbyMinesCount();
              }


              
      public void Uncover(int row, int col)
              
      {
                  
      if (!IsValidCell(row, col))
                      
      return;

                  
      if (status == GameStatus.NotStarted)
                  
      {
                      status 
      = GameStatus.Playing;
                  }


                  MineCell cell 
      = cells[row, col];

                  
      if (cell.Status != MineCellStatus.Covered)
                      
      return;
                  
                  
      if (cell.IsMine)
                  
      {
                      cells[row, col].Status 
      = MineCellStatus.Exploded;
                      
      this.status = GameStatus.Lose;
                      
      return;
                  }

                  
      else
                  
      {
                      cells[row, col].Status 
      = MineCellStatus.Uncovered;

                  }


                  
      // 如果周圍雷數是 0, 那么順便把周圍的 8 個位置都翻開
                  if (!cell.IsMine && cell.NearbyMines == 0)
                  
      {
                      
      for (int i = 0; i < moves.GetLength(0); i++)
                          Uncover(row 
      + moves[i, 0], col + moves[i, 1]);
                  }

              }


              
      /**/
              
      /// <summary>
              
      /// 設定或取消標志, 相當于鼠標右鍵單擊的行為
              
      /// </summary>
              
      /// <param name="row"></param>
              
      /// <param name="col"></param>

              public void ChangeMark(int row, int col)
              
      {
                  
      if (!IsValidCell(row, col))
                      
      return;
                  
                  
      if (status == GameStatus.NotStarted)
                  
      {
                      status 
      = GameStatus.Playing;
                  }

                  
                  MineCell cell 
      = cells[row, col];

                  
      // 輪換幾種標志
                  switch (cell.Status)
                  
      {
                      
      case MineCellStatus.Covered:
                          cell.Status 
      = MineCellStatus.MarkMine;
                          makedMines
      ++;
                          
      break;
                      
      case MineCellStatus.MarkMine:
                          cell.Status 
      = MineCellStatus.MarkDoubt;
                          
      break;
                      
      case MineCellStatus.MarkDoubt:
                          makedMines
      --;
                          cell.Status 
      = MineCellStatus.Covered;
                          
      break;
                      
      default:
                          
      break;
                  }


                  cells[row, col] 
      = cell;
              }


              
      /// <summary>
              
      /// 鼠標左右鍵同時按下行為
              
      /// </summary>
              
      /// <param name="row"></param>
              
      /// <param name="col"></param>

              public void UncoverNearBy(int row, int col)
              
      {
                  MineCell cell 
      = cells[row, col];

                  
      if (cell.Status == MineCellStatus.Uncovered && cell.NearbyMines > 0)
                  
      {
                      
      byte minesFound = 0;

                      
      for (int i = 0; i < moves.GetLength(0); i++)
                      
      {
                          
      int r = row + moves[i, 0];
                          
      int c = col + moves[i, 1];

                          
      if (IsValidCell(r, c) && cells[r, c].Status == MineCellStatus.MarkMine)
                              minesFound
      ++;
                      }


                      
      if (minesFound == cell.NearbyMines)
                      
      {
                          
      for (int i = 0; i < moves.GetLength(0); i++)
                          
      {
                              
      int r = row + moves[i, 0];
                              
      int c = col + moves[i, 1];

                              Uncover(r, c);
                          }

                      }

                  }

              }

              
              
      /// <summary>
              
      /// 檢驗游戲結果
              
      /// </summary>

              public void CheckGameResult()
              
      {
                  
      if (makedMines == totalMines)
                  
      {
                      
      for (int i = 0; i < Rows; i++)
                      
      {
                          
      for (int j = 0; j < Columns; j++)
                          
      {
                              
      if (cells[i, j].Status == MineCellStatus.Covered)
                              
      {
                                  
      return;
                              }

                          }

                      }


                      status 
      = GameStatus.Win;
                  }

              }


              
      private void PlaceRandomMines()
              
      {
                  
      int count = 0;
                  Random r 
      = new Random((int)DateTime.Now.Ticks);

                  
      while (count < totalMines)
                  
      {
                      
      int row = r.Next(0, Rows);
                      
      int col = r.Next(0, Columns);

                      
      if (!cells[row, col].IsMine)
                      
      {
                          cells[row, col].IsMine 
      = true;
                          count
      ++;
                      }

                  }

              }


              
      private bool IsValidCell(int row, int col)
              
      {
                  
      return (row >= 0 && col >= 0 && row < Rows && col < Columns);
              }


              
      /**/
              
      /// <summary>
              
      /// 從一個格子出發向四周的可能的位移
              
      /// </summary>

              private int[,] moves = new int[82-1-1 }-10 }-11 }0-1 }01 }1-1 }10 }11 } };

              
      private byte GetNearbyMines(int row, int col)
              
      {
                  
      byte minesFound = 0;

                  
      for (int i = 0; i < moves.GetLength(0); i++)
                  
      {
                      
      int r = row + moves[i, 0];
                      
      int c = col + moves[i, 1];

                      
      if (IsValidCell(r, c) && cells[r, c].IsMine)
                          minesFound
      ++;
                  }

                  
      return minesFound;
              }


              
      private void UpdateNearbyMinesCount()
              
      {
                  
      for (int i = 0; i < Rows; i++)
                  
      {
                      
      for (int j = 0; j < Columns; j++)
                      
      {
                          cells[i, j].NearbyMines 
      = GetNearbyMines(i, j);
                      }

                  }

              }

          }

      }

      窗口代碼如下:

      namespace xingd.Minesweeper
      {
          
      public partial class MineForm : Form
          
      {
              
      private MineBoard board = new MineBoard();

              
      private MouseButtons lastClickButton = MouseButtons.None;
              
      private long lastClickTicks = 0;
              
              
      private const int CellSize = 16;
              
      private const long ShortPeriod = 2000000L;
              
      private static readonly Rectangle CellRectangle = new Rectangle(00, CellSize, CellSize);

              
      public MineForm()
              
      {
                  InitializeComponent();

                  SetStyle(ControlStyles.ResizeRedraw 
      | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
              }


              
      protected override void OnLoad(EventArgs e)
              
      {
                  
      base.OnLoad(e);

                  Init(
      9910);
              }


              
      public void Init(int rows, int columns, int mines)
              
      {
                  board.Init(rows, columns, mines);
                  ClientSize 
      = new Size(columns * CellSize + 1, rows * CellSize + mainMenu.Height + 1);
                  Invalidate();
              }


              
      protected override void OnPaint(PaintEventArgs e)
              
      {
                  
      base.OnPaint(e);

                  Graphics g 
      = e.Graphics;
                  
                  
      for (int i = 0; i < board.Rows; i++)
                  
      {
                      
      for (int j = 0; j < board.Columns; j++)
                      
      {
                          g.ResetTransform();
                          g.TranslateTransform(j 
      * 16, i * 16 + mainMenu.Height);
                          
                          DrawCell(g, board[i, j]);
                      }

                  }

              }


              
      private void DrawCell(Graphics g, MineCell cell)
              
      {
                  Rectangle rt 
      = CellRectangle;
                  
                  StringFormat sf 
      = new StringFormat();
                  sf.Alignment 
      = StringAlignment.Center;
                  sf.LineAlignment 
      = StringAlignment.Center;

                  
      if (cell.IsMine && board.Status == GameStatus.Lose)
                  
      {
                      g.FillRectangle(Brushes.DarkGray, rt);
                      g.DrawString(
      "@", Font, cell.Status == MineCellStatus.Exploded ? Brushes.Red : Brushes.DarkBlue, rt, sf);
                  }

                  
      else
                  
      {
                      
      if (cell.Status == MineCellStatus.Covered)
                      
      {
                          g.FillRectangle(Brushes.DarkGray, rt);
                      }

                      
      else if (cell.Status == MineCellStatus.MarkMine)
                      
      {
                          g.FillRectangle(Brushes.DarkGray, rt);
                          g.DrawString(
      "#", Font, Brushes.DarkBlue, rt, sf);
                      }

                      
      else if (cell.Status == MineCellStatus.MarkDoubt)
                      
      {
                          g.FillRectangle(Brushes.DarkGray, rt);
                          g.DrawString(
      "?", Font, Brushes.DarkBlue, rt, sf);
                      }

                      
      else
                      
      {
                          
      if (cell.NearbyMines > 0)
                          
      {
                              g.DrawString(cell.NearbyMines.ToString(), Font, Brushes.DarkBlue, rt, sf);
                          }

                      }

                  }


                  g.DrawRectangle(Pens.Black, rt);

                  sf.Dispose();
              }


              
      protected override void OnMouseClick(MouseEventArgs e)
              
      {
                  
      base.OnMouseClick(e);

                  
      if (board.Status != GameStatus.Playing && board.Status != GameStatus.NotStarted)
                      
      return;
                  
                  
      int row, col;
                  HitTest(e.Location, 
      out row, out col);

                  
      if (DateTime.Now.Ticks - lastClickTicks < ShortPeriod && ((lastClickButton | e.Button) == (MouseButtons.Left | MouseButtons.Right)))
                  
      {
                      board.UncoverNearBy(row, col);
                  }

                  
                  
      if (e.Button == MouseButtons.Left)
                  
      {
                      board.Uncover(row, col);
                  }

                  
      else if (e.Button == MouseButtons.Right)
                  
      {
                      board.ChangeMark(row, col);
                  }


                  board.CheckGameResult();

                  
      if (board.Status == GameStatus.Win)
                  
      {
                      MessageBox.Show(
      "You Win!");
                  }


                  Invalidate();
              }


              
      protected override void OnMouseDown(MouseEventArgs e)
              
      {
                  
      base.OnMouseDown(e);

                  
      if (DateTime.Now.Ticks - lastClickTicks < ShortPeriod)
                  
      {
                      lastClickButton 
      |= e.Button;
                  }

                  
      else
                  
      {
                      lastClickButton 
      = e.Button;
                      lastClickTicks 
      = DateTime.Now.Ticks;
                  }

              }


              
      private void HitTest(Point pt, out int row, out int col)
              
      {
                  col 
      = pt.X / CellSize;
                  row 
      = (pt.Y - mainMenu.Height) / CellSize;
              }


              
      private void menuItemExit_Click(object sender, EventArgs e)
              
      {
                  
      this.Close();
              }


              
      private void menuItemNew_Click(object sender, EventArgs e)
              
      {
                  
      this.Init(9910);
              }

          }

      }

      非常簡單,不過已經可以玩了,系列稍后的文章會對功能進行改進。

      項目文件下載

      更正一:在MouseClick中,先Invalidate,再處理取勝判斷,用戶體驗要好一些。
      主站蜘蛛池模板: 精品国产av无码一区二区三区| 国产欧美一区二区日本加勒比| 亚洲狠狠婷婷综合久久久久图片| 综合成人亚洲网友偷自拍| 亚洲精品动漫一区二区三| 人妻系列无码专区无码中出| 99热精品毛片全部国产无缓冲 | 国产成人a在线观看视频免费| 国产乱码精品一品二品 | 亚洲区综合中文字幕日日| 国产精品一区二区中文| 成人福利国产午夜AV免费不卡在线 | 少妇愉情理伦片丰满丰满午夜| 国产学生裸体无遮挡免费| 亚洲国产超清无码专区| 国产色视频网站免费| 亚洲乱妇老熟女爽到高潮的片| 亚洲中文字幕精品无人区| 国产360激情盗摄全集| 国产色无码专区在线观看| 国产肥臀视频一区二区三区 | 亚洲精品日韩在线观看| 亚洲乱人伦中文字幕无码| 亚洲一区二区无码影院| 日本亲近相奷中文字幕| 国产成人精品一区二区三区| 狼人大伊人久久一区二区| 91福利视频一区二区| 中文字幕日韩精品无码内射 | 日韩欧国产美一区二区在线| 亚洲天堂伊人久久a成人| 日韩欧美aⅴ综合网站发布| 色综合视频一区二区三区| 日韩在线视频线观看一区| 欧美精品一区二区三区中文字幕| 欧美人与动zozo在线播放| 国产精品国产三级国快看| 无码精品人妻一区二区三区中| 成人亚洲狠狠一二三四区| 在线观看成人永久免费网站| 怀远县|