-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
200 lines (184 loc) · 6.3 KB
/
Copy pathscript.js
File metadata and controls
200 lines (184 loc) · 6.3 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
const boardContainer = document.getElementById('boardContainer');
const statusDiv = document.getElementById('status');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
const undoBtn = document.getElementById('undoBtn');
const aiBtn = document.getElementById('aiBtn');
let width = 3, height = 3, depth = 3, winLength = 3, aiDepth = 2;
let gameInProgress = false;
let aiThinking = false;
function getSettings() {
width = parseInt(document.getElementById('width').value);
height = parseInt(document.getElementById('height').value);
depth = parseInt(document.getElementById('depth').value);
winLength = parseInt(document.getElementById('winLength').value);
aiDepth = parseInt(document.getElementById('aiDepth').value);
}
async function checkGameInProgress() {
// If there are valid moves, assume game is in progress
const res = await fetch('/get_valid_moves');
const validMoves = await res.json();
gameInProgress = validMoves.length > 0;
updateControls();
}
async function startGame() {
getSettings();
await fetch(`/start?height=${height}&width=${width}&depth=${depth}&win_length=${winLength}`, { method: 'POST' });
await renderBoard();
statusDiv.textContent = `Game started! Player X's turn.`;
gameInProgress = true;
updateControls();
}
async function restartGame() {
await startGame();
}
async function undoMove() {
await fetch('/undo', { method: 'POST' });
await renderBoard();
await updateStatus();
}
function setAIThinking(thinking) {
aiThinking = thinking;
// Disable all controls and board
document.querySelectorAll('button, input').forEach(el => {
if (el.id !== 'aiDepth') el.disabled = thinking;
});
if (thinking) {
statusDiv.textContent = 'Computer is thinking ...';
}
}
async function aiMove() {
getSettings();
// Prevent AI move if there is a winner
const winnerRes = await fetch('/check_winner');
const winner = await winnerRes.json();
if (winner) {
statusDiv.textContent = `Player ${winner} has already won!`;
return;
}
setAIThinking(true);
await fetch(`/search_depth?search_depth=${aiDepth}`, { method: 'POST' });
await renderBoard();
await updateStatus();
setAIThinking(false);
}
async function quitGame() {
await fetch('/quit', { method: 'POST' });
gameInProgress = false;
updateControls();
boardContainer.innerHTML = '';
statusDiv.textContent = 'Game quit. Start a new game!';
}
async function makeMove(x, y, z) {
if (aiThinking) return;
// Prevent moves if there is a winner
const winnerRes = await fetch('/check_winner');
const winner = await winnerRes.json();
if (winner) {
statusDiv.textContent = `Player ${winner} has already won!`;
return;
}
const res = await fetch(`/move?x=${x}&y=${y}&z=${z}`, { method: 'POST' });
const valid = await res.json();
if (!valid) {
statusDiv.textContent = 'Invalid move!';
return;
}
await fetch('/switch_player', { method: 'POST' });
await renderBoard();
await updateStatus();
}
async function renderBoard() {
const res = await fetch('/get_board');
const data = await res.json();
const board = data.board;
// If board is null, clear UI
if (!board) {
boardContainer.innerHTML = '';
return;
}
// Get board dimensions
const depth = board.length;
const height = board[0].length;
const width = board[0][0].length;
boardContainer.innerHTML = '';
for (let z = 0; z < depth; z++) {
const layerDiv = document.createElement('div');
layerDiv.className = 'layer';
const title = document.createElement('div');
title.className = 'layer-title';
title.textContent = `Layer ${z}`;
layerDiv.appendChild(title);
const boardDiv = document.createElement('div');
boardDiv.className = 'board';
boardDiv.style.gridTemplateColumns = `repeat(${width}, 1fr)`;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const cellBtn = document.createElement('button');
cellBtn.className = 'cell';
cellBtn.dataset.x = x;
cellBtn.dataset.y = y;
cellBtn.dataset.z = z;
const value = board[z][y][x];
if (value === '.') {
cellBtn.textContent = '';
cellBtn.disabled = false;
cellBtn.onclick = () => makeMove(x, y, z);
} else {
cellBtn.textContent = value;
cellBtn.classList.add(value);
cellBtn.disabled = true;
}
boardDiv.appendChild(cellBtn);
}
}
layerDiv.appendChild(boardDiv);
boardContainer.appendChild(layerDiv);
}
}
async function updateStatus() {
if (!gameInProgress) {
statusDiv.textContent = '';
return;
}
// Check winner
const winnerRes = await fetch('/check_winner');
const winner = await winnerRes.json();
if (winner) {
statusDiv.textContent = `Player ${winner} wins!`;
disableAllCells();
return;
}
// Check draw
const drawRes = await fetch('/is_draw');
const isDraw = await drawRes.json();
if (isDraw) {
statusDiv.textContent = `It's a draw!`;
disableAllCells();
return;
}
// Otherwise, show current player
const boardRes = await fetch('/get_board');
const boardData = await boardRes.json();
statusDiv.textContent = `Player ${boardData.player}'s turn.`;
}
function disableAllCells() {
document.querySelectorAll('.cell').forEach(cell => cell.disabled = true);
}
function updateControls() {
document.getElementById('preGameControls').style.display = gameInProgress ? 'none' : '';
document.getElementById('inGameControls').style.display = gameInProgress ? '' : 'none';
if (!gameInProgress) {
statusDiv.textContent = '';
}
}
startBtn.onclick = startGame;
restartBtn.onclick = restartGame;
undoBtn.onclick = undoMove;
aiBtn.onclick = aiMove;
document.getElementById('quitBtn').onclick = quitGame;
document.addEventListener('DOMContentLoaded', () => {
checkGameInProgress();
renderBoard();
updateStatus();
});