Keep changing text in same place C# console - c#

I am creating a quiz with a timer. After asking for the number of questions they want to answer and the time for answering the questions, I would like to show a timer that keeps counting down on the same line. Below the timer I would like to show all the quiz questions.
However every time a question is asked, the timer appears on the new line.
I have already tried following this question, but it doesn't fix my problem. How can I update the current line in a C# Windows Console App?
public class GamePlay
{
private static int _secondPassed;
private static int _timeForAnswering;
private static bool _isTimerFinished;
private static void Timing()
{
Timer timer = new Timer(TimerCallback, null, 0, 1000);
Console.ReadKey();
}
private static void TimerCallback(Object o)
{
if (_secondPassed >= _timeForAnswering)
{
_isTimerFinished = true;
}
else
{
_isTimerFinished = false;
_secondPassed++;
Console.Write($"\rYou have {_timeForAnswering - _secondPassed} seconds left.");
}
}
public static async Task PlayGame(int numberOfQuestions, int timeForAnswering)
{
_timeForAnswering = timeForAnswering;
Random random = new Random();
await Task.Run(() => Timing());
for (int q = 1; q < numberOfQuestions + 1; q++)
{
if (_isTimerFinished)
{
Console.WriteLine();
Console.WriteLine("Game Over!");
break;
}
else
{
Console.WriteLine();
Console.WriteLine(/* Ask Question */);
// Get Answer
double usersAnswer = Console.ReadLine();
}
}
}
}

Console.SetCursorPosition is the way to go. With that you can modify any line in the Console.
https://learn.microsoft.com/de-de/dotnet/api/system.console.setcursorposition?view=net-6.0

Related

Updating multiple line in a console application

I've been struggling with Parallel.For and local variable. I'm trying to update percentages in a console app from a parallel for. I add page in multiple document and I would like an update on the percentage for each document.
Here's my attempt so far :
I'm taking the number of the line with Console.CursorTop, and I want to pass it to a method who's gonna override the line.
Loop from Program.cs
Parallel.For(0, generationFile.nbOfFile, optionsParallel,
i =>
{
string fileName = $"{tmpDirectoryPath}/{i + 1}_{guid}.pdf";
AddPage(fileName, generationFile, i);
});
The AddPage method
private static void AddPage(string fileName, GenerationFile generationFile, int i)
{
var cursorPosition = Console.CursorTop;
//Ajout des pages
for (int j = 0; j < generationFile.SizeMaxFile; j++)
{
Page page = Page.Create(outDoc, size);
AddText(outDoc, page, font, 14, i, fileName, j, generationFile.SizeMaxFile);
for (int k = 0; k < 292; k++)
{
AddImage(outDoc, page, 30, 30);
}
outDoc.Pages.Add(page);
ConsoleManager.UpdateConsole(i, j, cursorPosition, generationFile);
}
}
The UpdateConsole method
public static void UpdateConsole(int fileNumber, double progression, int cursorPosition, GenerationFile generationFile)
{
progression = (progression / 100) * generationFile.ArchiveESC;
Console.ForegroundColor = ConsoleColor.White;
Console.SetCursorPosition(0, cursorPosition);
Console.WriteLine($"\rFichier n°{fileNumber + 1}/{generationFile.SizeMaxFile} en cours de création : {progression}% ", Console.ForegroundColor);
}
I think everything works fine, except for the cursorPosition who take one value at the beginning and never change, so the same line is updated. I understand that there is something to do with local and/or shared variable, but I'm fairly new in parallel processing so even with the other threads on this topic and the MSDN, I don't understand what to do.
The way I prefer to handle progress reporting is to have all worker threads report to a shared progress field, and have a separate timer that reads this fields and reports the progress to the user. This lets me control how often progress is reported, regardless of how fast items are processed. I also want an abstraction layer that allows different ways to report progress. After all, the same method might be used from console, the UI, or not at all.
For example something like this:
public interface IMyProgress
{
void Increment(int incrementValue);
}
public sealed class MyProgress : IMyProgress, IDisposable
{
private readonly int totalItems;
private readonly Timer myTimer;
private volatile int progress;
private int lastUpdatedProgress;
public MyProgress(TimeSpan progressFrequency, int totalItems)
{
this.totalItems = totalItems;
myTimer = new Timer(progressFrequency.TotalMilliseconds);
myTimer.Elapsed += OnElapsed;
myTimer.Start();
}
private void OnElapsed(object sender, ElapsedEventArgs e)
{
var currentProgress = progress;
if (lastUpdatedProgress != currentProgress)
{
lastUpdatedProgress = currentProgress;
var percent = currentProgress * 100 / (double)totalItems;
Console.Write($"\rWork progress: {percent}%");
}
}
public void Increment(int incrementValue) => Interlocked.Add(ref progress, incrementValue);
public void Dispose() => myTimer?.Dispose();
}
This can be called from a parallel method like:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var myWorkItems = Enumerable.Range(1, 10000).ToList();
using var progress = new MyProgress(TimeSpan.FromSeconds(1), myWorkItems.Count);
DoProcessing(myWorkItems, progress);
}
private static void DoProcessing(IEnumerable<int> items, IMyProgress progress)
{
Parallel.ForEach(items, item =>
{
Thread.Sleep(20);
progress.Increment(1);
});
}
I would be a bit careful when using carriage returns. In my experience console applications tend to be used by other programs as much as by humans, and then it is likely that the output will be redirected to a file, and that does not support carriage returns. So I would try to make the output look good.
I would avoid trying to move the cursor around. I have tried that, but the result was unsatisfactory, YMMV.

