Monty Hall Problem C# Console Simulator

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4

    5 namespace MontyHallProblem

    6 {

    7     class Program

    8     {

    9         static void Main()

   10         {

   11             bool playGame = true;

   12             while (playGame)

   13             {

   14                 Console.WriteLine(“What strategy do you want to use?\r\nA) Always switch the door\r\nB) Never switch the door\r\nC) Both”);

   15                 string strategyChoice = Console.ReadLine();

   16                 MontyHallGame.Strategy strategy = MontyHallGame.Strategy.Switch;

   17                 switch (strategyChoice)

   18                 {

   19                     case “A”:

   20                     case “a”:

   21                         strategy = MontyHallGame.Strategy.Switch;

   22                         break;

   23                     case “B”:

   24                     case “b”:

   25                         strategy = MontyHallGame.Strategy.Keep;

   26                         break;

   27                     case “C”:

   28                     case “c”:

   29                         strategy = MontyHallGame.Strategy.None;

   30                         break;

   31                 }

   32

   33                 int numberOfSimulations = 100;

   34

   35                 Console.WriteLine(“How many simulations do you want to run?”);

   36                 if (!int.TryParse(Console.ReadLine(), out numberOfSimulations))

   37                     numberOfSimulations = 100;

   38

   39                 List<Result> results = new List<Result>();

   40

   41                 for (int i = 0; i < numberOfSimulations; i++)

   42                 {

   43                     results.Add(MontyHallGame.Play(strategy));

   44                 }

   45

   46                 // Count the number of wins

   47                 var winCountList = from w in results

   48                                    where w.ContestantWins

   49                                    select w;

   50

   51                 var switchDoorCountList = from s in results

   52                                           where s.ContestantSwitchedDoor

   53                                           select s;

   54

   55                 int switchedDoorCount = switchDoorCountList.Count(dcl => dcl.ContestantSwitchedDoor);

   56                 int totalWinCount = winCountList.Count(cl => cl.ContestantWins);

   57                 decimal winPercentage = (decimal)totalWinCount / (decimal)numberOfSimulations;

   58

   59                 Console.WriteLine(“\r\n****************************************\r\nMonty Hall Problem Simulation Results\r\n****************************************\r\n”);

   60                 Console.WriteLine(“Total Simulations…….. {0}”, numberOfSimulations);

   61                 Console.WriteLine(“Total Wins…………… {0}”, totalWinCount);

   62                 Console.WriteLine(“Win Percentage……….. {0}”, winPercentage.ToString(“0.0%”));

   63                 Console.WriteLine(“Total Switched Doors….. {0}”, switchedDoorCount);

   64                 Console.WriteLine(“\r\n\r\n”);

   65

   66                 Console.WriteLine(“Hit any key to continue or enter ‘Exit’ to quit.”);

   67                 switch (Console.ReadLine())

   68                 {

   69                     case “exit”:

   70                     case “Exit”:

   71                     case “EXIT”:

   72                     case “quit”:

   73                     case “QUIT”:

   74                     case “Quit”:

   75                         playGame = false;

   76                         break;

   77                 }

   78             }

   79

   80         }

   81

   82         #region Monty Hall Game

   83         static class MontyHallGame

   84         {

   85             public enum Strategy

   86             {

   87                 Switch,

   88                 Keep,

   89                 None

   90             }

   91

   92             ///<summary>

   93             /// Simulates one game of the Monty Hall Game.

   94             ///</summary>

   95             ///<param name=”strategy”>Determines whether or not the player would like to switch doors.</param>

   96             public static Result Play(Strategy strategy)

   97             {

   98

   99                 // Create three doors

  100                 Door door1 = new Door { Number = Door.DoorNumber.Door1 };

  101                 Door door2 = new Door { Number = Door.DoorNumber.Door2 };

  102                 Door door3 = new Door { Number = Door.DoorNumber.Door3 };

  103

  104                 // Create a list of the doors so we can implement LINQ

  105                 List<Door> doors = new List<Door>();

  106                 doors.Add(door1);

  107                 doors.Add(door2);

  108                 doors.Add(door3);

  109

  110                 // Randomly set the winning door

  111                 int winningDoorNumber = new Random(Guid.NewGuid().GetHashCode()).Next(1, 4);

  112                 doors[winningDoorNumber – 1].IsWinningDoor = true;

  113

  114

  115                 // Contestant picks a random door

  116                 int firstChoiceDoorNumber = new Random(Guid.NewGuid().GetHashCode()).Next(1, 4);

  117                 doors[firstChoiceDoorNumber – 1].ContestantFirstChoice = true;

  118

  119                 // Set the door that is revealed by Monty

  120                 // The revealed door must:

  121                 // 1) Not be a winning door

  122                 // 2) Not be the contestant’s first choice door

  123                 foreach (Door d in doors)

  124                 {

  125                     if (!d.ContestantFirstChoice && !d.IsWinningDoor)

  126                     {

  127                         d.MontySelected = true;

  128                         break; // Break out to avoid Monty from selecting multiple doors (i.e. the case where the contestant’s first choice is the winning door.

  129                     }

  130                 }

  131

  132                 // If the strategy of this game is indifference to switching or keeping the intial pick, then randomly pick to switch or keep on behalf of the user.

  133                 if (strategy == Strategy.None)

  134                     strategy = (Strategy)new Random(Guid.NewGuid().GetHashCode()).Next(0, 2);

  135

  136

  137                 if (strategy == Strategy.Switch)

  138                 {

  139                     foreach (Door d in doors)

  140                     {

  141                         if (!d.ContestantFirstChoice && !d.MontySelected)

  142                         {

  143                             d.ContestantSecondChoice = true;

  144                             break; // Break out to avoid more than one second choice selections

  145                         }

  146                     }

  147                 }

  148                 else if (strategy == Strategy.Keep)

  149                 {

  150                     // Contestant doesn’t want to change door

  151                     foreach (Door d in doors)

  152                     {

  153                         if (d.ContestantFirstChoice)

  154                             d.ContestantSecondChoice = d.ContestantFirstChoice;

  155                     }

  156                 }

  157

  158

  159                 // Results

  160                 Result result = new Result();

  161                 foreach (Door d in doors)

  162                 {

  163                     if (d.ContestantSecondChoice)

  164                     {

  165                         result.ContestantSwitchedDoor = !d.ContestantFirstChoice;

  166                         result.ContestantWins = d.IsWinningDoor;

  167                     }

  168

  169                 }

  170

  171

  172                 return (result);

  173             }

  174         }

  175         #endregion

  176

  177         #region Helper Classes

  178         ///<summary>

  179         /// Helper class that represents the result of one game.

  180         ///</summary>

  181         class Result

  182         {

  183             public bool ContestantWins { get; set; }

  184             public bool ContestantSwitchedDoor { get; set; }

  185         }

  186

  187         ///<summary>

  188         /// Helper class that represents a single door of the Monty Hall Game.

  189         ///</summary>

  190         class Door

  191         {

  192             bool contestantFirstChoice;

  193             bool contestantSecondChoice;

  194             bool montySelected;

  195

  196             public DoorNumber Number { get; set; }

  197

  198             public enum DoorNumber

  199             {

  200                 Door1 = 1,

  201                 Door2,

  202                 Door3

  203             }

  204

  205             public bool ContestantFirstChoice

  206             {

  207                 get

  208                 {

  209                     return (this.contestantFirstChoice);

  210                 }

  211

  212                 set

  213                 {

  214                     this.contestantFirstChoice = value;

  215

  216                     if (this.contestantFirstChoice && this.montySelected)

  217                         throw new Exception(“Contestant’s first choice cannot be the door that Monty revealed!”);

  218

  219                 }

  220             }

  221

  222             public bool ContestantSecondChoice

  223             {

  224                 get

  225                 {

  226                     return (this.contestantSecondChoice);

  227                 }

  228

  229                 set

  230                 {

  231                     this.contestantSecondChoice = value;

  232

  233                     if (this.contestantSecondChoice && this.montySelected)

  234                         throw new Exception(“Contestant’s second choice cannot be the door that Monty revealed!”);

  235

  236                 }

  237             }

  238

  239             public bool MontySelected

  240             {

  241                 get

  242                 {

  243                     return (this.montySelected);

  244                 }

  245

  246                 set

  247                 {

  248                     this.montySelected = value;

  249

  250                     if (this.contestantSecondChoice && this.montySelected)

  251                         throw new Exception(“Monty cannot reveal the contestant’s first choice door!”);

  252

  253                     if (this.IsWinningDoor && this.montySelected)

  254                         throw new Exception(“Monty cannot reveal the winning door!”);

  255

  256                 }

  257             }

  258

  259             public bool IsWinningDoor { get; set; }

  260         }

  261         #endregion

  262     }

  263 }

  264

Leave a comment