国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C#實現五子棋游戲

C#實現五子棋游戲

2022-02-19 15:39steveliu13 C#

這篇文章主要為大家詳細介紹了C#實現五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

曾經自學C#做計算機圖形學的作業,GDI+畫圖確實好用,目前在找.NET的實習,嘗試做了一個最基本的五子棋,復習一下C#的基本語法,目前只能當跟基友一起玩的單機小游戲,之后再加入AI和聯網對戰功能。目前我還是小菜鳥,過程設計和代碼有不合理或者能優化的地方歡迎各位大神指正。

首先是界面設計,最后就是這樣,控件一共有一個PictureBox;一個開始Button,命名為btnStart;一個重置Button,命名為btnReset;一個Label,用于顯示游戲狀態。

五子棋界面

C#實現五子棋游戲

然后是各基本類。新建一個MainSize類用于存放界面上的可能用到的參數,主框體大小520*460,棋盤是一個PictureBox控件,大小401*401,棋盤20行20列,每個格子邊長20,棋子直徑16。新建一個ChessBoard類表示棋盤,有一個靜態函數DrawBoard。之前做計算機圖形學作業畫函數時用到的畫坐標系方法在這里同樣適用,函數代碼如下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class ChessBoard
 {
 
 static readonly Color color = Color.Black;
 static readonly float penWid = 1.0f;
 static readonly Pen pen = new Pen(color, penWid);
 
 public static void DrawCB(Graphics gra,PictureBox pic)
 {
  //每排數量
  int horC = MainSize.CBWid / MainSize.CBGap;
  //間隔
  int gap = MainSize.CBGap;
  Image img = new Bitmap(MainSize.CBWid, MainSize.CBHei);
  gra = Graphics.FromImage(img);
  gra.Clear(Color.White);
  gra.DrawRectangle(pen, 0, 0, MainSize.CBWid, MainSize.CBHei);
  //畫棋盤
  for (int i = 0; i < horC; i++)
  {
  gra.DrawLine(pen, 0, i * gap, MainSize.CBWid, i * gap);
  gra.DrawLine(pen, i * gap, 0, i * gap, MainSize.CBHei);
  }
  gra.DrawLine(pen, 0, horC * gap, MainSize.CBWid, horC * gap - 1);
  gra.DrawLine(pen, horC * gap - 1, 0, horC * gap, MainSize.CBHei);
  pic.Image = img;
 }
 
 }

還有一個基本類Chess,用來表示棋子,有一個靜態函數DrawChess,代碼如下。這里代碼有點亂,寫的時候沒加注釋。bool型變量用于表示下棋的雙方,pen1和pen2用于繪制雙方的棋子,顏色設置為紅藍,因為自古紅藍出CP【其實是本來想用黑白的但picturebox背景白色再畫白色棋子就看不出來】。整型變量nexX和newY用于表示棋子在棋盤上的坐標,根據四舍五入就近原則落點。這里的四舍五入我花了很長時間,寫了很長的一段判斷代碼但都會出錯,最后借鑒了github上Xu Pu同學的數據結構假期作業中的方法才完成了這個函數,在此感謝這位同學~

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Chess
 {
 public static void DrawChess(bool type,PictureBox pic,Graphics graphic,MouseEventArgs e)
 {
  graphic = pic.CreateGraphics();
  Pen pen1 = new Pen(Color.Red, 1);
  Brush bru1 = new SolidBrush(Color.Red);
  Pen pen2 = new Pen(Color.Blue, 1);
  Brush bru2 = new SolidBrush(Color.Blue);
  int newX = (int)((e.X + MainSize.CBGap / 2) / MainSize.CBGap) * MainSize.CBGap - MainSize.ChessRadious / 2;
  int newY = (int)((e.Y + MainSize.CBGap / 2) / MainSize.CBGap) * MainSize.CBGap - MainSize.ChessRadious / 2;
  if (type)
  {
  graphic.DrawEllipse(pen1, newX, newY, MainSize.ChessRadious, MainSize.ChessRadious);
  graphic.FillEllipse(bru1, newX, newY, MainSize.ChessRadious, MainSize.ChessRadious);
  }
  if (!type)
  {
  graphic.DrawEllipse(pen2, newX, newY, MainSize.ChessRadious, MainSize.ChessRadious);
  graphic.FillEllipse(bru2, newX, newY, MainSize.ChessRadious, MainSize.ChessRadious);
  }
  graphic.Dispose();
 }
 
 }

