admin管理员组

文章数量:1794759

C#窗体程序编写 • 【五子棋】

C#窗体程序编写 • 【五子棋】

2022.4.16 更新:Chess类 添加代码,消除棋子边缘的锯齿

C#窗体编写的五子棋、每一步都有注释

末尾提供全部代码(去掉注释,代码其实很少,C#窗体真方便!)

第一步.窗体界面

拖控件:拖两个 panel(面板)控件,三个 button(按钮)控件,一个 label(标签)控件

设属性:为一个 panel 控件的 Dock属性选择 Fill(填满),另一个选择 right(右侧)。其他属性 如背景颜色根据喜好设置

三个按钮的Text,分别设置为 开始游戏、重新开始、退出

label用来提示游戏状态,如白子回合还是黑子回合

第二步.私有成员,窗体 Load(加载)事件,和 初始化游戏 方法

// 窗体程序 public partial class Form1 : Form { private bool start; // 游戏是否开始 private bool ChessCheck = true; // 白子黑子回合 private const int size = 15; // 棋盘大小 private int[,] CheckBoard = new int[size, size]; // 棋盘点位数组 public Form1() { InitializeComponent(); } // "窗口"Load事件 private void Form1_Load(object sender, EventArgs e) { initializeGame(); // 调用初始化游戏 this.Width = MainSize.FormWidth; // 设置窗口宽度 this.Height = MainSize.FormHeight; // 设置窗口高度 this.Location = new Point(400,75); // 设置窗口位置 } // 初始化游戏 private void initializeGame() { // 棋盘点位数组 重置为0 for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { CheckBoard[i, j] = 0; } } start = false; // 未开始 label1.Text = "游戏未开始"; // 提示文本改为"游戏未开始" button1.Visible = true; // 显示'开始游戏'按钮 button4.Visible = false; // 隐藏'重新开始'按钮 }

第三步.MainSize类(用来说明 窗口大小、棋盘大小等)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace day11_01 { // 成员大小类 class MainSize { // 窗口大小 public static int FormWidth { get { return 710; } } public static int FormHeight { get { return 640; } } // 棋盘大小 public static int CBoardWidth { get { return 600; } } public static int CBoardHeight { get { return 600; } } // 棋格宽度 public static int CBoardGap { get { return 40; } } // 棋子直径 public static int ChessDiameter { get { return 37; } } } }

第四步.ChessBoard棋盘类(用来 画棋盘)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; namespace day11_01 { // 棋盘类 class ChessBoard { // 画棋盘方法 public static void DrawCB(Graphics g) //这里的形参,是画布对象 { int GapWidth = MainSize.CBoardGap; // 棋格宽度 int GapNum = MainSize.CBoardWidth / GapWidth - 1; // 棋格数量 Bitmap image = new Bitmap("D:\\\\C语言\\\\代码\\\\day11\\\\day11_01_image\\\\CheckBoard1.png"); // 棋盘位图路径 g.DrawImage(image, new Point[] { new Point(0, 0), new Point(GapWidth * GapNum + 44, 0), new Point(0, GapWidth * GapNum + 44) }); // 画棋盘图片 /* 这个是 没有用棋盘图片时,用的“画笔”画棋盘方法 g.Clear(Color.Bisque); // 清除画布、并用Bisque颜色填满画布 Pen pen = new Pen(Color.FromArgb(192, 166, 107)); // 实例化画笔 // 画棋盘 for (int i = 0; i < GapNum + 1; i++) { g.DrawLine(pen, new Point(20, i * GapWidth + 20), new Point(GapWidth * GapNum + 20, i * GapWidth + 20)); g.DrawLine(pen, new Point(i * GapWidth + 20, 20), new Point(i * GapWidth + 20, GapWidth * GapNum + 20)); } */ } } }

第五步.Chess棋子类(用来画鼠标点击处的棋子、且页面重新聚集时,重新加载之前的棋子)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.Windows.Forms; using System.Drawing.Drawing2D; // 使支持渐变画刷 namespace day11_01 { // 棋子类 class Chess { // 画棋子 public static void DrawC(Panel p, bool ChessCheck, int PlacementX, int PlacementY) { Graphics g = p.CreateGraphics(); // 创建面板画布 // 消除棋子边缘的锯齿(后面加的,博客的图片没更新) g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; int AccurateX = PlacementX * MainSize.CBoardGap + 20 - 17; // 精确棋子的X中心位置 int AccurateY = PlacementY * MainSize.CBoardGap + 20 - 17; // 精确棋子的Y中心位置 // 判断谁的回合并画棋子 if (ChessCheck) { // 线性渐变会平铺整个面板,根据你的位置填颜色,从上至下渐变,使棋子具有真实感 g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(122, 122, 122), Color.FromArgb(0, 0, 0)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } else { g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(255, 255, 255), Color.FromArgb(204, 204, 204)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } } // 界面重新聚焦时,重新加载棋子 public static void ReDrawC(Panel p,int[,] CheckBoard) { Graphics g = p.CreateGraphics(); // 创建面板画布 // 消除棋子边缘的锯齿 g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; // 遍历 获取棋盘数组的每行 for (int i = 0; i < CheckBoard.GetLength(1); i++) { // 遍历 获取棋盘数组每行的每列 for (int j = 0; j < CheckBoard.GetLength(0); j++) { int Judgment = CheckBoard[j, i]; // 判断数组当前行列,白子还是黑子回合,0表示没有,1表示黑子,2表示白子 // 判断是否有棋子 if (Judgment != 0) { int AccurateX = j * MainSize.CBoardGap + 20 - 17; // 精确棋子的X中心位置 int AccurateY = i * MainSize.CBoardGap + 20 - 17; // 精确棋子的Y中心位置 // 判断谁的回合并画棋子 if (Judgment == 1) { // 线性渐变会平铺整个面板,根据你的位置填颜色,从上至下渐变,使棋子具有真实感 g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(122, 122, 122), Color.FromArgb(0, 0, 0)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } else { g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(255, 255, 255), Color.FromArgb(204, 204, 204)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } } } } } } }

第六步.两个 panel(面板)的Paint(重绘窗体时发生)事件(分别代表棋盘,和控制界面)

// 面板"棋盘"Paint事件 private void panel1_Paint(object sender, PaintEventArgs e) { Graphics g = panel1.CreateGraphics(); // 创建面板画布 ChessBoard.DrawCB(g); // 调用画棋盘方法 Chess.ReDrawC(panel1, CheckBoard); // 调用重新加载棋子方法 } // 面板"控制界面"Paint事件 private void panel2_Paint(object sender, PaintEventArgs e) { // 设置控制界面的大小 panel2.Size = new Size(MainSize.FormWidth - MainSize.CBoardWidth - 20, MainSize.FormHeight); }

第七步.三个按钮 Click(点击)事件(开始游戏、重新开始、退出)

// 按钮"开始游戏"CLick事件 private void button1_Click(object sender, EventArgs e) { start = true; // 开始 ChessCheck = true; // 黑子回合 label1.Text = "黑子回合"; // 提示文本改为"黑子回合" button1.Visible = false; // 隐藏'开始游戏'按钮 button4.Visible = true; // 显示'重新开始'按钮 panel1.Invalidate(); // 重绘面板"棋盘" } // 按钮"重新开始"CLick事件 private void button4_Click(object sender, EventArgs e) { // 确认是否重新开始 if (MessageBox.Show("确认要重新开始?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK) { initializeGame(); // 调用初始化游戏方法 button1_Click(sender, e); // 调用按钮"开始游戏"Click事件 } } // 按钮"退出"CLick事件 private void button5_Click(object sender, EventArgs e) { this.Dispose(); // 退出窗口 }

第八步.面板 “棋盘” 的 MouseDown(鼠标点击)事件(在点击位置画棋子)

// 面板"棋盘"MouseDown事件 private void panel1_MouseDown(object sender, MouseEventArgs e) { // 判断游戏是否开始 if (start) { int Judgment = 0; // 判断数组当前行列,白子还是黑子回合,0表示没有,1表示黑子,2表示白子、用来判断胜利 int PlacementX = e.X / MainSize.CBoardGap; // 求鼠标点击的X方向的第几个点位 int PlacementY = e.Y / MainSize.CBoardGap; // 求鼠标点击的Y方向的第几个点位 try { // 判断此位置是否为空 if (CheckBoard[PlacementX, PlacementY] != 0) { return; // 此位置有棋子 } // 黑子回合还是白子回合 if (ChessCheck) { CheckBoard[PlacementX, PlacementY] = 1; // 黑子回合 Judgment = 1; // 切换为判断黑子 label1.Text = "白子回合"; // 提示文本改为"白子回合" } else { CheckBoard[PlacementX, PlacementY] = 2; // 白子回合 Judgment = 2; // 切换为判断白子 label1.Text = "黑子回合"; // 提示文本改为"黑子回合" } Chess.DrawC(panel1, ChessCheck, PlacementX, PlacementY); // 画棋子 // 胜利判断 if (WinJudgment.ChessJudgment(CheckBoard, Judgment)) { // 判断黑子还是白子胜利 if (Judgment == 1) { MessageBox.Show("五连珠,黑胜!", "胜利提示"); // 提示黑胜 } else { MessageBox.Show("五连珠,白胜!", "胜利提示"); // 提示白胜 } initializeGame(); // 调用初始化游戏 } ChessCheck = !ChessCheck; // 换棋子 } catch(Exception) { } // 防止鼠标点击边界,导致数组越界 } else { MessageBox.Show("请先开始游戏!", "提示"); // 提示开始游戏 } }

第九步.WinJudgment胜利判断类(用来判断胜利)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace day11_01 { // 胜利判断 class WinJudgment { // 棋子判断 public static bool ChessJudgment(int[,] CheckBoard, int Judgment) { bool Win = false; // 胜利判断 // 遍历 获取棋盘数组的每行 for (int i = 0; i < CheckBoard.GetLength(1); i++) { // 遍历 获取棋盘数组每行的每列 for (int j = 0; j < CheckBoard.GetLength(0); j++) { // 判断是否有棋子 if (CheckBoard[j, i] == Judgment) { // 水平判断 if (j < 11) { if (CheckBoard[j + 1, i] == Judgment && CheckBoard[j + 2, i] == Judgment && CheckBoard[j + 3, i] == Judgment && CheckBoard[j + 4, i] == Judgment) { return Win = true; } } // 垂直判断 if (i < 11) { if (CheckBoard[j, i + 1] == Judgment && CheckBoard[j, i + 2] == Judgment && CheckBoard[j, i + 3] == Judgment && CheckBoard[j, i + 4] == Judgment) { return Win = true; } } // 右下判断 if (j < 11 && i < 11) { if (CheckBoard[j + 1, i + 1] == Judgment && CheckBoard[j + 2, i + 2] == Judgment && CheckBoard[j + 3, i + 3] == Judgment && CheckBoard[j + 4, i + 4] == Judgment) { return Win = true; } } // 左下判断 if (j > 3 && i < 11) { if (CheckBoard[j - 1, i + 1] == Judgment && CheckBoard[j - 2, i + 2] == Judgment && CheckBoard[j - 3, i + 3] == Judgment && CheckBoard[j - 4, i + 4] == Judgment) { return Win = true; } } } } } return Win; } } }

运行效果

全部源码

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace day11_01 { // 窗体程序 public partial class Form1 : Form { private bool start; // 游戏是否开始 private bool ChessCheck = true; // 白子黑子回合 private const int size = 15; // 棋盘大小 private int[,] CheckBoard = new int[size, size]; // 棋盘点位数组 public Form1() { InitializeComponent(); } // "窗口"Load事件 private void Form1_Load(object sender, EventArgs e) { initializeGame(); // 调用初始化游戏 this.Width = MainSize.FormWidth; // 设置窗口宽度 this.Height = MainSize.FormHeight; // 设置窗口高度 this.Location = new Point(400,75); // 设置窗口位置 } // 初始化游戏 private void initializeGame() { // 棋盘点位数组 重置为0 for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { CheckBoard[i, j] = 0; } } start = false; // 未开始 label1.Text = "游戏未开始"; // 提示文本改为"游戏未开始" button1.Visible = true; // 显示'开始游戏'按钮 button4.Visible = false; // 隐藏'重新开始'按钮 } // 按钮"开始游戏"CLick事件 private void button1_Click(object sender, EventArgs e) { start = true; // 开始 ChessCheck = true; // 黑子回合 label1.Text = "黑子回合"; // 提示文本改为"黑子回合" button1.Visible = false; // 隐藏'开始游戏'按钮 button4.Visible = true; // 显示'重新开始'按钮 panel1.Invalidate(); // 重绘面板"棋盘" } // 按钮"重新开始"CLick事件 private void button4_Click(object sender, EventArgs e) { // 确认是否重新开始 if (MessageBox.Show("确认要重新开始?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK) { initializeGame(); // 调用初始化游戏方法 button1_Click(sender, e); // 调用按钮"开始游戏"Click事件 } } // 按钮"退出"CLick事件 private void button5_Click(object sender, EventArgs e) { this.Dispose(); // 退出窗口 } // 面板"棋盘"Paint事件 private void panel1_Paint(object sender, PaintEventArgs e) { Graphics g = panel1.CreateGraphics(); // 创建面板画布 ChessBoard.DrawCB(g); // 调用画棋盘方法 Chess.ReDrawC(panel1, CheckBoard); // 调用重新加载棋子方法 } // 面板"控制界面"Paint事件 private void panel2_Paint(object sender, PaintEventArgs e) { // 设置控制界面的大小 panel2.Size = new Size(MainSize.FormWidth - MainSize.CBoardWidth - 20, MainSize.FormHeight); } // 面板"棋盘"MouseDown事件 private void panel1_MouseDown(object sender, MouseEventArgs e) { // 判断游戏是否开始 if (start) { int Judgment = 0; // 判断数组当前行列,白子还是黑子回合,0表示没有,1表示黑子,2表示白子、用来判断胜利 int PlacementX = e.X / MainSize.CBoardGap; // 求鼠标点击的X方向的第几个点位 int PlacementY = e.Y / MainSize.CBoardGap; // 求鼠标点击的Y方向的第几个点位 try { // 判断此位置是否为空 if (CheckBoard[PlacementX, PlacementY] != 0) { return; // 此位置有棋子 } // 黑子回合还是白子回合 if (ChessCheck) { CheckBoard[PlacementX, PlacementY] = 1; // 黑子回合 Judgment = 1; // 切换为判断黑子 label1.Text = "白子回合"; // 提示文本改为"白子回合" } else { CheckBoard[PlacementX, PlacementY] = 2; // 白子回合 Judgment = 2; // 切换为判断白子 label1.Text = "黑子回合"; // 提示文本改为"黑子回合" } Chess.DrawC(panel1, ChessCheck, PlacementX, PlacementY); // 画棋子 // 胜利判断 if (WinJudgment.ChessJudgment(CheckBoard, Judgment)) { // 判断黑子还是白子胜利 if (Judgment == 1) { MessageBox.Show("五连珠,黑胜!", "胜利提示"); // 提示黑胜 } else { MessageBox.Show("五连珠,白胜!", "胜利提示"); // 提示白胜 } initializeGame(); // 调用初始化游戏 } ChessCheck = !ChessCheck; // 换棋子 } catch(Exception) { } // 防止鼠标点击边界,导致数组越界 } else { MessageBox.Show("请先开始游戏!", "提示"); // 提示开始游戏 } } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace day11_01 { // 成员大小类 class MainSize { // 窗口大小 public static int FormWidth { get { return 710; } } public static int FormHeight { get { return 640; } } // 棋盘大小 public static int CBoardWidth { get { return 600; } } public static int CBoardHeight { get { return 600; } } // 棋格宽度 public static int CBoardGap { get { return 40; } } // 棋子直径 public static int ChessDiameter { get { return 37; } } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; namespace day11_01 { // 棋盘类 class ChessBoard { // 画棋盘方法 public static void DrawCB(Graphics g) { int GapWidth = MainSize.CBoardGap; // 棋格宽度 int GapNum = MainSize.CBoardWidth / GapWidth - 1; // 棋格数量 Bitmap image = new Bitmap("D:\\\\C语言\\\\代码\\\\day11\\\\day11_01_image\\\\CheckBoard1.png"); // 棋盘位图路径 g.DrawImage(image, new Point[] { new Point(0, 0), new Point(GapWidth * GapNum + 44, 0), new Point(0, GapWidth * GapNum + 44) }); // 画棋盘图片 /* Pen pen = new Pen(Color.FromArgb(192, 166, 107)); // 实例化画笔 // 画棋盘 for (int i = 0; i < GapNum + 1; i++) { g.DrawLine(pen, new Point(20, i * GapWidth + 20), new Point(GapWidth * GapNum + 20, i * GapWidth + 20)); g.DrawLine(pen, new Point(i * GapWidth + 20, 20), new Point(i * GapWidth + 20, GapWidth * GapNum + 20)); } */ } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace day11_01 { // 棋子类 class Chess { // 画棋子 public static void DrawC(Panel p, bool ChessCheck, int PlacementX, int PlacementY) { Graphics g = p.CreateGraphics(); // 创建面板画布 // 消除棋子边缘的锯齿(后面加的,博客的图片没更新) g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; int AccurateX = PlacementX * MainSize.CBoardGap + 20 - 17; // 精确棋子的X中心位置 int AccurateY = PlacementY * MainSize.CBoardGap + 20 - 17; // 精确棋子的Y中心位置 // 判断谁的回合并画棋子 if (ChessCheck) { // 线性渐变会平铺整个面板,根据你的位置填颜色,从上至下渐变,使棋子具有真实感 g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(122, 122, 122), Color.FromArgb(0, 0, 0)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } else { g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(255, 255, 255), Color.FromArgb(204, 204, 204)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } } // 界面重新聚焦时,重新加载棋子 public static void ReDrawC(Panel p,int[,] CheckBoard) { Graphics g = p.CreateGraphics(); // 创建面板画布 // 消除棋子边缘的锯齿 g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; // 遍历 获取棋盘数组的每行 for (int i = 0; i < CheckBoard.GetLength(1); i++) { // 遍历 获取棋盘数组每行的每列 for (int j = 0; j < CheckBoard.GetLength(0); j++) { int Judgment = CheckBoard[j, i]; // 判断数组当前行列,白子还是黑子回合,0表示没有,1表示黑子,2表示白子 // 判断是否有棋子 if (Judgment != 0) { int AccurateX = j * MainSize.CBoardGap + 20 - 17; // 精确棋子的X中心位置 int AccurateY = i * MainSize.CBoardGap + 20 - 17; // 精确棋子的Y中心位置 // 判断谁的回合并画棋子 if (Judgment == 1) { g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(122, 122, 122), Color.FromArgb(0, 0, 0)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } else { g.FillEllipse(new LinearGradientBrush(new Point(20, 0), new Point(20, 40), Color.FromArgb(255, 255, 255), Color.FromArgb(204, 204, 204)), new Rectangle(new Point(AccurateX, AccurateY), new Size(MainSize.ChessDiameter, MainSize.ChessDiameter))); } } } } } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace day11_01 { // 胜利判断 class WinJudgment { // 棋子判断 public static bool ChessJudgment(int[,] CheckBoard, int Judgment) { bool Win = false; // 胜利判断 // 遍历 获取棋盘数组的每行 for (int i = 0; i < CheckBoard.GetLength(1); i++) { // 遍历 获取棋盘数组每行的每列 for (int j = 0; j < CheckBoard.GetLength(0); j++) { // 判断是否有棋子 if (CheckBoard[j, i] == Judgment) { // 水平判断 if (j < 11) { if (CheckBoard[j + 1, i] == Judgment && CheckBoard[j + 2, i] == Judgment && CheckBoard[j + 3, i] == Judgment && CheckBoard[j + 4, i] == Judgment) { return Win = true; } } // 垂直判断 if (i < 11) { if (CheckBoard[j, i + 1] == Judgment && CheckBoard[j, i + 2] == Judgment && CheckBoard[j, i + 3] == Judgment && CheckBoard[j, i + 4] == Judgment) { return Win = true; } } // 右下判断 if (j < 11 && i < 11) { if (CheckBoard[j + 1, i + 1] == Judgment && CheckBoard[j + 2, i + 2] == Judgment && CheckBoard[j + 3, i + 3] == Judgment && CheckBoard[j + 4, i + 4] == Judgment) { return Win = true; } } // 左下判断 if (j > 3 && i < 11) { if (CheckBoard[j - 1, i + 1] == Judgment && CheckBoard[j - 2, i + 2] == Judgment && CheckBoard[j - 3, i + 3] == Judgment && CheckBoard[j - 4, i + 4] == Judgment) { return Win = true; } } } } } return Win; } } } 参考自:

blog.csdn/lfy905805357/article/details/81123656

.

新加了 悔棋 和 棋盘下满 时的判断! blog.csdn/qq_51756226/article/details/117604992

.

视频手把手教:

www.bilibili/video/BV1Kf4y1Y7ct

本文标签: 窗体五子程序