Making my dice throws produce more throws? - c#

I'm working on an assignment, where I have to make an application where you can throw 1-4 dice. The results are then added to a list.
However, if any of them is a 6, that one isn't added to the list, instead 2 additional dice are thrown.
As long as a die returns a 6, 2 more dice have to be thrown, until no die returns a 6.
Does anyone here know how to solve this? My programming skills are really basic, and I haven't used them much since last year.
for (int i = 0; i < qty; i++)
{
int diceNr = RollDice(random);
dicelist.Add(diceNr);
Console.WriteLine(diceNr);
if (diceNr == 6)
{
dicelist.Remove(diceNr);
Console.WriteLine("You got a six, that means you get 2 extra throws!");
for (int x = 0; x < 2; x++)
{
diceNr = RollDice(random);
dicelist.Add(diceNr);
}

You can try using a while loop as follows:
int i = quantity; #initialize a variable to your maximum number of throws
while(i > 0){ #until you have throws yet
i--; #this is the equivalent of one throw
int diceNr = RollDice(random);
dicelist.Add(diceNr);
Console.WriteLine(diceNr);
if(diceNr == 6){
Console.WriteLine("You got a six, that means you get 2 extra throws!");
i = i + 2; #add your bonus throws
}
}

You can use a while loop that exits once you are out of rolls. If you roll a six, add two more to the remaining quantity otherwise add the rolled value to the list.
int qty = 6;
// decrement remaining quantity each iteration
// until zero rolls remain
while(qty-- > 0)
{
int diceNr = RollDice(random);
Console.WriteLine(diceNr);
if (diceNr == 6)
{
// rolled six, add two more rolls
Console.WriteLine("You got a six, that means you get 2 extra throws!");
qty += 2;
}
else
{
// not six, add to list
dicelist.Add(diceNr);
}
}
// output all the non-six values
var allRolls = string.Join(",", diceList);
Console.WriteLine("All rolls: " + allRolls);
You could also do this with recursion (though I don't recommend it for this problem):
private static void Play(List<int> diceList, Random random, int rolls)
{
// base case, no rolls remain
if (rolls == 0)
return;
int diceNr = RollDice(random);
Console.WriteLine(diceNr);
if (diceNr == 6)
{
Console.WriteLine("You got a six, that means you get 2 extra throws!");
// add one to rolls since we are "reusing" this slot
// adding two would give us one more roll than we really want
rolls++
}
else
{
diceList.Add(diceNr);
// decrement rolls by one
rolls--;
}
// recursively call Play with updated roll count
// which is either original + 1 OR original - 1
Play(diceList, random, rolls);
}
private static int RollDice(Random r)
{
return r.Next(1, 7);
}
public static void Main()
{
var diceList = new List<int>();
var random = new Random();
int qty = 6;
Play(diceList, random, qty);
// output all the non-six values
var allRolls = string.Join(",", diceList);
Console.WriteLine("All rolls: " + allRolls);
}

My (readable) solution would look like:
class Program
{
static void Main(string[] args)
{
var game = new Game(4);
game.Play();
}
}
public class Game
{
private readonly int _noOfDices;
private readonly List<int> _result;
private readonly Random _random = new Random();
public Game(int noOfDices)
{
_noOfDices = noOfDices;
_result = new List<int>();
}
public void RollDice()
{
var no = _random.Next(1, 7);
if (no == 6)
{
RollDice();
RollDice();
}
else
{
_result.Add(no);
}
}
public void Play()
{
for (var i = 1; i <= _noOfDices; i++)
{
RollDice();
}
Console.WriteLine($"Output: {string.Join(',',_result)}");
}
}
Output:

Related

Can I find wins and draws faster

I have a time sensitive application where I get the rank of each object and work out who won or tied for first. With my current algorithm I get some lag in my program so am hoping to speed it up. In this demo version I just get a random number for the ranks as the real rank calc requires too much code to post.
Can anybody suggest how I might do this more quickly as the Update method can get called tens of thousands of times for a single run?
class Program
{
static int runOuts = 0;
static Dictionary<RankedObject, int> dictionaryWins = new Dictionary<RankedObject, int>();
static Dictionary<RankedObject, int> dictionaryDraws = new Dictionary<RankedObject, int>();
static Random random = new Random();
static List<RankedObject> rankedObjects = new List<RankedObject>();
static void Main(string[] args)
{
// create some objects for demo
rankedObjects.Add(new RankedObject());
rankedObjects.Add(new RankedObject());
rankedObjects.Add(new RankedObject());
// add each object to the win/draw dictionaries so we can count wins/draws for each
foreach (RankedObject rankedObj in rankedObjects)
{
dictionaryWins.Add(rankedObj, 0);
dictionaryDraws.Add(rankedObj, 0);
}
// calculate wins/draws many times
for (int i = 0; i < 10000; i++)
{
Update();
}
// set equity results in each ranked combo and print results
foreach (RankedObject rankedCombo in rankedObjects)
{
rankedCombo.WinEquity = dictionaryWins[rankedCombo] / (double)runOuts;
rankedCombo.DrawEquity = dictionaryDraws[rankedCombo] / (double)runOuts;
Console.WriteLine(rankedCombo);
}
}
private static void Update()
{
// keep a list of ranks for each object so we can get max/winning value easily
List<int> ranks = new List<int>();
// get a rank for each object
foreach (RankedObject rankedCombo in rankedObjects)
{
int rank = random.Next(3);
ranks.Add(rank);
rankedCombo.Rank = rank;
}
// get the maximum rank and how many times it occurs, so we know if their is a tie for the win
int max = ranks.Max();
int maxOccurences = 0;
foreach (int i in ranks)
{
if (i == max)
{
maxOccurences++;
}
}
// loop over each object to record if the object won or tied for win
foreach (RankedObject rankedObj in rankedObjects)
{
if (rankedObj.Rank == max && maxOccurences == 1) // current rankedObj was winner
{
dictionaryWins[rankedObj] += 1;
}
else if (rankedObj.Rank == max && maxOccurences > 1) // current rankedObj Tied for win
{
dictionaryDraws[rankedObj] += 1;
}
}
runOuts++;
}
}
class RankedObject
{
int rank;
double winEquity;
double drawEquity;
public int Rank { get => rank; set => rank = value; }
public double WinEquity { get => winEquity; set => winEquity = value; }
public double DrawEquity { get => drawEquity; set => drawEquity = value; }
public override string ToString()
{
return "Win Equity: " + winEquity + ", Draw Equity: " + drawEquity;
}
}

Creating a dice that doubles and continues to roll if it lands on a specific number in C#?

I am trying to make a program that I Believe has to make use of recursion. In short: create a program that will throw a Dice. If it lands on a 6, two Dices are created and rolled, and so on until no more 6 are rolled.
The problem is not creating a new or true random object, but the recursive Dices.
The recursion method looks like this:
public static int Recursion(int a)
{
Random m = new Random();
if (a < 6)
{
return a;
}
else
{
a = m.Next(1, 7);
return Recursion(a) * 2;
}
}
Possibly something like this?
public static int Roll() {
return Roll(new Random(), 1);
}
public static int Roll(Random random, int diceCount) {
int sum = 0;
for (int dice = 1; dice <= diceCount; ++dice) {
int rolled = random.Next(1, 7);
if (rolled == 6) {
sum += Roll(random, 2)
}
else
{
sum += rolled;
}
}
return sum;
}
So, first I roll one die/dice. If it is not 6, then I accept its value as the result. If it is six, then I remove that die/dice, and replace it with two other I roll. Then, for each of the new ones I follow the same rule, until all the dice on the table is rolled and none of them is 6. Now I sum all the value of dice. This is what this recursive algorithm does. Note, that - however it has infinitely low chance - you can play this until the end of times, since there is always chance of rolling 6, so you can possibly roll only 6's until you die.
You can make it more object oriented by creating a dice object:
using System;
using System.Collections.Generic;
class Dices
{
public class Dice
{
private static Random roler = new Random();
private int roledNumber;
public int Role()
{
roledNumber = roler.Next(6) + 1 ;
return roledNumber;
}
public int Number
{
get { return roledNumber; }
}
}
static void Main(string[] args)
{
List<Dice> allDices = new List<Dice>();
Dice firstDice = new Dice();
allDices.Add(firstDice);
if (firstDice.Role() == 6) createDices(allDices);
}
static void createDices(List<Dice> dices)
{
Dice first = new Dice();
dices.Add(first);
if (first.Role() == 6) createDices(dices);
Dice second = new Dice();
dices.Add(second);
if (second.Role() == 6) createDices(dices);
}
}

C# Dice Roll - Assigning scores to values

Currently working on a project and need some help. Still relatively new to c#. I have created a dice rolling game in which 5 dice are rolled at once in turns between 2 players. What I am stuck on is checking through these values for a three of a kind and assigning points .For example, A player presses enter and one appears three times then the player should receive three points or if four appears three times then the player receives the points. I have tried lots of different methods using if statements and for loops but cant seem to get it working. My code is provided below.Any help would be appreciated.
Thanks
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dice_v4
{
class Game
{
static void Main(string[] args)
{
Random RandomNum = new Random();
Player[] player1 = new Player[5];
Die[] myDie = new Die[5];
for (int i = 0; i < 5; i++)
{
myDie[i] = new Dice_v4.Die(RandomNum);
player1[i] = new Dice_v4.Player();
}
for (int i = 0; i < 2; i++) // Number of players
{
Console.Write("Enter Name for Player {0}:", i + 1);
string NewName = Console.ReadLine();
player1[i].SetName(NewName);
}
Console.WriteLine();
for (int j = 1; j < 20; j++)
{
for (int i = 0; i < 2; i++)
{
myDie[i].roll();
Console.WriteLine("{0} Rolled:{1} on the first dice", player1[i].GetName(), myDie[i].GetTopNumber());
Console.WriteLine("{0} Rolled:{1} on the second dice", player1[i].GetName(), myDie[i].GetTopNumber1());
Console.WriteLine("{0} Rolled:{1} on the third dice", player1[i].GetName(), myDie[i].GetTopNumber2());
Console.WriteLine("{0} Rolled:{1} on the fourth dice", player1[i].GetName(), myDie[i].GetTopNumber3());
Console.WriteLine("{0} Rolled:{1} on the fifth dice", player1[i].GetName(), myDie[i].GetTopNumber4());
Console.WriteLine("Total Throws:{0}", j);
Console.ReadLine(); }
}
}
}
class Die
{
private int NumberTop1; //attributes
private int NumberTop2;
private int NumberTop3;
private int NumberTop4;
private int NumberTop5;
int threepoints = 0;
private Random RandomNumGenerator;
public Die(Random RandomGenerator) // constructor
{
RandomNumGenerator = RandomGenerator; // initialises random number
}
public void roll()
{
NumberTop1 = RandomNumGenerator.Next(1, 6);
NumberTop2 = RandomNumGenerator.Next(1, 6);
NumberTop3 = RandomNumGenerator.Next(1, 6);
NumberTop4 = RandomNumGenerator.Next(1, 6);
NumberTop5 = RandomNumGenerator.Next(1, 6);
// generates random number / / Number of dice to be rolled
Console.WriteLine("\tTotal score = {0}", threepoints);
}
public int GetTopNumber()
{
return NumberTop1; // Returns number on top which equals dice roll
}
public int GetTopNumber1()
{
return NumberTop2;
}
public int GetTopNumber2()
{
return NumberTop3;
}
public int GetTopNumber3()
{
return NumberTop4;
}
public int GetTopNumber4()
{
return NumberTop5;
}
}
class Player
{
private string Name;
public void SetName(string NewName) // constructor
{
Name = NewName; // initalises name
}
public string GetName()
{
return Name; // Returns name when called
}
}
}
Advice:
Whenever you have variables or properties called something1, something2, ... - you're probably doing something wrong, and you probably want to use a list, array, hashmap...
My idea here would be to add all numbers to a list and then perhaps iterate to make a dictionary where key is the dice value and value is the count. Or you can do something else, depending which format you need for later operations.
List<int> diceValues = new List<int>();
diceValues.Add(die.GetTopNumber());
diceValues.Add(die.GetTopNumber1());
diceValues.Add(die.GetTopNumber2());
diceValues.Add(die.GetTopNumber3());
diceValues.Add(die.GetTopNumber4());
Now that you have them in a list, you can do something like:
var values = new Dictionary<int, int>();
foreach(var item in diceValues) {
if(values.Keys.Contain(item)) {
values[item]++;
} else {
values[item] = 1;
}
}
After this loop you will have a list of Dictionary items where a key will be the dice value, and the value the number of dice with that value.
E.g. if someone threw two threes, and two deuces and one four, the dictionary would look:
Key: 2, Value: 2
Key: 3, Value: 2
Key: 4, Value: 1
By iterating through these you can later make a scoring system...
I would remove these properties all along and use a list or array instead.
You declare a list:
public List<int> Roles { get; private set; }
And your roll method can become:
public void roll()
{
this.Roles = Enumerable.Range(1, 5)
.Select(i => RandomNumGenerator.Next(1, 6))
.ToList();
// Check for three of a kind:
bool threeOfAKind = this.Roles.GroupBy(i => i).Any(g => g.Count() >= 3);
// rest of your logic
Console.WriteLine("\tTotal score = {0}", threepoints);
}
Later you can access each individual roll by this.Roles[numOfRoll]

C# Console App -- Trying to access a list from else statement

This is for a data structures and algorithms class. We're just starting out with bubble sort. The instructions were to generate random, unique integers and sort them using the sorting technique of the lecture. It will be required to add different sorting techniques as well.
To generate the list of random numbers, I generated a list and then shuffled the list using the fisher-yates algorithm. So I have my unique, sorted list of whatever size I choose.
I'm getting stuck because after I generate the random list, I am having problems accessing the list to run it through BubbleSort.
Is there any way I can do this?
class Algorithms
{
static void Main(string[] args)
{
string response = "";
//Main Console Menu
while (response != "exit")
{
Console.WriteLine("Type help for list of commands");
response = Console.ReadLine();
//List<int> toSort = new List<int>();
if (response.StartsWith("exit"))
{
Environment.Exit(0);
}
else if (response.ToLower().StartsWith("help"))
{
Help(response);
}
else if (response.ToLower().StartsWith("generate"))
{
// Shuffle(Generate(response));
// have been using the line above but adding next line for
//an idea of my problem
List<int> toSort = Shuffle(Generate(response));
}
else if (response.ToLower().StartsWith("bubble"))
{
//This doesn't work and I'm trying to figure out how it can
BubbleSort(toSort);
}
}
}
//Displays help information
public static void Help(string input)
{
Console.WriteLine("\ngenerate <integer> -- Generates a data set of intended amount of integers\n"+
"algorithm <algorithm type> -- Choose which algorithm to sort data\nexit -- exit application\n" );
}
//Generates List of integers from 0 to number choosen by user
public static List<int> Generate(string size)
{
int cutString = size.Length - 9;
string sizeSubset = size.Substring(9, cutString);
List<int> numGen = new List<int>();
int dataSetSize = Convert.ToInt32(sizeSubset);
for(int i = 0; i <= dataSetSize; i++)
{
numGen.Add(i);
// Console.WriteLine(numGen[i]);
}
return numGen;
}
//Use Fisher-Yates algorithm to shuffle the list.
static Random randomize = new Random();
public static List<int> Shuffle(List<int>makeRandom)
{
List<int> shuffled = new List<int>();
int n = makeRandom.Count;
while (n > 1)
{
n--;
int k = randomize.Next(n + 1);
int value = makeRandom[k];
makeRandom[k] = makeRandom[n];
makeRandom[n] = value;
shuffled.Add(value);
Console.WriteLine(value);
}
return shuffled;
}
public static void BubbleSort(List<int>input)
{
for(int i = 0; i <= input.Count; i++)
{
for (int j = 0; j <= (input.Count - 1); j++)
{
if (input[j] > input[j + 1])
{
int temp = input[j];
input[j] = input[j + 1];
input[j + 1] = temp;
Console.WriteLine("hello");
}
}
}
}
}
}
You defined list in scope of else if (response.ToLower().StartsWith("generate")) code block, so it is not accessible outside of that block. Move declaration to Main method scope, like this:
static void Main(string[] args)
{
string response = "";
//define your list here.
List<int> toSort = new List<int>();
//Main Console Menu
while (response != "exit")
{
Console.WriteLine("Type help for list of commands");
response = Console.ReadLine();
if (response.StartsWith("exit"))
{
Environment.Exit(0);
}
else if (response.ToLower().StartsWith("help"))
{
Help(response);
}
else if (response.ToLower().StartsWith("generate"))
{
toSort = Shuffle(Generate(response));
}
else if (response.ToLower().StartsWith("bubble"))
{
List<int> sortedList = BubbleSort(toSort);
}
}
}

How to calculate number of wins, frequency played and winning percentage

I previously created a program for users to play my NumBaseBall Game. I would like to add three more functionalities to it:
(1) Display the number of wins,
(2) Display the frequency played
(3) Display the player's winning %
I have an external class called GameResults that contains a method for calculating strikes or balls that determines the outcome of the game and another that checks to see if the player wants to play again.
How can I achieve these additional three functionalities without having my cumulative data for each erased each time a new instance of GameResults is created if the user decides to play again?
Here is my working code:
class Program
{
static void Main(string[] args)
{
do
{
PlayBall();
}
while (GameResults.PlayAgain());
}
public static void PlayBall()
{
Console.WriteLine("\t\t\t*************************************");
Console.WriteLine("\t\t\t* Let's Have Fun *");
Console.WriteLine("\t\t\t* Welcome To The *");
Console.WriteLine("\t\t\t* Number Baseball Game *");
Console.WriteLine("\t\t\t*************************************\n");
GameResults gameresults = new GameResults();
for (int trysCounter = 1; trysCounter <= 5; trysCounter++)
{
gameresults.Strikes = 0;
Random r = new Random();
var myRange = Enumerable.Range(1, 9);
var computerNumbers = myRange.OrderBy(i => r.Next()).Take(3).ToList();
Console.WriteLine("The Game's Three Random Integers Are: (Hidden from user)");
foreach (int integer in computerNumbers)
{
Console.WriteLine("{0}", integer);
}
List<int> playerNumbers = new List<int>();
Console.WriteLine("Please Enter Three Unique Single Digit Integers and Press ENTER after each:");
for (int i = 0; i < 3; i++)
{
Console.Write("");
int number = Convert.ToInt32(Console.ReadLine());
playerNumbers.Add(number);
}
gameresults.StrikesOrBalls(computerNumbers, playerNumbers);
Console.WriteLine("-----------------------> Computer's Numbers = {0}{1}{2}", computerNumbers[0], computerNumbers[1], computerNumbers[2]);
Console.WriteLine("-----------------------> Player's Numbers = {0}{1}{2}", playerNumbers[0], playerNumbers[1], playerNumbers[2]);
Console.WriteLine("-----------------------> Game Results = {0} STRIKES & {1} BALLS\n", gameresults.Strikes, gameresults.Balls);
Console.WriteLine("You have tried {0} times\n", trysCounter);
gameresults.TotalStrikes = gameresults.TotalStrikes + gameresults.Strikes;
Console.WriteLine("STRIKES = {0} ", gameresults.TotalStrikes);
if (gameresults.TotalStrikes >= 3)
{
Console.WriteLine("-----------------------> YOU ARE A WINNER!!!");
break;
}
}
if (gameresults.TotalStrikes < 3)
{
Console.WriteLine("YOU LOSE :(");
}
}
}
Here are my external methods:
public void StrikesOrBalls(List<int> computer, List<int> player)
{
for (int c = 0; c < 3; c++)
{
for (int p = 0; p < 3; p++)
{
if (computer[c] == player[p] && computer[c] != player[c])
Balls++;
}
}
if(computer[0]== player[0])
Strikes++;
if(computer[1] == player[1])
Strikes++;
if(computer[2] == player[2])
Strikes++;
}
public static bool PlayAgain()
{
while (true)
{
Console.Write("Do you want to play again [YES/NO]?\n");
string answer = Console.ReadLine().ToUpper();
if (answer == "YES")
return true;
if (answer == "NO")
Console.WriteLine("Thanks for playing NumBaseBall :) Goodbye!");
return false;
}
}

Categories

Resources