最后是主程序,一共設置了四個全局變量,Graphics graphic用于畫圖,bool type用于表示下棋雙方,bool start表示游戲是否開始,二維數組ChessBack用于模擬下棋場景并進行計算。

主程序的構造函數對主框體和PictureBox的大小進行初始化,在Form1_Load函數中添加函數InitializeThis()對游戲進行初始化,包括將ChessBack數組全部置0,type設為true,start設為false,繪制棋盤,按鍵開始的enabled屬性設為true,按鍵重置設為false。

按鍵開始和重置的功能較為簡單,代碼如下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void btnStart_Click(object sender, EventArgs e)
 {
  start = true;
  label1.Text = "游戲開始!";
  btnStart.Enabled = false;
  btnReset.Enabled = true;
 }
 
 private void btnReset_Click(object sender, EventArgs e)
 {
 
  if (MessageBox.Show("確定要重新開始?", "提示", MessageBoxButtons.YesNo) == DialogResult.Yes)
  {   
  InitializeThis();
  }
 }

最重要的部分是點擊picturebox的函數,先判斷游戲是否開始,否則不會有反應。游戲開始后點擊即可落子,并修改ChessBack矩陣,紅色為1,藍色為2,如果已經有棋子則返回,即落子失敗。如果棋盤已滿但沒有分出勝負則彈出平局的提示框并給出提示。之后判斷是否分出勝負,添加函數bool Victory(int bx,int by),分出勝負后提示勝利,如果沒有則返回。最后換人,type=!type即可,然后修改label的文字表面到哪一方落子了。代碼如下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
 {
  if (start)
  {
  //在計算矩陣中的位置
  int bX = (int)((e.X + MainSize.CBGap / 2) / MainSize.CBGap);
  int bY = (int)((e.Y + MainSize.CBGap / 2) / MainSize.CBGap);
  //防止在同一個位置落子
  if (ChessBack[bX, bY] != 0)
   return;
  Chess.DrawChess(type, pictureBox1, graphic, e);
  ChessBack[bX,bY] = type?1:2;
  //判斷棋盤是否滿了
 
  if (IsFull() && !Victory(bX,bY))
  {
   if (MessageBox.Show("游戲結束,平局") == DialogResult.OK)
   InitializeThis();
   return;
  }
  //判斷勝利
  if (Victory(bX,bY))
  {
   string Vic = type ? "紅" : "藍";
   if (MessageBox.Show(Vic + "方勝利!") == DialogResult.OK)
   InitializeThis();
   return;
  }
 
  //換人
  type = !type;
  label1.Text = type ? "紅方's trun!" : "藍方's turn!";
  }
  else
  return;
 }

