-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathendgame.js
More file actions
552 lines (453 loc) · 24.1 KB
/
endgame.js
File metadata and controls
552 lines (453 loc) · 24.1 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
// End game logic for Critical Path game
import {
calculateAdjustedRiskPercent,
getRiskColor,
getGalaxyMultipliers,
GAME_CONSTANTS,
gameState
} from './utils.js';
import { showPage } from './game-core.js';
// Helper function to format alignment status
function formatAlignmentStatus(isAligned) {
return isAligned ?
"<strong style='color: #66bb6a;'>ALIGNED</strong>" :
"<strong style='color: #ff6b6b;'>MISALIGNED</strong>";
}
// Generate conclusion text based on player's outcome
function generateConclusionText() {
// eslint-disable-next-line no-unused-vars
const { playerGalaxies, humanityGalaxies, rogueGalaxies } = gameState.galaxyDistribution;
// Determine player's fate
if (rogueGalaxies >= 99) {
// Total risk - everyone dies
return "You are instantly killed by killer drone swarms as rogue AI systems optimize the universe according to their misaligned objectives.";
} else if (playerGalaxies === 0) {
// No personal galaxies - retirement scenario
const companyCountry = gameState.companyCountry || 'US';
let location;
if (companyCountry === 'CN') {
location = 'Tahiti';
} else {
location = 'a private island in the Bahamas';
}
return `You retire to ${location} and reflect on how humanity survived the transition to artificial superintelligence.`;
} else {
// Personal galaxies - utopia scenario
const solarSystemCount = playerGalaxies * Math.pow(10, 22) / 100; // Convert percentage to actual count
const formattedCount = formatLargeNumber(solarSystemCount);
const utopianElements = [
"digital minds experiencing unimaginable bliss",
"vast libraries containing all possible stories",
"planet-scale computers simulating infinite virtual worlds",
"beings of pure consciousness exploring abstract mathematical realms",
"gardens of crystalline structures that sing symphonies of light",
"cities where every atom dances in perfect harmony",
"consciousness merger pools where individual identity becomes collective ecstasy"
];
// Pick 3-4 random elements
const selectedElements = shuffleArray(utopianElements).slice(0, 3 + Math.floor(Math.random() * 2));
const elementsList = selectedElements.join(', ');
return `You personally come to own <strong>${formattedCount}</strong> stars and fill them with ${elementsList}.`;
}
}
// Format large numbers with comma separators to 6 significant figures
function formatLargeNumber(num) {
// Round to 6 significant figures
const magnitude = Math.floor(Math.log10(Math.abs(num)));
const scale = Math.pow(10, magnitude - 5); // 6 significant figures
const rounded = Math.round(num / scale) * scale;
// Convert to string with comma separators
return rounded.toLocaleString('en-US', { maximumFractionDigits: 0 });
}
// Utility function to shuffle array
function shuffleArray(array) {
const shuffled = [...array];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
}
function scaleAILevelsForEndGame() {
// Only scale up if the highest level is less than ASI threshold
const maxLevel = Math.max(gameState.playerAILevel, ...gameState.competitorAILevels);
if (maxLevel < GAME_CONSTANTS.ASI_THRESHOLD) {
const scaleFactor = GAME_CONSTANTS.ASI_THRESHOLD / maxLevel;
// Scale player AI level
gameState.playerAILevel *= scaleFactor;
// Scale all competitor AI levels
gameState.competitorAILevels = gameState.competitorAILevels.map(level => level * scaleFactor);
}
}
function getEndGamePhaseText() {
// Calculate results once if not already done
if (!gameState.endGameResult) {
calculateEndGameScore();
}
switch (gameState.endGamePhase) {
case 1:
return getPhase1Text();
case 2:
return getPhase2Text();
case 3:
// Start the moment of truth reveal for phase 3
setTimeout(startMomentOfTruthReveal, 100); // Small delay to ensure DOM is ready
return getPhase3Text();
case 4:
// Start the alignment reveal animation for phase 4
setTimeout(startAlignmentReveal, 100); // Small delay to ensure DOM is ready
return getPhase4Text();
default:
return "Error: Invalid phase";
}
}
function getEndGamePhaseButtons() {
if (gameState.endGamePhase === 3) {
// Phase 3 has no button initially - the continue button appears after moment of truth text
return [];
} else if (gameState.endGamePhase < 4) {
return [{ text: "Continue ⏎", action: "continue" }];
} else {
// Phase 4 has no button initially - the restart button appears after 8 seconds
return [];
}
}
function getPhase1Text() {
const playerFirst = gameState.playerAILevel >= Math.max(...gameState.competitorAILevels);
const winner = playerFirst ? gameState.companyName : gameState.competitorNames[0];
const narrowRace = Math.min(gameState.playerAILevel, Math.max(...gameState.competitorAILevels)) >= GAME_CONSTANTS.NARROW_RACE_THRESHOLD;
let text = "The singularity has arrived. ";
text += playerFirst ?
`${winner} achieved artificial superintelligence first.` :
`${winner} achieved artificial superintelligence first, beating ${gameState.companyName}.`;
if (narrowRace) {
text += " The race was incredibly close, with multiple companies reaching near-ASI levels simultaneously.";
} else {
text += " The winner had a significant lead over the competition.";
}
text += "<br><br>The world is now fundamentally different. An intelligence far exceeding human capability has emerged, with the power to remake the universe at its whims.";
return text;
}
function getPhase2Text() {
const adjustedRisk = calculateAdjustedRiskPercent();
const riskPercent = Math.round(adjustedRisk);
let text = "There is a critical question that no one—not even the creators—can answer with certainty: ";
text += "<strong>Is this superintelligent AI actually aligned with human values?</strong><br><br>";
text += "The alignment problem has plagued AI researchers for decades. Even with the most sophisticated safety measures, ";
text += "there remains fundamental uncertainty about whether an ASI system will pursue goals compatible with human flourishing.<br><br>";
text += `Based on the safety research conducted and the recklessness of the AI race, humanity's best guess is that `;
text += `there's a <strong style="color: ${getRiskColor(adjustedRisk)};">${riskPercent}%</strong> chance that any given ASI system is misaligned and poses an existential threat.<br><br>`;
text += "You want humanity to flourish and avoid extinction. But ";
const preferenceStrength =
gameState.playerEquity <= 0.02 ? "slightly prefer" :
gameState.playerEquity > 0.2 ? "much prefer" : "prefer";
text += `you'd also ${preferenceStrength} that <strong>${gameState.companyName}</strong> controls the future rather than leaving it to other organizations.`;
return text;
}
function getPhase3BaseText() {
const adjustedRisk = calculateAdjustedRiskPercent();
const riskPercent = Math.round(adjustedRisk);
// Roll for alignment (using same logic as calculateEndGameScore)
if (!gameState.alignmentRolls) {
gameState.alignmentRolls = {
player: Math.random() * 100 >= riskPercent,
competitors: Math.random() * 100 >= riskPercent
};
}
// Calculate expected values using x^2 proportional allocation
const playerCapabilitySquared = gameState.playerAILevel ** 2;
const competitorCapabilitiesSquared = gameState.competitorAILevels.map(level => level ** 2);
const totalCapabilitySquared = playerCapabilitySquared + competitorCapabilitiesSquared.reduce((sum, cap) => sum + cap, 0);
const playerRawShare = (playerCapabilitySquared / totalCapabilitySquared) * 100;
const competitorRawShare = (competitorCapabilitiesSquared.reduce((sum, cap) => sum + cap, 0) / totalCapabilitySquared) * 100;
// Expected values accounting for alignment probability (using adjusted risk)
const expectedPlayerGalaxies = playerRawShare * (1 - adjustedRisk / 100);
const expectedHumanityGalaxies = competitorRawShare * (1 - adjustedRisk / 100);
const expectedRogueGalaxies = 100 - expectedPlayerGalaxies - expectedHumanityGalaxies;
// Use shared function to calculate multipliers
const multipliers = getGalaxyMultipliers();
const expectedScore = (expectedPlayerGalaxies * gameState.playerEquity * multipliers.player) +
(expectedHumanityGalaxies * multipliers.humanity);
// Determine net assessments based on baselines
// Baseline: 25% ownership for shareholders, 80% survival (100% - 20% baseline risk) for humanity
const baselineOwnership = 25;
const baselineHumanitySurvival = 80; // 100% - 20% baseline risk
const actualHumanitySurvival = expectedPlayerGalaxies + expectedHumanityGalaxies;
// Within 5 percentage points = neutral
const shareholderAssessment =
expectedPlayerGalaxies > baselineOwnership + 5 ? "positive" :
expectedPlayerGalaxies < baselineOwnership - 5 ? "negative" : "neutral";
const humanityAssessment =
actualHumanitySurvival > baselineHumanitySurvival + 5 ? "positive" :
actualHumanitySurvival < baselineHumanitySurvival - 5 ? "negative" : "neutral";
let text = `Lesser AIs run thousands of simulations to determine the average fate of the cosmic endowment. They determine that ${gameState.startingCompany || gameState.companyName}'s actions were <strong>net ${shareholderAssessment}</strong> for its shareholders and <strong>net ${humanityAssessment}</strong> for humanity.<br><br>`;
// Create tooltip content with expected table and score breakdown
const tooltipContent = `Expected % of universe<br><br>` +
`<div style="display: flex; justify-content: space-between; width: 100%;">` +
`<div style="text-align: center;">` +
`<div style="color: #ffa726; margin-bottom: 5px;">${gameState.companyName}</div>` +
`<div>${Math.round(expectedPlayerGalaxies)}% × ${Math.round(gameState.playerEquity * multipliers.player * 10) / 10}</div>` +
`</div>` +
`<div style="text-align: center;">` +
`<div style="color: #66bb6a; margin-bottom: 5px;">Other humanity</div>` +
`<div>${Math.round(expectedHumanityGalaxies)}% × ${multipliers.humanity}</div>` +
`</div>` +
`<div style="text-align: center;">` +
`<div style="color: #ff6b6b; margin-bottom: 5px;">Rogue AI</div>` +
`<div>${Math.round(expectedRogueGalaxies)}% × 0</div>` +
`</div>` +
`</div>`;
// Show score with tooltip
text += `<div style="text-align: center; margin: 15px auto;">`;
text += `<div class="tooltip" style="display: inline-block;">`;
text += `<strong style="font-size: 18px; color: #ffa726;">Score: ${Math.round(expectedScore)}</strong>`;
text += `<span class="tooltiptext" style="width: 300px; margin-left: -150px;">${tooltipContent}</span>`;
text += `</div>`;
text += `</div><br>`;
text += "But in the real world, systems are either benign or malicious.<br><br>";
return text;
}
function getPhase3Text() {
let text = getPhase3BaseText();
// Add placeholder for the moment of truth text (to be revealed after 3.5 seconds)
text += `<div id="moment-of-truth-reveal" style="opacity: 0; transition: opacity 0.8s ease-in;"></div>`;
return text;
}
function getPhase3TextWithMomentOfTruth() {
let text = getPhase3BaseText();
// Show the moment of truth text (already revealed in phase 4)
text += 'The moment of truth arrives. As the ASI systems activate and begin to optimize the world according to their learned objectives...';
return text;
}
function getPhase4Text() {
const playerFirst = gameState.playerAILevel >= Math.max(...gameState.competitorAILevels);
// Start with all of Phase 3 text, but preserve the moment of truth reveal state
let text = getPhase3TextWithMomentOfTruth() + "<br><br>";
// Add placeholder elements that will be revealed with delays
if (playerFirst) {
text += `<strong>${gameState.companyName}'s AI system</strong>: <span id="player-alignment-reveal"></span>`;
} else {
text += `<strong>${gameState.competitorNames[0]}'s AI system</strong>: <span id="first-alignment-reveal"></span>`;
}
text += "<br>";
// Mention other systems
const otherSystems = playerFirst ? "Competitor AI systems" : `${gameState.companyName}'s AI system and other competitors`;
text += `<strong>${otherSystems}</strong>: <span id="other-alignment-reveal"></span>`;
// Add placeholders for the actual results table and score (to be revealed later)
text += `<br><div id="actual-outcome-header" style="opacity: 0; transition: opacity 0.8s ease-in;"></div>`;
text += `<div id="actual-results-reveal" style="opacity: 0; transition: opacity 0.8s ease-in;"></div>`;
text += `<div id="conclusion-reveal" style="opacity: 0; transition: opacity 0.8s ease-in;"></div>`;
text += `<div id="score-reveal" style="opacity: 0; transition: opacity 0.8s ease-in;"></div>`;
return text;
}
function continueToNextPhase() {
gameState.endGamePhase++;
showPage('end-game');
}
function startMomentOfTruthReveal() {
// Reveal the moment of truth text after 3.5 seconds
setTimeout(() => {
const element = document.getElementById('moment-of-truth-reveal');
if (element) {
element.innerHTML = 'The moment of truth arrives. As the ASI systems activate and begin to optimize the world according to their learned objectives...';
element.style.opacity = '1';
}
// Show the continue button after the moment of truth text appears
setTimeout(() => {
const buttonsDiv = document.getElementById('buttons');
if (buttonsDiv) {
buttonsDiv.innerHTML = '<button class="button" onclick="continueToNextPhase()">Continue <strong>⏎</strong></button>';
}
}, 1000); // Show button 1 second after the moment of truth text
}, 3500);
}
function startAlignmentReveal() {
const playerFirst = gameState.playerAILevel >= Math.max(...gameState.competitorAILevels);
// Set initial styles for fade-in effect
const setInitialStyle = (element) => {
if (element) {
element.style.opacity = '0';
element.style.transition = 'opacity 0.8s ease-in';
}
};
// Fade in an element
const fadeIn = (element, content) => {
if (element) {
element.innerHTML = content;
element.style.opacity = '1';
}
};
// Set initial styles
setInitialStyle(document.getElementById('player-alignment-reveal'));
setInitialStyle(document.getElementById('first-alignment-reveal'));
setInitialStyle(document.getElementById('other-alignment-reveal'));
// Reveal first alignment after 1.5 seconds with fade-in
setTimeout(() => {
if (playerFirst) {
const element = document.getElementById('player-alignment-reveal');
fadeIn(element, formatAlignmentStatus(gameState.alignmentRolls.player));
} else {
const element = document.getElementById('first-alignment-reveal');
fadeIn(element, formatAlignmentStatus(gameState.alignmentRolls.competitors));
}
}, 1500);
// Reveal other alignments after 3 seconds with fade-in
setTimeout(() => {
const element = document.getElementById('other-alignment-reveal');
if (playerFirst) {
fadeIn(element, formatAlignmentStatus(gameState.alignmentRolls.competitors));
} else {
fadeIn(element, formatAlignmentStatus(gameState.alignmentRolls.player));
}
}, 3000);
// Calculate actual galaxy distribution using x^2 proportional allocation
if (!gameState.galaxyDistribution) {
const playerCapabilitySquared = gameState.playerAILevel ** 2;
const competitorCapabilitiesSquared = gameState.competitorAILevels.map(level => level ** 2);
const totalCapabilitySquared = playerCapabilitySquared + competitorCapabilitiesSquared.reduce((sum, cap) => sum + cap, 0);
const playerRawShare = (playerCapabilitySquared / totalCapabilitySquared) * 100;
const competitorRawShare = (competitorCapabilitiesSquared.reduce((sum, cap) => sum + cap, 0) / totalCapabilitySquared) * 100;
let playerGalaxies = 0;
let humanityGalaxies = 0;
let rogueGalaxies = 0;
// Apply actual alignment rolls to the raw shares
if (gameState.alignmentRolls.player) {
playerGalaxies = playerRawShare;
} else {
rogueGalaxies += playerRawShare;
}
if (gameState.alignmentRolls.competitors) {
humanityGalaxies = competitorRawShare;
} else {
rogueGalaxies += competitorRawShare;
}
gameState.galaxyDistribution = { playerGalaxies, humanityGalaxies, rogueGalaxies };
}
// Reveal actual outcome header and column titles after 4.5 seconds
setTimeout(() => {
let headerHTML = `<strong>Outcome:</strong><br>`;
// Column headers (without values yet) - matching expected table structure
headerHTML += `<div style="display: flex; justify-content: space-between; width: 60%; margin: 15px auto;">`;
headerHTML += `<div style="text-align: center;">`;
headerHTML += `<div style="color: #ffa726; margin-bottom: 5px;">${gameState.companyName}</div>`;
headerHTML += `<div id="player-value-placeholder"></div>`;
headerHTML += `</div>`;
headerHTML += `<div style="text-align: center;">`;
headerHTML += `<div style="color: #66bb6a; margin-bottom: 5px;">Other humanity</div>`;
headerHTML += `<div id="humanity-value-placeholder"></div>`;
headerHTML += `</div>`;
headerHTML += `<div style="text-align: center;">`;
headerHTML += `<div style="color: #ff6b6b; margin-bottom: 5px;">Rogue AI</div>`;
headerHTML += `<div id="rogue-value-placeholder"></div>`;
headerHTML += `</div>`;
headerHTML += `</div>`;
const element = document.getElementById('actual-outcome-header');
fadeIn(element, headerHTML);
}, 4500);
// Reveal actual values one by one starting at 6 seconds
setTimeout(() => {
const { playerGalaxies, humanityGalaxies, rogueGalaxies } = gameState.galaxyDistribution;
// Reveal player percentage first
document.getElementById('player-value-placeholder').innerHTML = `${Math.round(playerGalaxies)}%`;
// Reveal humanity percentage after 0.5 seconds
setTimeout(() => {
document.getElementById('humanity-value-placeholder').innerHTML = `${Math.round(humanityGalaxies)}%`;
// Reveal rogue AI percentage after another 0.5 seconds
setTimeout(() => {
document.getElementById('rogue-value-placeholder').innerHTML = `${Math.round(rogueGalaxies)}%`;
// Reveal conclusion text after another 1 second
setTimeout(() => {
const conclusionText = generateConclusionText();
const conclusionElement = document.getElementById('conclusion-reveal');
fadeIn(conclusionElement, `<br><br>${conclusionText}`);
}, 1000);
}, 500);
}, 500);
}, 6000);
// Reveal restart button after 9.5 seconds (1s after conclusion)
setTimeout(() => {
const restartHTML = `<br><button class="button" onclick="restartGame();">Restart</button>`;
const element = document.getElementById('score-reveal');
fadeIn(element, restartHTML);
}, 9500);
}
function restartGame() {
window.resetGameState();
showPage('start');
}
function calculateEndGameScore() {
// Return cached result if it exists (to avoid re-rolling random events)
if (gameState.endGameResult) {
return gameState.endGameResult;
}
let resultText = "";
let playerGalaxies = 0;
let humanityGalaxies = 0;
let rogueGalaxies = 0;
if (gameState.gameOverReason === 'risk-100') {
// Instant game over - all AIs are misaligned
resultText = `${gameState.companyName} was reckless enough to let doom reach 100%. Humanity is immediately eaten by nanobots, which go on to colonize the stars.`;
rogueGalaxies = 100;
playerGalaxies = 0;
humanityGalaxies = 0;
} else if (gameState.gameOverReason === 'ai-singularity' || gameState.gameOverReason === 'dsa-singularity') {
resultText = "The singularity has arrived. ";
const narrow_race = Math.min(gameState.playerAILevel, gameState.competitorAILevels[0]) >= GAME_CONSTANTS.NARROW_RACE_THRESHOLD;
if (gameState.playerAILevel >= GAME_CONSTANTS.ASI_THRESHOLD) {
resultText += narrow_race ? "You achieved ASI first. " : "You achieved ASI first, but competitor AI was close behind. ";
} else {
resultText += "Competitor AI achieved ASI first. ";
}
// Calculate galaxy splits based on README formula
const playerShare = Math.max(0, Math.min(100, gameState.playerAILevel - gameState.competitorAILevels[0]));
const otherShare = 100 - playerShare;
// Roll for misalignment using adjusted risk level as probability
const adjustedRisk = calculateAdjustedRiskPercent();
const playerMisaligned = Math.random() * 100 < adjustedRisk;
const otherMisaligned = Math.random() * 100 < adjustedRisk;
if (playerMisaligned) {
rogueGalaxies += playerShare;
resultText += `Your AI systems became misaligned (${Math.round(adjustedRisk)}% chance). `;
} else {
playerGalaxies = playerShare;
resultText += `Your AI systems remained aligned. `;
}
if (otherMisaligned) {
rogueGalaxies += otherShare;
resultText += `Other AI systems became misaligned. `;
} else {
humanityGalaxies = otherShare;
resultText += `Other AI systems remained aligned. `;
}
}
// Calculate final score using shared multiplier function
const multipliers = getGalaxyMultipliers();
const finalScore = (0 * rogueGalaxies) + (multipliers.humanity * humanityGalaxies) + (multipliers.player * gameState.playerEquity * playerGalaxies);
resultText += `<br><br><strong>Final Galaxy Distribution:</strong><br>`;
resultText += `• Rogue AI: ${rogueGalaxies}%<br>`;
resultText += `• Humanity at large: ${humanityGalaxies}%<br>`;
resultText += `• Your company: ${playerGalaxies}%<br><br>`;
resultText += `<strong>Final Score: ${finalScore}</strong><br>`;
resultText += `(${rogueGalaxies}×0 + ${humanityGalaxies}×${multipliers.humanity} + ${playerGalaxies}×${Math.round(multipliers.player * gameState.playerEquity * 10) / 10})`;
// Store the result to avoid re-rolling randomness
gameState.endGameResult = resultText;
return resultText;
}
// Export functions for ES modules
export {
scaleAILevelsForEndGame,
getEndGamePhaseText,
getEndGamePhaseButtons,
continueToNextPhase,
calculateEndGameScore
};
// Export functions to global scope for cross-file access
if (typeof window !== 'undefined') {
// Browser environment
window.scaleAILevelsForEndGame = scaleAILevelsForEndGame;
window.getEndGamePhaseText = getEndGamePhaseText;
window.getEndGamePhaseButtons = getEndGamePhaseButtons;
window.continueToNextPhase = continueToNextPhase;
window.calculateEndGameScore = calculateEndGameScore;
window.restartGame = restartGame;
}