I have problem with my C# Bowling game and I would appericate some help I'll try to explain the code as well as i can. I've been trying to solve this issue for a long time and no success yet.
The calculation works fine but the only problem is my strike, the strike should count 10 + the next 2 coming throws.
So what my program does:
if you get a strike the first value will be set to 10, then I enter another strike and value is set to 21 but should be 20. The second box should then have a value of 30.
So first I have 3 arrays to hold all the textboxes
summa = new TextBox[] { textBox14, textBox15, textBox16, textBox17, textBox18, textBox19 };
slag1 = new TextBox[] { textBox1, textBox3, textBox5, textBox7, textBox9, textBox11 };
slag2 = new TextBox[] { textBox2, textBox4, textBox6, textBox8, textBox10, textBox12 };
So I have 2 methods, Slag1() and Slag2() the strike runs in the Slag1() method.
This is the part i use for the calculation of the strike
if (strike == true)
{
GotStrike[omgang] = true;
}
//strike = false;
//Kollar ifall textbox är lika med 10
if (slag1[omgang].Text == "10")
{
//Om text box är lika med 10 ändra värdet till X
//Lägg till 10 poäng på total
//Skriv ut värdet på summa (textbox)
Arbetar = true;
slag1[omgang].Text = "X";
total += 9;
summa[omgang].Text = total.ToString();
omgang++;
if (omgang == 6)
{
omgang--;
}
strike = true;
}
else if (slag1[omgang].Text == "X")
{
return;
}
else
{
checkSlag1 = Convert.ToInt32(slag1[omgang].Text);
total += checkSlag1;
summa[omgang].Text = total.ToString();
if (strike == true)
{
if (omgang != 0)
{
total += 10;
slag1[omgang - 1].Text = total.ToString();
if (omgang != 1)
{
slag1[omgang - 2].Text = total.ToString();
}
else
{
}
}
else
{
}
}
}
}
It's kinda hard to explain but I hope you understand, please tell me if you don't understand so I'll write a better explanation.
I hope you know how a bowling game works, a strike = the first strike and the value of the next 2 coming strikes. So if i hit a strike i get the value of 10, strike 2 value of 10 and strike 3 value of 10. That's the total of index 0.
Since you are having trouble with calculating the correct score for the bowling game, I would suggest to take out the bowling game mechanics, write tests that check if the different throws work correctly (ie normal, spare and strike). Then you can tinker with the code and when all tests pass, your scoring works. After that you can create any UI that uses the bowling game.
Also check the link I provided in the comment. The code is in Java but it is similar enough to C# and gives an example for a bowling game API with reasoning how they got to their particular design.
Your bowling game could look like this:
(I don't really know the bowling rules)
public class Bowling
{
public void Throw(int count) // How do you call these things that you need to knock over...
{
Debug.Assert(count >= 0);
Debug.Assert(count <= 12);
// ... Lots of interesting code.
}
public int GetScore()
{
return 16;
}
}
This code obviously doesn't work. The trick is to write tests that run "red" (=fail) and then to write code until the tests run "green" (=pass).
For these tests you can use a framework such as NUnit, ...
[TestClass]
public class BowlingTests
{
[Test]
public void ThrowNormal_NormalScore()
{
var b = new Bowling();
b.Throw(5);
b.Throw(6);
Assert.That(b.GetScore(), Is.EqualTo(11));
}
public void ThrowSpare_SpecialScore()
{
var b = new Bowling();
b.Throw(1);
b.Throw(11); // = spare
b.Throw(5); // score counts for double?
b.Throw(3); // No double score
Assert.That(b.GetScore(), Is.EqualTo(1 + 11 + (5 * 2) + 3));
}
// More tests for all the edge cases (strike, special end of game rules etc)
}
Related
I'm pretty new to C#, and programming overall. I'm doing a homework assignment right now and I'm losing my mind because I can't wrap my head around what my error here is. I feel like it's got to be something so obvious but I just can't see it. The errors are "ProgramBase.Menu()", "The name 'Console'does not exist in the current context", "QuestionRectangle does not exist in the current context".
using System;
namespace ProgLab3
{
class Program
{
static void Main(string[] args)
{
bool displayMenu = true;
while (displayMenu)
{
displayMenu = Menu();
}
}
private static bool Menu()
{
Console.Clear();
Console.WriteLine("Welcome to the menu! Below are your choices of options.");
Console.WriteLine("Type 1 to open Areas of Rectangles\n");
Console.WriteLine("Type 2 to open Biggest Number\n");
Console.WriteLine("Type 3 to open Valid Points\n");
Console.WriteLine("Type 4 to open Dollar Game\n");
Console.WriteLine("Type 5 to open Oldest Person\n");
Console.WriteLine("Type 6 to open Hi Lo Game\n");
Console.WriteLine("Type 7 to quit\n");
switch (Console.ReadLine())
{
case "1":
QuestionRectangle();
return true;
case "2":
return true;
case "3":
return false;
default:
return true;
}
}
private static void QuestionRectangle()
{
{
double width1, length1, area1;
double width2, length2, area2;
// Asking the user for measurements and then saving those numbers onto variables for the FIRST rectangle
Console.WriteLine("Welcome to the Areas of Rectangles choice.\nPlease start off by inputting the width of your first rectangle, do not include the metric unit of measurement.");
width1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Now please input the length of the first rectangle.");
length1 = Convert.ToDouble(Console.ReadLine());
//Calculating the area of the FIRST rectangle
area1 = width1 * length1;
// Asking the user for measurements and then saving those numbers onto variables for the SECOND rectangle
Console.WriteLine("Alright great, now please input the width of your second rectangle.");
width2 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Now what is the length of your second rectangle?");
length2 = Convert.ToDouble(Console.ReadLine());
//Calculating the area of the SECOND rectangle
area2 = width2 * length2;
// Checks if area 1 is greater than area 2
if (area1 > area2)
{
Console.WriteLine("Your first rectangle has a greater area, that area being " + area1);
}
// Checks if area 2 is greater than area 1
if (area1 < area2)
{
Console.WriteLine("Your second rectangle has a greater area, that area being " + area2);
}
// Checks if the areas are equal to each other
if (area1 == area2)
{
Console.WriteLine("Your rectangles have the same area, that area being " + area1);
}
}
}
}
}
The error is telling you that Console/QuestionRectangle is not reachable in the current context. This can mean one or more of the following:
you have a typo
the resource is not defined in the current namespace
the resource exists in another namespace which is not included using the using keyword
So, you will need to check your namespaces and fix the problems you have accordingly. I can see that QuestionRectangle is defined in your code, so I suppose that the actual code you have is either different, or has the problem at a place which was not shared.
EDIT
It turns out that in this particular case the copied content was corrupted along the way. carsonSgit looked into the issue and was able to localize what was missing. From then point on it was easier for him/her to find the path to the solution, by ensuring that the source and the target is identical.
I am using Visual Studio C# 2010 on Windows 10.
EDIT: My objective is to create an abort button which allows me to use the UI to cancel a loop.
I'm using an example I found online which is similar to this:
Here is the code:
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = "";
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(50); //do some intense task here.
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
}
}
(There was a bit of code sharing the date/time but I removed it since it was superfluous to the basic example).
How I'm understanding this code is that, 100 times, the code pauses the main thread and works on "some intense task" for 50ms. Is this the case?
If so, I think I've ran into a problem. I have this code I want to run:
private void btn_runtest_Click(object sender, EventArgs e)
{
// Exterior Platform Loop
Output.AppendText("Starting Test \n");
for (int i = 0; i <= 3200; i += 178)
{
// Interior Platform Loop
for (int ii = 0; i <= 6400; ii += 178)
{
comport7_interior.Write("#1N178\r"); //change to have actual length?
comport7_interior.Write("#1G\r");
Output.AppendText("Interior shift 5 degrees \n");
Thread.Sleep(4000);
// ***********************************************************************************
// Read data from comport2_lightsensor, Parse byte, store Lux value, store angle (i,ii)
// ***********************************************************************************
}
comport8_exterior.Write("#0N178\r");
comport8_exterior.Write("#0G\r");
Output.AppendText("Exterior shift 5 degrees \n");
Thread.Sleep(4000);
//flip direction for internal
if (IsOdd(jjj))
{
//
comport7_interior.Write("#1-\r");
Output.AppendText("Interior switching direction to counter clockwise \n");
}
else
{
comport7_interior.Write("#1+\r");
Output.AppendText("Interior switching direction to clockwise \n");
}
jjj = jjj + 1;
// ***********************************************************************************
// Read data from compart2_lightsensor, Parse byte, store Lux value, store angle (i,ii)
// ***********************************************************************************
}
Output.AppendText("Loop Ended");
// manually reverse mount direction
// repeat the whole double for loop
}
This is pretty "fatty" code, so to summarize, it controls two stepper motors, rotates them to follow the desired path, pauses for 4 seconds, and will eventually log data. We could do the exact math but simply estimating we can realize this code will take 1-2 hours. With all of this pausing, it does not seem conducive to being split into 100 little chunks on worked on separately (if my understanding of the previously stated code is correct). Correct me I'm wrong but I don't think this code would fit in the above code.
Does this mean I'm looking at the wrong approach?
Thank you all in advance.
So I created a game where player one and player two can play a game where they answer math questions, basically they go one after another for 5 rounds, so if one player answers the question right first they "Win" and if they both answer it right it is a "tie". Kind of a weird way to explain a weird game, but that's not my issue. I already finished the game inside of a class and it is functional and fine, my problem is that I need the players to play 5 games, and for it to tell who won the game the most, ex: "Player 1( or player 2, or draw) has won {0} times!" I have tried a lot of different things, but its all not working. Here is my code:
static void Main(string[] args)
{
string ID = "";
bool gOver = false;
Console.WriteLine("ID 1 ");
ID = Console.ReadLine();
MathGame p1 = new MathGame(1, ID);
Console.WriteLine();
Console.WriteLine("ID 2");
ID = Console.ReadLine();
MathGame p2 = new MathGame(2, ID);
Console.WriteLine();
while (!gOver)
{
MathGame.prblm();
while (!p1.Game() && !p2.Game())
gOver = true;
}
}
To reiterate; I'd like to make the game loop 5 times and tell me who won the most. I feel like my mistake is simple, make its just where I'm tired. Thanks for any and all help, this website is very helpful.
You need to wrap your game in a for loop, not a while. Then when the while loop (of your game) ends you should check who won and tally it. After the for loop you should have counters to display then.
There are many ways to "tally" but the easiest would be to add a variable for each player and increment when they win.
const in GAME_COUNT_TO_PLAY = 5;
for(int i = 0; i < GAME_COUNT_TO_PLAY; i++)
{
MathGame.prblm();
while (!p1.Game() && !p2.Game())
{
//Keep track of score here, incriment some counter for winner
//e.g. if(p1.Win) p1Count++;
}
}
After the for loop you can check for who won.
if(p1Count > p2Count)
Display("Player 1 Wins!");
else if(p1Count < p2Count)
Display("Player 2 Wins!")
else
Display("Draw!");
I'm making a program for keeping scores in a dart game where you can input x number of players and each player then gets to throw 3 arrows in the order they input their names and this repeats itself until someone reaches 501 points which ends the game.
The list for players seems to be working just fine but somehow I can't get the list for the arrows/score to work. I get no error in Visual Studio and I can run the program just fine, but if I try to print out the values in arrowList with a foreach loop nothing happens. As far as I can tell I've done the arrowList exactly as I did the players list which seems to work as intended, so why isn't the arrowList working??
I've been stuck on this task for my C# course for about a week now - I've found several questions here regarding a very similar task but I still can't get those suggestions to work with my code (and I don't want to just copy&paste their whole programs, after all I'm here to learn).
The code for my whole program:
class Program
{
static void Main(string[] args)
{
Game game = new Game();
game.PlayGame();
}
}
class Game
{
public Game()
{
//default constructor that takes 0 arguments
}
int playernumber = 0;
List<Player> players = new List<Player>();
public void PlayGame()
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Title = " Dartcounter 3000";
Console.WriteLine("Welcome to the Dartcounter 3000!");
NumberOfPlayers();
Console.WriteLine("");
foreach (var player in players)
{
if (player.ToString() == "Dator")
{
Console.WriteLine("Generating score for the NPC 'Dator'...");
Random random = new Random();
int randomThrow1 = random.Next(0, 60);
int randomThrow2 = random.Next(0, 60);
int randomThrow3 = random.Next(0, 60);
Arrows arrows = new Arrows(randomThrow1, randomThrow2, randomThrow3);
player.CalculatePoints();
}
else
{
Console.WriteLine("It's {0} turn to throw", player.ToString());
System.Threading.Thread.Sleep(500);
Console.WriteLine("Enter your score for the first arrow: ");
int arrowOne = int.Parse(Console.ReadLine());
Console.WriteLine("Your second arrow: ");
int arrowTwo = int.Parse(Console.ReadLine());
Console.WriteLine("Your third arrow: ");
int arrowThree = int.Parse(Console.ReadLine());
Arrows arrows = new Arrows(arrowOne, arrowTwo, arrowThree);
Console.WriteLine(arrows.ToString());
player.CalculatePoints();
}
}
Console.ReadLine();
}
// ------------ START of player methods in class Game ------------
public void NumberOfPlayers()
{
Console.WriteLine("Please enter the number of players: ");
start:
string playernumberinput = Console.ReadLine();
int value;
if (int.TryParse(playernumberinput, out value))
{
playernumber = int.Parse(playernumberinput);
AddPlayer();
}
else
{
Console.WriteLine("You did not input a number. Please try again: ");
goto start;
}
}
public void AddPlayer()
{
for (int i = 0; i < playernumber; i++)
{
Console.WriteLine("Enter name of player {0}:", i + 1);
players.Add(new Player(Console.ReadLine()));
}
}
// ------------ END of player methods in class Game ------------
}
class Arrows
{
public Arrows()
{
//default constructor that takes 0 arguements
}
public int roundScore;
public Arrows(int roundScore)
{
this.roundScore = roundScore;
}
public int arrowOne { get; set; }
public int arrowTwo { get; set; }
public int arrowThree { get; set; }
public Arrows(int Arrow1, int Arrow2, int Arrow3)
{
arrowOne = Arrow1;
arrowTwo = Arrow2;
arrowThree = Arrow3;
Player player = new Player();
player.AddArrows();
}
public int GetScore()
{
return arrowOne + arrowTwo + arrowThree;
}
public override string ToString()
{
return (string.Format("You got a total of {0} this round!", GetScore()));
}
}
class Player
{
public Player()
{
//default constructor that takes 0 arguments
}
public string Name;
public List<Arrows> arrowList = new List<Arrows>();
public Player(string Name)
{
this.Name = Name;
}
public void AddArrows()
{
Arrows arrows = new Arrows();
int roundScore = arrows.GetScore();
arrowList.Add(new Arrows(roundScore));
}
public void CalculatePoints()
{
foreach (var arrow in arrowList)
{
//Calculation to sum up the entry's in arrowList to see if someone has reached 501 points
}
}
public override string ToString()
{
return (string.Format("{0}", Name));
}
}
To follow up on this, I thought I'd walk through the process I use when developing and see if it helps. Plus, for some reason, this seemed like a fun project.
First, I copied/pasted the pseudo-code from my previous answer into a new console project, in the Main() method. Obviously a bunch of stuff was undefined, so then I started defining it so the code would compile.
The first thing that was undefined was Player, so I created an empty Player class:
public class Player { }
Next, the GetPlayers() method was undefined. This method will need to get all the players for the game and return them in a List, so I created the bare-bones method that returns a list of Players:
public static List<Player> GetPlayers()
{
var players = new List<Player>();
return players;
}
Next, the AnnounceRound method is undefined. I know this will simply announce that a new round is starting, and I decided to clear the console window at the start of each round as well:
public static void AnnounceRound(int roundNumber)
{
Console.Clear();
var announcement = string.Format("Beginning Round #{0}", roundNumber);
Console.WriteLine(announcement);
// The next line writes out a list of dashes that is the
// exact length of the announcement (like an underline)
Console.WriteLine(new string('-', announcement.Length));
}
Next, the AnnouncePlayer method is undefined. This will let everyone know who's turn it currently is:
private static void AnnouncePlayer(Player player)
{
Console.WriteLine("{0}It's now {1}'s turn.{0}", Environment.NewLine, player.Name);
}
But when I wrote the code the way I WANTED to use it, there was a problem: The Player class does not have a Name property. So back to the Player class. I will make the property read only (by making the setter private), and take the name as a parameter to the constructor. This way we do not allow someone to create a Player and then change his name later (this is how I want to do it, but it's not necessary. If we later decide to make it read-write, we can easily change the setter to public):
public class Player
{
public string Name { get; private set; }
public Player(string name)
{
Name = name;
}
}
The next thing that needs definition is the GetDarts method on the player object. Now that I've had a day to sleep on it, I don't like this name. Methods that begin with Get typically return some object, and my intention for this method is that it represents the player walking up to the dart board and grabbing the darts. Internally I imagine it will simply update a counter that represents how many darts the player is holding. So I will rename it in the original pseudo-code and also in the implementation in 'Player':
public class Player
{
public string Name { get; private set; }
private int dartsInHand;
public void GrabDarts()
{
dartsInHand = 3;
}
}
The next thing to implement is the 'HasUnthrownDarts' property. This is a bool that just represent whether the Player has any darts in hand or not.
public class Player
{
. . .
public bool HasUnthrownDarts { get { return dartsInHand > 0; } }
}
Next, we have the ThrowDart method. Now suddenly things get a little trickier. I noticed in your implementation, you let the human players enter their own score, and NPC players have a random-generated score. So this means a few things:
I have to have a property (or some other means) to differentiate between Human and NPC players
I have to do different things in this method depending on this property.
The simplest thing for now is to just create a bool property that defines the player type (and add this to the constructor with a default of false). If there were going to be more than two types of players, I would probably create an enum to define the types and a property on the Player object of that type. But for now, this will do:
public class Player
{
. . .
public bool IsNpc { get; private set; }
public Player(string name, bool isNpc = false)
{
. . .
IsNPC = isNpc;
}
}
Now, implement the ThrowDart method. All this method will do is get a score between 0 and 60, add it to the player's score, and decrement the number of darts in the player's hand. After some further thought, I might also want to return the score generated in this method so a "round score" can be tallied if necessary, and I decided to output the dart number and points as well. As usual, I wrote the code that I WANTED to use, with the plan to implement it afterwards.
public int ThrowDart()
{
if (dartsInHand < 1)
{
throw new Exception(string.Format("Player {0} has no darts to throw.", Name));
}
int dartScore;
int thisDartNumber = (3 - dartsInHand) + 1;
if (IsNpc)
{
// Get a random score for non-player characters
dartScore = rnd.Next(0, 60);
Console.WriteLine("{0} threw dart #{1} for {2} point{3}",
Name, thisDartNumber, dartScore, dartScore == 1 ? "" : "s");
}
else
{
dartScore =
ConsoleHelper.GetIntFromUser(string.Format(
"{0}, please enter the score for dart #{1} (0-60): ",
Name, thisDartNumber), "<Invalid score>",
(i) => i >= 0 && i <= 60);
}
Score += dartScore;
dartsInHand--;
return dartScore;
}
As I wrote this, I realized that I needed to get an integer from the user. This sounds simple, but it actually requires a bit of code to do the validation. The user could enter a non-integer string, in which case I'd have to ask them again. They could also enter a number that's outside of our bounds (0-60), in which case I would also have to ask them again. Because this code is semi-complex, and because I have a feeling we may need to get other integers from the user (we may need to ask how many NPC players they want to play against), I decided to create a new class called ConsoleHelper and add a method GetIntFromUser there. This method will simply get a string from the Console, convert it to an integer, apply some custom validation (if necessary), and return it. I've added some comments to help describe how it works as well:
public static class ConsoleHelper
{
/// <summary>
/// Gets an integer from the user
/// </summary>
/// <param name="prompt">A prompt to display to the user. Can be null.</param>
/// <param name="errorMessage">An error message to display if
/// the user enters an invalid integer. Can be null</param>
/// <param name="intValidator">A function to run which will validate
/// the integer. The integer will be passed to it, and it should
/// return true if the integer is valid. Can be null</param>
/// <returns>The integer entered by the user</returns>
public static int GetIntFromUser(string prompt, string errorMessage,
Func<int, bool> intValidator)
{
int intEntered;
while (true)
{
if (prompt != null) Console.Write(prompt);
var input = Console.ReadLine();
if (int.TryParse(input, out intEntered))
{
if (intValidator == null || intValidator(intEntered))
{
break;
}
}
if (errorMessage != null) Console.WriteLine(errorMessage);
}
return intEntered;
}
}
I also realized we also need to get random numbers for the NPC players. To do this, I created a private random property and set it in the constructor:
public class Player
{
. . .
private readonly Random rnd;
public Player(string name, bool isNpc = false)
{
. . .
rnd = new Random();
}
}
And I also am updating the imaginary Score property in this method, so let's implement that now, too:
public class Player
{
. . .
public int Score { get; private set; }
}
This also seems as good a time as any to take advantage of the fact that ThrowDarts returns the score for that dart number. For each player, for each round, I can give them a summary of how well they threw for that round:
. . .
var roundScore = 0;
while (p.HasUnthrownDarts)
{
roundScore += p.ThrowDart();
. . .
}
if (winner != null) break;
Console.WriteLine("{0} threw for {1} points this round.", p.Name, roundScore);
. . .
Another thing I decided to add was a 'MaxDarts' property to the Player. This allows me to store the number of darts in a single place, rather than have hard-coded '3's everywhere. So I added it to the Player class and updated the hard-coded values.
public class Player
{
. . .
public int MaxDarts { get; set; }
public Player(string name, bool isNpc = false)
{
. . .
MaxDarts = 3;
}
}
public void GrabDarts()
{
dartsInHand = MaxDarts;
}
public int ThrowDart()
{
. . .
int thisDartNumber = (MaxDarts - dartsInHand) + 1;
. . .
}
So, now that everything is compiling, the last thing left to do is actually implement the GetPlayers method. In order to collect both human and computer player information from the user without writing duplicate code, I created a second GetPlayers method that takes in a boolean that says if it should be computer players or not. Then, the GetPlayers() method simply calls this overload twice - once with false and once with true. Here are both methods:
public static List<Player> GetPlayers()
{
var players = GetPlayers(false);
Console.WriteLine();
players.AddRange(GetPlayers(true));
return players;
}
private static List<Player> GetPlayers(bool npcPlayers)
{
var players = new List<Player>();
var playerType = npcPlayers ? "NPC" : "human";
int numberOfPlayers = ConsoleHelper.GetIntFromUser(
string.Format("How many {0} players will be playing? ", playerType),
"<Invalid number>", (x) => x >= 0);
for (int i = 1; i <= numberOfPlayers; i++)
{
string name;
if (npcPlayers)
{
// Generate computer player names
name = string.Format("ComputerPlayer{0}", i);
}
else
{
// Get human names from the user
Console.Write("Enter the name for player #{0}: ", i);
name = Console.ReadLine();
}
players.Add(new Player(name, npcPlayers));
}
return players;
}
One other thing I decided to do is, at the beginning of each round, display the current standings. This code would normally be a copy of the code at the end of the game (that shows the final scores). Because we should never write duplicated code if possible, I wrapped it in a method called ShowScores:
public static void ShowScores(string message, List<Player> players)
{
if (message != null) Console.WriteLine(message);
foreach (var p in players.OrderByDescending(p => p.Score))
{
Console.WriteLine(" {0}: {1}", p.Name, p.Score);
}
}
Then I added code to call this method at the beginning of each round, and at the end of the game:
private static void Main()
{
. . .
while (winner == null)
{
round++;
AnnounceRound(round);
ShowScores("The current standings are:", players);
. . .
}
Console.Clear();
Console.WriteLine("We have a winner! Congratulations, {0}!!", winner.Name);
ShowScores("The final scores are:", players);
. . .
}
Now we're getting there. I decided to wrap the whole game inside another loop, in order to allow the users to play more than one game per session. To do enable this, I did a few things. First, added a Reset() method to the player class so their score would go back to zero:
public void Reset()
{
Score = 0;
dartsInHand = 0;
}
Then I wrapped the code in a loop, and reset the player's scores (if they already existed):
private static void Main()
{
Console.Write("Would you like to play a game of darts (y/n)? ");
var playGame = Console.ReadKey();
List<Player> players = null;
while (playGame.Key == ConsoleKey.Y)
{
Console.WriteLine(Environment.NewLine);
if (players == null)
{
players = GetPlayers();
}
else
{
players.ForEach(p => p.Reset());
}
. . .
Console.Write("{0}Would you like to play another game (y/n)? ",
Environment.NewLine);
playGame = Console.ReadKey();
}
Console.Write("{0}Thanks for playing! Press any key to quit...",
Environment.NewLine);
Console.ReadKey();
}
Hope this trip through my brain helped in some way! :)
That code needs... some work.
To answer your question though, you asked why the foreach doesn't print anything. I'll assume that you are referring to this one:
foreach (var arrow in arrowList)
{
//Calculation to sum up the entry's in arrowList to see if someone has reached 501 points
}
The only thing that adds to that collection is AddArrows which is weird, since you create arrows with the default constructor; call GetScore (which will always return 0, since you never initialized the arrows), then create a new Arrows object with that score.
Regardless, the only thing that calls that function is the overloaded constructor of Arrows which is even weirder; especially because you construct a new Player object here:
Player player = new Player();
player.AddArrows();
So your "new" arrows are scoped to that constructor; and then they fall out of scope and disappear.
You should be calling that function somewhere else; and about a million other things should be different (no goto statements for a start). Without re-writing your code for you (which you don't want; good for you!) its hard to say how to fix it. Honestly, the program is very small; I would just start over and maybe talk to my instructor on how to design it properly. Perhaps ask a few good questions here that relate to how to set this up.
It's great you're learning programming, and I thought I'd take a minute to share one way to approach a problem like this that has helped me in the past.
Know the Scenario and Key Pieces
When writing a simulation of real-world events and objects (which is pretty much what all programs do), I find it helpful to play out the scenario in my head first, figure out what the objects are, what their relevant properties and actions would be, and then try to write code to represent them. If the program is being written for someone else, this will come from an instructor or client in the real world.
Write a Flow Chart
Before writing any code, create a flow chart for the scenario that the code is representing. For the example of a darts game (let's assume they're playing 301), I would picture how it would happen in real life. A number of friends get together, each picks up 3 darts, they decide on the order in which they'll throw, and then, one at a time, each player throws all their darts and adds up their score. This 'round' score is added to their total score. At the moment when a player throws a dart that gives them a total score of 501 or more, the game is over and that player is the winner.
Create a UML diagram
Define the objects and how they will relate to each other. Define the relationships (one to many, many to many, is-a, has-a, etc.).
Write pseudo-code
Write some sample code, using imagined objects to represent how you'd LIKE to use them. This should really give you a sense of which objects should have which properties and methods.
Here's one way I can imagine writing the code:
List<Player> players = GetPlayers();
Player winner = null;
int round = 0;
while (winner == null)
{
round++;
AnnounceRound(round);
foreach(Player p in players)
{
AnnouncePlayer(p);
p.GetDarts();
while (p.HasUnthrownDarts)
{
p.ThrowDart();
if (p.Score >= 501)
{
winner = p;
break;
}
}
if (winner != null) break;
}
}
Console.WriteLine("We have a winner! Congratulations, {0}!!", winner.Name);
Console.WriteLine("The final scores are:");
foreach(Player p in players.OrderByDescending(p => p.Score))
{
Console.WriteLine(" {0}: {1}", p.Name, p.Score);
}
Now you have to define how the 'GetPlayers()' method will work using similar techniques, how the ThrowDart() method will update the player's score and his 'HasUnthrownDarts' property (and potentially output the resulting score of the specific throw), and what the AnnounceRound() and AnnouncePlayer() methods will output to the screen.
Hope that helps.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
So, Im a beginning C# programmer. I know basic syntax and simple things like if statements and loops(methods and classes too). I've only used console apps right now havent bothered with windows forms yet.
So any simple app ideas that introduce new things important for C# programming.
Also, NO tutorials. I want to make all by myself.
I'm a big fan of Halo, and one of the first things I did with C# was write an application that downloaded and parsed my online gaming stats while playing Halo 2. From there, I loaded all of the information into a database and redisplayed it in ASP.NET. In retrospect, the code was horrendous, but it was a fun exercise.
Another exercise was to parse the XML file for my iTunes music library, load it into a database, and (of course) display bits of it in ASP.NET.
Anyway, find ways to work with things you enjoy, be it games, music, television, or whatever.
A simple game might be a good start but those code golf questions can be a bit more advanced.
Why not try to write a 'test your reflexes' game, where you output a letter and time how long it takes for that letter to be keyed in? Then display the response time taken and the best response time to date.
Once i had to learn bash scripting for linux by writing the hangman game, it should be a good example for a console app in c#.
Hint:
start with
while(true)
{
//Game code goes here, use "continue" or "break" according to game logic.
}
One fun way to develop your skills is through code katas and programming contests like Top Coder and Google Code Jam. There are tons of example problems that will make you think, and many come with solutions that you can compare against after you are finished.
Even when you've been a developer for a while, these kind of simple problems allow you to incorporate new practices in your programming style (for instance, a kata is a great way to start learning the principles of TDD). Plus, they make for fun distractions.
I think solving Top-Coder problems will be great practice! It's specially suited since all their problems are console based, and they will make you increase not only your knowledge of c#, but also your problem solving skills and your data structure/algorithms knowledge.
That said, you probably wont learn much about new or more platform specific stuff about C#, such as linq, event handlers, threading, parallel tasks library, etc etc. For that, the best would be to find a good C# book and go through it.
Another way could be making little games. I know its console, but you can actually make games like Snake, Pac-man, hangman, etc, of course, with a little extra imagination, but it still works and games are great learning exercises (and are fun to show to people)
Write something recursive, like a routine that calculates the value of a factorial.
I recently developed a sudoku solver and a 8Queens solver.
I made the sudoku solver in console where the puzzle itself was hard coded in the project. You could try to make it possible to use a textfile as an input. I implemented a brute force algorithm witch works with recursion. It's is nice to develop such a solver and once you're ready there probably will be lots of improvements possible.
The 8Queens solver learned me two things. First I had to made a chessboard, which I did with forms. Learned me about Pens, Brushes and drawing. Also it was a nice practice for recursion which you have to do a lot before you understand it...
I'd suggest writing a command-line tool that does something that maybe can't be done by anything else.
The one thing that springs to mind is something that applies XSL stylesheets to XML files and spits out the output. There's sample code everywhere but no straightforward Windows tool that I've seen.
Potential benefits of this approach are that you end up with a useful tool and you then have the option of making it open-source to get additional input/support.
Well they are all tough to do, so i suggest using the copy paste method with my Blackjack app
remember to reference add system speech synth
using System;
using System.Speech.Synthesis;
namespace Blackjack
{
class Blackjack
{
static string[] playerCards = new string[11];
static string hitOrStay = "";
static int total = 0, count = 1, dealerTotal = 0;
static Random cardRandomizer = new Random();
static void Main(string[] args)
{
using (SpeechSynthesizer synth = new System.Speech.Synthesis.SpeechSynthesizer())
{
Console.Title = "Blackjack";
synth.Speak("Please enter your blackjack table's name followed by a comma then the secondary name (AKA table number)");
string bjtn = Console.ReadLine();
Console.Clear();
Console.Title = bjtn;
}
Start();
}
static void Start()
{
dealerTotal = cardRandomizer.Next(15, 22);
playerCards[0] = Deal();
playerCards[1] = Deal();
do
{
Console.WriteLine("Welcome to Blackjack! You were dealed " + playerCards[0] + " and " + playerCards[1] + ". \nYour total is " + total + ".\nWould you like to hit or stay? h for hit s for stay.");
hitOrStay = Console.ReadLine().ToLower();
}
while (!hitOrStay.Equals("h") && !hitOrStay.Equals("s"));
Game();
}
static void Game()
{
if (hitOrStay.Equals("h"))
{
Hit();
}
else if (hitOrStay.Equals("s"))
{
if (total > dealerTotal && total <= 21)
{
Console.WriteLine("\nCongrats! You won the game! The dealer's total was " + dealerTotal + ".\nWould you like to play again? y/n");
PlayAgain();
}
else if (total < dealerTotal)
{
Console.WriteLine("\nSorry, you lost! The dealer's total was " + dealerTotal + ".\nWould you like to play again? y/n");
PlayAgain();
}
}
Console.ReadLine();
}
static string Deal()
{
string Card = "";
int cards = cardRandomizer.Next(1, 14);
switch (cards)
{
case 1: Card = "Two"; total += 2;
break;
case 2: Card = "Three"; total += 3;
break;
case 3: Card = "Four"; total += 4;
break;
case 4: Card = "Five"; total += 5;
break;
case 5: Card = "Six"; total += 6;
break;
case 6: Card = "Seven"; total += 7;
break;
case 7: Card = "Eight"; total += 8;
break;
case 8: Card = "Nine"; total += 9;
break;
case 9: Card = "Ten"; total += 10;
break;
case 10: Card = "Jack"; total += 10;
break;
case 11: Card = "Queen"; total += 10;
break;
case 12: Card = "King"; total += 10;
break;
case 13: Card = "Ace"; total += 11;
break;
default: Card = "2"; total += 2;
break;
}
return Card;
}
static void Hit()
{
count += 1;
playerCards[count] = Deal();
Console.WriteLine("\nYou were dealed a(n) " + playerCards[count] + ".\nYour new total is " + total + ".");
if (total.Equals(21))
{
Console.WriteLine("\nYou got Blackjack! The dealer's total was " + dealerTotal + ".\nWould you like to play again?");
PlayAgain();
}
else if (total > 21)
{
Console.WriteLine("\nYou busted, therefore you lost. Sorry. The dealer's total was " + dealerTotal + ".\nWould you like to play again? y/n");
PlayAgain();
}
else if (total < 21)
{
do
{
Console.WriteLine("\nWould you like to hit or stay? h for hit s for stay");
hitOrStay = Console.ReadLine().ToLower();
}
while (!hitOrStay.Equals("h") && !hitOrStay.Equals("s"));
Game();
}
}
static void PlayAgain()
{
string playAgain = "";
do
{
playAgain = Console.ReadLine().ToLower();
}
while (!playAgain.Equals("y") && !playAgain.Equals("n"));
if (playAgain.Equals("y"))
{
Console.WriteLine("\nPress enter to restart the game!");
Console.ReadLine();
Console.Clear();
dealerTotal = 0;
count = 1;
total = 0;
Start();
}
else if (playAgain.Equals("n"))
{
using (SpeechSynthesizer synth = new System.Speech.Synthesis.SpeechSynthesizer())
{
synth.Speak("\nPress enter to close Black jack." + dealerTotal);
}
ConsoleKeyInfo info = Console.ReadKey();
if (info.Key == ConsoleKey.Enter)
{
Environment.Exit(0);
}
else
{
Console.Read();
Environment.Exit(0);
}
}
}
}
}