C#窗体编写 • 【五子棋】- 进阶版!
1.0版:C#窗体程序编写 • 【五子棋】
进阶内容,主要有 悔棋 功能,和 棋盘下满 时的处理
友情提示:先了解之前的 1.0版五子棋
" class="reference-link">No1.悔棋
第一步.定义一个列表(用于记录下棋顺序)
// 窗体程序
public partial class Form1 : Form
{
private bool start; // 游戏是否开始
private bool ChessCheck = true; // 白子黑子回合
private const int size = 15; // 棋盘大小
private int[,] CheckBoard = new int[size, size]; // 棋盘点位数组
--> private List<Retract> RetractList = new List<Retract>(); *用于悔棋的列表*
List<Retract> 里的Retract是一个类,先不要纠结为什么报错,请看第二步
}
第二步.定义一个类,记录棋子的 X 轴和 Y 轴,也就是点位
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace day11_01
{
// 记录上一个棋子放的位置
class Retract
{
// 构造函数,实例化时传坐标参数
public Retract(int X, int Y)
{
this.X = X;
this.Y = Y;
}
// 默认-1,也就是无效坐标
public int X = -1, Y = -1;
}
}
第三步.”略微”修改棋盘的点击事件
***星号包裹的代码,就是添加的代码 ***
// 面板"棋盘"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); // 画棋子
-----> RetractList.Add(new Retract(PlacementX, PlacementY)); *记录棋子的位置,用于悔棋*
// 胜利判断
if (WinJudgment.ChessJudgment(CheckBoard, Judgment))
{
// 判断黑子还是白子胜利
if (Judgment == 1)
{
MessageBox.Show("五连珠,黑胜!", "胜利提示"); // 提示黑胜
}
else
{
MessageBox.Show("五连珠,白胜!", "胜利提示"); // 提示白胜
}
initializeGame(); // 调用初始化游戏
}
ChessCheck = !ChessCheck; // 换棋子
}
catch(Exception) {
} // 防止鼠标点击边界,导致数组越界
}
else
{
MessageBox.Show("请先开始游戏!", "提示"); // 提示开始游戏
}
}
第四步.添加“悔棋”按钮(和它的点击事件)
按钮的点击事件
// 按钮‘悔棋’Click事件
private void button2_Click(object sender, EventArgs e)
{
// 获取悔棋列表中,最后一个棋子的索引
int Index = RetractList.Count - 1;
// 判断悔棋列表是否为空
if (Index == -1)
{
MessageBox.Show("成功撤回空气!", "提示");
return;
}
// 判断并获取最后一个棋子是白子还是黑子
string ChessCheckStr = "";
if (ChessCheck)
{
ChessCheckStr = "白方";
}
else
{
ChessCheckStr = "黑方";
}
// 得到最后一个棋子的位置
Retract retract = RetractList[Index];
// 确认是否悔棋
if (MessageBox.Show("确认要撤回\"" + ChessCheckStr + " : 坐标[" + retract.X + ", " + retract.Y + "]\"的棋子吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
{
// 在悔棋列表中,删除上一个棋子
RetractList.RemoveAt(Index);
// 点位数组中,清除上一个棋子
CheckBoard[retract.X, retract.Y] = 0;
// 刷新窗体
this.Refresh();
// 换棋子
ChessCheck = !ChessCheck;
}
}
到这里就OK了吗? no no no
第五步.调整一些方法(比如 初始化时,顺便把“悔棋”列表清空)
// 初始化游戏
private void initializeGame()
{
// 棋盘点位数组 重置为0
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
CheckBoard[i, j] = 0;
}
}
--> RetractList.Clear(); *清空悔棋列表*
start = false; // 未开始
label1.Text = "游戏未开始"; // 提示文本改为"游戏未开始"
button1.Visible = true; // 显示'开始游戏'按钮
button4.Visible = false; // 隐藏'重新开始'按钮
--> btnRetract.Visible = false; *隐藏'悔棋'按钮*
}
// 按钮"开始游戏"CLick事件
private void button1_Click(object sender, EventArgs e)
{
start = true; // 开始
ChessCheck = true; // 黑子回合
label1.Text = "黑子回合"; // 提示文本改为"黑子回合"
button1.Visible = false; // 隐藏'开始游戏'按钮
button4.Visible = true; // 显示'重新开始'按钮
--> btnRetract.Visible = true; *显示'悔棋'按钮*
panel1.Invalidate(); // 重绘面板"棋盘"
}
OK了,最后的棋盘下满判断!只需要3行!
No2.棋盘下满时
就一步.“着重”修改棋盘的点击事件
别问我怎么下满的~
// 面板"棋盘"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); // 画棋子
RetractList.Add(new Retract(PlacementX, PlacementY)); // 记录棋子的位置,用于悔棋
// 胜利判断
if (WinJudgment.ChessJudgment(CheckBoard, Judgment))
{
// 判断黑子还是白子胜利
if (Judgment == 1)
{
MessageBox.Show("五连珠,黑胜!", "胜利提示"); // 提示黑胜
}
else
{
MessageBox.Show("五连珠,白胜!", "胜利提示"); // 提示白胜
}
initializeGame(); // 调用初始化游戏
}
-----> else if (RetractList.Count == size * size) 悔棋列表的总数 = 棋盘点位总数时
{
-----> MessageBox.Show("平局!可喜可贺,找到了旗鼓相当的对手!", "胜利提示"); *提示平局*
-----> initializeGame(); *调用初始化游戏*
}
ChessCheck = !ChessCheck; // 换棋子
}
catch(Exception) {
} // 防止鼠标点击边界,导致数组越界
}
else
{
MessageBox.Show("请先开始游戏!", "提示"); // 提示开始游戏
}
}
还没有评论,来说两句吧...