C# dice game logic errors - c#

I'm learning C# are I am writing a program that makes an array fills it with 50 random numbers1-6 like dice and then checks how many times each value or 'side' comes up. I made a dice game in python earlier in the week and I had a lot of trouble so I made i= j= and match= print outs to test if the loops and matching were iterating correctly, so I did the same here and I noticed a few logic errors:
the i loop seems to iterate fine but for every 1 iteration of i, j should iterate 50 times but i only get it once.
The i OR j loops don't iterate at all unless in line 47 it states while j > dice.Length. Writing as it should be j < dice.Length makes it not iterate at all. The 50 random numbers display on screen so i know dice is 50 in length and j is 0.
Thirdly in line 50 if dice[i] == dice[j] I get an error that j isn't valid unless I declare j above the for loop, and if I do that I can't do int j = 0 in the for loop, so I scrapped the for loop and did a while loop, but it still only adds a value for the first match and not the next possible 49.
I am only coding inside the static void since it's a simple console application, thank you for your help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace wk8hw2
{
class Program
{
static void Main(string[] args)
{//staticvoid
int size = 50;
int diceSides = 7;
int matchAdd = 0;
int[] dice = new int[size];
int[] match = new int[diceSides];
Random rnd = new Random();
int j = 0;
Console.WriteLine("Press any key to roll the dice " + size + " times.");
Console.ReadKey();
for (int i = 0; i < dice.Length; i++)//roll dice
{
dice[i] = rnd.Next(1, diceSides);
}
for (int i = 0; i < dice.Length; i++)//show dice
{
Console.Write(dice[i] + " ");
}
Console.WriteLine("done showing dice");//DEBUG
for (int i = 0; i < dice.Length; i++)//outer match loop
{
Console.Write("i = " + i);//DEBUG
if (match[dice[i]] == 0)//if not matched add to match array
{
Console.WriteLine("not yet matched");
matchAdd = 1;
}
else//if alerady matched add no more
{
Console.WriteLine("already matched");
matchAdd = 0;
}
j = 0;
while (j > dice.Length)//inner match loopSUPPOSED TRO BE LESS THAN
{
Console.WriteLine("j = " + j);
if (dice[i] == dice[j])//if equal add to match array
{
match[dice[i]] = match[dice[i]] + matchAdd;
Console.WriteLine("val " + match[dice[i]]);
}
j++;
}
}//endFORouter
for (int i = 1; i < match.Length; i++)
{
Console.WriteLine(i + " came up " + match[i] + " times.");
}
Console.ReadKey();
}//endstaticvoid
}
}

I agree with the first answer however...you said you are learning C# and based on the namespace this is a homework assignment and you are most likely learning about arrays so I would rewrite it a bit different
You seem to be doing way to many loops and generally doing to much. Make your code as simple as possible and name your variables to tell anyone reading the code what they do.
int numberOfRolls = 50;
int diceSides = 6;
int[] dice = new int[numberOfRolls];
int[] match = new int[diceSides];
Random random = new Random();
Console.WriteLine("Press any key to roll the dice " + numberOfRolls + " times.");
Console.ReadKey();
for (int rollCount = 0; rollCount < numberOfRolls; rollCount++)
{
var rollResult = random.Next(1, diceSides+1);
match[rollResult-1]++;
}
for (int i = 0; i < match.Length; i++)
{
Console.WriteLine(i+1 + " came up " + match[i] + " times.");
}
Console.ReadKey();

I'd rewrite this whole thing as:
Random rnd = new Random();
const int diceSides = 6;
const int numDice = 50;
Console.WriteLine("Press any key to roll the dice {0} times.", numDice);
Console.ReadKey();
var diceByValue = Enumerable.Range(0, numDice)
.Select(_ => rnd.Next(diceSides) + 1)
.GroupBy(v => v)
.OrderBy(g => g.Key);
foreach (var group in diceByValue)
Console.WriteLine("{0} came up {1} times.", group.Key, group.Count());

Related

Count the number of occurrences in an array with random numbers without methods or list in C#