C# Use timer to control program

I am trying to create a console application similar to speedsum site. The speedsum is a website which is really useful and fun to test our own mathematical ability in 30s.
After giving few try-s I was just thought to create one small C# console application with same concept.
Following is my code which is working fine. But I could not display countdown ?!
My code:
static void Main(string[] args)
{
int testCount = 0;
Console.Write("\n Get.. Set... Go.... : This is a 30s test.. " +
"Once each problem is completed the time finished will be shown \n Good Luck.. :) \n \n");
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 1; i < 100000; i++)
{
if (watch.Elapsed.TotalSeconds >= 30)
break;
TimeSpan timeSpan = TimeSpan.FromSeconds(Convert.ToInt32(watch.Elapsed.TotalSeconds));
Console.Write($"\n {timeSpan.ToString("c")}" );
Random r = new Random();
int number1 = r.Next(10);
int number2 = r.Next(10);
int operation = r.Next(4);
var method = (operation > 2) ? '+' : '*';
int result = 0;
result = method == '+' ? (number1 + number2) : (number1 * number2);
Console.Write($" \n {number1} {method} {number2} = ");
var getAnswer = Convert.ToInt32(Console.ReadLine());
if (result == getAnswer)
{
testCount++;
continue;
}
else
break;
}
watch.Stop();
if(testCount >= 1 && testCount <=5)
Console.Write($"\n No Worries!! Try Hard ... \n you have solved {testCount} problems \n");
else if(testCount >=6 && testCount <=10)
Console.Write($"\n Good!! You can do well next time ... \n you have solved {testCount} problems \n");
else
Console.Write($"\n Awesome!! You are really a Genius ... \n you have solved {testCount} problems \n");
Console.Write("\n Thank you for playing with me... \n Enter a key to exit");
Console.Read();
}
I would like to get the countdown from 30s to 0s at,
Get.. Set... Go.... : This is a 30s test.. Once each problem is completed the time finished will be shown
Good Luck.. :)
<<Timer Should go here>> (30, 29... 0)
5 * 5 = 25 ...
This SO Question Showing how to get countdown into our program, But I am confused at how I can do both parallely countdown and giving problems.
Any suggestion would be helpful to me.
It looks like you want to use BackgroundWorker. Then, DoWork event will decrement amount of seconds left, while ProgressChanged event will report current progress. The advantage of this solution is that background worker is running async, so you will not block your main thread allowing the user to enter answer anytime they want.
private static int secondsLeft;
private static BackgroundWorker bgWorker;
static void Main(string[] args)
{
secondsLeft = 30;
bgWorker = new BackgroundWorker();
bgWorker.DoWork += bgWorker_DoWork;
bgWorker.ProgressChanged += bgWorker_ProgressChanged;
bgWorker.WorkerReportsProgress = true;
bgWorker.RunWorkerAsync();
Console.ReadLine();
}
private static void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (secondsLeft >= 0)
{
bgWorker.ReportProgress(secondsLeft);
Thread.Sleep(1000);
secondsLeft--;
}
}
private static void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine($"Seconds left: {e.ProgressPercentage}");
}

