C# Method returning array issue - c#

class Program
{
public static void Main()
{
double[,, ] stats = new double[3, 2, 10];
string[] players = new string[3];
int x, y, z;
players[0] = "Tom Brady";
players[1] = "Drew Brees";
players[2] = "Peyton Manning";
for (x = 0; x < 3; ++x)
{
Console.WriteLine("Enter stats for {0}", players[x]);
for (y = 0; y < 2; ++y)
{
Console.WriteLine("Game {0}", y + 1);
stats[x, y, z] = ***inputstats(stats[x, y, z])***;
}
}
}
public static double[] inputstats(double[] methodstats)
{
methodstats = new double[10];
Console.WriteLine("Enter pass attempts: ");
methodstats[0] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter completions: ");
methodstats[1] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter completion percentage: ");
methodstats[2] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter total yards: ");
methodstats[3] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter touchdowns: ");
methodstats[4] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter interceptions: ");
methodstats[5] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter rushing yards: ");
methodstats[6] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter rushing touchdowns: ");
methodstats[7] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter fumbles: ");
methodstats[8] = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter QB rating: ");
methodstats[9] = Convert.ToDouble(Console.ReadLine());
return methodstats;
}
}
Here is my code I have so far. Keep in mind that I am VERY beginner. I am trying to create a console that will ask for user input for 3 different players over 2 games. Once I get all the data input by the user, I will go on to add the ability for the user to be prompted to display either the game 1 statline, game 2 statline, or the average of the two games.
Right now I'm stuck on just getting the input. I am getting an error where I have bold and italics on the line that the best overload method match has some invalid arguments. What am I messing up here? I'm pretty sure it is in z, but I'm not quite sure how to input it into the third dimension of the array for the 10 stats. Halp!