I am trying to solve an exercise in C# as follows:
Write a program that generates 20 random integers between 0 and 9 and displays the count for each number.
Use an array of ten integers, say counts, to store the counts for the number of 0s, 1s, ..., 9s.)
This is what i come up with which kind of work but i have a problem with the 0's counting 1 extra all the time.
using System.Collections.Generic;
using System.Text;
namespace ArrayExercises
{
class TaskFive
{
public static void FindNumberCount()
{
int c0=0,c1=02,c2=0,c3=0,c4=0,c5=0,c6=0,c7=0,c8=0,c9=0;
int[] arr = new int[20];
Random rand = new Random();
Console.WriteLine("Numbers generated ");
for (int i = 0; i < 19; i++)
{
arr[i] = rand.Next(0, 10);
Console.WriteLine(arr[i]);
}
foreach(int number in arr)
{
if (number == 0) { c0++; }
else if (number == 1) { c1++; }
else if (number == 2) { c2++; }
else if (number == 3) { c3++; }
else if (number == 4) { c4++; }
else if (number == 5) { c5++; }
else if (number == 6) { c6++; }
else if (number == 7) { c7++; }
else if (number == 8) { c8++; }
else if (number == 9) { c9++; }
}
Console.WriteLine
(
$"Number of 0's: {c0} \n" +
$"Number of 1's: {c1} \n" +
$"Number of 2's: {c2} \n" +
$"Number of 3's: {c3} \n" +
$"Number of 4's: {c4} \n" +
$"Number of 5's: {c5} \n" +
$"Number of 6's: {c6} \n" +
$"Number of 7's: {c7} \n" +
$"Number of 8's: {c8} \n" +
$"Number of 9's: {c9}"
);
}
}
}
Thanks in advance :)
You could shorten it like this
public static void FindNumberCount()
{
int[] count = new int[10];
Random rand = new Random();
int[] arr = new int[20];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = rand.Next(0, 10);
Console.WriteLine(arr[i]);
count[arr[i]]++;
}
for (int i = 0; i < count.Length; i++)
{
Console.WriteLine($"Number of {i}'s: {count[i]}");
}
}
If you want draw 20 numbers you should for (int i = 0; i < 20; i++) not 19.
int[] counts = new int[10];
int[] numbers = new int[20];
var random = new Random();
for (int i = 0; i < numbers.Length; i++)
{
// Generate random numbers
numbers[i] = random.Next(0, 9);
// Increment the count of the generated number
counts[numbers[i]]++;
}
the for loop you use loops only 19 times.
You must change the "i < 19" to "i < 20".
In your program, the for loop leaves the last int in the array at it's default value (0),
this also explains, why you always have one more zero.
Hope this helped.
The issues is in this line
for (int i = 0; i < 19; i++)
You initialized an array with 20 int and set only value to 19 of them.
If you don't set the value int defaults to Zero and hence you always get one extra zero
Change your code as below
for (int i = 0; i <= 19; i++)
The halting condition of the first for loop should be i<20. Then your program should work.
This is how I would solve it:
static void Main(string[] args)
{
Random random = new Random();
//Fill array with random numbers
int[] array = new int[20];
for (int i = 0; i < array.Length; i++)
array[i] = random.Next(0, 10);
//Count how many times a number occurs
int[] numberCounts = new int[10];
for (int i = 0; i < array.Length; i++)
numberCounts[array[i]]++;
//Print the count of the numbers
for(int i = 0; i < numberCounts.Length; i++)
Console.WriteLine("Number of " + i + "'s: " + numberCounts[i]);
//Keep the console open
Console.ReadLine();
}

Bubble sorting issues

