Sebastiankay commited on
Commit
de7d29f
·
verified ·
1 Parent(s): dc86199

Create damelogic.js

Browse files
Files changed (1) hide show
  1. damelogic.js +408 -0
damelogic.js ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const boardSize = 8;
2
+ let board = [],
3
+ currentPlayer = 1,û
4
+ selectedPiece = null,
5
+ validMoves = [],
6
+ gameRunning = false,
7
+ vsCPU = false;
8
+
9
+ const playerColors = {
10
+ 1: "168, 208, 230",
11
+ 2: "246, 171, 182",
12
+ };
13
+
14
+ let players = {
15
+ 1: { name: "Spieler 1", color: "168, 208, 230" },
16
+ 2: { name: "Spieler 2", color: "246, 171, 182" },
17
+ };
18
+
19
+ const captureHighlightColors = {
20
+ 1: "128, 168, 190",
21
+ 2: "206, 131, 142",
22
+ };
23
+
24
+ const pieceColors = {
25
+ 1: "77, 129, 199",
26
+ 2: "214, 106, 139",
27
+ };
28
+
29
+ const body = document.body;
30
+ body.style.setProperty("--player1-color", players[1].color);
31
+ body.style.setProperty("--player2-color", players[2].color);
32
+
33
+ const inputPlayerName1 = document.getElementById("inputPlayerName1");
34
+ inputPlayerName1.value = players[1].name;
35
+
36
+ const inputPlayerName2 = document.getElementById("inputPlayerName2");
37
+ inputPlayerName2.value = players[2].name;
38
+
39
+ const savePlayerNamesButton = document.getElementById("savePlayerNames");
40
+ const boardElement = document.getElementById("board");
41
+ const statusElement = document.getElementById("status");
42
+ const newGameButton = document.getElementById("new-game");
43
+ const winMessageElement = document.getElementById("winMessage");
44
+ const cpuToggle = document.getElementById("cpuToggle");
45
+
46
+ function inBounds(row, col) {
47
+ return row >= 0 && row < boardSize && col >= 0 && col < boardSize;
48
+ }
49
+
50
+ function isEmpty(row, col) {
51
+ return board[row][col] === 0;
52
+ }
53
+
54
+ function isOpponent(piece, player) {
55
+ return piece !== 0 && (player === 1 ? piece === 2 || piece === 4 : piece === 1 || piece === 3);
56
+ }
57
+
58
+ function isPlayerPiece(piece, player) {
59
+ return player === 1 ? piece === 1 || piece === 3 : player === 2 && (piece === 2 || piece === 4);
60
+ }
61
+
62
+ function isKing(piece) {
63
+ return piece === 3 || piece === 4;
64
+ }
65
+
66
+ function initGame() {
67
+ board = Array.from({ length: boardSize }, () => Array(boardSize).fill(0));
68
+
69
+ for (let row = 0; row < 3; row++) {
70
+ for (let col = 0; col < boardSize; col++) {
71
+ if ((row + col) % 2 === 1) board[row][col] = 1;
72
+ }
73
+ }
74
+
75
+ for (let row = boardSize - 3; row < boardSize; row++) {
76
+ for (let col = 0; col < boardSize; col++) {
77
+ if ((row + col) % 2 === 1) board[row][col] = 2;
78
+ }
79
+ }
80
+
81
+ currentPlayer = 1;
82
+ selectedPiece = null;
83
+ validMoves = [];
84
+ gameRunning = true;
85
+ winMessageElement.style.display = "none";
86
+ newGameButton.style.display = "inline-block";
87
+ vsCPU = cpuToggle.checked;
88
+ cpuToggle.disabled = false;
89
+ updateStatus();
90
+ updateBackground();
91
+ renderBoard();
92
+
93
+ if (vsCPU && currentPlayer === 2) {
94
+ setTimeout(cpuMove, 500);
95
+ }
96
+ }
97
+
98
+ function updateStatus() {
99
+ statusElement.textContent = `${players[currentPlayer].name} ist am Zug`;
100
+ }
101
+
102
+ function updateBackground() {
103
+ body.style.setProperty("--active-background-color", players[currentPlayer].color);
104
+ }
105
+
106
+ function getValidMoves(row, col) {
107
+ const moves = [];
108
+ const piece = board[row][col];
109
+
110
+ if (!isPlayerPiece(piece, currentPlayer)) return moves;
111
+
112
+ const directions = isKing(piece)
113
+ ? [[1, 1], [1, -1], [-1, 1], [-1, -1]]
114
+ : currentPlayer === 1
115
+ ? [[1, -1], [1, 1]]
116
+ : [[-1, -1], [-1, 1]];
117
+
118
+ directions.forEach(([dr, dc]) => {
119
+ const newRow = row + dr, newCol = col + dc;
120
+ if (inBounds(newRow, newCol) && isEmpty(newRow, newCol)) {
121
+ moves.push({ row: newRow, col: newCol, capture: false });
122
+ }
123
+
124
+ const captureRow = row + 2 * dr, captureCol = col + 2 * dc;
125
+ if (inBounds(newRow, newCol) && inBounds(captureRow, captureCol) && isOpponent(board[newRow][newCol], currentPlayer) && isEmpty(captureRow, captureCol)) {
126
+ moves.push({ row: captureRow, col: captureCol, capture: true, captured: { row: newRow, col: newCol } });
127
+ }
128
+ });
129
+
130
+ return moves;
131
+ }
132
+
133
+ function getValidMovesForPlayer(row, col, player) {
134
+ const moves = [];
135
+ const piece = board[row][col];
136
+
137
+ if (!isPlayerPiece(piece, player)) return moves;
138
+
139
+ const directions = isKing(piece)
140
+ ? [[1, 1], [1, -1], [-1, 1], [-1, -1]]
141
+ : player === 1
142
+ ? [[1, -1], [1, 1]]
143
+ : [[-1, -1], [-1, 1]];
144
+
145
+ directions.forEach(([dr, dc]) => {
146
+ const newRow = row + dr, newCol = col + dc;
147
+ if (inBounds(newRow, newCol) && isEmpty(newRow, newCol)) {
148
+ moves.push({ row: newRow, col: newCol, capture: false });
149
+ }
150
+
151
+ const captureRow = row + 2 * dr, captureCol = col + 2 * dc;
152
+ if (inBounds(newRow, newCol) && inBounds(captureRow, captureCol) && isOpponent(board[newRow][newCol], player) && isEmpty(captureRow, captureCol)) {
153
+ moves.push({ row: captureRow, col: captureCol, capture: true, captured: { row: newRow, col: newCol } });
154
+ }
155
+ });
156
+
157
+ return moves;
158
+ }
159
+
160
+ function hasAnyMoves(player) {
161
+ for (let row = 0; row < boardSize; row++) {
162
+ for (let col = 0; col < boardSize; col++) {
163
+ if (isPlayerPiece(board[row][col], player) && getValidMovesForPlayer(row, col, player).length > 0) {
164
+ return true;
165
+ }
166
+ }
167
+ }
168
+ return false;
169
+ }
170
+
171
+ function hasAnyCapture() {
172
+ for (let row = 0; row < boardSize; row++) {
173
+ for (let col = 0; col < boardSize; col++) {
174
+ if (isPlayerPiece(board[row][col], currentPlayer) && getValidMoves(row, col).some(move => move.capture)) {
175
+ return true;
176
+ }
177
+ }
178
+ }
179
+ return false;
180
+ }
181
+
182
+ function makeMove(fromRow, fromCol, move) {
183
+ board[move.row][move.col] = board[fromRow][fromCol];
184
+ board[fromRow][fromCol] = 0;
185
+
186
+ if (move.capture) {
187
+ const captured = move.captured;
188
+ board[captured.row][captured.col] = 0;
189
+ }
190
+
191
+ if (currentPlayer === 1 && move.row === boardSize - 1 && board[move.row][move.col] === 1) {
192
+ board[move.row][move.col] = 3;
193
+ } else if (currentPlayer === 2 && move.row === 0 && board[move.row][move.col] === 2) {
194
+ board[move.row][move.col] = 4;
195
+ }
196
+ }
197
+
198
+ function switchPlayer() {
199
+ currentPlayer = currentPlayer === 1 ? 2 : 1;
200
+ selectedPiece = null;
201
+ renderBoard();
202
+ validMoves = [];
203
+ updateStatus();
204
+ updateBackground();
205
+
206
+ if (hasAnyMoves(currentPlayer)) {
207
+ if (vsCPU && currentPlayer === 2) {
208
+ setTimeout(cpuMove, 500);
209
+ }
210
+ } else {
211
+ endGame(currentPlayer === 1 ? 2 : 1);
212
+ }
213
+ }
214
+
215
+ function cpuMove() {
216
+ let possibleMoves = [];
217
+ const mustCapture = hasAnyCapture();
218
+
219
+ for (let row = 0; row < boardSize; row++) {
220
+ for (let col = 0; col < boardSize; col++) {
221
+ if (isPlayerPiece(board[row][col], currentPlayer)) {
222
+ let moves = getValidMoves(row, col);
223
+ if (mustCapture) {
224
+ moves = moves.filter(move => move.capture);
225
+ }
226
+ if (moves.length > 0) {
227
+ possibleMoves.push({ row, col, moves });
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ if (possibleMoves.length === 0) {
234
+ endGame(currentPlayer === 1 ? 2 : 1);
235
+ return;
236
+ }
237
+
238
+ const { row, col, moves } = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];
239
+ const move = moves[Math.floor(Math.random() * moves.length)];
240
+
241
+ setTimeout(() => {
242
+ makeMove(row, col, move);
243
+ renderBoard();
244
+ if (move.capture) {
245
+ cpuCaptureChain(move.row, move.col);
246
+ } else {
247
+ checkWin() || switchPlayer();
248
+ }
249
+ }, 500);
250
+ }
251
+
252
+ function cpuCaptureChain(row, col) {
253
+ let captureMoves = getValidMoves(row, col).filter(move => move.capture);
254
+ if (captureMoves.length > 0) {
255
+ const move = captureMoves[Math.floor(Math.random() * captureMoves.length)];
256
+ setTimeout(() => {
257
+ makeMove(row, col, move);
258
+ renderBoard();
259
+ cpuCaptureChain(move.row, move.col);
260
+ }, 500);
261
+ } else {
262
+ checkWin() || switchPlayer();
263
+ }
264
+ }
265
+
266
+ function checkWin() {
267
+ let player1Pieces = 0, player2Pieces = 0;
268
+
269
+ for (let row = 0; row < boardSize; row++) {
270
+ for (let col = 0; col < boardSize; col++) {
271
+ if (board[row][col] === 1 || board[row][col] === 3) {
272
+ player1Pieces++;
273
+ } else if (board[row][col] === 2 || board[row][col] === 4) {
274
+ player2Pieces++;
275
+ }
276
+ }
277
+ }
278
+
279
+ if (player1Pieces === 0) {
280
+ endGame(2);
281
+ return true;
282
+ } else if (player2Pieces === 0) {
283
+ endGame(1);
284
+ return true;
285
+ } else if (!hasAnyMoves(currentPlayer === 1 ? 2 : 1)) {
286
+ endGame(currentPlayer);
287
+ return true;
288
+ }
289
+
290
+ return false;
291
+ }
292
+
293
+ function endGame(winner) {
294
+ gameRunning = false;
295
+ newGameButton.style.display = "none";
296
+ winMessageElement.textContent = `Spieler ${winner} hat gewonnen! (Zum Neustart klicken)`;
297
+ winMessageElement.style.display = "block";
298
+ winMessageElement.style.backgroundColor = `rgba(${players[winner].color}, 1.0)`;
299
+ cpuToggle.disabled = false;
300
+ winMessageElement.addEventListener("click", initGame, { once: true });
301
+ }
302
+
303
+ function renderBoard() {
304
+ boardElement.innerHTML = "";
305
+
306
+ for (let row = 0; row < boardSize; row++) {
307
+ for (let col = 0; col < boardSize; col++) {
308
+ const cell = document.createElement("div");
309
+ cell.classList.add("cell");
310
+ cell.classList.add((row + col) % 2 === 0 ? "light" : "dark");
311
+ cell.dataset.row = row;
312
+ cell.dataset.col = col;
313
+
314
+ if (validMoves.some(move => move.row === row && move.col === col)) {
315
+ cell.classList.add("highlight");
316
+ }
317
+
318
+ if (selectedPiece && selectedPiece.row === row && selectedPiece.col === col) {
319
+ cell.classList.add("selected");
320
+ }
321
+
322
+ const piece = board[row][col];
323
+ if (piece !== 0) {
324
+ const pieceElement = document.createElement("div");
325
+ pieceElement.classList.add("piece");
326
+ pieceElement.style.setProperty("--player-color", players[piece % 2 === 0 ? 2 : 1].color);
327
+
328
+ if (isKing(piece)) {
329
+ pieceElement.classList.add("king");
330
+ }
331
+
332
+ if (getValidMoves(row, col).some(move => move.capture)) {
333
+ pieceElement.classList.add("must-capture");
334
+ } else {
335
+ pieceElement.classList.remove("must-capture");
336
+ }
337
+
338
+ cell.appendChild(pieceElement);
339
+ }
340
+
341
+ cell.addEventListener("click", handleCellClick);
342
+ boardElement.appendChild(cell);
343
+ }
344
+ }
345
+ }
346
+
347
+ function handleCellClick(event) {
348
+ if (!gameRunning || (vsCPU && currentPlayer === 2)) return;
349
+
350
+ const row = parseInt(event.currentTarget.dataset.row);
351
+ const col = parseInt(event.currentTarget.dataset.col);
352
+
353
+ if (selectedPiece) {
354
+ const move = validMoves.find(move => move.row === row && move.col === col);
355
+ if (move) {
356
+ makeMove(selectedPiece.row, selectedPiece.col, move);
357
+ renderBoard();
358
+ if (move.capture) {
359
+ const captureMoves = getValidMoves(move.row, move.col).filter(move => move.capture);
360
+ if (captureMoves.length > 0) {
361
+ selectedPiece = { row: move.row, col: move.col };
362
+ validMoves = captureMoves;
363
+ return;
364
+ }
365
+ }
366
+ selectedPiece = null;
367
+ validMoves = [];
368
+ checkWin() || switchPlayer();
369
+ return;
370
+ }
371
+ }
372
+
373
+ if (isPlayerPiece(board[row][col], currentPlayer)) {
374
+ if (hasAnyCapture()) {
375
+ const captureMoves = getValidMoves(row, col).filter(move => move.capture);
376
+ if (captureMoves.length === 0) return;
377
+ selectedPiece = { row, col };
378
+ validMoves = captureMoves;
379
+ } else {
380
+ selectedPiece = { row, col };
381
+ validMoves = getValidMoves(row, col);
382
+ }
383
+ renderBoard();
384
+ }
385
+ }
386
+
387
+ function openSavePlayerNamesDialog() {
388
+ if (!cpuToggle.checked) {
389
+ inputPlayerName2.value = inputPlayerName2.value === "CPU" ? "Spieler 2" : inputPlayerName2.value;
390
+ } else {
391
+ inputPlayerName2.value = "CPU";
392
+ }
393
+ inputPlayerName2.disabled = cpuToggle.checked;
394
+ document.getElementById("setPlayerNamesWrapperBackdrop").style.display = "block";
395
+ }
396
+
397
+ savePlayerNamesButton.addEventListener("click", () => {
398
+ players[1].name = inputPlayerName1.value.length > 0 ? inputPlayerName1.value : "Spieler 1";
399
+ players[2].name = inputPlayerName2.value.length > 0 ? inputPlayerName2.value : "Spieler 2";
400
+ document.getElementById("setPlayerNamesWrapperBackdrop").style.display = "none";
401
+ cpuToggle.disabled = false;
402
+ initGame();
403
+ });
404
+
405
+ newGameButton.addEventListener("click", openSavePlayerNamesDialog);
406
+ cpuToggle.addEventListener("click", openSavePlayerNamesDialog);
407
+
408
+ initGame();