You have 2 mismatches on that line:
stats[x, y, z] = inputstats(stats[x, y, z]);
double[] inputstats(double[] methodstats)
{
}
The expression stats[x, y, z] is a single double, not an array. So when you fix the argument error you will get one for the assignment of the return value.
This line would compile:
stats[x, y, z] = Math.Sin(stats[x, y, z]);
because the function is declared as double Sin(double a)
Your input method collects an array of doubles, that is not possible with your current array form. You would have to use a jagged array (array-of-array-of-array:
double[][][] stats = ...
// extra code to create the arrays
inputstats(stats[x][y]);
void inputstats(double[] methodstats)
{
}
But you might as well bite the bullet and write a proper class for your data:
class PlayerStats
{
public double PassAttempts { get; set; }
public double Completions { get; set; }
// etc ...
}

A simpler solution would be:
public static void Main()
{
double[][][] stats = new double[3][2][10];
string[] players = new string[3];
players[0] = "Tom Brady";
players[1] = "Drew Brees";
players[2] = "Peyton Manning";
for (int player = 0; player < 3; ++player)
{
Console.WriteLine("Enter stats for {0}", players[ player ]);
for (int game = 0; game < 2; ++game)
{
Console.WriteLine("Game {0}", game + 1);
stats[player][game] = inputstats();
}
}
public static double[] inputstats()
{
//same code
}
A few notes. I used an array of an array of an array instead of a multidimensional array so that an array can be assigned to stats[][] (More Info Here). Also, you should use more descriptive iterator variables (player and game here) and locally scope them. That is declare them in the for loop declaration. Generally, the more local the scope of a variable, the better.
edit:
According to Kevin DiTraglia you can assign an array to [,]. But anyway [][][] is apparently faster and more natural for me coming from Java and C/C++

Related

How to work out how many times a value appears in an array c#

I have been set an assignment, that means I need to create a '3 or more dice game'. What I'm stuck on is the scoring system that is needed with this game, it goes as follows:
"
Players in turn roll all five dice and score for three-of-a-kind or better. If a player only has two-of-a-kind, they may re-throw the remaining dice in an attempt to improve the matching dice values. If no matching numbers are rolled, a player scores 0.
Players score the following number of points accordingly:
3-of-a-kind: 3 points
4-of-a-kind: 6 points
5-of-a-kind: 12 points
A set number of rounds are played (say 50) and the player with the highest total score at the end of a game, is the winner.
"
I need to work out how to add up the random dice's numbers to see which numbers are matching.
namespace DiceGame
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, I am your computer and I am speaking to you, welcome to the dice game, here are the rules:");
Console.WriteLine("3-of-a-kind: 3 points ");
Console.WriteLine("4-of-a-kind: 6 points ");
Console.WriteLine("5-of-a-kind: 12 points");
Console.WriteLine("First player to reach 50 wins");
//integer array to store 5 values for the dice
int[] Rolls = new int[5];
//Calls from class Dice (calls integer value)
for (int numdice = 0; numdice < 5; numdice++)
{
Rolls[numdice] = Dice.Roll();
//For each loop, get position of array and place number we want in that position
Console.WriteLine(Rolls[numdice]);
}
//Makes a new game object which is used to call functions
Game game = new Game();
game.startGame();
Console.ReadLine();
}
//produces one random number
public class Dice
{
static Random rng = new Random();
public static int Roll()
{
//create a random number generator
return rng.Next(1, 7);
}
}
public class Game
{
public void startGame()
{
//prompts user to input value and then stores it
int playerNo = numberofPlayers();
while (playerNo < 2)
{
Console.WriteLine("Please enter a number between 2-4");
playerNo = numberofPlayers();
}
//Now have number of players, need to loop through now
//creates the number of players in array
player[] listofPlayers = new player[playerNo];
//this looks at the current player that the code is looking at
for (int currentPlayer = 0; currentPlayer < playerNo; currentPlayer++)
{
listofPlayers[currentPlayer] = new player();
Console.WriteLine("It is player {0}'s turn", currentPlayer + 1);
listofPlayers[currentPlayer].rollplayerDice();
Console.WriteLine(listofPlayers[currentPlayer].score);
listofPlayers[currentPlayer].playersScore();
}
}
void inputPlayers()
{
//create number of players code
//create a way to input name of players
//depending on the number of players, repeat the code below that many times
string player1 = Console.ReadLine();
}
public int numberofPlayers()
{
int playerNum = 0;
try
{
Console.WriteLine("Please Enter the number of players you would like to play with 2-4");
playerNum = int.Parse(Console.ReadLine());
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return playerNum;
//if playerNo is equal to 2 = 2 players
//if playerNO is equal to 3 = 3 players
//if playerNO is equal to 4 = 4 players
//if playerNo is less than 2 and more than 4 then loop back through the if statement and ask to input and number "between 2-4"
}
public class player
{
public int score = 0;
int[] playerRoll = new int[5];
public void rollplayerDice()
{
for (int currentDice = 0; currentDice < playerRoll.Length; currentDice++)
{
playerRoll[currentDice] = Dice.Roll();
Console.WriteLine("Dice {0} rolled a {1}", currentDice, playerRoll[currentDice]);
}
}
public int playersScore()
{
int[] diceFaces = new int[6];
/*for (int diceFace = 0; diceFace < playerRoll.Length; diceFace++)
{
int oneCounter = 0;
//number of 1's =
//number of 2's =
//number of 3's =
//number of 4's =
//number of 5's =
//number of 6's =
//create a system to work out the score
//create a switch to see what the player score is equal to (switch 3, 4, 5 and add up the points that correlate)
}
*/
foreach (int d in playerRoll)
diceFaces[d]++;
int caseSwitch = 0;
switch (caseSwitch)
{
case 3:
//add on the points to a players score
score += 3;
break;
case 4:
//add on the points to a player score
break;
case 5:
//add on the points of a players score
break;
}
return 0;
}
}
}
}
}
^Above is my whole code and below is the code I am working in right now on attempting the scoring.
public int playersScore()
{
int[] diceFaces = new int[6];
/*for (int diceFace = 0; diceFace <
playerRoll.Length; diceFace++)
{
int oneCounter = 0;
//number of 1's =
//number of 2's =
//number of 3's =
//number of 4's =
//number of 5's =
//number of 6's =
//create a system to work out the score
//create a switch to see what the player score is equal to (switch 3, 4, 5 and add up the points that correlate)
}
*/
foreach (int d in playerRoll)
diceFaces[d]++;
int caseSwitch = 0;
switch (caseSwitch)
{
case 3:
//add on the points to a players score
score += 3;
break;
case 4:
//add on the points to a player score
break;
case 5:
//add on the points of a players score
break;
}
return 0;
}
You can use GroupBy(), then Count():
int score = 0;
var grouped = dice.GroupBy(x => x);
//Score 3 of a kinds
score += grouped.Count(x => x.Count() == 3) * 3;
//Score 4 of a kinds
score += grouped.Count(x => x.Count() == 4) * 6;
//Score 5 of a kinds
score += grouped.Count(x => x.Count() == 5) * 12;
Working fiddle

