Member 13390086 Ответов: 3

C# Угадай игру со случайными числами


Должно быть случайное число от 1000 до 9999, и пользователь должен угадать это число. Для этого я сделал 4 разных текстовых поля. Если номер правильный и он находится на нужном месте, он должен стать зеленым. Если число неправильное, оно должно стать красным, а если число правильное, но оно находится в неправильном месте, оно должно стать желтым. Например:
если число 1245, а пользователь вводит 2143, то оно должно быть таким: желтый , желтый, зеленый, красный ...


Этот код работает, но пользователь может угадать число только один раз, а при втором нажатии кнопки появляется еще одно случайное число. Я хочу, чтобы он позволял пользователю угадывать, пока все текстовые поля не станут зелеными. Кроме того, в моем коде много повторений, которые я не знаю, как исправить... (все эти if, else if, elses)

[edit]добавлен блок кода-OriginalGriff [/edit]

Что я уже пробовал:

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 guess
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
                Random random1 = new Random();
                int rand1 = random1.Next(1, 9);

                Random random2 = new Random();
                int rand2 = random2.Next(0, 9);

                Random random3 = new Random();
                int rand3 = random3.Next(0, 9);

                Random random4 = new Random();
                int rand4 = random4.Next(0, 9);

                if (textBox1.Text == rand1.ToString())
                {
                    textBox1.BackColor = Color.LightGreen;
                }
                else if (textBox1.Text == rand2.ToString() || textBox1.Text == rand3.ToString() || textBox1.Text == rand4.ToString())
                {
                    textBox1.BackColor = Color.Yellow;
                }
                else
                {
                    textBox1.BackColor = Color.Red;
                }

                if (textBox2.Text == rand2.ToString())
                {
                    textBox2.BackColor = Color.LightGreen;
                }
                else if (textBox2.Text == rand1.ToString() || textBox2.Text == rand3.ToString() || textBox2.Text == rand4.ToString())
                {
                    textBox2.BackColor = Color.Yellow;
                }
                else { textBox2.BackColor = Color.Red; }

                if (textBox3.Text == rand3.ToString())
                {
                    textBox3.BackColor = Color.LightGreen;
                }
                else if (textBox3.Text == rand1.ToString() || textBox3.Text == rand2.ToString() || textBox3.Text == rand4.ToString())
                {
                    textBox3.BackColor = Color.Yellow;
                }
                else
                {
                    textBox3.BackColor = Color.Red;
                }

                if (textBox4.Text == rand4.ToString())
                {
                    textBox4.BackColor = Color.LightGreen;
                }
                else if (textBox4.Text == rand1.ToString() || textBox4.Text == rand2.ToString() || textBox4.Text == rand3.ToString())
                {
                    textBox4.BackColor = Color.Yellow;
                }
                else
                {
                    textBox4.BackColor = Color.Red;
                }

                label1.Text = rand1.ToString() + rand2.ToString() + rand3.ToString() + rand4.ToString();

        }   
    }
}

3 Ответов

Рейтинг:
2

Graeme_Grant

Ваш код не соответствует вашим инструкциям. Перечитайте ваши инструкции, разбейте их на части, а затем соответствующим образом структурируйте свой код. Например:

1. нажимается кнопка Пуск / перезапуск, текстовые поля очищаются и генерируется случайное число

2. пользователь вводит 4 числа и нажимает кнопку "угадать".

3. код проверяет значения и устанавливает состояние "цвет" для каждой записи. После завершения перейдите к шагу 5.

4. вернитесь к Шагу 2

5. уведомить Пользователя о том, что игра закончилась.

6. Спрашивать пользователя, если они хотят играть снова.

Теперь вы готовы написать свой код. Подсказка: требуется более одной кнопки.


Рейтинг:
1

OriginalGriff

Начните с того, что сделайте себе много одолжений:
1) Создайте один случайный экземпляр вне обработчика событий нажатия кнопки и используйте его вместо четырех. Когда вы создаете экземпляр Random, он инициализируется из системных часов - поэтому, если у вас нет чрезвычайно медленного компьютера, четыре экземпляра почти наверняка будут генерировать точно такую же последовательность чисел...
2) перестаньте использовать имена Visual Studio по умолчанию для всего - вы можете помнить, что" TextBox8 " - это номер мобильного телефона сегодня, но когда вам нужно будет изменить его через три недели, вы это сделаете? Используйте описательные имена - например, "tbMobileNo" - и ваш код станет легче читать, более самодокументируемым, более легким в обслуживании-и на удивление быстрее кодировать, потому что Intellisense может добраться до" tbMobile "за три нажатия клавиш, где" TextBox8 " занимает размышление и 8 нажатий клавиш...
Не преобразуйте числа в строки и не сравнивайте их - преобразуйте то, что должно быть числами в виде строк в текстовых полях, в числа и сравните их. Это легко сделать:

