Inheritance - storing objects list<class> with loops C# - c#

I'm stuck one an exercise which is very important to understand for my soon come final exam, in a basic C# course.
I have an issue that I can't describe in words. So I'll show you with code and perhaps then you might help me.
I've been stuck on this, not being able to solve it, for a long time. Cuz of that, I don't want any copy paste code. I want to understand it. So please enlighten me where I've failed.
Explanation what I want to do.
I want to create a dart game 501. So first I add players, they throw their darts, you get the score after each turn announced, then when one player reach 501 points, the game announce the winner and all of his throws.
My idea of approaching the problem is to have an add player loop, which terminates (I got this fixed already).
Once you done creating the players(list elements), then you'll execute the methods with a foreach loop running all the players in the player list, executing the objects one at a time and finally Here is my real problem: storing all their scores in another list.
Here we go with the code
The list.
private List<Player> players = new List<Player>(); //This list is fine
Here is the loop.
foreach (Player dartThrows in players) //My loop
{
dartThrows.DoThrow();
dartThrows.GetScore();
}
SubClass1(named Player)
public List<Darts> dartList = new List<Darts>(); //<--HERE IS THE PROBLEM
Just some random constructors and methods.
The throw method. It's not an issue but I typed it down to give you an idea
public void DoThrow()
{
var tries = 3;
for (int i = 0; i < tries; i++)
{
//No problems here just int read-user input data
}
AddDarts(int a, int b, intc)
}
Here lies all my problems, it would make my life so much easier if this could get solved.
public void AddDarts(Darts toDartList)
{
dartList.Add(toDartList);
}
SubClass2 (Darts)
Here are my constructors
private int dartOne;
private int dartOne;
private int dartOne;
Here is my method
public Darts(int DartOne, int DartTwo, int DartThree)
{
dartOne = DartOne;
dartTwo = DartTwo;
dartThree = DartThree;
}
Best regards Marcus Johansson
Here is my full program
class Program
{
static void Main(string[] args)
{
Game game = new Game();
game.PlayGame();
}
}
class Game
{
private List<Player> players = new List<Player>();
private List<Player> computers = new List<Player>();
public void AddPlayer(string newPlayers)
{
players.Add(new Player(newPlayers));
}
public void AddComputer(string newComputer)
{
computers.Add(new Player(newComputer));
}
static string UpperCaseFirst(string s)
{
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
return char.ToUpper(s[0]) + s.Substring(1);
}
public void PlayGame()
{
bool noWinner = false;
bool stopLoop = false;
Console.WriteLine("<<<WELCOME TO DART 501>>>");
Console.WriteLine("\nPress [S] to start game!");
Console.Beep();
Console.ReadLine();
Console.Clear();
do
{
Console.WriteLine("Enter name of players and type [D]ator for adding NPC\nType [S]top to start the game");
string addPlayer = Console.ReadLine();
string FirstUpperLetter = UpperCaseFirst(addPlayer);
if (FirstUpperLetter == "Stop" || FirstUpperLetter == "S")
{
stopLoop = true;
}
if (FirstUpperLetter == "D" || FirstUpperLetter == "Dator")
{
string computer = FirstUpperLetter;
AddComputer(computer);
}
else
{
AddPlayer(FirstUpperLetter);
}
} while (stopLoop == false) ;
players.RemoveAt(players.Count - 1);
do
{
Console.Clear();
foreach (Player arrowThrows in players)
{
noWinner = true;
Console.WriteLine("\n~~~Starting Round~~~~");
arrowThrows.DoThrow();
Console.WriteLine("This round you got {0}", arrowThrows.CalculatePoints());
if (arrowThrows.Score > 501)
{
Console.Clear();
Console.WriteLine("<<<WE HAVE A WINNER>>>");
System.Threading.Thread.Sleep(500);
Console.WriteLine("...The winner is: ");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("{0} He made these epic throws: ", arrowThrows.Name);
foreach(Arrows finalResult in arrowThrows.arrowList)
{
Console.WriteLine(finalResult);
Console.ReadLine();
}
noWinner = false;
}
}
foreach (Player computerThrows in computers)
{
computerThrows.RandomThrow();
System.Threading.Thread.Sleep(500);
}
}while(noWinner == true);
}
}
class Player
{
public List<Arrows> arrowList = new List<Arrows>();
public List<int> ScoreBoard = new List<int>();
public Player() { }
public int Score { get; set; }
public Player(int score)
{
Score = score;
}
public string Name { get; set; }
public Player(string name)
{
Name = name;
}
public int RoundScore { get; set; }
public void RandomThrow()
{
Random rndComp = new Random();
Console.WriteLine("...Loading Npc_throw.exe");
System.Threading.Thread.Sleep(300);
int random1 = rndComp.Next(0, 60);
System.Threading.Thread.Sleep(300);
int random2 = rndComp.Next(0, 60);
System.Threading.Thread.Sleep(300);
int random3 = rndComp.Next(0, 60);
Console.WriteLine("Random computer got this random score {0}", random1 + random2 + random3);
arrowList.Add(new Arrows(random1, random2, random3));
}
public void DoThrow()
{
Console.WriteLine("###{0} make your throws###", Name);
var tries = 3;
for (int i = 0; i < tries; i++)
{
Console.WriteLine("\nEnter score for {0} arrow", i + 1);
string arrowScore = Console.ReadLine();
int addScore = int.Parse(arrowScore);
while(-1 > addScore || 61 < addScore)
{
Console.WriteLine("\nInvalid score! Enter a score between 0-60/n<<<You may type [R]andom or [R] for a random score>>>");
arrowScore = Console.ReadLine().ToUpper();
if (arrowScore == "R" || arrowScore == "RANDOM")
{
Random rnd = new Random();
addScore = rnd.Next(0, 60);
goto start;
}
else
{
addScore = int.Parse(arrowScore);
}
}
start:
ScoreBoard.Add(addScore);
}
ScoreBoard.ToArray();
arrowList.Add(new Arrows(ScoreBoard[0],ScoreBoard[1], ScoreBoard[2]));
}
public int CalculatePoints()
{
Score = ScoreBoard.Sum();
return Score;
}
public void AddArrows(Arrows toArrowList)
{
toArrowList.ToString();
arrowList.Add(new Arrows(ScoreBoard[0], ScoreBoard[1], ScoreBoard[2]));
}
}
class Arrows
{
private int arrowOne;
private int arrowTwo;
private int arrowThree;
public int score { get; set; }
public Arrows(int ArrowOne, int ArrowTwo, int ArrowThree)
{
arrowOne = ArrowOne;
arrowTwo = ArrowTwo;
arrowThree = ArrowThree;
}
public int GetScore()
{
return arrowOne + arrowTwo + arrowThree;
}
public override string ToString()
{
return string.Format("{0}-1:st arrow: {1}-2:nd arrow: {2}- 3:rd arrow: {3}", GetScore(), arrowOne, arrowTwo, arrowThree);
}
}
}

