Simple, Quality, Awesome Software

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);
        }
    }
}