-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplaySolo.html
175 lines (156 loc) · 4.31 KB
/
playSolo.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<!DOCTYPE html>
<html ng-app="playApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.min.js"></script>
<script language="javascript">
"use strict";
var N = 52;
var cardsPerSuits = N / 4;
function simulate(nbCards, nbTrials) {
var startTime = window.performance.now();
// Counts
var sum = 0;
var nbVictories = 0;
for (var i = 0; i < nbTrials; ++i) {
var deck = deal(nbCards);
var res = play(deck).length;
if (res === 0) {
nbVictories++;
} else {
sum += res;
}
}
return {
elapsed : window.performance.now() - startTime,
sum : sum,
nbVictories : nbVictories,
nbTrials : nbTrials
};
}
function deal(N) {
var deck = [];
var available = new Array(N);
for (var i = 0; i < N; ++i) {
available[i] = i;
}
for (var j = 0; j < N; ++j) {
var idx = Math.floor(Math.random() * available.length);
deck.push(available[idx]);
available.splice(idx, 1);
}
return deck;
}
function color(n) {
return Math.floor(n / cardsPerSuits);
}
function face(n) {
return n % cardsPerSuits;
}
function colorName(n) {
return {
0 : "Heart",
1 : "Diamon",
2 : "Spade",
3 : "Club",
}[color(n)];
}
function faceName(n) {
return {
0 : "2",
1 : "3",
2 : "4",
3 : "5",
4 : "6",
5 : "7",
6 : "8",
7 : "9",
8 : "10",
9 : "Jack",
10 : "Queen",
11 : "King",
12 : "Ace"
}[face(n)];
}
function cardName(n) {
return faceName(n) + " of " + colorName(n);
}
function play(deck) {
var hand = [];
while (deck.length) {
hand.push(deck.pop());
while (hand.length > 3) {
var card1 = hand[hand.length - 4];
var card4 = hand[hand.length - 1];
if (color(card1) === color(card4)) {
// Remove the two in between
hand.splice(hand.length - 2, 2);
continue;
}
if (face(card1) === face(card4)) {
// Remove the last four
hand.splice(hand.length - 4, 4);
continue;
}
// Nothing changed.
break;
}
}
return hand;
}
// Dummy angular controller.
angular
.module("playApp", [])
.controller("PlayController", ["$scope", function($scope) {
$scope.simulations = [];
$scope.runSimulation = function() {
var deck = deal(N);
$scope.simulations.push(play(deck).map(cardName));
};
$scope.runMonteCarloSimulation = function() {
$scope.monteCarloSimulation = simulate(N, $scope.monteCarloIterationCount);
};
$scope.clearSimulations = function() {
$scope.simulations = [];
};
}]);
</script>
</head>
<body>
<div ng-controller="PlayController">
<h2>Single simulation</h2>
<div ng-if="!simulations.length">Run a simulation to see it's outcome.</div>
<div ng-if="simulations.length">
<ul class="unstyled">
<li ng-repeat="simulation in simulations">
<span ng-if="simulation.length">
<p>You loose : there are {{simulation.length}} cards at the end :</p>
<p>{{simulation.join(", ") | json}}</p>
</span>
<span ng-if="!simulation.length">
You won !
</span>
</li>
</ul>
</div>
<input class="btn-primary" type="submit" value="Run One Simulation" ng-click="runSimulation()">
<input class="btn-primary" type="submit" value="Clear" ng-click="clearSimulations()">
<br/><br/>
<div>
<h2>Monte-Carlo simulation</h2>
<label>Number of iterations :</label><input type="text" ng-model="monteCarloIterationCount" placeholder="Iteration count">
<div ng-if="monteCarloSimulation">
<h3>Results :</h3>
<ul>
<li>Ran experiment {{monteCarloSimulation.nbTrials}} times</li>
<li>Won {{monteCarloSimulation.nbVictories}} times</li>
<li>Average hand size at the end : {{monteCarloSimulation.sum / monteCarloSimulation.nbTrials}} cards</li>
<li>Win probability : {{monteCarloSimulation.nbVictories / monteCarloSimulation.nbTrials * 100}}%</li>
<li>Took {{monteCarloSimulation.elapsed / 1000 | number:3}} seconds ({{monteCarloSimulation.nbTrials / (monteCarloSimulation.elapsed / 1000) | number:0}} simulations per second).</li>
</ul>
</div>
<input class="btn-primary" type="submit" value="Run" ng-click="runMonteCarloSimulation()">
</div>
</div>
</body>
</body>
</html>