int valueFromTheUser;
if (!int.TryParse(myTextBox.Text, out valueFromTheUser))
   {
   // Report problem with his input to the user
   ...
   return;
   }
if (myRandomNumber == valueFromTheUser)
   {
   ...

3) Напишите метод, который возвращает bool: вы передаете ему четыре числа, и он проверяет, совпадает ли какое-либо из последних трех с первым. Затем вызовите его три раза, передавая преобразованное значение текстового поля. Внезапно ваше повторение исчезает...
4) это плохая "игра" - шансы пользователя получить ее правильно в любой момент составляют 1:1000, что просто не произойдет: вы не можете генерировать новое случайное число каждый раз, когда он пытается угадать его, если вы хотите, чтобы ваши пользователи играли в него более одного раза...


Рейтинг:
1

Thomas Nielsen - getCore

Привет
При работе со случайным классом неплохо иметь только один и засеять его текущим временем.

Тогда то, что вы делаете, когда нажимаете кнопку, - это переназначение ваших случайных величин, поэтому они меняются.

Итак, уберите свою логику из вашего интерфейса и получите свой интерфейс с правильным именованием. Я имею в виду форму 1, кнопку 1, правда? и даже над проектом кода. Позвольте мне побудить вас вырасти из этого быстро :)

Итак, давайте придумаем объект яслей для вашей случайной обработки и набор для сопоставления!
Но сначала проверьте свой ввод, чтобы получить читаемый код, в котором нет нечетных ошибок.

private int GetValidInputOrThrow(TextBox textbox)
    {
        if (string.IsNullOrEmpty(textbox.Text) || textbox.Text.Length != 1)
            throw new ArgumentException("Only one number in each box, please", "textbox");
        return int.Parse(textbox.Text);
    }

private void button1_Click(object sender, EventArgs e)
{
    //TODO: Add a trycatch in case of validation problems
    int one = GetValidInputOrThrow(textBox1);
    int two = GetValidInputOrThrow(textBox2);
    int three = GetValidInputOrThrow(textBox3);
    int four = GetValidInputOrThrow(textBox4);

    MatchSet matchThis = MatchManager.GetMatchSet();

    if (one.Equals(matchThis.NumberOne))
        TextBox1.Backcolor = Color.LightGreen;

        //...


Теперь перейдем к классу matchmanager, который по существу обертывает matchset и позволяет сбросить его с помощью getnewmatchset, если вам также нужна эта опция.

public class RandomMatchManager
    {
        private Random _rnd = new Random((int)DateTime.Now.Ticks);
        private MatchSet _matchSet;

        public MatchSet GetNewMatchSet()
        {
            _matchSet = new MatchSet
            {
                NumberOne = _rnd.Next(0, 9),
                NumberTwo = _rnd.Next(0, 9),
                NumberThree = _rnd.Next(0, 9),
                NumberFour = _rnd.Next(0, 9)
            };
            return _matchSet;
        }

        public MatchSet GetMatchSet()
        {
            if (_matchSet == null)
                return GetNewMatchSet();
            return _matchSet;
        }
    }

    public class MatchSet : IEquatable<MatchSet>
    {
        public int NumberOne { get; set; }
        public int NumberTwo { get; set; }
        public int NumberThree { get; set; }
        public int NumberFour { get; set; }

        public bool Equals(MatchSet other)
        {
            return NumberOne.Equals(other.NumberOne) && NumberTwo.Equals(other.NumberTwo) && NumberThree.Equals(other.NumberThree) && NumberFour.Equals(other.NumberFour);
        }
    }

Вы заметите, что Random сохраняется и что matchset предлагает возможность сравнивать весь набор, отдельные значения имеют одинаковый тип значений. Случайное число обновляется с текущим значением тика времени, чтобы избежать получения того же ряда значений, что и случайное, на самом деле не обязательно такое случайное :)

И так из последних нераскрытых делает ленивый собственность на форме типа менеджер

public partial class Form1 : Form
  {
      private RandomMatchManager MatchManager
      {
          get
          {
              if (_matchManager == null)
                  _matchManager = new RandomMatchManager();
              return _matchManager;
          }
      }
      private RandomMatchManager _matchManager;