The problem with your approach, is your utilizing a List. This collection has no unique information, simply a grouping of data. Which would have me recommend either a Tuple, Dictionary, KeyValuePair, or a clean Data Model.
Without the requirements are approaches may not be viable. Your issue stems from persistence related issues. Your multiple inheritance title is also incorrect, C# only allows a single class to be inherited.
What I would potentially do would be:
public class Player
{
public string Name { get; set; }
public string Throw { get; set; }
public string Points { get; set; }
}
What this does, is incredibly beneficial. The above class represents a specific Model. When your method is called for a throw you apply said results. Then when you calculate the score you iterate through the List<Player> for a specific person or all and display the output.
I'm not going to write your application, but think of it like this:
Player Registers
Player Turn
Player Throws
Play Scored
Store Player Result
Repeat Steps two through five, three times.
Display Output: Player, Throw, Score, and Total Score
By utilizing that model, you hold the relative information for your outcome. This conceptual notion is important for Object Oriented Programming.

You can use a Dictionary to save scores for each player
Dictionary<Player, List<int>> playerScores = new Dictionary<Player, List<int>>();
playerScores.Add(player1, new List<int>()); //init dictionary with a new player
playerScores[player1].Add(number); //add a value to the list associated with the player
So each player has a list of scores.

Related

C# Updating a value in a list of objects is updating other values too

