用c#窗體做五子棋小游戲 :
首先是界面設(shè)計(jì),控件一共有4個(gè),1個(gè)PictureBox ;1個(gè)開始按鈕,命名為btnStart;1個(gè)重置按鈕,命名為btnReset;1個(gè)文本框Label,用于顯示游戲狀態(tài);
2. 新建一個(gè)MainSize類用于存放界面上的可能用到的參數(shù),主框體大小520*460,棋盤是一個(gè)PictureBox控件,大小401*401,棋盤20行20列,每個(gè)格子邊長20,棋子直徑16。
3. 新建一個(gè)ChessBoard類表示棋盤,有一個(gè)靜態(tài)函數(shù)DrawBoard,函數(shù)代碼如下:
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){//每排數(shù)量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;}}
4. 新建一個(gè)基本類Chess,用來表示棋子,有一個(gè)靜態(tài)函數(shù)DrawChess,代碼如下:
class Chess{ public static void DrawChess(bool type,PictureBox pic,Graphics graphic,MouseEventArgs e)
//bool型變量用于表示下棋的雙方
{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;
//pen1和pen2用于繪制雙方的棋子,顏色設(shè)置為紅藍(lán)
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); }
//整型變量nexX和newY用于表示棋子在棋盤上的坐標(biāo),根據(jù)四舍五入就近原則落點(diǎn) graphic.Dispose();
}
}
5. 主程序,一共設(shè)置了4個(gè)全局變量,Graphics graphic用于畫圖,bool type用于表示下棋雙方,bool start表示游戲是否開始,二維數(shù)組ChessBack用于模擬下棋場景并進(jìn)行計(jì)算。 主程序的構(gòu)造函數(shù)對主框體和PictureBox的大小進(jìn)行初始化,在Form1_Load函數(shù)中添加函數(shù)InitializeThis()對游戲進(jìn)行初始化,包括將ChessBack數(shù)組全部置0,type設(shè)為true,start設(shè)為false,繪制棋盤,按鍵開始的Enabled屬性設(shè)為true,按鍵重置設(shè)為false。 按鍵開始和重置的功能較為簡單,代碼如下:
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();}}
6. picturebox的函數(shù),先判斷游戲是否開始,否則不會(huì)有反應(yīng)。游戲開始后點(diǎn)擊即可落子,并修改ChessBack矩陣,紅色為1,藍(lán)色為2,如果已經(jīng)有棋子則返回,即落子失敗。如果棋盤已滿但沒有分出勝負(fù)則彈出平局的提示框并給出提示。之后判斷是否分出勝負(fù),添加函數(shù)bool Victory(int bx,int by),分出勝負(fù)后提示勝利,如果沒有則返回。最后換人,type=!type即可,然后修改label的文字表面到哪一方落子了。代碼如下。
private void pictureBox1_MouseClick(object sender, MouseEventArgs e){if (start){//在計(jì)算矩陣中的位置int bX = (int)((e.X + MainSize.CBGap / 2) / MainSize.CBGap);int bY = (int)((e.Y + MainSize.CBGap / 2) / MainSize.CBGap);//防止在同一個(gè)位置落子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("游戲結(jié)束,平局") == DialogResult.OK)InitializeThis();return;}//判斷勝利if (Victory(bX,bY)){string Vic = type ? "紅" : "藍(lán)";if (MessageBox.Show(Vic + "方勝利!") == DialogResult.OK)InitializeThis();return;}//換人type = !type;label1.Text = type ? "紅方's trun!" : "藍(lán)方's turn!";}elsereturn;}
7. 判斷勝負(fù)的函數(shù),先寫了一個(gè)橫向的進(jìn)行測試,如果橫向兩端的值與當(dāng)前值相同則變量count++,最后返回count的值,如果>4則表示勝利。但是這個(gè)函數(shù)運(yùn)行出錯(cuò),顯示為stackoverflow,但我不知道錯(cuò)誤在哪,只好換一種判斷方法。后來才想明白兩端的值都是0則會(huì)溢出,應(yīng)該判斷兩端的值是否為1或2而不是當(dāng)前值。此處借鑒了實(shí)驗(yàn)樓網(wǎng)站上的C語言版五子棋的判斷勝負(fù)方式,從當(dāng)前落子的矩陣中,橫豎斜4個(gè)方向任意一個(gè)方向有連續(xù)5個(gè)數(shù)的值與當(dāng)前的值相同則勝利,實(shí)現(xiàn)也不復(fù)雜,細(xì)分為三個(gè)函數(shù)實(shí)現(xiàn)。代碼如下:
#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;elsereturn 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
8 .經(jīng)過測試,沒有問題大功告成
樓主要及時(shí)采納加分哦