Pig Dice
Below is the complete code for the Pig Dice Try It Out! problem.
Program Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CSharpBook.Examples.PigDice
{
class Program
{
/// <summary>
/// Starts up a game of Pig Dice, by asking for the number of players
/// to include in the game and kicking off the game.
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.Write("How many players are there? ");
int amount = Convert.ToInt32(Console.ReadLine());
// Build a game with the correct number of players.
Game game = Game.CreateGame(amount);
// Starts the actual game.
game.PlayGame();
}
}
}
Player Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CSharpBook.Examples.PigDice
{
/// <summary>
/// A class for storing information about a single player.
/// </summary>
public class Player
{
/// <summary>
/// Gets or sets the player's name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets the player's total score.
/// </summary>
public int TotalScore { get; set; }
/// <summary>
/// Gets or sets the current score for the current round.
/// </summary>
public int RoundScore { get; set; }
/// <summary>
/// Gets or sets the color that should be used in the GUI to
/// represent this player.
/// </summary>
public ConsoleColor Color { get; set; }
/// <summary>
/// Creates a new player with a specific name and color.
/// Scores are set to 0.
/// </summary>
public Player(string name, ConsoleColor color)
{
Name = name;
Color = color;
TotalScore = 0;
RoundScore = 0;
}
}
}
Game Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CSharpBook.Examples.PigDice
{
/// <summary>
/// Represents a game of Pig Dice.
/// </summary>
public class Game
{
/// <summary>
/// Stores the list of players involved in the game.
/// </summary>
private List<Player> Players { get; set; }
/// <summary>
/// A random number generator, used to simulate die rolls
/// </summary>
private Random random = new Random();
/// <summary>
/// Creates a new game with the given players.
/// </summary>
/// <param name="players"></param>
public Game(List<Player> players)
{
Players = players;
}
/// <summary>
/// Goes through and plays a complete game of Pig Dice.
/// Admittedly, this method is a little long and does more than one
/// thing. Breaking it down into smaller, more manageable pieces
/// would be better.
/// </summary>
public void PlayGame()
{
int playerIndex = 0;
bool gameComplete = false;
Player winningPlayer = null;
// Loop until a player wins.
// Each loop represents a single players turn.
while (!gameComplete)
{
Console.Clear();
PrintTurnStart(playerIndex);
Player currentPlayer = Players[playerIndex];
Console.WriteLine("Press any key to start your turn.");
Console.ReadKey(false);
// Loop until they either roll a 1 or choose to hold.
while (true)
{
Console.Clear();
PrintTurnStart(playerIndex);
// Roll the dice
int die1 = random.Next(6) + 1;
int die2 = random.Next(6) + 1;
PrintDice(die1, die2);
if (die1 == 1 || die2 == 1)
{
currentPlayer.RoundScore = 0;
playerIndex = (playerIndex + 1) % Players.Count;
PrintPigMessage();
break;
}
else
{
currentPlayer.RoundScore += die1 + die2;
PrintRoundInformation(currentPlayer);
ConsoleKeyInfo keyInfo = Console.ReadKey(false);
if (keyInfo.Key == ConsoleKey.Enter)
{
currentPlayer.TotalScore += currentPlayer.RoundScore;
Players[playerIndex].RoundScore = 0;
if (HasWon(currentPlayer))
{
winningPlayer = currentPlayer;
gameComplete = true;
}
playerIndex = (playerIndex + 1) % Players.Count;
break;
}
}
}
}
Console.WriteLine(winningPlayer.Name + " won!");
Console.ReadKey();
}
/// <summary>
/// Prints out the message that they rolled a 1, and so they
/// lost all their points for the round and it's the next
/// //player's turn.
/// </summary>
private static void PrintPigMessage()
{
Console.ForegroundColor = ConsoleColor.Magenta;
// Pig ASCII art from
// http://www.geocities.com/spunk1111/farm.htm#pig
Console.WriteLine(@" .-~~~~-. |\\_");
Console.WriteLine(@" @_/ / oo\_");
Console.WriteLine(" | \\ \\ _(\")");
Console.WriteLine(@" \ /-| ||'--'");
Console.WriteLine(@" \_\ \_\\");
Console.WriteLine("PIG! You lose all points from this turn.");
Console.ReadKey(false);
}
/// <summary>
/// Prints information that is needed at the start of the round, like
/// the current score of every player.
/// </summary>
/// <param name="currentPlayer"></param>
public void PrintTurnStart(int currentPlayer)
{
for (int index = 0; index < Players.Count; index++)
{
Player player = Players[index];
Console.ForegroundColor = ConsoleColor.White;
Console.Write(index == currentPlayer ? "-->" : " ");
Console.ForegroundColor = player.Color;
Console.WriteLine("{0, -15}{1}", player.Name, player.TotalScore);
}
Console.ForegroundColor = ConsoleColor.White;
}
/// <summary>
/// Prints information about the current state of the round.
/// </summary>
/// <param name="currentPlayer"></param>
private static void PrintRoundInformation(Player currentPlayer)
{
Console.ForegroundColor = currentPlayer.Color;
Console.WriteLine(currentPlayer.Name + " has " +
currentPlayer.RoundScore + " this round.");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(
"Press <Space> to keep going or <Enter> to hold.");
}
/// <summary>
/// Prints out the value of the two dice in a fancy way that
/// actually looks something like dice.
/// </summary>
/// <param name="value1"></param>
/// <param name="value2"></param>
private void PrintDice(int value1, int value2)
{
Console.ForegroundColor = ConsoleColor.White;
for (int row = 0; row < 5; row++)
{
Console.WriteLine(
diceDrawings[value1 - 1][row] +
" " +
diceDrawings[value2 - 1][row]);
}
}
/// <summary>
/// Determines whether a player has won or not yet.
/// </summary>
/// <param name="player"></param>
/// <returns></returns>
private bool HasWon(Player player)
{
if (player.TotalScore >= 100) { return true; }
else { return false; }
}
private static string[][] diceDrawings;
/// <summary>
/// Static constructor which initializes the type as a whole,
/// including any static class variables included in the type.
/// In this case, that is only the diceDrawings variable, which
/// stores little ASCII art dice for each of the possible numbers
/// 1-6.
/// </summary>
static Game()
{
diceDrawings = new string[6][];
diceDrawings[0] = new string[] {
"┏───────┑",
"┃ ┃",
"┃ O ┃",
"┃ ┃",
"┖───────┙"};
diceDrawings[1] = new string[] {
"┏───────┑",
"┃ O ┃",
"┃ ┃",
"┃ O ┃",
"┖───────┙"};
diceDrawings[2] = new string[] {
"┏───────┑",
"┃ O ┃",
"┃ O ┃",
"┃ O ┃",
"┖───────┙"};
diceDrawings[3] = new string[] {
"┏───────┑",
"┃ O O ┃",
"┃ ┃",
"┃ O O ┃",
"┖───────┙"};
diceDrawings[4] = new string[] {
"┏───────┑",
"┃ O O ┃",
"┃ O ┃",
"┃ O O ┃",
"┖───────┙"};
diceDrawings[5] = new string[] {
"┏───────┑",
"┃ O O ┃",
"┃ O O ┃",
"┃ O O ┃",
"┖───────┙"};
}
/// <summary>
/// Creates a game, adding in the right number of players. Anything
/// over 4 players will default to just four players.
/// </summary>
/// <returns></returns>
public static Game CreateGame(int numberOfPlayers)
{
List<Player> allPlayers = new List<Player>();
if (numberOfPlayers >= 1)
{
allPlayers.Add(new Player("Player 1", ConsoleColor.Red));
}
if (numberOfPlayers >= 2)
{
allPlayers.Add(new Player("Player 2", ConsoleColor.Blue));
}
if (numberOfPlayers >= 3)
{
allPlayers.Add(new Player("Player 3", ConsoleColor.Green));
}
if (numberOfPlayers >= 4)
{
allPlayers.Add(new Player("Player 4", ConsoleColor.Yellow));
}
return new Game(allPlayers);
}
}
}