I'm working on a project in C# that involves keeping track of the top five high scores for a rock paper scissors game. Right now I have an array to hold the top five scores (which are integers), I sort the array in descending order, and I use a for loop to compare the score just earned by the user to the scores currently in the array. If the new score is higher than one in the array, right now the new score just takes the space in the array that the lower one occupied.
For example, if the scores were 9, 8, 5, 3, 1 and the user scored a 6, the scores would then look like this: 9, 8, 6, 3, 1. I wondered if there's a way for me to shift the lower scores over and insert the new one, so the list would look like this: 9, 8, 6, 5, 3.
This is the code I currently have, where successPercent is the score, calculated as wins divided by losses and ties:
int[] scoreArray = { 84, 25, 36, 40, 50 };
Array.Sort(scoreArray);
Array.Reverse(scoreArray);
for (int x = 0; x <= scoreArray.Length; ++x)
{
if (successPercent > scoreArray[x])
{
scoreArray[x] = Convert.ToInt32(successPercent);
break;
}
}
Something like this can do the trick:
Create temporary list
Add new score
Sort it by descending order
Take top 5...
int[] scoreArray = { 84, 25, 36, 40, 50 };
var tempList = new List<int>(scoreArray );
int newScore = ...;//Get the new score
tempList.Add(newScore);
scoreArray = tempList.OrderByDescending(x=>x)
.Take(5)
.ToArray();
You can do this without creating a new list.
[Algo]: Replace the smallest number by the new number and then sort!
int[] scoreArray = { 5, 3, 9, 8, 1 };
int new_number = 6;
//Replaces smallest number by your new number
int min_index = Array.IndexOf(scoreArray, scoreArray.Min());
scoreArray[min_index] = new_number;
Array.Sort(scoreArray);
Array.Reverse(scoreArray);
I believe your way is correct and more effient than creating redundant lists, just you are calling the Reverse method unnecessarily.Instead, leave your elements sorted in ascending order, then loop through the array, and sort it in descending order.
int[] scoreArray = { 84, 25, 36, 40, 50 };
int userScore = 100;
Array.Sort(scoreArray);
for (int x = 0; x <= scoreArray.Length; ++x)
{
if (userScore > scoreArray[x])
{
scoreArray[x] = Convert.ToInt32(userScore);
break;
}
}
Array.Sort(scoreArray,(x,y) => y.CompareTo(x));
Note: My first solution was throwing away the second highest score so I have deleted it.
Related
I am trying to create an array based on the ones that I have. I have two arrays which look like this
sample array A: {AB01, AB01, AB01, AB02, AB02, AB02, AB03, AB01}
sample array B: {10, 10, 20, 10, 20, 20, 40, 10}
Both arrays are dynamic so provided data is just a sample data. Same indexes in both arrays creates a pair: so for example: pair 1: AB01 10 , pair 2: AB01 10 and so on. Based on those two arrays I want to create third array which will represent indexes but including duplicates. So I want my third array to look like this:
array (3) C: {10, 10, 20, 30, 40, 40, 50, 10}
FYI I cannot use LINQ 4+
I tried nested loop over the arrays but I do not get the expected result.
for(int i = 0; i < arrayA.Length; i++){
for(int j = i + 1; j < arrayA.Length; j++){
if(arrayA[i] == arrayA[j] && arrayB[i] == arrayB[j]){
arrayC.Insert(i, 10 * (i+1));
}
else
arrayC.Insert(i, 10 * (i+2));
}
}
As I mentioned I expext my array C to be indexes of each element but I want to include duplicates:
array (3) C:
{10, 10, 20, 30, 40, 40, 50, 10}
EDIT:
As the result is not clear.
If there was no duplicates in the arrays I would want my array C to look like this:
{10, 20, 30, 40, 50, 60, 70, 80}
It means that each pair eg(AB01, 10) will be given index 10 in array C.
But when it comes to duplicates array C will look different.
Pair AB01 - 10 appears as first so I want to give it index 10. And because it appears three times at position: 0, 1 and 7 I want number 10 to be at those positions in array C. Next on I have pair AB01 - 20 it appears only one time at position 2 and values are different than in pair to so I want to give it index 20. And so on.
As written in the comments, a re-formulation of the task is:
for each pair, if it has been encountered before, use the already
allocated "index", otherwise create a new one as (previous index) +
10.
You need to remember the already assigned indexes, e.g. in a Dictionary<(string, int), int>, mapping a pair to the index. In addition. you need to keep track of the highest index assigned so far.
var arrayA = new string[] { "AB01", "AB01", "AB01", "AB02", "AB02", "AB02", "AB03", "AB01"};
var arrayB = new int[] {10, 10, 20, 10, 20, 20, 40, 10};
var assignedIndexes = new Dictionary<(string, int), int>();
var highestIndex = 0;
var result = new int[arrayA.Length];
for (var i = 0; i < arrayA.Length; i++)
{
var tuple = (arrayA[i], arrayB[i]);
if (!assignedIndexes.TryGetValue(tuple, out var index))
{
index = highestIndex + 10;
assignedIndexes.Add(tuple, index);
highestIndex = index;
}
result[i] = index;
}
Console.WriteLine(string.Join(", ", result));
Prints: 10, 10, 20, 30, 40, 40, 50, 10
If you cannot use ValueTuples, too, replace them by Tuples:
var assignedIndexes = new Dictionary<Tuple<string, int>, int>();
var tuple = Tuple.Create(arrayA[i], arrayB[i]);
I am currently following a tutorial on making a game in Unity using C#. In it, they showed us how to show the score in the center of the screen using
using UnityEngine;
using UnityEngine.UI;
public class Score : MonoBehaviour
{
public Transform player;
public Text scoreText;
// Update is called once per frame
void Update()
{
scoreText.text = player.position.z.ToString("0");
}
}
However, I want to go further and figure out how to make a high score list in the top left corner. My only experience is with python so I know I would go about making an empty array of size 10, and then each time the game restarts, if the score is greater than any of the highest 10 scores in the mentioned list, it is inserted in the corresponding position (keeping the elements ordered), and the lowest value is dropped from the list (to keep a list of just 10 elements). However, I am confused about the syntax of C#.
Currently, my thought process for the code (which would go on my restart statement), if it were python is this
##this is how I would write it in python I believe
array = np.zeros[10]
for i in range(0, len(array)):
if player.position.z.ToString("0") < array[-i]
continue
else:
array[-i-1] = player.position.z.ToString("0")
Where obviously the player.position statement is from c#. I was wondering if anyone could help me translate the thought process over. It seems I need to declare an array of strings before I can use it but I am not sure.
Thanks for any help
As I understood you want an array with 10 elements where you store the top 10 scores. So each new score which is higher than the existing top 10 is placed in the correct position of that top 10.
Something like
current Top10 => 2, 3, 5, 7, 8, 9, 12, 15, 18, 20
newScore = 16
new Top10 => 3, 5, 7, 8, 9, 12, 15, 16, 18, 20
Option 1:
string[] scoreArray = new string[10];
//Initializing the score array
for (int i = 0; i < 10; i++)
{
scoreArray[i] = 0;
}
//Somewhere in your code a new score will be assigned to this variable
int newScore;
//Checking potentially higher score
boolean replaceFlag = false;
for (int i = 0; i < 10; i++)
{
if(newScore > scoreArray[i])
{
replaceFlag = true;
}else{
//newScore lower than lowest stored score
if(i == 0)
{
//Stop the loop
i = 11;
}else if(replaceFlag){
//The rest of the elements in the array move one position back
for(int j = 0 ; j < i-1; j++ )
{
scoreArray[j] = scoreArray[j+1];
}
//Finally we insert the new score in the correct place
scoreArray[i-1] = newScore;
}
}
}
Option 2: Using List
//Create and initialize list of scores
List<int> listScores = new List<int>{ 0,0,0,0,0,0,0,0,0,0};
// If later, at some point we have the following scores 2, 3, 5, 7, 8, 9, 12, 15, 18, 20
//When you get a new score (our list will have)
listScores.Add(newScore);
//After inserting 2, 3, 5, 7, 8, 9, 12, 15, 18, 20, 16
//Ordering the list in descending order
listScores.Sort()
//Now we have 2, 3, 5, 7, 8, 9, 12, 15, 16, 18, 20,
//Drop last element of the list to keep the fixed size of 10.
listScores.RemoveAt(0)
//Now we have 3, 5, 7, 8, 9, 12, 15, 16, 18, 20
//In case you want to have the list in descending order
listScores.Sort((a, b) => -1* a.CompareTo(b));
if Score is the array, then add the scores to this Score array variable and then sort and reverse this array whenever u want to update the high score.
private void UpdateScore(int[] ScoreArray)
{
Array.Sort(ScoreArray);
Array.Reverse(ScoreArray);
}
You would create a known array size of 10 like this:
string[] aStringArray = new string[10];
Also add this at top;
using System.Collections.Generic;
Arrays - C# Programming Guide
Array must have length, if you want unknown size then use List
List<int> player = new List<int>();
player.Add(1);
I have an array like this
int[] intnumber = new int[]{10,25,12,36,100,54,68,75,63,24,1,6,9,5};
I want to find the greatest number and make it In order from largest to smallest
like this
100,75,68,63,54,36,25,24,12,10,9,6,5,1
int[] intnumber = new int[] { 10, 25, 12, 36, 100, 54, 68, 75, 63, 24, 1, 6, 9, 5 };
int maxValue = intnumber.Max();
You can sort the array for viewing elements in ascending order
Array.Sort(intnumber);
Array.Reverse(intnumber);
foreach (var str in intnumber )
{
MessageBox.Show(str.ToString());
}
Try this,
int[] intnumber = new int[] { 10, 25, 12, 36, 100, 54, 68, 75, 63, 24, 1, 6, 9, 5 };
//Maximum Value
int maxValue = intnumber.Max();
//Maximum Index
int maxIndex = intnumber.ToList().IndexOf(maxValue);
You can use :
int[] intnumber = new int[]{10,25,12,36,100,54,68,75,63,24,1,6,9,5};
Array.Sort(intnumber );
Array.Reverse(intnumber );
int max = intnumber[0];
exactly output that you want.
int[] intnumber = new int[] { 10,25,12,36,100,54,68,75,63,24,1,6,9,5 };
Array.Sort<int>(intnumber ,
new Comparison<int>(
(i1, i2) => i2.CompareTo(i1)
));
intnumber .Dump();
P.S. To run this demo you need to follow these steps:
1.Download LINQPad.
2.Download the demo file, open it with LINQPad and hit F5.
I found my answer with your helps
Console.WriteLine("How many Numbers Do you want? ");
int counter = int.Parse(Console.ReadLine());
double[] numbers = new double[counter];
for (int i = 0; i < numbers.Length; i++)
{
Console.Write((i + 1) + " : ");
numbers[i] = Convert.ToDouble(Console.ReadLine());
}
Console.WriteLine("_______________________________________________");
Array.Sort(numbers);
Array.Reverse(numbers);
foreach (double item in numbers)
{
Console.WriteLine(item);
}
Console.WriteLine("_______________________________________________");
Console.WriteLine("The Greatest Number is " + numbers[0]);
Console.ReadKey();
Let intNumbers be the array that you are using, Then you can use the .Max() method of the Array Class to get the maximum value, that is the greatest number. If you want to Sort the Current array means You have to use the .Sort() method. The requirement is simply Printing the Array in descending order means you have to use the .OrderBy()
int[] inputNumbers = new int[] { 15, 12, 11, 23, 45, 21, 2, 6, 85, 1 };
Console.WriteLine("Input Array is : {0}\n",String.Join(",",inputNumbers.OrderByDescending(x=>x)));
Console.WriteLine("Max value in the array is : {0}\n",inputNumbers.Max());
Console.WriteLine("Array in descending order : {0}\n",String.Join(",",inputNumbers.OrderByDescending(x=>x)));
Here is a working Example
int max = Integer.MIN_VALUE;
for (int i =0; i < intnumber.length; i++)
{
int num = intnumber[i];
//Check to see if num > max. If yes, then max = num.
}
System.out.println(max);
This is homework assignment for school, but I'm begging for someone to just correct my code. I've been working at this for two days and I think I have everything worked out except I can't get it to work as a 2D Array, so I set this up temporarily just to try to figure things out, but I'm digging myself deeper into a hole I think.
The assignment requires that two dice be rolled 36,000 times and then the results for each sum be displayed on the right, and the sum of the two dice on the left, like this in a 2D array:
12 850
11 1020
10 1200
...
2 900
I've got the right column displaying correctly, but the left column won't display the sums, it just displays "System.Int32[]" a bunch of times.
Here's the code:
Random rand = new Random();
const int ARRAY_SIZE = 13;
const double DICE_ROLLS = 36000;
int sum = 0;
int die1 = 0;
int die2 = 0;
int[] sums = new int[ARRAY_SIZE];
int[] dice = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < DICE_ROLLS; i++ )
{
die1 = rand.Next(1, 7);
die2 = rand.Next(1, 7);
sum = die1 + die2;
sums[sum] += 1;
}
for (int i = 2; i < sums.Length; i++)
{
Console.WriteLine("{0,2} {1,8}", dice, sums[i]);
}
In the spirit of the homework assignment, rather than fixing the code outright, I will try to explain the parts you need to fix, and let you do the actual fixing.
The primary issue in your code is that you are trying to print dice as the value for the left column of the output, rather than individual elements of dice (e.g. dice[i]).
Note, however, that you can't just use dice[i], because your dice array has fewer elements in it than the sums array. If you just replaced dice with dice[i] in your WriteLine() statement, you'd get an index-out-of-bounds exception.
IMHO, the best way to address this is to initialize sums with 11 elements instead of 13, and then when tracking the sums (i.e. in your first loop), subtract 2 from the actual sum value to get the index for the sums array:
sums[sum - 2] += 1;
Then in your second loop, you can safely just use i to index both arrays.
I hope that helps. Please feel free to ask for any clarifications and good luck with your assignment.
Since you'll be using a 2d array you'll want to do something like this:
var rand = new Random();
const double diceRolls = 36000;
var sums = new[,] {{2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, {12, 0}};
for (var i = 0; i < diceRolls; i++)
{
var die1 = rand.Next(1, 7);
var die2 = rand.Next(1, 7);
var sum = die1 + die2;
sums[sum - 2, 1] += 1;
}
for (var i = 0; i < sums.GetLength(0); i++)
{
Console.WriteLine("{0,2} {1,8}", sums[i, 0], sums[i, 1]);
}
Note 1: sum - 2. Since the array length is only 11 you need to subtract 2 from the dice value. (0-10 instead of 2-12).
Note 2: sums.GetLength(0). If you use sums.Length you'll get 22 since there actually are 22 elements in the array. You need to get the length for rank 0
Note 3: Since you're dealing with 2d arrays you'll have the sum of the dice roll in sum[i, 0] and the total count in sum[i, 1].
So...
I have two lists. One is created by adding numbers 1-48 into it. The other one is empty at the beginning:
int max = 35;
int[] Numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
47, 48};
List<int> allNumbers = new List<int>();
List<int> newNumbers = new List<int>();
I use this method to fill up the allNumbers list:
for (int i = 0; i < Numbers.Length - 1; i++)
{
allNumbers.Add(Numbers[i]);
}
My application is supposed to select a random item in the allNumbers list and add it to the newNumbers list:
Random r = new Random();
int now;
for (int i = 1; i < max; i++)
{
now = r.Next (1, allNumbers.Count);
allNumbers.Remove(now);
newNumbers.Add(now);
This works (as in it doesn't crash or anything) but it doesn't remove the random number, i.e. I usually get the same number in my newNumbers list more than once (e.g. I could get 11, 4, 5, 5, 11, 27, 33, 4 etc.).
This is supposed to be a game somewhat similar to lottery so there can't be any double numbers. How would I go about to select a random list item from the allNumbers list, add it to the newNumbers list and then remove it from the allNumbers list? So that when the for loop goes through it again, the allNumbers.Count would be smaller by 1 and the number I previously selected is not in the allNumbers list any more.
Any help appreciated!
That is because you are selecting a random index, removing the value at that index and then adding that index as a value to the newNumbers list.
Using this snippet should fix it:
for (int i = 0; i < max; i++)
{
now = r.Next(0, allNumbers.Count);
newNumbers.Add(allNumbers[now]);
allNumbers.RemoveAt(now);
}
The problem is that you are adding the number generated by the Random.Next method, instead of the content of the list on the random index.
replace your code with:
newNumbers.Add(allnumbers[now]);
That should do the trick.
First of all the method you use to fill the allNumbers list is to much effort for something that can be done using the ToList() method on the array and assign it to allNumbers, like this:
List<int> allNumbers = Numbers.ToList();
The use the random to take the index from the list and add the value of the item at that index and insert it into the newNumbers list. Then you can use the index to remove it from the allNumbers list.
int index;
for (int i = 0; i < max; i++)
{
index = r.Next (0, allNumbers.Count);
newNumbers.Add(allNumbers[index]);
allNumbers.RemoveAt(index);
}
You're randomizing an index with now = r.Next(allNumbers.Count);, then you try removing this index as a value. Change the above line (the index starts at 0!) and use the RemoveAt method instead of Remove.
the now variable represents an index (a position) inside the list of numbers.
So you need to retrieve the number corresponding to this index, using the [] operator.
Then you can add this number to newNumbers list, and after you can remove the same number from allNumbers using the RemoveAt method, passing the index as parameter.
for (int i = 0; i < max; i++)
{
now = r.Next(0, allNumbers.Count);
newNumbers.Add(allNumbers[now]);
allNumbers.RemoveAt(now);
}
If you prefer, you can also use the Remove method, passing the number to remove as parameter, and not the index.
allNumbers.Remove(allNumbers[now]);
be careful with the indexes, in C# they start from 0.