How can I improve this logic? C#

I have a library that returns CS:GO stats in real-time from the game. I'm making a program that stores the stats and analyse it.
I have this function:
private void UpdateKills(GameState gs)
{
int currentKills = -1;
if (lastKills == -1) // first time getting player info
{
int temp = gs.Player.MatchStats.Kills;
currentKills = temp;
lastKills = temp;
}
else
{
currentKills = gs.Player.MatchStats.Kills;
int dif = currentKills - lastKills;
if (currentKills == 0 && lastKills != 0) // maybe changed server/map/whatever
{
lastKills = -1;
}
else
{
if (dif != 0 && dif > 0) // player killed someone AND it was not teamkill
{
ps.Kills += dif; // add the kills to the main variable
lastKills = currentKills;
dif = 0;
playSimpleSound();
}
}
}
}
This is my function that handles the kills. The most of the time it works very well, but sometimes it just freaks out, and I don't know if the problem is my logic or if it is a library problem.
Note: I'm using this library: github.com/rakijah/CSGSI
My logic is:
Get the player kills
Increment those kills in the PlayerStats object.
Is my code logically correct? Can my code be more "correct"?
I'm still not entirely sure what this function is supposed to be doing, but I simplified it for you:
private void UpdateKills(GameState gs)
{
lastKills = currentKills;
int currentKills = gs.Player.MatchStats.Kills;
int diff = currentKills - lastKills;
if (currentKills == 0 && lastKills != 0) // maybe changed server/map/whatever
{
lastKills = -1;
}
else if (diff > 0) // player killed someone AND it was not teamkill
{
ps.Kills += diff; // add the kills to the main variable
playSimpleSound();
}
}
Well, after some research in finally undertand your problem. You DON'T have to do anything!, the API does all the work for you, watch the next image:
As you can see, the console app shows my steam name, the map and kills. I start with zero kills, then I kill a teammate and after that an enemy. The API created by #rakijah autoupdates those values.
Now the code:
static void Main(string[] args)
{
CsGoIntegration();
}
private static void CsGoIntegration()
{
var gsl = new GameStateListener(3000);
gsl.NewGameState += new NewGameStateHandler(OnNewGameState);
if (!gsl.Start())
{
Environment.Exit(0);
}
System.Console.WriteLine("Listening...");
}
private static void OnNewGameState(GameState gs)
{
System.Console.WriteLine("Map: {0}", gs.Map.Name);
System.Console.WriteLine("Player Name: {0}", gs.Player.Name);
System.Console.WriteLine("Player Kills: {0}", gs.Player.MatchStats.Kills);
}
UPDATE: The OP needs to store the total kills even when the map changes. I experimented with paper and pencil, please try running the program and tell me if it worked or not
private static void Main()
{
CsGoIntegration();
}
private static void CsGoIntegration()
{
var gsl = new GameStateListener(3000);
gsl.NewGameState += OnNewGameState;
if (!gsl.Start())
{
Environment.Exit(0);
}
Console.WriteLine("Listening...");
}
private static void OnNewGameState(GameState gameState)
{
SaveMatchsData(gameState);
}
private static int? _totalKillScore;
private static string _lastMapName;
private static int? _lastKillScore;
private static void SaveMatchsData(GameState gameState)
{
const string undefinedString = "Undefined";
// If the SaveMatchsData is running and the CSGO server is offline
if (gameState.Map.Name == undefinedString && string.IsNullOrEmpty(_lastMapName))
return;
// When the match is not started, the Round is -1
if (gameState.Map.Name != undefinedString && gameState.Map.Round > -1)
{
if (string.IsNullOrEmpty(_lastMapName))
{
UpdateData(gameState, true);
}
else
{
// Same map
if (_lastMapName == gameState.Map.Name)
{
// Check if the Score Changes
if (_lastKillScore == gameState.Player.MatchStats.Kills) return;
UpdateData(gameState);
}
// The Map Changes
else
{
UpdateData(gameState, true);
}
}
}
}
private static void UpdateData(GameState gameState, bool updateMap = false)
{
if (updateMap)
_lastMapName = gameState.Map.Name;
_lastKillScore = gameState.Player.MatchStats.Kills;
_totalKillScore += gameState.Player.MatchStats.Kills;
}
Cheers.