Im currently writing code to sort an array through bubble sort. I've previously written it using a set array that i created and it worked perfectly. However, i tried to change it to a randomly generated array and its now broken. wondered if anyone could give me a hand. thanks in advance.
using System;
namespace BubbleSot_Fin
{
class Program
{
static void Main(string[] args)
{
int N = 5;
int m = 100;
int i = 1; //n = number of values m = max value in array
Random Rand = new Random();
int[] array = new int[N + 1];
for ( i = 1; i <= N; i++)
{
array[i] = Rand.Next(1, m); //Randomise the array
Console.WriteLine("This is the unsorted array");
Console.WriteLine("");
for (i = 0; i < array.Length; i++)
{
Console.WriteLine("A[" + i + "] = " + array[i] ); // shows the unsorted numbers
}
int[] Bubble = BubbleSort(array);
Console.WriteLine("");
Console.WriteLine("Array after Bubble Sort");
Console.WriteLine("");
for ( i = 0; i < Bubble.Length; i++)
{
Console.WriteLine("A[" + i + "] = " + Bubble[i]); // shows the numbers after sorting
}
Console.ReadLine();
}
private static int[] BubbleSort(int[] BSArray)
{
int length = array.Length;
for ( i = 0; i < length - 1; i++)
{
for (int j = 0; j < length - 1 - i; j++)
{
if (array[j] > array[j + 1])
{
int number = array[j];
array[j] = array[j + 1];
array[j + 1] = number;
}
}
}
return BSArray;
}
}
}
The errors i'm having are that the private and static word for the bubble sort are incorrect.
The errors are :
- CS0106 The modifier 'Private' is not valid for this item
- CS0106 The modifier 'Static' is not valid for this item

Comparing arrays without using linq

I am making a lottery game that asks the user for 10 numbers and then check it against random numbers that i have created in an array. I need to compare the two but I am not allowed to use the contains method.
I think I need to use a foreach loop to compare the arrays but really I am at a loss of what to do. I have been piecing it together from the little I know and would like to know if I am on the right track.
Is a foreach loop the correct way to compare the two arrays?
This is my code so far.
using System;
namespace lotto2
{
class Program
{
static void Main(string[] args)
{
//an array named "input" to hold the users' 10 guesses
int[] inputs = new int[10];
//an array named "lotNum" to hold 10 random numbers
int[] lotNums = new int[10];
//a for loop to loop over the inputs array. each loop will ask the user for a number
Console.WriteLine("Enter your 10 lottery numbers one at a time. The numbers must be between 1 and 25.");
for (int i = 0; i < inputs.Length; i++)
{
inputs[i] = Convert.ToInt32(Console.ReadLine());
}
//a random number generator
Random ranNum = new Random();
//loop to call the random generator 10 times and store 10 random numbers in the "lotNum" array
for (int i = 0; i < 10; i++)
{
lotNums[i] = ranNum.Next(1, 26); //chooses random numbers between 1 and 25
}
//writes out the randomly generated lotto numbers
Console.Write("\nThe lottery numbers are: ");
for (int i = 0; i < 10; i++)
{
Console.Write("{0} ", lotNums[i]);
}
//loop for checking users inputs against random generated numbers..
//foreach loop maybe?
foreach (var input in lotNums)
{
}
//print out if there are any matches, which numbers matched
//declared integer for the correct numbers the user guessed
int correct;
//end progam
Console.WriteLine("\n\nPress any key to end the program:");
Console.ReadKey();
}
}
}
Here's a program that correctly does what you want. It even ensures that you don't have duplicate lotto numbers.
void Main()
{
const int count = 10;
const int max = 25;
//an array named "input" to hold the users' 10 guesses
int[] inputs = new int[count];
//a for loop to loop over the inputs array. each loop will ask the user for a number
Console.WriteLine("Enter your {0} lottery numbers one at a time. The numbers must be between 1 and {1}.", count, max);
for (int i = 0; i < inputs.Length; i++)
{
inputs[i] = Convert.ToInt32(Console.ReadLine());
}
//a random number generator
Random ranNum = new Random();
//an array named "allNums" to hold all the random numbers
int[] allNums = new int[max];
for (int i = 0; i < allNums.Length; i++)
{
allNums[i] = i + 1;
}
//shuffle
for (int i = 0; i < allNums.Length; i++)
{
int j = ranNum.Next(0, allNums.Length);
int temporary = allNums[j];
allNums[j] = allNums[i];
allNums[i] = temporary;
}
//an array named "lotNum" to hold 10 random numbers
int[] lotNums = new int[count];
Array.Copy(allNums, lotNums, lotNums.Length);
//writes out the randomly generated lotto numbers
Console.Write("\nThe lottery numbers are: ");
for (int i = 0; i < lotNums.Length; i++)
{
Console.Write("{0} ", lotNums[i]);
}
int correct = 0;
Console.Write("\nThe correct numbers are: ");
for (int i = 0; i < lotNums.Length; i++)
{
for (int j = 0; j < inputs.Length; j++)
{
if (lotNums[i] == inputs[j])
{
Console.Write("{0} ", lotNums[i]);
correct++;
};
}
}
Console.Write("\nYou got {0} correct. ", correct);
Console.WriteLine("\n\nPress any key to end the program:");
Console.ReadLine();
}
You're on the right way.
My implementation would be:
foreach (var input in inputs)
{
for (int i = 0; i < lotNums.Length; i++){
if(input == lotNums[i]){
Console.WriteLine(lotNums[i]);
}
}
}
This will compare every number of the input array with the lottery array.
I'm printing every match, but you can set a variable to True if it finds a match or add every matching number into an array if you need it.
This is what I have tried.I hope it makes sense?
static void LottoMethod(int[] randNums,int[] userNums)
{
Console.WriteLine("Guess 10 numbers");
for(int i = 0; i <= userNums.Length-1; i++)
{
userNums[i] = Int32.Parse( Console.ReadLine());
}
Console.WriteLine("The numbers you entered: ");
foreach(int k in userNums)
{
Console.Write(k+" ");
}
//generate 10 numbers randomly
Random rnds = new Random();
for(int k = 0; k <= randNums.Length - 1; k++)
{
randNums[k] = rnds.Next(1, 26);
}
Console.WriteLine("Random Numbers");
foreach(int i in randNums)
{
Console.Write(i + " ");
}
int correctNums = 0;
//Check if random numbers correspond with entered numbers
try
{
for(int i = 0; i <= randNums.Length-1; i++)
{
for(int j = 0; j <= userNums.Length-1; j++)
{
if (randNums[i] == userNums[j])
{
correctNums++;
}
}
}
Console.WriteLine($"There are {correctNums} numbers ");
}
catch(Exception e) {
throw new Exception(e.ToString());
}
}
You have to calculate intersection of two sequences. You have three options:
Double foreach loop. This is something to avoid as it has time complexity O(m*n). It it not a problem for 10 items, but we should make programs that scale.
Using hash join. You can use HashSet for this and it would be my preferred method. But as it inherently implies using Contains, it is not the option here.
Merging sorted sequences. This would be the way to go here.
The program is rather self explanatory, it produces and intersects two random sequences.
static Random rnd = new Random((int)DateTime.Now.Ticks);
static int[] GetRandomArray(int arrSize, int minNumber, int maxNumber)
{
int[] tmpArr = new int[maxNumber - minNumber + 1];
for (int i = 0; i < tmpArr.Length; ++i)
{
tmpArr[i] = i + minNumber; // fill with 1, 2, 3, 4,...
}
int[] ret = new int[arrSize];
for (int i = 0; i < ret.Length; ++i)
{
int index = rnd.Next(tmpArr.Length - i); //choose random position
ret[i] = tmpArr[index];
tmpArr[index] = tmpArr[tmpArr.Length - 1 - i]; //fill last of the sequence into used position
}
return ret;
}
static IEnumerable<int> GetMatches(int[] a, int[] b)
{
Array.Sort(a);
Array.Sort(b);
for (int i = 0, j = 0; i < a.Length && j < b.Length;)
{
if (a[i] == b[j])
{
yield return a[i];
++i;
++j;
}
else if (a[i] > b[j])
{
++j;
}
else
{
++i;
}
}
}
static void Main(string[] args)
{
var a = GetRandomArray(5, 3, 7);
var b = GetRandomArray(10, 1, 25);
Console.WriteLine("A: " + string.Join(", ", a));
Console.WriteLine("B: " + string.Join(", ", b));
Console.WriteLine("Matches: " + string.Join(", ", GetMatches(a, b)));
Console.ReadKey();
}
The result is something like:
A: 7, 4, 6, 3, 5
B: 17, 1, 8, 14, 11, 22, 3, 20, 4, 25
Matches: 3, 4
You can think about what would happen if one or both of the sequences contain duplicities.

How to get an element from list of list

I wrote program and I used in that program a list of lists (in int type).
Every list in the big list stores a different number of integers but when I try to approach those integers and use them for division I don't know how.
That's the program:
Console.WriteLine("How many students in the class?");
int students = int.Parse(Console.ReadLine());
List<List<int>> studentsclass = new List<List<int>>();
for (int i = 0; i < students; i++)
{
Console.WriteLine("How many jumps student number " + (i + 1) + " did?");
int studentjumps = int.Parse(Console.ReadLine());
Console.WriteLine("Write student number " + (i+1) + " high jumps: ");
List<int> jumps= new List<int> (studentjumps);
for (int j = 0; j < studentjumps; j++)
{
jumps.Add(int.Parse(Console.ReadLine()));
}
}
for (int k = 0; k < studentsclass.Count; k++)
{
int sum = 0;
for (int m = 0; m < studentsclass[m].Count; m++)
{
(That is a program that calculates student's average high jumps).
The rest of the code should be: sum = sum\index M of index K of the list.
Edit:
I continued my code and then when it came to the division part I've got lots of errors.
this is what I wrote:
for (int k = 0; k < studentsclass.Count; k++)
{
double sum = 0;
for (int m = 0; m < studentsclass[m].Count; m++)
{
sum = sum + studentsclass[k][m];
}
sum = (double)sum \ studentsclass[m]; \\<-- Error
Console.WriteLine("student number " + (k + 1) + " did an average of " + sum + " meter high jumps");
}
simply use.
studentsclass[k][m]
to access the inner list
and use
studentsclass[k].Count
in your second for loop
Using LINQ you can do somthing like the following to get your desired result:
var result = studentsclass.Select((l, i) => new { Id = i, Average = l.Average() });
See THIS fiddle.

updating variable from inside a loop?

I'm writing a mastermind game and I need to update the value of an array size using a variable inside a while loop which increments on each loop is there any way i can do this?
bool game = false;
do
{
int codeSize;
int colourSize;
int guessNumber = 1;
int userGuess;
int black = 0;
int white = 0;
int count = 1;
Console.WriteLine("Welcome to Mastermind coded by ****");
Console.Write("How many positions > ");
codeSize = Convert.ToInt32(Console.ReadLine());
Console.Write("How many colours > ");
colourSize = Convert.ToInt32(Console.ReadLine());
Random rand = new Random();
int[] code = new int[codeSize];
int[] guess = new int[codeSize];
for (int i = 0; i < codeSize; i++)
{
code[i] = rand.Next(1, colourSize + 1);//filling the secret code array
}
Console.WriteLine("O.k. - I've generated a code -- guess it!");
while (black < codeSize)
{
int[,] history = new int[count, codeSize + 2];
Console.WriteLine("Next guess please.");
for (int n = 0; n < codeSize; n++)
{
Console.Write("Position " + guessNumber + " >");
userGuess = Convert.ToInt32(Console.ReadLine());
guess[n] = userGuess;
history[count - 1, n] = guess[n];
guessNumber++;
}
for (int x = 0; x < codeSize; x++)
{
int caseSwitch = 1;
switch (caseSwitch)
{
case 1:
{
if (guess[x] == code[x])
{
black++;
break;
}
goto case 2;
}
case 2:
{
if (guess[x] == code[x])
{
break;
}
int i = 0;
while (i < codeSize)
{
if ((guess[x] == code[i]) && (guess[i] != code[i]))
{
white++;
break;
}
i++;
}
break;
}
}
}
guessNumber = 1;
if (black == codeSize)
{
white = 0;
}
history[count - 1, codeSize + 1] = white;
history[count - 1, codeSize] = black;
count++;
Debug.WriteLine("-----------\nSecret code\n-----------");
for (int x = 0; x < codeSize; x++)
{
Debug.WriteLine(code[x]);
}
Console.WriteLine("Correct positions : {0}", black);
Console.WriteLine("Correct colours : {0}\n", white);
Console.WriteLine("History");
for (int t = 1; t < codeSize + 1; t++)
{
Console.Write(t + " ");
}
Console.WriteLine("B W");
for (int g = 0; g < codeSize + 3; g++)
{
Console.Write("--");
}
Console.Write("\n");
for (int t = 0; t < count - 1; t++)
{
for (int g = 0; g < codeSize + 2; g++)
{
Console.Write("{0} ", history[t, g]);
}
Console.WriteLine("\n");
}
if (codeSize > black)//reseting values for next turn
{
black = 0;
white = 0;
}
}
int play;
Console.WriteLine("\nYou Win!\n\nPress 1 to play again or any other number to quit");
play = Convert.ToInt32(Console.ReadLine());
if (play == 1)
game = true;
} while (game == true);
Arrays have a fixed size when you declare them and you cannot change the size afterwards without creating a new array. Try using a strongly typed List instead.
List<int> MyList = new List<int>();
// Add the value "1"
MyList.Add(1);
or the following for a table:
List<List<int>> MyTable = new List<List<int>>();
// Add a new row
MyTable.Add(new List<int>());
// Add the value "1" to the 1st row
MyTable[0].Add(1);
I believe you are asking whether you can change the length property of an array from within a loop, extending it as required.
Directly, no. There are helpers and classes which provide for such functionality, allocating more memory as needed, but I doubt this is what you really need. You could try using an array of fixed dimensions (the maximum codeSize your program will tolerate or expect), and then an integer next to it to record the length/position.
Alternatively, if you really need to expand to arbitrary sizes and store all codes, just use a List.
List<int[]> theList = new List<int[]>();
theList.Add(code);
Creates a list of integer arrays (your codes) that you can keep adding onto, and index just like any simple array.
There is a way to resize array size:
Array.Resize<T>
method. Details there: http://msdn.microsoft.com/en-us/library/bb348051(v=vs.110).aspx
But it's usually a pretty bad idea to resize the arrays loop based. You need to select another data structure to save your data or i.e. create an array of bigger size filled i.e. with zeroes.
You also need to add the items to the list as so. The list will dynamically grow based on it's size.
int myInt = 6;
List<int> myList = new List<int>();
myList.Add(myInt);

Categories

Resources