I was working on a simple turn based RPG game. I was working on a battle system. I had it working with 1 enemy, and wanted to update it to work on multiple enemies. I have it spawning multiple enemies, but I am having issues targeting them.
Basically, the enemies are stored in a list called actualEnemies. The enemies are generated at run time, and there can be between 1-3. A label is generated to display the enemy name, and the enemy is selected by double clicking on it.
The issue seems to be in the naming of the enemy's. They have a property called characterName to identify an enemy. The problem is, there can be 2 or more of the same type of character (for example, 3x Goblin). So in the code where the enemies are generated, I was wanting to add a 1 to the characterName if there already is one in the list. The idea is to give each enemy a unique name.
The problem is, when I try this, it changes the values of all of the enemies of the same name, and this is screwing with everything. Here is the relevant section of code:
if (EnemyExists(e)) {
e.characterName += c.ToString();
}
c is simply a counter that is being used, to let me know if it is enemy 1, 2 or 3.
The EnemyExists function is as follows:
public bool EnemyExists(Enemy e) {
bool exists = false;
int eCount = 0;
foreach (Enemy en in actualEnemies) {
if (en.characterName == e.characterName) {
eCount++;
}
}
if (eCount > 1) {
exists = true;
}
return exists;
}
Just to note, the enemies all start off with a default name. For this example I am working on, there are only 2 kinds of enemy. The game picks a random number between 1-3, to decide how many enemies there are. Each enemy will be one of the 2 pre defined enemies, picked at random again. This is why I just want to add a number to the end of a name that is already present.
I suspect it has something to do with how I am creating the list of enemies:
public void CreateActualEnemies() {
int r;
int potEnemyNum = potentialEnemies.Count;
int numEnemies;
Random rand = new Random();
numEnemies = rand.Next(1, 4 );
for (int i = 0; i < numEnemies; i++) {
r = rand.Next(0,potEnemyNum);
Enemy ene = new Enemy();
ene = potentialEnemies.ElementAt(r);
actualEnemies.Add(ene);
}
DisplayEnemyDetails();
}
When I add to actualEnemies, am I just pointing to an address in potentialEnemies, so even though I am instantiating a new Enemy, each one, if it has the same name, points to the same place? Do I need to properly copy the object?
It is late, I am tired, but I feel like I am getting closer, any help would be great, thanks.
EDIT:
Enemy Class:
public class Enemy:Character {
public int xpGiven { get; set; }
public LootTable lootTable { get; set; }
public int goldDropped { get; set; }
public bool alive { get; set; }
public NamedTimer timer { get; set; }
public Enemy() {
alive = true;
xpGiven = 10;
lootTable = new LootTable();
goldDropped = 10;
timer = new NamedTimer();
}
}
Breaking down your question:
When I add to actualEnemies, am I just pointing to an address in potentialEnemies, so even though I am instantiating a new Enemy, each one, if it has the same name, points to the same place?
By doing
Enemy ene = new Enemy();
You are essentialy creating a new pointer in memory with a "blank" valued-reference.
However, since you did
ene = potentialEnemies.ElementAt(r);
You overwrote it with the reference to the element in the list. So whatever changes you do the ene object will reflect the item in the list.
If you want to segregate said changes, try using a MemberwiseClone.
From the example given at MSDN:
public class Person
{
public int Age;
public string Name;
public IdInfo IdInfo;
public Person ShallowCopy()
{
return (Person) this.MemberwiseClone();
}
public Person DeepCopy()
{
Person other = (Person) this.MemberwiseClone();
other.IdInfo = new IdInfo(IdInfo.IdNumber);
other.Name = String.Copy(Name);
return other;
}
}
1: Property names should start with a capital letter in C#. I.e. public int xpGiven { get; set; } should be public int XpGiven { get; set; }. If it's a class variable (no get or set defined), you start with a lower case letter. To more easily identify class variables from local variables, programmers typically start them with a _, although this is not mandatory.
2: When doing ==, please be aware enemyA == enemya will return false. Use enemyA.Equals(enemya, StringComparison.OrdinalIgnoreCase) to ignore capital differences.
3:
public void CreateActualEnemies()
{
int r;
int potEnemyNum = potentialEnemies.Count;
int numEnemies;
Random rand = new Random();
numEnemies = rand.Next(1, 4 );
for (int i = 0; i < numEnemies; i++)
{
r = rand.Next(0,potEnemyNum);
Enemy ene = new Enemy();
ene = potentialEnemies.ElementAt(r);
actualEnemies.Add(ene);
}
DisplayEnemyDetails();
}
should be:
public void CreateActualEnemies()
{
Random rand = new Random();
int numEnemies = rand.Next(1, 4 );
for (int i = 0; i < numEnemies; i++)
{
Enemy ene = new Enemy();
ene.characterName = "" + ene.GetType().Name + " " + i; // or something similar to give the ene a unique name.
actualEnemies.Add(ene);
}
DisplayEnemyDetails();
}