How to allow user to try again or quit console program in C#?

I have created a game that gives a player 5 chances to play after which I would like to ask the player if they would like to play again or quit. I have seen it done in Python, but I do not know python. My code works perfectly fine, but I would like to add these two additional functions
How can I achieve these functionality in C#?
For reference this is what my code main class code looks like.
namespace NumBaseBall
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("\t\t\t*************************************");
Console.WriteLine("\t\t\t* Let's Have Some 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 played this games {0} times\n", trysCounter);
gameresults.TotalStrikes = gameresults.TotalStrikes + gameresults.Strikes;
Console.WriteLine("STRIKES = {0} ", gameresults.TotalStrikes);
if (gameresults.TotalStrikes >= 3)
{
gameresults.Wins++;
Console.WriteLine("YOU ARE A WINNER!!!");
break;
}
}
if (gameresults.TotalStrikes <3)
Console.WriteLine("YOU LOSE :( PLEASE TRY AGAIN!");
}
}
}
Insert your code inside an loop which checks if the user wants to continue:
while(true) // Continue the game untill the user does want to anymore...
{
// Your original code or routine.
while(true) // Continue asking until a correct answer is given.
{
Console.Write("Do you want to play again [Y/N]?");
string answer = Console.ReadLine().ToUpper();
if (answer == "Y")
break; // Exit the inner while-loop and continue in the outer while loop.
if (answer == "N")
return; // Exit the Main-method.
}
}
But perhaps it would be better to split one big routine up into seperate routines.
Lets rename your Main-method to PlayTheGame.
Split up my routines into:
static public bool PlayAgain()
{
while(true) // Continue asking until a correct answer is given.
{
Console.Write("Do you want to play again [Y/N]?");
string answer = Console.ReadLine().ToUpper();
if (answer == "Y")
return true;
if (answer == "N")
return false;
}
}
And now the Main-method can be:
static void Main(string[] args)
{
do
{
PlayTheGame();
}
while(PlayAgain());
}
You'de have to move some local variables to the class as static fields. Or you could make an instance of a Game class, but I think that is one step to far right now.
There are two ways you could accomplish this:
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.kill%28v=vs.110%29.aspx
System.Diagnostics.Process.GetCurrentProcess().Kill();
Or
https://msdn.microsoft.com/en-us/library/system.environment.exit(v=vs.110).aspx
int exitCode =1;
System.Environment.Exit(exitCode);
Environment.Exit is the preferred way to exit your program since the Kill command "causes an abnormal process termination and should be used only when necessary."[msdn]
First, take the suggestion of moving the code for the actual game playing into a separate function. It will clean things up a lot.
Something like
private static bool PlayGame()
{
// Win branch returns true.
// Loss branch returns false.
}
This then lets you greatly simplify the Main function allowing it to only handle the menu functionality.
For the actual menu functionality, I tend to prefer do/while loops. You have a bit of an extra stipulation that you only ask after 5 plays, but that's easy enough to deal with.
static void Main(string[] args)
{
int playCount = 0;
string answer = "Y";
bool winner;
do
{
if(playCount < 5)
{
playCount++;
}
else
{
do
{
Console.Write("Play again? (Y/N): ");
answer = Console.ReadLine().ToUpper();
} while(answer != "Y" && answer != "N");
}
winner = PlayGame();
} while(!winner && answer == "Y");
Console.WriteLine("Thanks for playing!");
}
You could simplify it a bit by moving the test for 5 games into the if conditional with the use of an increment operator. The only issue is if someone plays your game a billion or so times, things might get weird.
static void Main(string[] args)
{
int playCount = 0;
string answer = "Y";
bool winner;
do
{
if(playCount++ > 3)
{
do
{
Console.Write("Play again? (Y/N): ");
answer = Console.ReadLine().ToUpper();
} while(answer != "Y" && answer != "N");
}
winner = PlayGame();
} while(!winner && answer == "Y");
Console.WriteLine("Thanks for playing!");
}
Edit: Changed things a bit as it looks like in your original code the game ends after the person wins the game.
Per your question in your comment below, you could make a static instance of your GameResults class in your Program class. Your code would end up looking something like the following
class Program
{
private static GameResults results = new GameResults();
public static void Main(string[] args)
{
// Code
}
private static bool PlayGame()
{
// Code
}
}
In PlayGame you would just use the static results object instead of creating a new one every time PlayGame is called.

