Spaces:
Running
Running
Update index.html
Browse files- index.html +38 -15
index.html
CHANGED
@@ -36,28 +36,52 @@
|
|
36 |
this.game_ended = false;
|
37 |
};
|
38 |
this.reset();
|
39 |
-
this.
|
40 |
-
this.
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
};
|
44 |
-
this.submit_board = async function (
|
|
|
45 |
const obs = tf.tensor(this_.board, [this_.num_rows, this_.num_cols], 'float32');
|
46 |
const normalized_obs = tf.mul(obs, this_.ai_player);
|
47 |
normalized_obs.print();
|
48 |
const [action_logits, value] = this_.agent.predict(normalized_obs);
|
49 |
action_logits.print();
|
|
|
50 |
const action = await tf.argMax(action_logits).array();
|
51 |
return {
|
52 |
-
"terminated":
|
53 |
"action": action,
|
54 |
};
|
55 |
};
|
56 |
this.end_game = function () {
|
57 |
this.game_ended = true;
|
58 |
-
setTimeout(function() {this_.reset();}, 3000);
|
59 |
};
|
60 |
-
this.ai_play = function() {
|
61 |
this_.submit_board().then(
|
62 |
function (info) {
|
63 |
document.body.style.cursor = 'default';
|
@@ -74,12 +98,12 @@
|
|
74 |
this_.end_game();
|
75 |
}
|
76 |
}
|
77 |
-
).catch(function (e) { });
|
78 |
};
|
79 |
-
document.getElementById("ai-first").onclick = function() {
|
80 |
this_.reset();
|
81 |
this_.ai_player = 1;
|
82 |
-
this_.ai_play();
|
83 |
};
|
84 |
document.getElementById("game-board").addEventListener('click', function (e) {
|
85 |
var rect = this.getBoundingClientRect();
|
@@ -89,7 +113,7 @@
|
|
89 |
var loc_y = Math.floor(y / this_.board_scale - 0.5);
|
90 |
this_.mouse_x = loc_x;
|
91 |
this_.mouse_y = this_.get_candidate(this_.mouse_x)[1];
|
92 |
-
|
93 |
if (
|
94 |
this_.mouse_x >= 0 &&
|
95 |
this_.mouse_y >= 0 &&
|
@@ -169,7 +193,6 @@
|
|
169 |
}
|
170 |
};
|
171 |
document.getElementById("game-board").onmousemove = function (e) {
|
172 |
-
// important: correct mouse position:
|
173 |
var rect = this.getBoundingClientRect();
|
174 |
var x = e.clientX - rect.left;
|
175 |
var y = e.clientY - rect.top;
|
@@ -181,7 +204,7 @@
|
|
181 |
};
|
182 |
};
|
183 |
const modelUrl = '/static/ntt123/Connect-4-Game/model.json';
|
184 |
-
const init_fn = async function() {
|
185 |
const model = await tf.loadGraphModel(modelUrl);
|
186 |
await tf.setBackend('wasm');
|
187 |
return model;
|
@@ -189,7 +212,7 @@
|
|
189 |
document.addEventListener("DOMContentLoaded", function (event) {
|
190 |
init_fn().then(function (agent) {
|
191 |
game = new BoardGame(agent, 6, 7);
|
192 |
-
game.render();
|
193 |
});
|
194 |
});
|
195 |
</script>
|
|
|
36 |
this.game_ended = false;
|
37 |
};
|
38 |
this.reset();
|
39 |
+
this.get = function (row, col) {
|
40 |
+
return this.board[this.num_cols * row + col];
|
41 |
+
}
|
42 |
+
this.is_terminated = function () {
|
43 |
+
// check if the game is terminated
|
44 |
+
const num_empty_cells = this.board.reduce((a, b) => a + b);
|
45 |
+
if (num_empty_cells == 0) return true;
|
46 |
+
for (let i = 0; i < this.num_rows; i++) {
|
47 |
+
for (let j = 0; j < this.num_cols; j++) {
|
48 |
+
// check winner at cell i, j
|
49 |
+
var p = this.get(i, j);
|
50 |
+
for (let dxy of [[1, 0], [0, 1], [1, 1], [-1, 1]]) {
|
51 |
+
var count = 0;
|
52 |
+
for (let k = 1; k <= 4; k++) {
|
53 |
+
const u = i + dx * k;
|
54 |
+
const v = j + dy * k;
|
55 |
+
if (u < 0 || u >= this.num_rows) break;
|
56 |
+
if (v < 0 || v >= this.num_cols) break;
|
57 |
+
if (this.get(u, v) != p) break;
|
58 |
+
count = count + 1;
|
59 |
+
}
|
60 |
+
if (count >= 4) return true;
|
61 |
+
}
|
62 |
+
}
|
63 |
+
}
|
64 |
+
return false;
|
65 |
};
|
66 |
+
this.submit_board = async function () {
|
67 |
+
if (this_.is_terminated()) return { "terminated": true, "action": -1 };
|
68 |
const obs = tf.tensor(this_.board, [this_.num_rows, this_.num_cols], 'float32');
|
69 |
const normalized_obs = tf.mul(obs, this_.ai_player);
|
70 |
normalized_obs.print();
|
71 |
const [action_logits, value] = this_.agent.predict(normalized_obs);
|
72 |
action_logits.print();
|
73 |
+
value.print();
|
74 |
const action = await tf.argMax(action_logits).array();
|
75 |
return {
|
76 |
+
"terminated": this_.is_terminated(),
|
77 |
"action": action,
|
78 |
};
|
79 |
};
|
80 |
this.end_game = function () {
|
81 |
this.game_ended = true;
|
82 |
+
setTimeout(function () { this_.reset(); }, 3000);
|
83 |
};
|
84 |
+
this.ai_play = function () {
|
85 |
this_.submit_board().then(
|
86 |
function (info) {
|
87 |
document.body.style.cursor = 'default';
|
|
|
98 |
this_.end_game();
|
99 |
}
|
100 |
}
|
101 |
+
).catch(function (e) { });
|
102 |
};
|
103 |
+
document.getElementById("ai-first").onclick = function () {
|
104 |
this_.reset();
|
105 |
this_.ai_player = 1;
|
106 |
+
this_.ai_play();
|
107 |
};
|
108 |
document.getElementById("game-board").addEventListener('click', function (e) {
|
109 |
var rect = this.getBoundingClientRect();
|
|
|
113 |
var loc_y = Math.floor(y / this_.board_scale - 0.5);
|
114 |
this_.mouse_x = loc_x;
|
115 |
this_.mouse_y = this_.get_candidate(this_.mouse_x)[1];
|
116 |
+
|
117 |
if (
|
118 |
this_.mouse_x >= 0 &&
|
119 |
this_.mouse_y >= 0 &&
|
|
|
193 |
}
|
194 |
};
|
195 |
document.getElementById("game-board").onmousemove = function (e) {
|
|
|
196 |
var rect = this.getBoundingClientRect();
|
197 |
var x = e.clientX - rect.left;
|
198 |
var y = e.clientY - rect.top;
|
|
|
204 |
};
|
205 |
};
|
206 |
const modelUrl = '/static/ntt123/Connect-4-Game/model.json';
|
207 |
+
const init_fn = async function () {
|
208 |
const model = await tf.loadGraphModel(modelUrl);
|
209 |
await tf.setBackend('wasm');
|
210 |
return model;
|
|
|
212 |
document.addEventListener("DOMContentLoaded", function (event) {
|
213 |
init_fn().then(function (agent) {
|
214 |
game = new BoardGame(agent, 6, 7);
|
215 |
+
game.render();
|
216 |
});
|
217 |
});
|
218 |
</script>
|