C#窗体程序编写,猜数字游戏(几A几B)

游戏玩法:

随机四位数,每猜一次,就会根据猜的数字给出几A几B,

其中A前面的数字表示位置正确的数的个数,

而B前的数字表示数字正确而位置不对的数的个数。

获胜条件:4A0B

如正确答案为5543,
猜的人猜5255,

则在这里不能认为猜测的第一个5对正确答案第二个,

根据最优结果为准的原理和每个数字只能有一次的规则,两个比较后应该为1A1B

ps:游戏规则其实是四位不重复数字的,但是我觉得猜起来太简单,弄了个可重复的,
导致判断几A几B的逻辑变的更难,数字不重复的判断我都写出来了,想了好久也没想到怎么写判断重复的
我苦思冥想,终于想到了解决方法,就是写一个数组,用来标记。

接下来上代码和窗体界面

窗体界面

在这里插入图片描述

右边有5个按钮,分别为 开始游戏、重新开始、游戏规则、退出、确认

数字和删除键也都是按钮、backcolor设为白色

拖三个 Label 控件,用来提示次数,几A几B,和输入的数字

我用的是4个label显示数字,大家根据喜好设置

窗体代码(控件的点击(Click)方法等等)
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_02
{
    public partial class Form1 : Form
    {
        public static Form1 form;                    // 创建一个可以在其他类调用的窗口属性

        private bool start;                          // 是否开始游戏

        private String[] EnterNum = new String[4];   // 输入的数字数组,下标0-3,千 百 十 个

        private String[] GuessNum = new String[4];   // 要猜的数字数组,下标0-3,千 百 十 个

        private int[] SignGuessNum = new int[4]{0, 0, 0, 0};   // 标记要猜的数字,默认都是0,0代表没被匹配,1代表数字被匹配,2代表位置被匹配

        int Chance = 0;                              // 机会

        public Form1()
        {
            InitializeComponent();
            form = this;                             // 窗口赋值给创建的窗口属性
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            initializeGame();                        // 调用初始化游戏
            this.Width = 560;                        // 设置窗口宽度
            this.Height = 510;                       // 设置窗口高度
            this.Location = new Point(400, 75);      // 设置窗口位置
        }

        // 初始化游戏
        private void initializeGame()
        {
            // 清空输入的数字数组
            for (int i = 0; i < EnterNum.Length; i++)
            {
                EnterNum[i] = null;
            }
            Num.ShowNum(EnterNum);                   // 调用显示数字方法
            start = false;                           // 未开始
            LblTips.Text = "游戏未开始";             // 提示改为"游戏未开始"
            button16.Visible = true;                 // 显示'开始游戏'按钮
            button15.Visible = false;                // 隐藏'重新开始'按钮
        }

        // 按钮“开始游戏”的Click事件
        private void button16_Click(object sender, EventArgs e)
        {
            start = true;                            // 开始
            label8.Text = Convert.ToString(Chance = 7);  // 次数设为7,并提示
            GuessNum = Num.RepeatRandomNum(GuessNum);// 随机四位数
            LblTips.Text = "0A0B";                   // 提示改为"0A0B"
            button16.Visible = false;                // 隐藏'开始游戏'按钮
            button15.Visible = true;                 // 显示'重新开始'按钮
        }

        // 按钮“重新开始”的Click事件
        private void button15_Click(object sender, EventArgs e)
        {
            // 确认是否重新开始
            if (MessageBox.Show("确认要重新开始?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                initializeGame();                    // 调用初始化游戏方法
                button16_Click(sender, e);           // 调用按钮“开始游戏”的Click事件
            }
        }

        // 按钮“游戏规则”的Click事件
        private void button12_Click(object sender, EventArgs e)
        {
            MessageBox.Show("随机四位数,每猜一次,就会根据猜的数字给出几A几B,\n其中A前面的数字表示位置正确的数的个数,\n而B前的数字表示数字正确而位置不对的数的个数。\n获胜条件:4A0B\t7次机会", "提示");
            MessageBox.Show("如正确答案为5543,\n猜的人猜5255,\n则在这里不能认为猜测的第一个5对正确答案第二个,根据最优结果为准的原理和每个数字只能有一次的规则,两个比较后应该为1A1B");
        }

        // 按钮“确认”的Click事件
        private void button13_Click(object sender, EventArgs e)
        {
            // 判断有没有开始游戏
            if (start)
            {
                // 判断个位有没有数字,没有就结束事件
                if (EnterNum[3] == null)
                {
                    MessageBox.Show("输入四位数", "提示");
                    return;                          // 结束事件
                }
                
				label8.Text = Convert.ToString(--Chance);  // 次数减1,并提示
				
				// 更新提示
                LblTips.Text = Judgment.Tips(String.Join("", GuessNum), String.Join("", EnterNum), SignGuessNum);

                // 通过提示判断胜利
                if (LblTips.Text.Equals("4A0B"))
                {
                    MessageBox.Show("还剩" + Chance + "次机会时,你猜对了!", "提示");
                    initializeGame();                // 调用初始化方法
                    return;                          // 结束事件
                }

                // 次数为0时,提示
                if (Chance == 0)
                {
                    MessageBox.Show("次数不足,挑战失败\n\n正确答案为:" + string.Join("", GuessNum), "提示");
                    initializeGame();                // 调用初始化方法
                }
            }
            else
            {
                MessageBox.Show("请先开始游戏!", "提示");
            }
        }

        // 按钮“退出”的Click事件
        private void button14_Click(object sender, EventArgs e)
        {
            this.Dispose();                          // 关闭并销毁窗体
        }

        // 按钮“数字键”的Click事件
        // 所有数字键的同一个点击事件
        private void btn_1_Click(object sender, EventArgs e)
        {
            // 判断游戏是否开始
            if (start == false)
            {
                MessageBox.Show("请先开始游戏!", "提示");
                return;
            }
            // 调用Num类的"添加数字方法"
            // 传入[输入数字的数组,和当前控件(数字按钮)的Text值]
            Num.AddNum(EnterNum, ((Button)sender).Text);
        }

        // 按钮“退格”的Click事件
        private void button11_Click(object sender, EventArgs e)
        {
            if (start == false)
            {
                MessageBox.Show("请先开始游戏!", "提示");
                return;
            }
            // 判断千位有没有数字,没有数字就结束事件
            if (EnterNum[0] == null)
            {
                return;                              // 结束事件
            }

            // 遍历输入的数字数组
            for (int i = EnterNum.Length - 1; i >= 0; i--)
            {
                // 从个位开始判断,有没有数字,没有数字就跳过循环
                if (EnterNum[i] == null)
                {
                    continue;                        // 跳过本轮循环
                }

                EnterNum[i] = null;                  // 清除数字

                Num.ShowNum(EnterNum);               // 调用显示数字方法

                break;                               // 结束遍历
            }
        }
    }
}

数字类 代码(添加输入数字,显示输入数字,随机四位数字)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace day11_02
{
    // 数字类
    class Num
    {
        // 显示数字方法
        public static void ShowNum(String[] EnterNum)
        {
            Form1.form.label2.Text = EnterNum[0];     // 显示千位
            Form1.form.label3.Text = EnterNum[1];     // 显示百位
            Form1.form.label4.Text = EnterNum[2];     // 显示十位
            Form1.form.label5.Text = EnterNum[3];     // 显示个位
        }

        // 添加数字方法
        public static void AddNum(String[] EnterNum, String Digit)
        {
            // 判断个位有没有数字,有数字就结束方法
            if (EnterNum[3] != null)
            {
                return;                                  // 结束方法
            }

            // 遍历输入的数字数组
            for (int i = 0; i < EnterNum.Length; i++)
            {
                // 从千位开始判断,有没有数字,没有就添加数字
                if (EnterNum[i] == null)
                {
                    EnterNum[i] = Digit;                 // 添加数字
                    Num.ShowNum(EnterNum);               // 调用显示数字方法
                    break;                               // 结束遍历
                }
            }
        }

        // 随机四位可重复数字方法
        public static String[] RepeatRandomNum(String[] GuessNum)
        {
            Random r = new Random();                     // 实例化随机数生成器

            // 随机四位数字
            for (int i = 0; i < GuessNum.Length; i++)
            {
                string RandomStr = r.NextDouble().ToString();                // 返回一个随机数,并转换为字符串
                GuessNum[i] = RandomStr.Substring(RandomStr.Length - 2, 1);  // 截取最后一位数字给数组
            }
            return GuessNum;                             // 返回数组
        }
    }
}

裁判类 代码(刷新提示,提示用来判断胜利)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace day11_02
{
    // 判断(裁判)
    class Judgment
    {
        // 刷新提示,并用来判断胜利
        public static string Tips(String GuessNum, String EnterNum, int[] SignGuessNum)
        {
            // 保存A的数量
            int ANum = 0;

            // 保存要猜的数字与输入的数字的各个数字的数量,不保存A的数字
            int[] cntG = new int[10];
            int[] cntE = new int[10];

            // 遍历两个数字
            for (int i = 0; i < 4; i++)
            {
                // 数字与位置相同,则A的数量+1
                if (GuessNum[i] == EnterNum[i])
                {
                    ANum++;
                }
                // 数字不同,则统计数量
                else
                {
                    cntG[GuessNum[i] - '0']++;
                    cntE[EnterNum[i] - '0']++;
                }
            }

            // 保存B的数量
            int BNum = 0;
            // B的数量为分别统计的相同数字的最小值,即多余的没有匹配,不为B
            for (int i = 0; i < 10; i++)
            {
                BNum += Math.Min(cntG[i], cntE[i]);
            }

            return ANum + "A" + BNum + "B";
        }
    }
}

效果图:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
ps: 我觉得7次机会太难了,你们可以多加点次数。
因为可以重复,确实不好猜哈哈哈哈哈

另一个窗体小游戏:五子棋

  • 15
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值