The array dont save my numbers

I am trying to learn C# and doing some questions i googeld. This is the task to do:
*"Beginner level:
The task is to make
a dice game where the user throws 3
Each 12-sided dice (numbers
shall be randomly selected and stored in an array / field or list).
Add up the total of the dice and show on the screen.
Create a function / method that accepts a figure
(the total sum of the dice). Function / method
should return the text "Good throw" if the figure
is higher or equal to 20.
In all other cases, the text
"Sorry" is returned.
Call the function / method in the main method
and prints the total and the text.
Advanced level:
This is an extension of the task where you must use a class to simulate a dice. The user shall have the option of writing a x y-sided dice himself.
If the total sum of a roll of the dice generates a score that is> 50% of the maximum score, the words "good throw" is displayed.
This logic can be in your main method.
Create the class described in the class diagram and use appropriate
way in your code."*
The thing is that i cant get it to work, the array in my class do not save my numbers im typing in... I only get the reslut 0. I think i have just done some big misstake i cant see...
This is the Main code:
static void Main(string[] args)
{
List<Dice> _Dice = new List<Dice>();
int a = 0;
int times = int.Parse(Interaction.InputBox("Write how many times you want to repeat the game:"));
while (a != times)
{
int antThrow = int.Parse(Interaction.InputBox("Write how many times you want each dice to get thrown:"));
int xChoice = int.Parse(Interaction.InputBox("Write how many dice you want to throw:"));
int yChoice = int.Parse(Interaction.InputBox("Write how many sides you want each dice should have:"));
_Dice.Add(new Dice(xChoice,yChoice, antThrow));
a++;
}
int e = 1;
foreach (var item in _Dice)
{
Interaction.MsgBox(string.Format("Result of game {0}: {1}", e++, item.Tostring()));
}
}
This is the Dice class:
class Dice
{
static int _xChoice, _yChoice, _throw;
static List<int> sum = new List<int>();
static int w = 0;
static int _sum;
static int[,] dice = new int[_xChoice, _yChoice];
public string Tostring()
{
int half = _sum / 2;
if (half <= _sum/2)
{
return "Good throw!" + _sum;
}
else
{
return "Bad throw!";
}
}
void random()
{
Random rnd = new Random();
while (w != _throw)
{
for (int i = 0; i < dice.GetLength(0); i++)
{
for (int j = 0; j < dice.GetLength(1); j++)
{
dice[i, j] = rnd.Next(1, _yChoice);
_sum += dice[j, i];
sum.Add(_sum);
}
}
w++;
}
}
public Tarning(int Xchoice, int Ychoice, int throw)
{
_throw = thorw;
_xChoice = Xchoice;
_yChoice = Ychoice;
}
}
Your main problem is in the static keyword. Static field means that there's only
one field for all the instances, which is not your case: you need each instance of Dice has its own fields' values.
class Dice {
// no static here
private int _xChoice, _yChoice, _throw;
// no static here
private List<int> sum = new List<int>();
// no static here
private int w = 0;
// no static here
private int _sum;
// no static here
private int[,] dice = new int[_xChoice, _yChoice];
// BUT, you want a random generator for all the instances, that's why "static"
private static Random rnd = new Random();
// When overriding method mark it with "override"
// And Be Careful with CAPitalization:
// the method's name "ToString" not Tostring
public override string ToString() {
...
}
void random() {
// Do not create Random generator each time you call it:
// It makes the random sequences skewed badly!
// Istead use one generator for all the calls, see the code above
// private static Random rnd = new Random();
// Random rnd = new Random();
...
}
...
class Program
{
static void Main(string[] args)
{
var dice = new List<DiceLogic>();
int a = 0;
int times = GetTimes();
while (a != times)
{
int antThrow = GetAntThrow();
int xChoice = GetXChoice();
int yChoice = GetYChoice();
dice.Add(new DiceLogic(xChoice, yChoice, antThrow));
a++;
}
int e = 1;
foreach (var item in dice)
{
Console.WriteLine("Result of game {0}: {1}", e++, item.Tostring());
}
Console.ReadLine();
}
private static int GetTimes()
{
while (true)
{
Console.WriteLine("Write how many times you want to repeat the game:");
int times;
var result = int.TryParse(Console.ReadLine(), out times);
if (result) return times;
Console.WriteLine("Value must be a number.");
}
}
private static int GetAntThrow()
{
while (true)
{
Console.WriteLine("Write how many times you want each dice to get thrown:");
int antThrow;
var result = int.TryParse(Console.ReadLine(), out antThrow);
if (result) return antThrow;
Console.WriteLine("Value must be a number.");
}
}
private static int GetXChoice()
{
while (true)
{
Console.WriteLine("Write how many dice you want to throw:");
int getXChoice;
var result = int.TryParse(Console.ReadLine(), out getXChoice);
if (result) return getXChoice;
Console.WriteLine("Value must be a number.");
}
}
private static int GetYChoice()
{
while (true)
{
Console.WriteLine("Write how many sides you want each dice should have:");
int getXChoice;
var result = int.TryParse(Console.ReadLine(), out getXChoice);
if (result) return getXChoice;
Console.WriteLine("Value must be a number.");
}
}
}
public class DiceLogic
{
public string Tostring()
{
int maxScore = _diceSides*_dices;
if (_result >= maxScore / 2)
{
return "Good throw! " + _result;
}
return "Bad throw! " + _result;
}
private readonly int _dices;
private readonly int _diceSides;
private readonly int _throwDice;
private int _result;
private void CalculateResult()
{
var rnd = new Random();
for (int i = 0; i < _dices; i++)
{
int currentResult = 0;
for (int j = 0; j < _throwDice; j++)
{
currentResult = rnd.Next(0, _diceSides);
}
_result += currentResult;
}
}
public DiceLogic(int dices, int diceSides, int throwEachDice)
{
_dices = dices;
_diceSides = diceSides;
_throwDice = throwEachDice;
CalculateResult();
}
}
This is an example of how you could implement what they are asking, go through te code line by line with the debugger so you understand what is going on.
You never call the method random(). Therefore, the value of your member variable _sum is never changed and remains 0. You need to call the method random() somewhere. You should probably make it public and call it from your main method after you have set up all your dice.
Furthermore, your member variables in the Dice class are all static! That means that the different Dice instances will all share the same values. I think this is not intended. You should make the variables instance variables by removing the static modifier.
Your method Tarning is not called and it takes a reserved word “throw” [I believe it was supposed to be thorw]. The method is not void so it must return a type.
Random() is not invoked and does display anything.
Dice has not constructor that has 3 arguments within its braces but it’s declared as _Dice.Add(new Dice(xChoice,yChoice, antThrow));

Categories