Adding the sum of two randomly generated numbers (using arrays)

class Program
{
const int ROLLS = 51;
static void Main(string[] args)
{
Random r = new Random();
int sum = 0;
int[] dice1 = new int[ROLLS];
int[] dice2 = new int[ROLLS];
for (int roll = 0; roll <= 50; roll++)
{
dice1[roll] = GenerateNum(r);
dice2[roll] = GenerateNum(r);
Console.WriteLine("ROLL{0}: {1} + {2} = sum goes here", roll+1, dice1[roll]+1, dice2[roll]+1);
}
}
static int GenerateNum (Random r)
{
return r.Next(1, 7);
}
}
}
So what I have is two arrays to store two different int values that are randomly generated and what I am trying to achieve is the sum of these two randomly generated int values.
Upon execution it should display:
Roll 1: (random number) + (random number) = (sum of the two random numbers)
Just add the two together and store them in sum. Then present sum in the same manner you have presented the rest of the values in the output of the console:
dice1[roll] = GenerateNum(r);
dice2[roll] = GenerateNum(r);
sum = dice1[roll] + dice2[roll];
Console.WriteLine("ROLL{0}: {1} + {2} = {3}", roll + 1, dice1[roll], dice2[roll], sum);

C# Arrays in a Bowling Program. Wont use Lowest Score

