五子棋-进阶版:C#窗体编写

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

进阶内容,主要有 悔棋 功能,和 棋盘下满 时的处理

友情提示:先了解之前的 1.0版五子棋

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("请先开始游戏!", "提示");      // 提示开始游戏
    }
}
  • 46
    点赞
  • 192
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值