Assigning objects to an array C#

Struggling to assign objects to an array in C#.
The output of the code is unexpected because I get the nameOfProject.ClassName(?) x3 rather than name and life points of 3 monsters i added using my for loop.
Debug suggests monsters aren't being assigned. Is there a logical flaw that people like me should be looking out for?
class Monsters
{
public Monsters(string name, int points)
{
var monsterName = name;
var monsterLifePoints = points;
}
}
class Program
{
static void Main(string[] args)
{
Monsters[] monster = new Monsters[3];
for (int i = 0; i < monster.Length; i++)
{
Console.WriteLine("Please enter a name");
string name = Console.ReadLine();
Console.WriteLine("Please enter life points");
int points = Convert.ToInt32(Console.ReadLine());
monster[i] = new Monsters(name,points);
Console.Clear();
}
foreach (var element in monster)
{
Console.WriteLine(element);
}
Console.ReadKey();
}
Assignment works just fine. The problem is that you never asign the monster's name and points to a field or property:
class Monsters
{
public Monsters(string name, int points)
{
var monsterName = name;
var monsterLifePoints = points;
}
}
This code just assigns the input to local values and then discards them.
Your class should look like this:
class Monsters
{
public string Name {get;set;}
public int Points {get;set;}
public Monsters(string name, int points)
{
Name = name;
Points = points;
}
}
This line still won't print the details :
Console.WriteLine(element);
You need to either create a string from the properties :
Console.WriteLine($"{element.Name} {element.Points}");
Or override the ToString() method of your class :
public override string ToString()
{
return $"{element.Name} {element.Points}";
}
How should WriteLine know that you want to print those two properties and not e.g. the type-name (which it does per default) or any other wierd string? You have to tell your program how to do this. This is done by overriding ToString
class Monster
{
public override string ToString() {
return this.name + " " + this.lifePoints;
}
}
Furthermore your variables need to be fields:
class Monster
{
private readonly string name;
private readonly int lifePoints;
Monster(string name, int points)
{
this.name = name;
this.lifePoints = points;
}
}

C# Poker: how to keep track of players and make game engine (classes) preflop, flop, turn, river?

Im recently studying c# and want to create a 'simple' console app poker game.
Ive created classes: player, hand, deck, dealer. Dealer gets cards out of the deck and assigns it to player instances. What I'm struggling with now is how to progress further? I need to make some gameplay possible.
This is what i have coded thusfar:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication10
{
class Program
{
static void Main(string[] args)
{
//Deck d = new Deck();
Player[] players = new Player[2];
Dealer dealer = new Dealer();
players[0] = new Player("M");
players[1] = new Player("T");
foreach (var player in players)
{
Console.WriteLine(player.name);
}
Console.WriteLine();
foreach (var player in players)
{
player.AddCardsToHand(dealer);
}
Console.WriteLine("View hand van player 1");
foreach (string card in players[0].ViewHandCards())
{
Console.WriteLine(card);
}
Console.WriteLine();
Console.WriteLine("View hand van player 2");
foreach (string card in players[1].ViewHandCards())
{
Console.WriteLine(card);
}
Console.WriteLine();
Console.WriteLine("Number of players instantiated:");
Console.WriteLine(Player.playerCount);
Console.WriteLine();
Console.WriteLine("Number of hands instantiated:");
Console.WriteLine(Hand.handCount);
Console.WriteLine();
dealer.SetMoneyAmount(players[0]);
dealer.SetMoneyAmount(players[1], 150);
Console.WriteLine("Money player 1:");
Console.WriteLine(players[0].MoneyAmount);
Console.WriteLine();
Console.WriteLine("Money player 2:");
Console.WriteLine(players[1].MoneyAmount);
Console.WriteLine();
int index = 0;
dealer.SetDealer(players[index]);
Console.WriteLine("Dealer: " + dealer.GetDealer());
// how to know in a class how many players there are and there values?
// create a class containing the players array?
}
}
class Settings
{
// static string dealer;
public static int dealerIndex;
public static string dealerName;
public
}
class User
{
public string name;
}
class Player : User
{
Hand h = new Hand();
public static int playerCount;
private double moneyAmount;
public bool dealerButton;
public double MoneyAmount
{
get
{
return moneyAmount;
}
set
{
moneyAmount = value;
}
}
public int NumOfCardsInHand()
{
return h.cardsInHand;
}
public string[] ViewHandCards()
{
return h.handCards;
}
public void AddCardsToHand(Dealer d)
{
d.DealCard(h);
d.DealCard(h);
}
public Player(string n)
{
this.name = n;
playerCount++;
}
}
class Hand
{
public static int handCount;
public int cardsInHand = 0;
public string[] handCards = new string[2];
public Hand()
{
handCount++;
}
}
class Dealer
{
Deck d = new Deck();
//public void StartGame()
//{
//}
public void DealCard(Hand h)
{
if (h.cardsInHand < 2)
{
if (h.cardsInHand == 0)
h.handCards[0] = d.NextCard();
if (h.cardsInHand == 1)
h.handCards[1] = d.NextCard();
h.cardsInHand++;
}
else
{
Console.WriteLine("Meer dan 2 kaarten per hand is niet toegestaan");
}
}
public void SetMoneyAmount(Player p, double amount = 100)
{
p.MoneyAmount = amount;
}
public void SetDealer(Player p)
{
p.dealerButton = true;
Settings.dealerName = p.name;
}
public string GetDealer()
{
return Settings.dealerName;
}
}
class Deck
{
public int numOfCards = 52;
public string[] cards = new string[13];
public string[] playingCards = new string[52];
public string[] cardsDealt = new string[52];
Random r = new Random();
int y = 0;
public string NextCard()
{
string nextCard = "-";
int x = 0;
while (x < 1)
{
nextCard = playingCards[r.Next(0, playingCards.Length)];
if (!cardsDealt.Contains(nextCard))
{
cardsDealt[y] = nextCard;
y++;
x++;
}
else
{
Console.WriteLine("Reeds gedeelde kaart bijna opnieuw gedeeld!");
x = 0;
}
}
return nextCard;
}
public void ConstructDeck()
{
// spade club heart diamond
this.cards[0] = "A";
this.cards[1] = "K";
this.cards[2] = "Q";
this.cards[3] = "J";
this.cards[4] = "10";
this.cards[5] = "9";
this.cards[6] = "8";
this.cards[7] = "7";
this.cards[8] = "6";
this.cards[9] = "5";
this.cards[10] = "4";
this.cards[11] = "3";
this.cards[12] = "2";
int x = 0;
foreach (string card in this.cards)
{
this.playingCards[x] = card + "s";
x++;
this.playingCards[x] = card + "c";
x++;
this.playingCards[x] = card + "h";
x++;
this.playingCards[x] = card + "d";
x++;
}
}
public Deck()
{
ConstructDeck();
}
}
class Bet
{
public double betAmount;
public Bet(Player p, double betInput)
{
betAmount = betInput;
}
}
}
I have put the player instances in an array and can call them like this players[0] (player 1).
I would like to know if im on the right track here and more specifically how do I keep track of the players I instantiated so that other classes can access the player instance variables? Im assigning one player the dealer status and would need to know where to start asking for other players initiative in the game like needing to bet call check or fold at some given point. I dont know what kind of classes I would need to create for a preflop game, a flop game, a turn game and the river game. Classes for each game name? How would I check if a player finished his action?
I think I should create a class like: preflopgame and identify the dealer than ask initiative (bet fold etc (make classes of betting folding checking etc) of the player thats not the dealer and keep track via a variable that player finished its initiative in the preflopgame class? And if preflopgame is played out: some kind of static boolean field in the class indicating its finished. Than move on to the next game: flopgame. Is this the right way of thinking about this game?
Any suggestions would certainly be much apreciated.
Excuse my English im Dutch from origin.

Knights Tour recursive C# Im getting something wrong in my way of doing the stuff

class Knight
{
public static readonly double LegalDistance = Math.Sqrt(5);
public Stack<Field> Steps { get; set; }
private static readonly List<Field> board = Board.GameBoard;
private static List<Field> fields;
private static readonly Random random = new Random();
private static readonly object synLock = new object();
public Knight(Field initial)
{
Steps = new Stack<Field>();
Steps.Push(initial);
}
public void Move()
{
Field destination = Choose();
if (destination == null)
{
return;
}
Console.WriteLine("Moving from " + GetPosition().GetFieldName() + " to " + destination.GetFieldName());
Steps.Push(destination);
}
public Field Back()
{
Field from = Steps.Pop();
Console.WriteLine("Moving back from " + from.GetFieldName() + " to " + GetPosition().GetFieldName());
return from;
}
public Field Choose()
{
List<Field> legalMoves = Behaviour();
legalMoves.RemoveAll(field => Steps.Contains(field, new FieldValueComparer()));
if (legalMoves.Count == 0)
{
return null;
}
Field theChoosenOne;
int index;
lock (synLock)
{
index = random.Next(0, legalMoves.Count);
}
theChoosenOne = legalMoves.ElementAt(index);
return theChoosenOne;
}
private List<Field> Behaviour()
{
fields = new List<Field>();
fields.AddRange(board);
for (int i = fields.Count - 1; i >= 0; i--)
{
double actualDistance = fields[i].GetDistance(GetPosition());
if (!actualDistance.Equals(LegalDistance))
{
fields.Remove(fields[i]);
}
}
return fields;
}
public List<Field> GetSteps()
{
return Steps.ToList();
}
public Field GetPosition()
{
return Steps.Peek();
}
}
So this is how I'd do the stuff. The problem is, I am missing some key functionality, because on low given stepcount it backtracks to the start, on high stepcount, it causes StackOverFlow.
Here are some other functions to let you understand what I want to do:
Calculating distance:
public double GetDistance(Field other)
{
return Math.Sqrt(Math.Pow(other.X - X, 2) + Math.Pow(other.Y - Y, 2));
}
Finding the path:
class PathFinder
{
public static void FindPath(Knight knight)
{
if (knight.Steps.Count != 20)
{
knight.Move();
FindPath(knight);
knight.Back();
}
}
}
Your path search is essentially random walk. On large board, this may take a while anyway.
Now about StackOverflow: notice that you don't push anything on Move() when there are no places to go. So, on recursive call to FindPath() there still will be the same knight.Steps.Count, the same position, the same null return on Choose()... and so on, until you're out of stack space.
Obvious fix would be to add bool return value to Move() indicating if there was any move. Unless there is actual reason behind using random moves, more deterministic search algorithm is recommended.

How to tie in an object that's related with others- C#, OOD

I'm struggling on a blackjack console app and need help designing/relating my Seat class.
For the game, there are six seats and a seat can only have one player but a player can occupy (or bet) on up to three seats if the seat is unoccupied. Also, the TableGame has six seats available.
Regarding the TableGame class, it should have six seats. So should I construct the six seats in the TableGame constructor? What about creating a public property i.e. SeatsAvailable that uses an array to catch which seats are available?
Also, a player occupies a seat, and places a bet on it. How should I go about coupling these guys together so that it's tied to the player making the bet?
Advice on how to couple the Seat class with the TableGame, Player class would be greatly appreciated as well as any critiques, direction I should take note of. Thank you in advance for helping a beginner learn the ropes of OO design.
public class TableGame
{
public TableGame(IEnumerable<string> playerNames)
{
List<Player> players = new List<Player>();
foreach (string name in playerNames)
{
players.Add(new Player(name));
// add the player to a new instance of a seat or to an array of already created seats(6)???
}
Dealer dealer = new Dealer();
players.Add(dealer);
PlayGame(players, dealer);
}
private void PlayGame(List<Player> players, Dealer dealer)
{
try
{
Deck playingDeck = new Deck();
Deal(playingDeck, players);
Play(playingDeck, players);
DetermineHandResults(players, dealer);
TransferBets(players, dealer);
}
catch (InvalidTransferAmountException ex)
{
players.Remove(ex.OffendingPlayer);
}
DisplayResults(players); // I want this here so that DispayResults() is still called even if an InvalidTransferAmount exception is caught.
} // However other types of exceptions (unhandled) will kick me out of PlayGame() and DisplayResults() will not be
// called. Use a finally block to execute something no matter what exception is thrown- handled or unhandled.
public void Deal(Deck deck, List<Player> players)
{
deck.Shuffle();
for (int i = 1; i < 3; i++)
foreach (Player player in players)
player.ReceiveCard(deck.Deal());
}
public void Play(Deck playingDeck, List<Player> players)
{
foreach (Player player in players)
player.Strategy(playingDeck);
}
public void DetermineHandResults(List<Player> players, Dealer dealer)
{
foreach (Player player in players)
{
if (player.playerHand.HandValue() > 21)
player.result = Result.Lose;
else if (player.playerHand.HandValue() <= 21 && dealer.playerHand.HandValue() > 21)
player.result = Result.Win;
else if (player.playerHand.HandValue() <= 21 && player.playerHand.HandValue() > dealer.playerHand.HandValue())
player.result = Result.Win;
else if (player.playerHand.HandValue() == dealer.playerHand.HandValue())
player.result = Result.Draw;
else
player.result = Result.Lose;
}
}
public void TransferChips(Player playerTo, Player playerFrom, decimal value)
{
if (playerFrom.TotalChips < value)
throw new InvalidTransferAmountException(string.Format("Can not transfer {0} from {1}'s bank roll, only {2:2d} available!",
value, playerFrom.Name, playerFrom.TotalChips), playerFrom);
playerTo.TotalChips += value;
playerFrom.TotalChips -= value;
}
public void TransferBets(List<Player> players, Dealer dealer)
{
foreach (Player player in players)
{
if (player.result == Result.Win)
{
TransferChips(player, dealer, player.Bet);
Console.WriteLine("{0} wins {1} dollars.", player.Name, player.Bet);
}
else if (player.result == Result.Lose)
{
//if (player.TotalChips < player.Bet)
TransferChips(dealer, player, player.Bet);
Console.WriteLine("{0} loses {1} dollars.", player.Name, player.Bet);
}
else
Console.WriteLine("{0} pushes.", player.Name);
}
}
public void DisplayResults(List<Player> players)
{
foreach (Player player in players)
{
Console.WriteLine("{0} has {1} and {2}s. Total chips: {3}", player.Name, player.playerHand.HandValue(), player.result, player.TotalChips);
player.ShowHandValues();
Console.WriteLine();
}
}
}
public class Seat
{
public Seat()
{ }
public bool Occupied;
}
public class Player
{
private string name;
private decimal bet =10, totalChips = 100;
public Hand playerHand = new Hand();
public Player()
{ }
public Player(string name)
{
this.Name = name;
}
public string Name
{
get { return name; }
set { name = value; }
}
public Result result { get; set; }
public decimal TotalChips
{
get
{
return totalChips;
}
set
{
totalChips = value;
}
}
public decimal Bet
{
get
{
return bet;
}
}
public void ReceiveCard(Card card)
{ playerHand.Hit(card); }
public void AskForCard(Deck deck)
{
playerHand.Hit(deck.Deal());
}
public virtual void Strategy(Deck deck)
{
while (playerHand.HandValue() < 17)
{
AskForCard(deck);
if (playerHand.HandValue() == 21)
Console.WriteLine("Congratulations {0} you got 21!", Name);
if (playerHand.HandValue() > 21)
Console.WriteLine("Sorry {0} you busted.", Name);
}
}
public void ShowHandValues()
{
foreach (Card card in playerHand.GetCards())
{
Console.Write(card.ToString() + " ");
}
}
}
public class InvalidTransferAmountException : ApplicationException
{
public InvalidTransferAmountException(string msg, Player offendingPlayer) : base(msg)
{
OffendingPlayer = offendingPlayer;
}
public Player OffendingPlayer { get; private set; }
}

Categories

Resources