I am trying to create a bowling program that when you enter in your name followed by your score, it will take the average, lowest, and highest scores of the players and print them. However for some reason I cannot get the lowest score to print, as when I hit enter twice, it will use the blank value instead of the lowest entered value and name. How can I fix this so that it will display the lowest score?
{
class Program
{
static void Main(string[] args)
{
const int SIZE = 10;
int i;
// create an array with 10 elements
string[] scoreInfo = new string[SIZE];
string[] names = new string[SIZE];
int[] scores = new int[SIZE];
for (i = 0; i < SIZE; i++)
{
// Prompt the user
Console.Write("Enter your first name and score on one line");
Console.WriteLine(" separated by a space.");
// Read one line of data from the file and save it in inputStr
string inputStr = Console.ReadLine( );
// if statement to break when the user enters a zero
if (inputStr == String.Empty)
{
break;
}
// The Split method creates an array of two strings
scoreInfo = inputStr.Split();
// Parse each element of the array into the correct data type
names[i] = scoreInfo[0];
scores[i] = int.Parse(scoreInfo[1]);
}
Console.WriteLine("The avarage score is {0}", AverageScore(scores, i));
Console.WriteLine("{0} scored the lowest at {1}", names[LowScore(scores, i--)], scores[LowScore(scores, i--)]);
Console.WriteLine("{0} scored the highest at {1}", names[HighScore(scores)], scores[HighScore(scores)]);
Console.ReadLine();
Console.ReadLine();
}
static int LowScore(int[] scores, int j)
{
int min = scores.Min();
return Array.IndexOf(scores, min);
}
static int HighScore(int[] scores)
{
int max = scores.Max();
return Array.IndexOf(scores, max);
}
static double AverageScore(int[] numbers, int j)
{
double average = 0;
for (int i = 0; i < j--; i++)
{
int product = 1;
product = numbers[i] * product;
average = product / j;
}
return average;
}
}
}
Use a different data structure and make less work for yourself.
Start with a dictionary that maps names to scores so that you don't have to mess around with indexes.
Then, LINQ is your friend, as you've already noticed. You don't need to create functions for things that already exist (like min/max/average).
eg.
Dictionary<string, int> ranking = new Dictionary<string, int>();
ranking.Add("adam", 20);
ranking.Add("bill", 10);
ranking.Add("carl", 30);
double avg = ranking.Average(kvp => (double)kvp.Value);
var sorted = ranking.OrderBy(kvp => kvp.Value);
var min = sorted.First();
var max = sorted.Last();
Console.WriteLine("Average: {0}", avg);
Console.WriteLine("Lowest: {0} with {1}", min.Key, min.Value);
Console.WriteLine("Highest: {0} with {1}", max.Key, max.Value);
Modify your Average function like this:-
static double AverageScore(int[] numbers, int j)
{
double sum = 0;
for (int i = 0; i < j; i++)
{
sum += numbers[i];
}
return (double)sum / j;
}
I am not sure why you were taking product of items for finding average of scores.
And Your Min function like this:-
static int LowScore(int[] scores, int j)
{
int min = scores.Where((v, i) => i < j).Min();
return Array.IndexOf(scores, min);
}
Here, you are passing the complete array of integer, so if only 3 players entered values, rest of the values will be initialized to default, i.e. 0 for int, Thus you were getting 0 as Min value.
Also, You need to change the method invocation like this:-
Console.WriteLine("{0} scored the lowest at {1}", names[LowScore(scores, i)], scores[LowScore(scores, i)]);

