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