-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
executable file
·153 lines (133 loc) · 3.59 KB
/
main.js
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
"use strict";
let game = Game({ gameHeight: 12, gameWidth: 10 });
let evaluator = Evaluator(game);
let view = View(game);
let brain = Brain({ game, evaluator });
let specializedBrain = SpecializedBrain(game, evaluator, brain.getConfig());
console.log(brain.getConfig());
const archiveName = "archive_" + Random.intNumberBetween(0, 5000);
// Used to help create a seeded generated random number for choosing shapes. makes results deterministic (reproducible) for debugging
let rndSeed = Random.intNumberBetween(0, 1000); // 1;
//GAME VALUES
//for storing current state, we can load later
let saveState;
// Game speed
let speeds = [512, 256, 128, 1, 0, 2048];
let speedIndex = 0;
const speedUp = () => speedIndex = ++speedIndex % speeds.length;
const speedDown = () => speedIndex = (--speedIndex + speeds.length) % speeds.length;
const generationScore = [];
// Current move
let movesTaken = 0;
let moveLimit = 20000;
// TODO deplacer dans brain et afficher les stats par le brain
//stores genomes
let genomes = [];
let genomeIndex = -1;
//generation number
let generation = 0;
// Size of solution population to train
let populationSize = 50;
// Is AI enabled?
let ai = true;
const toggleAi = () => ai = !ai;
// Key control
window.onkeydown = function (event) {
if (event.ctrlKey) {
loadJSON("./" + archiveName + ".json", brain.loadArchive);
return false;
}
const characterPressed = String.fromCharCode(event.keyCode);
switch (characterPressed.toUpperCase()) {
case 'Q': {
saveState = specializedBrain.getState();
break;
}
case 'W': {
specializedBrain.loadState(saveState);
break;
}
case 'D': {
speedDown();
break;
}
case 'E': {
speedUp();
break;
}
case 'A': {
toggleAi();
break;
}
case 'R': {
//load saved generation values
brain.loadArchive(prompt("Insert archive:"));
break;
}
case 'G': {
if (localStorage.getItem(archiveName) === null) {
alert("No archive saved. Archives are saved after a generation has passed, and remain across sessions. Try again once a generation has passed");
} else {
prompt("Archive from last generation (including from last session):", localStorage.getItem(archiveName));
}
break;
}
default: {
if (!ai) {
game.control(event, characterPressed);
}
}
}
// Stops propagation
return false;
};
/**
* Updates the game.
*/
function update() {
/*
TODO
algo devrait etre:
- appliquer coup suivant et moveTaken++
- si fini, genome suivant et moveTaken = 0
*/
// Execute next game step (e.g. tetris would be move down)
const results = game.step();
if (ai) {
if (movesTaken > moveLimit || results.end) {
brain.evaluateNextGenome();
movesTaken = 0;
} else if (!results.moved) {
// TODO voyageur de commerce ne passe jamais ici
// reparer moveDown dans tetris et separer la logique du brain
brain.makeNextMove();
movesTaken++;
}
}
// Refresh game board if not unlimited speed
speeds[speedIndex] !== 0 && view.displayGame();
// Refresh the score and stats view
view.displayData();
};
/**
* Resets the game.
*/
function reset() {
movesTaken = 0;
game.reset();
}
// main function, called on load
let initialize = function () {
game.initialize();
view.initialize();
brain.initialize();
// Game main loop
const loop = function () {
// Play next game move, evaluate...
update();
setTimeout(loop, speeds[speedIndex]);
};
//timer interval
setTimeout(loop, speeds[speedIndex]);
};
document.onLoad = initialize();