Member 14017552 Ответов: 2

C# случайная функция для броска 3 кубиков


Привет,
Как я могу запустить функцию, которая будет случайным образом генерировать целые числа для 3 кубиков, когда я бросаю их одновременно?
Моя цель состоит в том, чтобы получить 3 числа и поставить их рядом друг с другом (от большего к меньшему), например, если я катаю 3,1,4, мне нужно отобразить 431. Я начал код, не зная, как продолжить. Я создал 3 метки и 3 текстовых поля для 3 кубиков и кнопку "бросок", которая будет отображать случайные результаты, но я застрял и не знаю, как действовать дальше!
Можете ли вы пожалуйста, дайте мне толчок?
Спасибо

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

Random rnd = new Random();
int dice1 = rnd.Next(1,6); // creates a number between 1 and 6 from dice 1
int dice2 = rnd.Next(1,6);   // creates a number between 1 and 6 from dice 2
int dice3 = rnd.Next(1,6);  // creates a number between 1 and 6 from dice 3

MadMyche

Каковы же результаты этого? Работает ли он так, как задумано?

Gerry Schmitz

Может быть, это моя "версия", но вы можете обнаружить, что вам нужно использовать .Next(1,7), чтобы получить числа от 1 до 6!

Вы можете поместить свои результаты в список<int>, использовать LINQ для сортировки, а затем скопировать каждое значение в соответствующее текстовое поле.

2 Ответов

Рейтинг:
2

OriginalGriff

Начните с перемещения Random экземпляр выходит из метода и помещает его в переменную уровня класса:

private Random rnd = new Random();
void MyMethod()
    {
    int dice1 = rnd.Next(1,6); // creates a number between 1 and 6 from dice 1
    int dice2 = rnd.Next(1,6);   // creates a number between 1 and 6 from dice 2
    int dice3 = rnd.Next(1,6);  // creates a number between 1 and 6 from dice 3
    ...
    }
Причина этого заключается в том, что Random инициализируется системными часами, поэтому вы не хотите создавать их снова и снова, или вы получите ту же последовательность, если вызовете свой метод слишком быстро. Если сделать его классовым, то это означает, что он создается один раз, так что вы не получите этого повторения.

Затем посмотрите на определение понятия Next метод, и вы увидите, что верхняя граница является исключительной - возвращаемое значение никогда не будет равно ей, - поэтому вам нужно добавить один, чтобы получить справедливый бросок на шестигранном кубике:
private Random myDie = new Random();
public int RollStandardDie()
    {
    return myDie.Next(1, 6 + 1);
    }

Тогда называть RollStandardDie три раза, чтобы получить ваши ценности и отсортировать их. Самый простой способ таков:
private Random myDie = new Random();
public int RollStandardDie()
    {
    return myDie.Next(1, 6 + 1);
    }