判斷勝負的函數有點復雜,我自己是用遞歸的方式判斷,先寫了一個橫向的進行測試,如果橫向兩端的值與當前值相同則變量count++,最后返回count的值,如果>4則表示勝利。但是這個函數運行出錯,顯示為stackoverflow,但我不知道錯誤在哪,只好換一種判斷方法。后來才想明白兩端的值都是0則會溢出,應該判斷兩端的值是否為1或2而不是當前值。此處借鑒了實驗樓網站上的C語言版五子棋的判斷勝負方式,從當前落子的矩陣中,橫豎斜4個方向任意一個方向有連續5個數的值與當前的值相同則勝利,實現也不復雜,細分為三個函數實現。代碼如下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#region 判斷勝利
 private bool Victory(int bx,int by)
 {
  if (HorVic(bx, by))
  return true;
  if (VerVic(bx, by))
  return true;
  if (Vic45(bx, by))
  return true;
  else
  return false;
 }
 
 private bool Vic45(int bx, int by)
 {
 
  int b1 = (bx - 4) > 0 ? bx - 4 : 0;
  int b2 = (by - 4) > 0 ? by - 4 : 0;
  //int buttom = b1 > b2 ? b2 : b1;
  int val = ChessBack[bx, by];
  for (int i = b1,j=b2; i < 16&&j<16; i++,j++)
  {
  if (ChessBack[i, j] == val && ChessBack[i + 1, j + 1] == val &&
   ChessBack[i + 2, j + 2] == val && ChessBack[i + 3, j + 3] == val
   && ChessBack[i + 4, j + 4] == val)
   return true;
  }
  for (int i = b1, j = b2; i < 16 && j < 16; i++, j++)
  {
  if (ChessBack[i, j] == val && ChessBack[i + 1, j - 1] == val &&
   ChessBack[i + 2, j - 2] == val && ChessBack[i + 3, j - 3] == val
   && ChessBack[i - 4, j - 4] == val)
   return true;
  }
  return false;
 }
 
 private bool VerVic(int bx, int by)
 {
  int buttom = (by - 4) > 0 ? by - 4 : 0;
  int val = ChessBack[bx, by];
  for (int i = buttom; i < 16; i++)
  {
  if (ChessBack[bx, i] == val && ChessBack[bx, i+1] == val &&
   ChessBack[bx, i+2] == val && ChessBack[bx ,i+3] == val
   && ChessBack[bx, i+4] == val)
   return true;
  }
  return false;
 }
 
 private bool HorVic(int bx, int by)
 {
  int left = (bx-4)>0?bx-4:0;
  int val = ChessBack[bx,by];
  for (int i = left; i < 16; i++)
  {
  if (ChessBack[i, by] == val && ChessBack[i + 1, by] == val &&
   ChessBack[i + 2, by] == val && ChessBack[i + 3, by] == val
   && ChessBack[i + 4, by] == val)
   return true;
  }
  return false;
 }
 #endregion

完成后進行測試,都沒有問題,即認為大功告成了。總結了一下編寫過程中問題,變量命名不太好,type,start等變量容易與關鍵詞混淆;主函數代碼行數還是太多,不方便閱讀,或許應該把判定勝負和判定棋盤是否已滿也移到棋盤類中;之后添加新游戲模式不方便,比如添加AI和聯機對戰,需要修改的代碼有點多,個人想法是分別新建一個帶AI的框體和聯機的框體,然后修改基本類,在這種情況下最大化的代碼復用。

回想一個這個小程序編寫并不復雜,但我花了很多時間在改錯上,落子的函數和判斷勝利的函數花的時間最多,事前用筆進行一下簡單的演算再寫或許能省一點時間。這是我的第一篇博客,暫時當實驗報告來寫吧,雖然是出于興趣做的,但還是希望各位大神能指出不足,給出建議,我會虛心學習的。最后再次感謝實驗樓網站【不是軟廣】和github上的Xu Pu同學,還有各位看到最后的朋友們~

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/steveliu13/article/details/50573831

延伸 · 閱讀

精彩推薦
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
主站蜘蛛池模板: 欧美一区二区三区久久精品 | www.久久99| www.成人| 97热在线观看 | 91视频网页 | 亚洲欧美激情精品一区二区 | 久久国产精品一区二区 | 久久久久亚洲美女啪啪 | 欧美在线不卡视频 | 成人综合区一区 | 中文字幕一区在线 | 欧美一区二区在线视频 | 国产精品一区二区视频 | 91视频网 | 国产精品精品久久久 | 国产精品二区一区二区aⅴ污介绍 | 国产在线精品一区 | 免费视频爱爱太爽了 | 国产免费av网站 | 国产精品久久久久久久久久 | 91亚洲精品在线观看 | 久久99深爱久久99精品 | 国产精品大片 | 高清一区二区三区 | 亚洲中午字幕 | 国产激情一区二区三区成人免费 | 欧美久久免费 | 欧美午夜影院 | 亚洲综合大片69999 | 日干夜操| 一级毛片在线播放 | 国产精品成人一区二区三区夜夜夜 | 亚洲一区中文字幕 | 色接久久 | 亚洲人视频 | 亚洲精品久久久一区二区三区 | 精品国产三级 | 2023国产精品久久久精品双 | 在线观看亚洲免费视频 | 成人黄色片网站 | 国产片在线 |