Using the array split method to separate names / numbers [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have been instructed to write a program that collects a bowling score (integer) and a name from the user, separated by a space, and sorts each of them into an array using the Split method. The output has to be formatted to find the average score and output it to the console, as well as sort the scores (and names) in order of lowest to highest.
I have been able to do everything except find a way to sort the names with their corresponding scores.
Here is what I have so far. To clarify, I need help writing a sorting algorithm for my array of names.
using System;
class Program
{
//class variables
const int MAX = 10;
static void Main()
{
//declare array
int[] score = new int[MAX];
string[] name = new string[MAX];
//program prologue
Console.WriteLine("****************Bowling Project****************");
Console.WriteLine("Please enter a name and a score for each player. For example 'John 145'.\nHit enter when you are done.");
//for loop to get input
for (int i=0; i<MAX; i++)
{
Console.Write("Enter a name and a score for player #{0}: ", (i + 1));
string input = Console.ReadLine();
if (input == "")
{
break; // if nothing is entered, it will break the loop
}
//split the user data into 2 arrays (integer and string)
string[] separateInput = input.Split();
name[i] = separateInput[0];
score[i] = int.Parse(separateInput[1]);
}
Console.WriteLine("\n****************Input Complete****************");
//calculate the average score and send to the console
CalculateScores(score);
Console.WriteLine("The scores for the game are:");
//sort the scores
BubbleSort(score);
Console.ReadLine();
}//End Main()
//CalculateScores Method
//Calculates the average score of an array of integers
//Takes an array of integers as parameters
//Returns void
//Outputs the average to the console
static void CalculateScores(int[] score)
{
int sum = 0;
int average = 0;
for (int i = 0; i < score.Length; i++)
{
sum += score[i];
average = sum / score.Length;
}
Console.WriteLine("The average score was {0}", average);
}//End calculateScores
//Swap method
//Takes 2 integers as parameters
//Switches the value of 2 integers (a and b)
static void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
//BubbleSort method
//Sorts an array of integers
//Takes an array of integers as a parameter
//Returns void
//Outputs to the console
static void BubbleSort(int[] score)
{
for (int j = 0; j < score.Length -1; j++)
{
for (int i = 0; i < score.Length - 1; i++)
{
if (score[i] > score[i + 1])
{
Swap(ref score[i], ref score[i + 1]);
}
}
}
foreach (int a in score)
Console.WriteLine("{0}", a);
Console.ReadLine();
}
}//End class Program
Assuming that names[] corresponds 1 to 1 with score[]:
Just take your BubbleSort method, and pass both names[] and score[] into it
Then, you whenever you do an operation on score[] do it on names[] too.
something like this
static void BubbleSort(int[] score, string[] names)
{
for (int j = 0; j < score.Length -1; j++)
{
for (int i = 0; i < score.Length - 1; i++)
{
if (score[i] > score[i + 1])
{
Swap(ref score[i], ref score[i + 1]);
Swap(ref names[i], ref names[i + 1]);
}
}
}
foreach (int a in score)
Console.WriteLine("{0}", a);
Console.ReadLine();
}
you might have to make a swap method for strings
static void Swap(ref string a, ref string b)
{
string temp = a;
a = b;
b = temp;
}
you should make a separate class that will store a player with its score array.
then make an array of players that you can sort based upon their name
EDIT: I've updated my answer to be an implemented player class that builds upon your original code. If this is for a university project this may get seen by plagiarism checkers so I'd be wary to use it.
public class Player
{
public Player(){}
public Player(string name, int score)
{
m_name = name;
m_score = score;
}
public Player(Player p)
{
m_name = p.Name;
m_score = p.Score;
}
public string Name
{
get{return m_name;}
}
public int Score
{
get{return m_score;}
}
private string m_name
private int m_score
}
Player[] players = new Player[MAX];
static void BubbleSort(Player[] players)
{
for (int j = 0; j < players.Length -1; j++)
{
for (int i = 0; i < players.Length - 1; i++)
{
if (players[i].Score > players[i + 1].Score)
{
Swap(ref players[i], ref players[i + 1]);
}
}
}
foreach (Player a in players)
Console.WriteLine("{0}", a.Score);
Console.ReadLine();
}
static void Swap(ref Player a, ref Player b)
{
Player temp = a;
a = b;
b = temp;
}
Instead of using two collections of loosely associated values, use a single collection of a class:
public class BowlingScore {
public string Name { get; private set; }
public int Score { get; private set; }
public BowlingScore(string name, int score) {
Name = name;
Score = score;
}
}
Use a list rather than an array for the collection:
List<BowlingScore> scores = new List<BowlingScore>();
In your loop you can create instances of the class and add to the list:
BowlingScore item = new BowlingScore(separateInput[0], int.Parse(separateInput[1]);
scores.Add(item);
By using a list instead of an array, it will only contain the items that you actually add. Your current code would need another variable to keep track of how many items in the array was actually used, so that you don't include the ones left empty at the end.
Now, as you have the name and score as a single unit, you can sort the list using the same approach as you used for sorting an array, only you compare a property of the objects. As you swap the whole objects, the name will follow the score when you sort on scores, and vice versa.
The items in the list can be accessed using index just like an array, only the length of the list is in the Count property instead of Length.
No need to create two arrays because you are losing the semantic meaning between the player's name and its score. But also no need to create a new class for that. You can re-use built-in classes/structs like Tuple<...> or KeyValuePair<...>. For ordering, you can use linq-extension methods.
static void Main(string[] args)
{
// just some sample players
const string player1 = "David 100";
const string player2 = "Jennifer 1430";
const string player3 = "Eve 234";
// the string-array with information about players
var players = new[] { player1, player2, player3 };
// initialize the array: a tuple is the name of the player and the score
var scores = new List<Tuple<string, int>>(players.Length);
foreach (string player in players)
{
// split by whitespace
string[] info = player.Split(' ');
// be failure tolerant: split must result in at least 2 entries and second one must be integer
int score;
if (info.Length <= 2 && int.TryParse(info[1], out score))
scores.Add(new Tuple<string, int>(info[0], score));
}
// print average score
Console.WriteLine("Average score for {0} players is: {1}{2}", scores.Count, scores.Select(t => t.Item2).Average(), Environment.NewLine);
// print score of each single player (ordered from highest to lowest score)
foreach (Tuple<string, int> score in scores.OrderByDescending(t=>t.Item2))
Console.WriteLine("Player '{0}' => score: {1}", score.Item1, score.Item2);
Console.WriteLine();
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}

Displaying Array within Method

This relates to another code I posted earlier but since this is a different question I decided to make a new post. I'm currently stuck with this code, I'm a c# beginner so this look complicated to me. I've been working on this code that is supposed to get an array from the user, calculate its average then display the results inside show(). I got this working to show the average of the array but now I need to actually display the array each value individually i.e. The 1st value you entered was : 12
The 2nd value you enteres was : 32
Thank guys!
private static int Array()
{
string inValue;
int[] score = new int[10];
int total = 0;
for (int i = 0; i < score.Length; i++)
{
Console.Write("Enter Value {0}: ", i + 1);
inValue = Console.ReadLine();
score[i] = Convert.ToInt32(inValue);
}
for (int i = 0; i < score.Length; i++)
{
total += score[i];
}
return total;
}
Change your GetValues() function to actually return the array of integers, then use the return value in your other functions.
i.e. change GetValues() to:
private static int[] GetValues()
{
string inValue;
int[] score = new int[5];
int total = 0;
for (int i = 0; i < score.Length; i++)
{
Console.Write("Enter Value {0}: ", i + 1);
inValue = Console.ReadLine();
score[i] = Convert.ToInt32(inValue);
}
return score;
}
EDIT: Here is how to use the GetValues() function above in a function to print out all the values. You should be able to work out the rest from here:
private static void PrintArray(int[] scoreArray)
{
for (int i = 0; i < scoreArray.Length; i++)
{
Console.WriteLine("Value #{0}: {1}", i + 1, scoreArray[i]);
}
}
Note how the scoreArray is passed in, as well as how each value is accessed, using scoreArray[i] (where i is a number from 0 to 4 inclusive).
Move int[] score out of GetValues and declare it at the class level making it static:
static int[] score = new int[5];
My next recommendation is that you don't do inside your functions more than what they claim to do from their name; for example, GetValues() should only get the values from user; not calculate totals (as you are doing) because it's misleading; it forces you to look at the implementation to know exactly what it does. Similarly for Show(); if the purpose is to show values entered by user, then call it ShowValues(); If the purpose is to show values entered by user as well as calculate the average, then name it something along the lines of ShowValuesAndAverage()
Here's a complete implementation of your program with my recommendations:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testscores
{
class Program
{
static int[] score = new int[5];
//Get Values
private static void GetValues()
{
string inValue;
for (int i = 0; i < score.Length; i++)
{
Console.Write("Enter Value {0}: ", i + 1);
inValue = Console.ReadLine();
score[i] = Convert.ToInt32(inValue);
}
}
//FIND AVERAGE
private static double FindAverage()
{
double total = 0.0;
for (int i = 0; i < score.Length; i++)
{
total += score[i];
}
double average = total / 5.0;
return average;
}
//Show
static void ShowValuesAndAverage()
{
Console.WriteLine("The values are:");
for (int i = 0; i < score.Length; i++)
{
Console.WriteLine(string.Format("The {0} value you entered was {1}", i + 1, score[i]));
}
Console.WriteLine("The average is: {0}", FindAverage());
}
//Main
static void Main()
{
GetValues();
ShowValuesAndAverage();
Console.ReadKey();
}
}
}
Make one function for GetValues() and return the array. Then pass the array into a AddValues() function, and into Show().
Either that or read up on how to use pointers, but that might be overcomplicating things a little.

Categories

Resources