C#實(shí)現(xiàn)簡(jiǎn)單的五子棋游戲
最近利用業(yè)余時(shí)間寫(xiě)了一個(gè)簡(jiǎn)單的五子棋游戲,沒(méi)有利用深層次的面向?qū)ο蠹夹g(shù),自學(xué)一年,代碼和程序設(shè)計(jì)有不妥之處,還望大神指出,先看下實(shí)現(xiàn)的功能,三個(gè)button按鈕,黑棋和白棋選擇先出,和重置。

其他的不多說(shuō)了,直接上全部代碼(通過(guò)測(cè)試)。計(jì)算輸贏的時(shí)候,左斜和右斜用了數(shù)學(xué)y=kx+b的線(xiàn)性函數(shù)計(jì)算。
private Image myImage;
/// <summary>
/// 初始化背景數(shù)組
/// int[x,y] x為行 y為列
/// </summary>
private int[,] bgGround = new int[11, 11]; /*{
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0}
};*/
private int CurrentX;//當(dāng)前bgGround的x行
private int CurrentY;//當(dāng)前bgGround的y列
private bool IsWhite = false;//判斷白棋還是黑棋先
private bool IsOver = false;//記錄游戲是否結(jié)束
private void Form1_Load(object sender, EventArgs e)
{
myImage = new Bitmap(panel1.Width, panel1.Height);
}
protected override void OnPaint(PaintEventArgs e)
{
Draw();
base.OnPaint(e);
}
/// <summary>
/// 畫(huà)棋盤(pán)
/// </summary>
private void Draw()
{
Graphics g = Graphics.FromImage(myImage);
g.Clear(this.BackColor);
g.FillRectangle(Brushes.White,new Rectangle(new Point(10,10),new Size(400,400)));
//循環(huán)次數(shù)應(yīng)比背景bgGround行、列少1
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
g.DrawRectangle(new Pen(Brushes.Black), i * 40 + 10, j * 40 + 10, 40, 40);
}
}
Graphics gg = panel1.CreateGraphics();
gg.DrawImage(myImage, 0, 0);
}
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
if (IsOver)
{
return;
}
Graphics g = panel1.CreateGraphics();
//設(shè)置當(dāng)鼠標(biāo)點(diǎn)擊坐標(biāo)在某一落棋點(diǎn)坐標(biāo)想x,y的+-10的范圍內(nèi)即可落子
int x = (e.X - 10) % 40;
int y = (e.Y - 10) % 40;
if (x > 30)
{
x = (e.X - 10) / 40 + 1;
}
else
{
x = (e.X - 10) / 40;
}
if (y > 30)
{
y = (e.Y - 10) / 40 + 1;
}
else
{
y = (e.Y - 10) / 40;
}
if (bgGround[x, y] == 0)
{
if (IsWhite)
{
DrawChess(g, x, y, new Pen(Brushes.White), Brushes.White, 1);
IsWhite = false;
JudgeResult(1);
}
else
{
DrawChess(g, x, y, new Pen(Brushes.Black), Brushes.Black, 2);
IsWhite = true;
JudgeResult(2);
}
}
}
/// <summary>
/// 判斷輸贏
/// </summary>
/// <param name="flag">1為白棋 2為黑棋</param>
private void JudgeResult(int flag)
{
int x = CurrentX;
int y = CurrentY;
int MinXNum = 0;
int MaxXNum = 0;
int count = 0;
if (x > 4)
{
MinXNum = x - 4;
if (x + 4 > 10)
{
MaxXNum = 10;
}
else
{
MaxXNum = x + 4;
}
}
else
{
MaxXNum = x + 4;
}
int MinYNum = 0;
int MaxYNum = 0;
if (y > 4)
{
MinYNum = y - 4;
if (y + 4 > 10)
{
MaxYNum = 10;
}
else
{
MaxYNum = y + 4;
}
}
else
{
MaxYNum = y + 4;
}
#region //橫向
for (int i = MinXNum; i < MaxXNum+1; i++)
{
if (bgGround[i, y] == flag)
{
count++;
if (count > 4)
goto Label;
}
else
{
count = 0;
if (i > MaxXNum - 4)
break;
}
}
#endregion
#region //豎向
for (int i = MinYNum; i < MaxYNum+1; i++)
{
if (bgGround[x, i] == flag)
count++;
else
{
count = 0;
if (i > MaxYNum - 4)
break;
}
if (count > 4)
goto Label;
}
#endregion
//左斜
for (int i = MinXNum; i < MaxXNum+1; i++)
{
if (CurrentX + CurrentY - i < 0)
break;
if (CurrentX + CurrentY - i <= 10)
{
if (bgGround[i, CurrentX + CurrentY - i] == flag)
{
count++;
}
else
{
count = 0;
if (i > MaxYNum - 4)
break;
}
}
if (count > 4)
goto Label;
}
//右斜
for (int i = MinXNum; i < MaxXNum+1; i++)
{
if (i < CurrentX - CurrentY)
break;
if (i + CurrentY - CurrentX > 10)
break;
if (bgGround[i, i + CurrentY - CurrentX] == flag)
{
count++;
}
else
{
count = 0;
if (i > MaxYNum - 4)
break;
}
if (count > 4)
goto Label;
}
Label:
if (flag == 1 && count > 4)
{
IsOver = true;
MessageBox.Show("白棋贏,游戲結(jié)束");
return;
}
else if (flag == 2 && count > 4)
{
IsOver = true;
MessageBox.Show("黑棋贏,游戲結(jié)束");
return;
}
else
{
IsOver = false;
}
}
/// <summary>
/// 畫(huà)棋子
/// </summary>
/// <param name="g"></param>
/// <param name="x">bgGround中x位置</param>
/// <param name="y">bgGround中y位置</param>
/// <param name="p">畫(huà)筆</param>
/// <param name="brush">棋子顏色</param>
/// <param name="flag">1為白棋 2為黑棋</param>
private void DrawChess(Graphics g, int x, int y, Pen p, Brush brush, int flag)
{
CurrentX = x; CurrentY = y;
bgGround[x, y] = flag;
g.DrawEllipse(p, x * 40, y * 40, 20, 20);
g.FillEllipse(brush, x * 40, y * 40, 20, 20);
}
///btn_Chess_Click是黑棋先和白棋先按鈕的共同事件,設(shè)置白棋先button的tag值為1,黑棋先button的tag值為2
/// <summary>
/// 判斷哪個(gè)先下 設(shè)置button控件的tag值
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Chess_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
string tag = btn.Tag.ToString();
if (tag.Equals("1"))//白棋先
{
IsWhite = true;
}
else//黑棋先 tag=2
{
IsWhite = false;
}
}
/// <summary>
/// 重置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_reset_Click(object sender, EventArgs e)
{
IsOver = false;
Draw();
bgGround = new int[11, 11];
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#函數(shù)式程序設(shè)計(jì)之用閉包封裝數(shù)據(jù)的實(shí)現(xiàn)代碼
如果一個(gè)程序設(shè)計(jì)語(yǔ)言能夠用高階函數(shù)解決問(wèn)題,則意味著數(shù)據(jù)作用域問(wèn)題已十分突出。當(dāng)函數(shù)可以當(dāng)成參數(shù)和返回值在函數(shù)之間進(jìn)行傳遞時(shí),編譯器利用閉包擴(kuò)展變量的作用域,以保證隨時(shí)能得到所需要的數(shù)據(jù)2014-03-03
C#實(shí)現(xiàn)客戶(hù)端彈出消息框封裝類(lèi)實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)客戶(hù)端彈出消息框封裝類(lèi),實(shí)例分析了C#彈出窗口的實(shí)現(xiàn)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03
C#基于Socket實(shí)現(xiàn)簡(jiǎn)單聊天室功能
這篇文章主要為大家詳細(xì)介紹了C#基于Socket實(shí)現(xiàn)簡(jiǎn)單聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
C#傳值方式實(shí)現(xiàn)不同程序窗體間通信實(shí)例
Form2構(gòu)造函數(shù)中接收一個(gè)string類(lèi)型參數(shù),即Form1中選中行的文本,將Form2的TextBox控件的Text設(shè)置為該string,即完成了Form1向Form2的傳值2013-12-12
基于C#編寫(xiě)一個(gè)接受圖片流的OCR識(shí)別接口
這篇文章主要為大家詳細(xì)介紹了如何使用C#寫(xiě)一個(gè)接受圖片流的OCR識(shí)別接口,以及測(cè)試用例調(diào)用接口,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
C#利用OLEDB實(shí)現(xiàn)將DataTable寫(xiě)入Excel文件中
這篇文章主要為大家詳細(xì)介紹了C#如何利用OLEDB實(shí)現(xiàn)將DataTable寫(xiě)入Excel文件中,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,需要的可以參考一下2023-02-02