private void MyButton_Click(object sender, EventArgs ew)
    {
    int[] dice = new int[3];
    for (int i = 0; i < dice.Length; i++)
        {
        dice[i] = RollStandardDie();
        }
    Array.Sort(dice);
Затем просто введите свои значения в метки или текстовые поля:
label1.Text = dice[0].ToString();
TextBox2.Text = dice[1].ToString();


Gerry Schmitz

"Пурист" / ОКР во мне хочет использовать "параллельные" броски, потому что требование состоит в том, чтобы "бросить 3 кости".

(Для И Цзин вы можете уменьшить количество бросков "3 монеты" до одного из 4 чисел).

OriginalGriff

Ваше ОКР опасно: случайность.Далее решительно не потокобезопасно! :смеяться:
https://blogs.msdn.microsoft.com/pfxteam/2009/02/19/getting-random-numbers-in-a-thread-safe-way/

Gerry Schmitz

Мне никогда не приходило в голову использовать "тот же самый" Рэндом для параллельных операций.

Один создает несколько экземпляров в разные моменты времени (если явно не "посев").


OriginalGriff

А на многоядерной машине это означает, что все они, вероятно, начинаются с одного и того же семени ... или вы должны создать массив жукеров! :смеяться:

Gerry Schmitz

Они засеваются, когда создаются; вы не "создаете" их одновременно.

Параллельная операция-это "прокатка".

(И вы можете повторно инициализировать, случайным образом, ожидая, пока пользователь нажмет кнопку).

Вы создаете машины состояний, а не просто "массив случайных чисел".

Member 14017552

Спасибо OriginalGriff,

Вот последний код в соответствии с вашим советом, спасибо... но когда я добавляю последнюю строку, чтобы показать результат, я получаю ошибку!
---------------
использование системы.Окна.Формы;

пространство имен DiceGame
{
общественности частичного класс form1 : форма
{
открытый form1()
{
метод InitializeComponent();
}

private Random myDice = новый случайный();
public int RollDice()
{
верните myDice.Next(1, 6 + 1);
}

Play_Button_Click частная недействительным(объект отправителя, EventArgs в электронной)
{
int[] dice = новый int[3];
для (int i = 0; i < dice.Длина; i++)
{
dice[i] = RollDice();
}

Array.Sort(кости);

Dice1_input.Text = dice[0].Метод toString();
Dice2_input.Текст = кости[1].Метод toString();
Dice3_input.Текст = кости[2].Метод toString();

Player1_Result.Text = ("Игрок 1: {0}{1}{2}", Dice1_input, Dice2_input, Dice3_input);

}

}
}
-----------------------------
Пожалуйста смотрите прилагаемый скриншот здесь https://imgur.com/a/6DgY5VE

С уважением

OriginalGriff

Нет. Вы хотите, чтобы я посмотрел на ошибку, вы копируете и вставляете ее - я не собираюсь смотреть на плохой скриншот сообщения об ошибке!

Но это только предположение ... Что случилось с "строку.Формат"?

Member 14017552

Все исправлено, спасибо за подсказку и извините за скриншот.

Если вы не возражаете я задам еще один вопрос:
Наш второй проект теперь состоит в том, чтобы собрать двух игроков, сравнить результаты и сказать, кто победит. Я скопировал и вставил точный код, а также добавил игрока 2...

Dice1_input_Player1.Text = dice_Player1[0].Метод toString();
Dice2_input_Player1.Text = dice_Player1[1].Метод toString();
Dice3_input_Player1.Text = dice_Player1[2].Метод toString();

Dice1_input_Player2.Text = dice_Player2[0].Метод toString();
Dice2_input_Player2.Text = dice_Player2[1].Метод toString();
Dice3_input_Player2.Text = dice_Player2[2].Метод toString();

Player1_Result.Текстовая строка.Формат("Плеер 1: {0}{1}{2}", Dice1_input_Player1.Text, Dice2_input_Player1.Text, Dice3_input_Player1.Text);
Player2_Result.Текстовая строка.Формат("Плеер 2: {0}{1}{2}", Dice1_input_Player2.Text, Dice2_input_Player2.Text, Dice3_input_Player2.Text);

int P1R = преобразовать.ToInt32(Player1_Result.Текст);
int P2R = конвертировать.ToInt32(Player2_Result.Текст);

если (P1R >= P2R)
Приставка.Напишите("Игрок 1 Выигрывает!");
еще
Приставка.Напишите("Игрок 2 Выигрывает!");

-----
но когда я запускаю код, кнопка "Play" становится не кликабельной, и я получаю сообщение об ошибке: "System.FormatException: входная строка была не в правильном формате."

и это показывает ошибку на
int P1R = преобразовать.ToInt32(Player1_Result.Текст);
int P2R = конвертировать.ToInt32(Player2_Result.Текст);

я много пробовал, но ничего не могу понять, не могли бы вы мне помочь?
Извините, я все еще очень новичок в программировании и все еще нахожусь в процессе обучения...
Спасибо

OriginalGriff

Посмотри на свой код.
Используйте отладчик, если это необходимо, но ... посмотрите, что находится в Player_1_Result.Text. Это что, число?

Member 14017552

Я так и сделал, и получив "вы должны переименовать идентификатор", я просто не могу этого понять!
Player_1_Result.Текст-это строка, и мы должны преобразовать ее в Int, чтобы использовать ее в операторе IF.
Пожалуйста, исправьте, если я ошибаюсь,
Спасибо

OriginalGriff

Да, это веревка. И да, вам нужен номер. Но... что ты вложил в веревку?

Подумайте об этом в течение минуты (используйте отладчик, если вы не уверены, он покажет вам точно, что содержит строка).
Тогда подумайте : к какому числу это приравнивается?

Member 14017552

Проблема в том, что я не получаю никаких ошибок в "списке ошибок", поэтому программа работает, но когда я нажимаю на кнопку "Play", она зависает и выскакивает сообщение об ошибке "System.FormatException: 'входная строка была не в правильном формате. Я запустил отладчик, но ничего не добился. Пожалуйста, парень, подтолкни меня.

OriginalGriff

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

Рейтинг:
2

Member 14017552

Большое спасибо за помощь... есть ли способ сделать последний бит без использования массива? Я знаю, что это может быть долгое решение, но я просто хочу сравнить и узнать разницу.
Спасибо снова


MadMyche

Вместо того чтобы присваивать значения массиву, вы можете использовать StringBuilder и добавлять их на каждый рулон штампа

OriginalGriff

Да, но это проще сортировать с помощью массива - и более гибко в будущем.
Но вы можете сделать это с помощью "обычного" кода, просто это дольше и хлопотнее:

if (a > c)
  {
  temp = a;
  a = c;
  c = temp;
  }
if (a > b)
  {
  temp = a;
  a = b;
  b = temp;
  }
if (b > c)
  {
  temp = b;
  b = c;
  c = temp;
  }
Он становится намного более длинным для четырех и выше!

Richard Deeming

Если вы хотите ответить на решение, нажмите кнопку "есть вопрос или комментарий?" кнопка под этим решением.

НЕ опубликуйте свой комментарий как новое "решение".