Chicken117 commited on
Commit
429dc12
·
verified ·
1 Parent(s): f9701cf

Add 2 files

Browse files
Files changed (2) hide show
  1. index.html +561 -337
  2. prompts.txt +1 -0
index.html CHANGED
@@ -3,192 +3,160 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Kids Coding Adventure</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
- .command-block {
11
- background-color: #f0f9ff;
12
- border: 2px dashed #7dd3fc;
13
- border-radius: 12px;
14
- padding: 10px;
15
- margin: 5px;
16
- cursor: grab;
 
 
17
  }
18
- .command-block:active {
19
- cursor: grabbing;
20
  }
21
- .workspace {
22
- min-height: 150px;
23
- background-color: #f8fafc;
24
- border: 3px solid #e2e8f0;
25
- border-radius: 12px;
26
- padding: 15px;
27
  }
28
- .character {
29
- transition: all 0.3s ease;
 
30
  }
31
- .success-animation {
32
- animation: celebrate 1s ease infinite;
33
  }
34
- @keyframes celebrate {
35
- 0%, 100% { transform: translateY(0); }
36
- 50% { transform: translateY(-20px); }
37
  }
38
- .path-cell {
39
- width: 60px;
40
- height: 60px;
41
- border: 1px solid #cbd5e1;
42
- display: flex;
43
- align-items: center;
44
- justify-content: center;
45
  }
46
- .obstacle {
47
  background-color: #fca5a5;
48
  }
49
- .treasure {
50
- background-color: #fcd34d;
 
 
 
 
 
 
 
51
  }
52
- .highlight {
53
- box-shadow: 0 0 0 3px #86efac;
 
 
 
 
 
54
  }
55
  </style>
56
  </head>
57
- <body class="bg-blue-50 min-h-screen">
58
  <div class="container mx-auto px-4 py-8">
59
  <div class="text-center mb-8">
60
- <h1 class="text-4xl font-bold text-blue-800 mb-2">🐱 Cat Coding Adventure 🐱</h1>
61
  <p class="text-blue-600 max-w-2xl mx-auto">
62
- Help the cat reach the fish by dragging coding blocks to create a path!
63
  </p>
64
  </div>
65
 
66
- <div class="flex flex-col lg:flex-row gap-8">
67
- <!-- Game Board -->
68
- <div class="lg:w-1/2 bg-white rounded-xl shadow-md p-6">
69
- <div class="mb-6">
70
- <div class="grid grid-cols-5 gap-0 border-2 border-slate-200 rounded-lg overflow-hidden">
71
- <!-- Row 1 -->
72
- <div class="path-cell" id="cell-0-0"><div id="character" class="character text-4xl">🐱</div></div>
73
- <div class="path-cell" id="cell-0-1"></div>
74
- <div class="path-cell obstacle" id="cell-0-2"><div class="text-2xl">🌵</div></div>
75
- <div class="path-cell" id="cell-0-3"></div>
76
- <div class="path-cell" id="cell-0-4"></div>
77
-
78
- <!-- Row 2 -->
79
- <div class="path-cell" id="cell-1-0"></div>
80
- <div class="path-cell obstacle" id="cell-1-1"><div class="text-2xl">🌵</div></div>
81
- <div class="path-cell" id="cell-1-2"></div>
82
- <div class="path-cell obstacle" id="cell-1-3"><div class="text-2xl">🌵</div></div>
83
- <div class="path-cell" id="cell-1-4"></div>
84
-
85
- <!-- Row 3 -->
86
- <div class="path-cell" id="cell-2-0"></div>
87
- <div class="path-cell" id="cell-2-1"></div>
88
- <div class="path-cell" id="cell-2-2"></div>
89
- <div class="path-cell" id="cell-2-3"></div>
90
- <div class="path-cell" id="cell-2-4"></div>
91
-
92
- <!-- Row 4 -->
93
- <div class="path-cell" id="cell-3-0"></div>
94
- <div class="path-cell obstacle" id="cell-3-1"><div class="text-2xl">🌵</div></div>
95
- <div class="path-cell" id="cell-3-2"></div>
96
- <div class="path-cell" id="cell-3-3"></div>
97
- <div class="path-cell" id="cell-3-4"></div>
98
-
99
- <!-- Row 5 -->
100
- <div class="path-cell" id="cell-4-0"></div>
101
- <div class="path-cell" id="cell-4-1"></div>
102
- <div class="path-cell" id="cell-4-2"></div>
103
- <div class="path-cell obstacle" id="cell-4-3"><div class="text-2xl">🌵</div></div>
104
- <div class="path-cell treasure" id="cell-4-4"><div class="text-4xl">🐟</div></div>
105
- </div>
106
- </div>
107
 
108
- <div id="game-message" class="p-4 bg-blue-100 text-blue-800 rounded-lg mb-4">
109
- <i class="fas fa-info-circle mr-2"></i>
110
- <span>Drag coding blocks to the workspace to help the cat reach the fish!</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  </div>
112
-
113
- <div class="flex justify-center gap-4">
114
- <button id="run-btn" class="px-6 py-3 bg-green-500 text-white rounded-lg hover:bg-green-600">
115
- <i class="fas fa-play mr-2"></i>Run Code
116
- </button>
117
- <button id="reset-btn" class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600">
118
- <i class="fas fa-redo mr-2"></i>Reset
119
- </button>
 
 
 
 
 
120
  </div>
121
  </div>
 
122
 
123
- <!-- Coding Area -->
124
- <div class="lg:w-1/2 bg-white rounded-xl shadow-md p-6">
125
- <h2 class="text-xl font-bold text-blue-800 mb-4">Coding Blocks</h2>
126
-
127
- <div class="mb-6">
128
- <h3 class="text-lg font-medium text-blue-700 mb-2">Movement</h3>
129
- <div class="grid grid-cols-2 gap-3">
130
- <div class="command-block" draggable="true" data-command="moveUp">
131
- <div class="flex items-center justify-center p-2">
132
- <i class="fas fa-arrow-up text-blue-500 mr-2"></i>
133
- <span class="font-medium">Move Up</span>
134
- </div>
135
- </div>
136
- <div class="command-block" draggable="true" data-command="moveDown">
137
- <div class="flex items-center justify-center p-2">
138
- <i class="fas fa-arrow-down text-blue-500 mr-2"></i>
139
- <span class="font-medium">Move Down</span>
140
- </div>
141
- </div>
142
- <div class="command-block" draggable="true" data-command="moveLeft">
143
- <div class="flex items-center justify-center p-2">
144
- <i class="fas fa-arrow-left text-blue-500 mr-2"></i>
145
- <span class="font-medium">Move Left</span>
146
- </div>
147
- </div>
148
- <div class="command-block" draggable="true" data-command="moveRight">
149
- <div class="flex items-center justify-center p-2">
150
- <i class="fas fa-arrow-right text-blue-500 mr-2"></i>
151
- <span class="font-medium">Move Right</span>
152
- </div>
153
- </div>
154
  </div>
155
  </div>
156
 
157
- <div class="mb-6">
158
- <h3 class="text-lg font-medium text-blue-700 mb-2">Loops</h3>
159
- <div class="grid grid-cols-2 gap-3">
160
- <div class="command-block" draggable="true" data-command="repeat2">
161
- <div class="flex items-center justify-center p-2">
162
- <i class="fas fa-redo text-purple-500 mr-2"></i>
163
- <span class="font-medium">Repeat 2 Times</span>
164
- </div>
165
- </div>
166
- <div class="command-block" draggable="true" data-command="repeat3">
167
- <div class="flex items-center justify-center p-2">
168
- <i class="fas fa-redo text-purple-500 mr-2"></i>
169
- <span class="font-medium">Repeat 3 Times</span>
170
- </div>
171
- </div>
172
  </div>
173
  </div>
174
-
175
- <h3 class="text-lg font-medium text-blue-700 mb-2">Your Code</h3>
176
- <div id="workspace" class="workspace mb-6">
177
- <!-- Dropped commands will appear here -->
178
- </div>
179
  </div>
180
  </div>
181
 
182
- <!-- Success Modal -->
183
- <div id="success-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden">
184
  <div class="bg-white rounded-xl p-8 max-w-md w-full text-center">
185
- <div class="text-yellow-500 text-6xl mb-4">
186
- <i class="fas fa-star success-animation"></i>
187
  </div>
188
- <h2 class="text-3xl font-bold text-blue-800 mb-2">Great Job!</h2>
189
- <p class="text-blue-600 mb-6">You helped the cat reach the fish!</p>
190
  <button id="play-again-btn" class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600">
191
- Play Again
192
  </button>
193
  </div>
194
  </div>
@@ -198,212 +166,459 @@
198
  document.addEventListener('DOMContentLoaded', function() {
199
  // Game state
200
  const gameState = {
201
- characterPosition: { row: 0, col: 0 },
202
- commands: [],
203
- isRunning: false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  };
205
 
206
  // DOM elements
207
- const character = document.getElementById('character');
208
- const workspace = document.getElementById('workspace');
209
- const runBtn = document.getElementById('run-btn');
210
- const resetBtn = document.getElementById('reset-btn');
 
 
 
 
 
 
 
211
  const gameMessage = document.getElementById('game-message');
212
- const successModal = document.getElementById('success-modal');
 
 
213
  const playAgainBtn = document.getElementById('play-again-btn');
214
- const commandBlocks = document.querySelectorAll('.command-block');
215
- const cells = document.querySelectorAll('.path-cell');
216
 
217
- // Initialize drag and drop for command blocks
218
- commandBlocks.forEach(block => {
219
- block.addEventListener('dragstart', function(e) {
220
- e.dataTransfer.setData('text/plain', this.dataset.command);
221
- });
222
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
- // Set up drop zone
225
- workspace.addEventListener('dragover', function(e) {
226
- e.preventDefault();
227
- this.classList.add('highlight');
228
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
 
230
- workspace.addEventListener('dragleave', function() {
231
- this.classList.remove('highlight');
232
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
- workspace.addEventListener('drop', function(e) {
235
- e.preventDefault();
236
- this.classList.remove('highlight');
237
 
238
- const command = e.dataTransfer.getData('text/plain');
239
- addCommandToWorkspace(command);
 
 
 
240
  });
241
 
242
- // Add command to workspace
243
- function addCommandToWorkspace(command) {
244
- const commandElement = document.createElement('div');
245
- commandElement.className = 'command-block bg-white mb-2';
246
- commandElement.dataset.command = command;
247
-
248
- let content = '';
249
- switch(command) {
250
- case 'moveUp':
251
- content = '<i class="fas fa-arrow-up text-blue-500 mr-2"></i><span>Move Up</span>';
252
- break;
253
- case 'moveDown':
254
- content = '<i class="fas fa-arrow-down text-blue-500 mr-2"></i><span>Move Down</span>';
255
- break;
256
- case 'moveLeft':
257
- content = '<i class="fas fa-arrow-left text-blue-500 mr-2"></i><span>Move Left</span>';
258
- break;
259
- case 'moveRight':
260
- content = '<i class="fas fa-arrow-right text-blue-500 mr-2"></i><span>Move Right</span>';
261
- break;
262
- case 'repeat2':
263
- content = '<i class="fas fa-redo text-purple-500 mr-2"></i><span>Repeat 2 Times</span>';
264
- break;
265
- case 'repeat3':
266
- content = '<i class="fas fa-redo text-purple-500 mr-2"></i><span>Repeat 3 Times</span>';
267
- break;
268
- }
269
 
270
- commandElement.innerHTML = content;
271
- workspace.appendChild(commandElement);
272
 
273
- // Store the command
274
- gameState.commands.push(command);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  }
276
 
277
- // Run the code
278
- runBtn.addEventListener('click', async function() {
279
- if (gameState.isRunning) return;
280
 
281
- if (gameState.commands.length === 0) {
282
- showMessage("Add some commands first to help the cat move!");
 
 
 
283
  return;
284
  }
285
 
286
- gameState.isRunning = true;
287
- runBtn.disabled = true;
 
 
 
 
 
 
 
288
 
289
- // Reset character position
290
- gameState.characterPosition = { row: 0, col: 0 };
291
- updateCharacterPosition();
 
 
 
 
292
 
293
- // Execute commands
294
- let i = 0;
295
- while (i < gameState.commands.length) {
296
- const command = gameState.commands[i];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
 
298
- if (command.startsWith('repeat')) {
299
- const repeatCount = parseInt(command.replace('repeat', ''));
300
- const startIndex = i + 1;
301
- const endIndex = findMatchingEnd(i);
302
 
303
- if (endIndex === -1) {
304
- showMessage("Oops! There's a problem with the repeat block.");
305
- break;
306
- }
307
 
308
- // Execute the repeated commands
309
- for (let r = 0; r < repeatCount; r++) {
310
- for (let j = startIndex; j < endIndex; j++) {
311
- await executeCommand(gameState.commands[j]);
312
- }
 
 
 
313
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
- i = endIndex;
316
- } else {
317
- await executeCommand(command);
318
- i++;
 
319
  }
320
 
321
- // Check if we reached the treasure
322
- if (gameState.characterPosition.row === 4 && gameState.characterPosition.col === 4) {
323
- showSuccess();
324
- break;
325
  }
 
 
 
 
 
 
 
 
 
326
  }
327
 
328
- gameState.isRunning = false;
329
- runBtn.disabled = false;
330
- });
 
 
 
 
331
 
332
- // Find the end of a repeat block
333
- function findMatchingEnd(startIndex) {
334
- let depth = 1;
335
- for (let i = startIndex + 1; i < gameState.commands.length; i++) {
336
- if (gameState.commands[i].startsWith('repeat')) {
337
- depth++;
338
- } else if (gameState.commands[i] === 'end') {
339
- depth--;
340
- if (depth === 0) {
341
- return i;
342
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  }
345
- return -1;
 
 
 
346
  }
347
 
348
- // Execute a single command
349
- async function executeCommand(command) {
350
- return new Promise(resolve => {
351
- setTimeout(() => {
352
- let newRow = gameState.characterPosition.row;
353
- let newCol = gameState.characterPosition.col;
354
-
355
- switch(command) {
356
- case 'moveUp':
357
- newRow = Math.max(0, gameState.characterPosition.row - 1);
358
- break;
359
- case 'moveDown':
360
- newRow = Math.min(4, gameState.characterPosition.row + 1);
361
- break;
362
- case 'moveLeft':
363
- newCol = Math.max(0, gameState.characterPosition.col - 1);
364
- break;
365
- case 'moveRight':
366
- newCol = Math.min(4, gameState.characterPosition.col + 1);
367
- break;
368
- }
369
-
370
- // Check for obstacles
371
- const cellId = `cell-${newRow}-${newCol}`;
372
- const cell = document.getElementById(cellId);
373
-
374
- if (cell.classList.contains('obstacle')) {
375
- showMessage("Oh no! The cat hit a cactus. Try a different path.");
376
- } else {
377
- gameState.characterPosition.row = newRow;
378
- gameState.characterPosition.col = newCol;
379
- updateCharacterPosition();
380
- }
381
-
382
- resolve();
383
- }, 500);
384
- });
385
  }
386
 
387
- // Update character position on the grid
388
- function updateCharacterPosition() {
389
- const cellId = `cell-${gameState.characterPosition.row}-${gameState.characterPosition.col}`;
390
- const cell = document.getElementById(cellId);
391
-
392
- // Remove character from all cells
393
- cells.forEach(c => {
394
- if (c.querySelector('.character')) {
395
- c.removeChild(c.querySelector('.character'));
396
- }
397
  });
 
 
 
 
 
398
 
399
- // Add character to new cell
400
- cell.appendChild(character);
 
 
 
 
 
 
 
 
 
 
401
  }
402
 
403
- // Show success message
404
- function showSuccess() {
405
- character.classList.add('success-animation');
406
- successModal.classList.remove('hidden');
 
 
 
 
 
407
  }
408
 
409
  // Show message
@@ -411,40 +626,49 @@
411
  gameMessage.querySelector('span').textContent = text;
412
  gameMessage.classList.remove('hidden');
413
 
414
- // Hide after 5 seconds
415
  setTimeout(() => {
416
  gameMessage.classList.add('hidden');
417
- }, 5000);
418
  }
419
 
420
- // Reset the game
421
- function resetGame() {
422
- gameState.commands = [];
423
- gameState.characterPosition = { row: 0, col: 0 };
424
- gameState.isRunning = false;
425
 
426
- // Clear workspace
427
- workspace.innerHTML = '';
428
-
429
- // Reset character position
430
- updateCharacterPosition();
431
-
432
- // Enable run button
433
- runBtn.disabled = false;
434
-
435
- // Hide success modal
436
- successModal.classList.add('hidden');
437
- character.classList.remove('success-animation');
438
-
439
- showMessage("Drag coding blocks to the workspace to help the cat reach the fish!");
440
- }
441
 
442
- // Event listeners
443
- resetBtn.addEventListener('click', resetGame);
444
- playAgainBtn.addEventListener('click', resetGame);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
 
446
  // Initialize the game
447
- resetGame();
448
  });
449
  </script>
450
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Chicken117/kids-coding" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Battleship Game</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
+ .cell {
11
+ width: 40px;
12
+ height: 40px;
13
+ border: 1px solid #94a3b8;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ cursor: pointer;
18
+ transition: all 0.2s ease;
19
  }
20
+ .cell:hover:not(.hit):not(.miss) {
21
+ background-color: #e2e8f0;
22
  }
23
+ .ship {
24
+ background-color: #64748b;
 
 
 
 
25
  }
26
+ .hit {
27
+ background-color: #ef4444;
28
+ color: white;
29
  }
30
+ .miss {
31
+ background-color: #93c5fd;
32
  }
33
+ .ship-hit {
34
+ background-color: #ef4444;
35
+ color: white;
36
  }
37
+ .placement {
38
+ background-color: #cbd5e1;
39
+ }
40
+ .placement-valid {
41
+ background-color: #86efac;
 
 
42
  }
43
+ .placement-invalid {
44
  background-color: #fca5a5;
45
  }
46
+ .ship-preview {
47
+ background-color: #64748b;
48
+ opacity: 0.7;
49
+ }
50
+ .rotate-btn {
51
+ transition: all 0.3s ease;
52
+ }
53
+ .rotate-btn:hover {
54
+ transform: rotate(90deg);
55
  }
56
+ @keyframes explosion {
57
+ 0% { transform: scale(1); opacity: 1; }
58
+ 50% { transform: scale(1.5); opacity: 0.7; }
59
+ 100% { transform: scale(1); opacity: 1; }
60
+ }
61
+ .explosion {
62
+ animation: explosion 0.5s ease;
63
  }
64
  </style>
65
  </head>
66
+ <body class="bg-slate-100 min-h-screen">
67
  <div class="container mx-auto px-4 py-8">
68
  <div class="text-center mb-8">
69
+ <h1 class="text-4xl font-bold text-blue-800 mb-2">🚢 Battleship Game 🚢</h1>
70
  <p class="text-blue-600 max-w-2xl mx-auto">
71
+ Sink all your opponent's ships to win the game!
72
  </p>
73
  </div>
74
 
75
+ <!-- Game Phase Selector -->
76
+ <div id="phase-selector" class="bg-white rounded-xl shadow-md p-6 mb-8 text-center">
77
+ <h2 class="text-xl font-bold text-blue-800 mb-4">Select Game Mode</h2>
78
+ <div class="flex justify-center gap-4">
79
+ <button id="single-player-btn" class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600">
80
+ <i class="fas fa-user mr-2"></i>Single Player
81
+ </button>
82
+ <button id="two-player-btn" class="px-6 py-3 bg-green-500 text-white rounded-lg hover:bg-green-600">
83
+ <i class="fas fa-users mr-2"></i>Two Players
84
+ </button>
85
+ </div>
86
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
+ <!-- Ship Placement Phase -->
89
+ <div id="placement-phase" class="hidden bg-white rounded-xl shadow-md p-6 mb-8">
90
+ <h2 class="text-xl font-bold text-blue-800 mb-4 text-center">Place Your Ships</h2>
91
+
92
+ <div class="flex flex-col lg:flex-row gap-8">
93
+ <!-- Player Board -->
94
+ <div class="lg:w-1/2">
95
+ <div class="flex justify-between items-center mb-4">
96
+ <h3 class="text-lg font-medium text-blue-700">Your Board</h3>
97
+ <button id="rotate-btn" class="rotate-btn px-4 py-2 bg-yellow-500 text-white rounded-lg hover:bg-yellow-600">
98
+ <i class="fas fa-sync-alt mr-2"></i>Rotate Ship
99
+ </button>
100
+ </div>
101
+ <div id="player-board" class="grid grid-cols-10 gap-0 border-2 border-slate-200 rounded-lg overflow-hidden mb-4">
102
+ <!-- 10x10 grid will be generated by JavaScript -->
103
+ </div>
104
  </div>
105
+
106
+ <!-- Ships to Place -->
107
+ <div class="lg:w-1/2">
108
+ <h3 class="text-lg font-medium text-blue-700 mb-4">Ships to Place</h3>
109
+ <div id="ships-to-place" class="space-y-4">
110
+ <!-- Ships will be generated by JavaScript -->
111
+ </div>
112
+
113
+ <div class="mt-6 text-center">
114
+ <button id="start-game-btn" class="px-6 py-3 bg-green-500 text-white rounded-lg hover:bg-green-600 hidden">
115
+ <i class="fas fa-play mr-2"></i>Start Game
116
+ </button>
117
+ </div>
118
  </div>
119
  </div>
120
+ </div>
121
 
122
+ <!-- Game Phase -->
123
+ <div id="game-phase" class="hidden bg-white rounded-xl shadow-md p-6 mb-8">
124
+ <h2 id="game-status" class="text-xl font-bold text-blue-800 mb-4 text-center">Your Turn</h2>
125
+
126
+ <div class="flex flex-col lg:flex-row gap-8">
127
+ <!-- Player Board -->
128
+ <div class="lg:w-1/2">
129
+ <h3 class="text-lg font-medium text-blue-700 mb-4">Your Ships</h3>
130
+ <div id="player-game-board" class="grid grid-cols-10 gap-0 border-2 border-slate-200 rounded-lg overflow-hidden mb-4">
131
+ <!-- 10x10 grid will be generated by JavaScript -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  </div>
133
  </div>
134
 
135
+ <!-- Computer Board -->
136
+ <div class="lg:w-1/2">
137
+ <h3 class="text-lg font-medium text-blue-700 mb-4">Attack Enemy</h3>
138
+ <div id="computer-board" class="grid grid-cols-10 gap-0 border-2 border-slate-200 rounded-lg overflow-hidden mb-4">
139
+ <!-- 10x10 grid will be generated by JavaScript -->
 
 
 
 
 
 
 
 
 
 
140
  </div>
141
  </div>
142
+ </div>
143
+
144
+ <div id="game-message" class="p-4 bg-blue-100 text-blue-800 rounded-lg mt-4">
145
+ <i class="fas fa-info-circle mr-2"></i>
146
+ <span>Click on the enemy grid to attack!</span>
147
  </div>
148
  </div>
149
 
150
+ <!-- Game Over Modal -->
151
+ <div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden">
152
  <div class="bg-white rounded-xl p-8 max-w-md w-full text-center">
153
+ <div id="game-result-icon" class="text-6xl mb-4">
154
+ <i class="fas fa-trophy text-yellow-500"></i>
155
  </div>
156
+ <h2 id="game-result-text" class="text-3xl font-bold text-blue-800 mb-2">You Won!</h2>
157
+ <p id="game-result-details" class="text-blue-600 mb-6">Congratulations! You sank all enemy ships.</p>
158
  <button id="play-again-btn" class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600">
159
+ <i class="fas fa-redo mr-2"></i>Play Again
160
  </button>
161
  </div>
162
  </div>
 
166
  document.addEventListener('DOMContentLoaded', function() {
167
  // Game state
168
  const gameState = {
169
+ phase: 'selection', // 'selection', 'placement', 'game', 'gameOver'
170
+ mode: null, // 'single', 'twoPlayer'
171
+ currentPlayer: 'player', // 'player' or 'computer'
172
+ playerShips: [],
173
+ computerShips: [],
174
+ playerHits: [],
175
+ playerMisses: [],
176
+ computerHits: [],
177
+ computerMisses: [],
178
+ currentShip: null,
179
+ shipOrientation: 'horizontal', // 'horizontal' or 'vertical'
180
+ placedShips: 0,
181
+ totalShips: 5,
182
+ ships: [
183
+ { name: 'Carrier', size: 5 },
184
+ { name: 'Battleship', size: 4 },
185
+ { name: 'Destroyer', size: 3 },
186
+ { name: 'Submarine', size: 3 },
187
+ { name: 'Patrol Boat', size: 2 }
188
+ ]
189
  };
190
 
191
  // DOM elements
192
+ const phaseSelector = document.getElementById('phase-selector');
193
+ const placementPhase = document.getElementById('placement-phase');
194
+ const gamePhase = document.getElementById('game-phase');
195
+ const gameOverModal = document.getElementById('game-over-modal');
196
+ const playerBoard = document.getElementById('player-board');
197
+ const playerGameBoard = document.getElementById('player-game-board');
198
+ const computerBoard = document.getElementById('computer-board');
199
+ const shipsToPlace = document.getElementById('ships-to-place');
200
+ const rotateBtn = document.getElementById('rotate-btn');
201
+ const startGameBtn = document.getElementById('start-game-btn');
202
+ const gameStatus = document.getElementById('game-status');
203
  const gameMessage = document.getElementById('game-message');
204
+ const gameResultIcon = document.getElementById('game-result-icon');
205
+ const gameResultText = document.getElementById('game-result-text');
206
+ const gameResultDetails = document.getElementById('game-result-details');
207
  const playAgainBtn = document.getElementById('play-again-btn');
208
+ const singlePlayerBtn = document.getElementById('single-player-btn');
209
+ const twoPlayerBtn = document.getElementById('two-player-btn');
210
 
211
+ // Initialize the game
212
+ function initGame() {
213
+ // Clear boards
214
+ playerBoard.innerHTML = '';
215
+ playerGameBoard.innerHTML = '';
216
+ computerBoard.innerHTML = '';
217
+ shipsToPlace.innerHTML = '';
218
+
219
+ // Reset game state
220
+ gameState.playerShips = [];
221
+ gameState.computerShips = [];
222
+ gameState.playerHits = [];
223
+ gameState.playerMisses = [];
224
+ gameState.computerHits = [];
225
+ gameState.computerMisses = [];
226
+ gameState.currentPlayer = 'player';
227
+ gameState.placedShips = 0;
228
+ gameState.currentShip = null;
229
+ gameState.shipOrientation = 'horizontal';
230
+
231
+ // Create boards
232
+ createBoard(playerBoard, 'player');
233
+ createBoard(playerGameBoard, 'player-game');
234
+ createBoard(computerBoard, 'computer');
235
+
236
+ // Create ships to place
237
+ createShipsToPlace();
238
+
239
+ // Place computer ships randomly
240
+ placeComputerShips();
241
+
242
+ // Update UI
243
+ updateGameStatus();
244
+ }
245
 
246
+ // Create a game board
247
+ function createBoard(boardElement, type) {
248
+ // Create 10x10 grid
249
+ for (let row = 0; row < 10; row++) {
250
+ for (let col = 0; col < 10; col++) {
251
+ const cell = document.createElement('div');
252
+ cell.className = 'cell';
253
+ cell.dataset.row = row;
254
+ cell.dataset.col = col;
255
+
256
+ if (type === 'player') {
257
+ // For placement phase
258
+ cell.addEventListener('mouseover', () => handlePlacementHover(row, col));
259
+ cell.addEventListener('mouseout', () => handlePlacementHoverOut(row, col));
260
+ cell.addEventListener('click', () => placeShip(row, col));
261
+ } else if (type === 'computer') {
262
+ // For game phase (attack)
263
+ cell.addEventListener('click', () => playerAttack(row, col));
264
+ }
265
+
266
+ boardElement.appendChild(cell);
267
+ }
268
+ }
269
+ }
270
 
271
+ // Create ships to place UI
272
+ function createShipsToPlace() {
273
+ gameState.ships.forEach((ship, index) => {
274
+ const shipElement = document.createElement('div');
275
+ shipElement.className = 'p-4 border border-slate-300 rounded-lg cursor-pointer hover:bg-slate-100';
276
+ shipElement.innerHTML = `
277
+ <div class="flex items-center justify-between">
278
+ <div>
279
+ <h4 class="font-medium">${ship.name}</h4>
280
+ <p class="text-sm text-slate-600">Size: ${ship.size} cells</p>
281
+ </div>
282
+ <div class="flex ${gameState.shipOrientation === 'horizontal' ? 'flex-row' : 'flex-col'}">
283
+ ${Array(ship.size).fill('<div class="w-6 h-6 bg-slate-600 m-1"></div>').join('')}
284
+ </div>
285
+ </div>
286
+ `;
287
+ shipElement.dataset.shipIndex = index;
288
+ shipElement.addEventListener('click', () => selectShip(index));
289
+
290
+ shipsToPlace.appendChild(shipElement);
291
+ });
292
+
293
+ // Select first ship by default
294
+ if (gameState.ships.length > 0) {
295
+ selectShip(0);
296
+ }
297
+ }
298
+
299
+ // Select a ship for placement
300
+ function selectShip(shipIndex) {
301
+ gameState.currentShip = shipIndex;
302
+
303
+ // Update UI
304
+ const shipElements = shipsToPlace.querySelectorAll('div');
305
+ shipElements.forEach((el, idx) => {
306
+ if (idx === shipIndex) {
307
+ el.classList.add('bg-blue-100', 'border-blue-400');
308
+ } else {
309
+ el.classList.remove('bg-blue-100', 'border-blue-400');
310
+ }
311
+ });
312
+ }
313
 
314
+ // Rotate ship orientation
315
+ rotateBtn.addEventListener('click', function() {
316
+ gameState.shipOrientation = gameState.shipOrientation === 'horizontal' ? 'vertical' : 'horizontal';
317
 
318
+ // Update ships to place display
319
+ const shipDisplays = shipsToPlace.querySelectorAll('div > div > div:last-child');
320
+ shipDisplays.forEach(display => {
321
+ display.className = `flex ${gameState.shipOrientation === 'horizontal' ? 'flex-row' : 'flex-col'}`;
322
+ });
323
  });
324
 
325
+ // Handle ship placement hover
326
+ function handlePlacementHover(row, col) {
327
+ if (!gameState.currentShip) return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
 
329
+ const ship = gameState.ships[gameState.currentShip];
330
+ const cells = getShipCells(row, col, ship.size, gameState.shipOrientation);
331
 
332
+ if (cells) {
333
+ cells.forEach(cell => {
334
+ const cellElement = playerBoard.querySelector(`[data-row="${cell.row}"][data-col="${cell.col}"]`);
335
+ if (cellElement && !cellElement.classList.contains('ship')) {
336
+ cellElement.classList.add('ship-preview');
337
+ }
338
+ });
339
+ }
340
+ }
341
+
342
+ // Handle ship placement hover out
343
+ function handlePlacementHoverOut(row, col) {
344
+ const previewCells = playerBoard.querySelectorAll('.ship-preview');
345
+ previewCells.forEach(cell => {
346
+ cell.classList.remove('ship-preview');
347
+ });
348
  }
349
 
350
+ // Place ship on the board
351
+ function placeShip(row, col) {
352
+ if (!gameState.currentShip) return;
353
 
354
+ const ship = gameState.ships[gameState.currentShip];
355
+ const cells = getShipCells(row, col, ship.size, gameState.shipOrientation);
356
+
357
+ if (!cells) {
358
+ showMessage("Ship doesn't fit there!");
359
  return;
360
  }
361
 
362
+ // Check if placement is valid (no overlaps)
363
+ const isValid = cells.every(cell => {
364
+ return !isShipAt(cell.row, cell.col, gameState.playerShips);
365
+ });
366
+
367
+ if (!isValid) {
368
+ showMessage("Ships can't overlap!");
369
+ return;
370
+ }
371
 
372
+ // Place the ship
373
+ gameState.playerShips.push({
374
+ name: ship.name,
375
+ size: ship.size,
376
+ cells: cells,
377
+ hits: 0
378
+ });
379
 
380
+ // Update UI
381
+ cells.forEach(cell => {
382
+ const cellElement = playerBoard.querySelector(`[data-row="${cell.row}"][data-col="${cell.col}"]`);
383
+ cellElement.classList.remove('ship-preview');
384
+ cellElement.classList.add('ship');
385
+ });
386
+
387
+ // Mark ship as placed
388
+ const shipElement = shipsToPlace.querySelector(`[data-ship-index="${gameState.currentShip}"]`);
389
+ shipElement.classList.add('hidden');
390
+
391
+ // Select next ship
392
+ gameState.placedShips++;
393
+ if (gameState.placedShips < gameState.totalShips) {
394
+ selectShip(gameState.currentShip + 1);
395
+ } else {
396
+ gameState.currentShip = null;
397
+ startGameBtn.classList.remove('hidden');
398
+ }
399
+ }
400
+
401
+ // Get all cells a ship would occupy
402
+ function getShipCells(row, col, size, orientation) {
403
+ const cells = [];
404
+
405
+ if (orientation === 'horizontal') {
406
+ if (col + size > 10) return null;
407
+
408
+ for (let i = 0; i < size; i++) {
409
+ cells.push({ row: row, col: col + i });
410
+ }
411
+ } else {
412
+ if (row + size > 10) return null;
413
+
414
+ for (let i = 0; i < size; i++) {
415
+ cells.push({ row: row + i, col: col });
416
+ }
417
+ }
418
+
419
+ return cells;
420
+ }
421
+
422
+ // Check if there's a ship at given coordinates
423
+ function isShipAt(row, col, ships) {
424
+ return ships.some(ship => {
425
+ return ship.cells.some(cell => {
426
+ return cell.row === row && cell.col === col;
427
+ });
428
+ });
429
+ }
430
+
431
+ // Place computer ships randomly
432
+ function placeComputerShips() {
433
+ gameState.ships.forEach(ship => {
434
+ let placed = false;
435
 
436
+ while (!placed) {
437
+ const orientation = Math.random() > 0.5 ? 'horizontal' : 'vertical';
438
+ const row = Math.floor(Math.random() * 10);
439
+ const col = Math.floor(Math.random() * 10);
440
 
441
+ const cells = getShipCells(row, col, ship.size, orientation);
 
 
 
442
 
443
+ if (cells && !cells.some(cell => isShipAt(cell.row, cell.col, gameState.computerShips))) {
444
+ gameState.computerShips.push({
445
+ name: ship.name,
446
+ size: ship.size,
447
+ cells: cells,
448
+ hits: 0
449
+ });
450
+ placed = true;
451
  }
452
+ }
453
+ });
454
+ }
455
+
456
+ // Start the game
457
+ startGameBtn.addEventListener('click', function() {
458
+ phaseSelector.classList.add('hidden');
459
+ placementPhase.classList.add('hidden');
460
+ gamePhase.classList.remove('hidden');
461
+
462
+ // Update player game board with placed ships
463
+ gameState.playerShips.forEach(ship => {
464
+ ship.cells.forEach(cell => {
465
+ const cellElement = playerGameBoard.querySelector(`[data-row="${cell.row}"][data-col="${cell.col}"]`);
466
+ cellElement.classList.add('ship');
467
+ });
468
+ });
469
+ });
470
+
471
+ // Player attacks computer's board
472
+ function playerAttack(row, col) {
473
+ if (gameState.currentPlayer !== 'player') return;
474
+
475
+ // Check if already attacked this cell
476
+ if (isAlreadyAttacked(row, col, gameState.playerHits, gameState.playerMisses)) {
477
+ showMessage("You've already attacked this location!");
478
+ return;
479
+ }
480
+
481
+ // Check if hit
482
+ const hitShip = getShipAt(row, col, gameState.computerShips);
483
+
484
+ if (hitShip) {
485
+ // Hit
486
+ gameState.playerHits.push({ row, col });
487
+ hitShip.hits++;
488
+
489
+ const cellElement = computerBoard.querySelector(`[data-row="${row}"][data-col="${col}"]`);
490
+ cellElement.classList.add('hit');
491
+ cellElement.innerHTML = '<i class="fas fa-burst explosion"></i>';
492
+
493
+ showMessage(`Hit! ${hitShip.name}`);
494
+
495
+ // Check if ship is sunk
496
+ if (hitShip.hits === hitShip.size) {
497
+ showMessage(`You sank the enemy's ${hitShip.name}!`);
498
 
499
+ // Mark all ship cells as hit
500
+ hitShip.cells.forEach(cell => {
501
+ const cellEl = computerBoard.querySelector(`[data-row="${cell.row}"][data-col="${cell.col}"]`);
502
+ cellEl.innerHTML = '<i class="fas fa-skull-crossbones"></i>';
503
+ });
504
  }
505
 
506
+ // Check if all ships are sunk
507
+ if (gameState.computerShips.every(ship => ship.hits === ship.size)) {
508
+ endGame(true);
509
+ return;
510
  }
511
+ } else {
512
+ // Miss
513
+ gameState.playerMisses.push({ row, col });
514
+
515
+ const cellElement = computerBoard.querySelector(`[data-row="${row}"][data-col="${col}"]`);
516
+ cellElement.classList.add('miss');
517
+ cellElement.innerHTML = '<i class="fas fa-water"></i>';
518
+
519
+ showMessage("Miss!");
520
  }
521
 
522
+ // Switch to computer's turn
523
+ gameState.currentPlayer = 'computer';
524
+ updateGameStatus();
525
+
526
+ // Computer's turn (with delay for better UX)
527
+ setTimeout(computerTurn, 1000);
528
+ }
529
 
530
+ // Computer's turn
531
+ function computerTurn() {
532
+ if (gameState.currentPlayer !== 'computer') return;
533
+
534
+ let row, col;
535
+
536
+ // Simple AI: random attack
537
+ do {
538
+ row = Math.floor(Math.random() * 10);
539
+ col = Math.floor(Math.random() * 10);
540
+ } while (isAlreadyAttacked(row, col, gameState.computerHits, gameState.computerMisses));
541
+
542
+ // Check if hit
543
+ const hitShip = getShipAt(row, col, gameState.playerShips);
544
+
545
+ if (hitShip) {
546
+ // Hit
547
+ gameState.computerHits.push({ row, col });
548
+ hitShip.hits++;
549
+
550
+ const cellElement = playerGameBoard.querySelector(`[data-row="${row}"][data-col="${col}"]`);
551
+ cellElement.classList.add('ship-hit');
552
+ cellElement.innerHTML = '<i class="fas fa-burst explosion"></i>';
553
+
554
+ showMessage(`Enemy hit your ${hitShip.name}!`);
555
+
556
+ // Check if ship is sunk
557
+ if (hitShip.hits === hitShip.size) {
558
+ showMessage(`Enemy sank your ${hitShip.name}!`);
559
  }
560
+
561
+ // Check if all ships are sunk
562
+ if (gameState.playerShips.every(ship => ship.hits === ship.size)) {
563
+ endGame(false);
564
+ return;
565
+ }
566
+ } else {
567
+ // Miss
568
+ gameState.computerMisses.push({ row, col });
569
+
570
+ const cellElement = playerGameBoard.querySelector(`[data-row="${row}"][data-col="${col}"]`);
571
+ cellElement.classList.add('miss');
572
+ cellElement.innerHTML = '<i class="fas fa-water"></i>';
573
+
574
+ showMessage("Enemy missed!");
575
  }
576
+
577
+ // Switch back to player's turn
578
+ gameState.currentPlayer = 'player';
579
+ updateGameStatus();
580
  }
581
 
582
+ // Check if cell has already been attacked
583
+ function isAlreadyAttacked(row, col, hits, misses) {
584
+ return hits.some(coord => coord.row === row && coord.col === col) ||
585
+ misses.some(coord => coord.row === row && coord.col === col);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  }
587
 
588
+ // Get ship at given coordinates
589
+ function getShipAt(row, col, ships) {
590
+ return ships.find(ship => {
591
+ return ship.cells.some(cell => cell.row === row && cell.col === col);
 
 
 
 
 
 
592
  });
593
+ }
594
+
595
+ // End the game
596
+ function endGame(playerWon) {
597
+ gameState.phase = 'gameOver';
598
 
599
+ // Show game over modal
600
+ if (playerWon) {
601
+ gameResultIcon.innerHTML = '<i class="fas fa-trophy text-yellow-500"></i>';
602
+ gameResultText.textContent = 'You Won!';
603
+ gameResultDetails.textContent = 'Congratulations! You sank all enemy ships.';
604
+ } else {
605
+ gameResultIcon.innerHTML = '<i class="fas fa-sad-tear text-blue-500"></i>';
606
+ gameResultText.textContent = 'You Lost!';
607
+ gameResultDetails.textContent = 'All your ships have been sunk. Better luck next time!';
608
+ }
609
+
610
+ gameOverModal.classList.remove('hidden');
611
  }
612
 
613
+ // Update game status display
614
+ function updateGameStatus() {
615
+ if (gameState.currentPlayer === 'player') {
616
+ gameStatus.textContent = 'Your Turn';
617
+ gameStatus.className = 'text-xl font-bold text-green-600 mb-4 text-center';
618
+ } else {
619
+ gameStatus.textContent = 'Enemy\'s Turn';
620
+ gameStatus.className = 'text-xl font-bold text-red-600 mb-4 text-center';
621
+ }
622
  }
623
 
624
  // Show message
 
626
  gameMessage.querySelector('span').textContent = text;
627
  gameMessage.classList.remove('hidden');
628
 
629
+ // Hide after 3 seconds
630
  setTimeout(() => {
631
  gameMessage.classList.add('hidden');
632
+ }, 3000);
633
  }
634
 
635
+ // Play again
636
+ playAgainBtn.addEventListener('click', function() {
637
+ gameOverModal.classList.add('hidden');
638
+ initGame();
 
639
 
640
+ if (gameState.mode === 'single') {
641
+ phaseSelector.classList.add('hidden');
642
+ placementPhase.classList.remove('hidden');
643
+ gamePhase.classList.add('hidden');
644
+ } else {
645
+ // For two-player mode, you'd reset to the selection phase
646
+ phaseSelector.classList.remove('hidden');
647
+ placementPhase.classList.add('hidden');
648
+ gamePhase.classList.add('hidden');
649
+ }
650
+ });
 
 
 
 
651
 
652
+ // Game mode selection
653
+ singlePlayerBtn.addEventListener('click', function() {
654
+ gameState.mode = 'single';
655
+ phaseSelector.classList.add('hidden');
656
+ placementPhase.classList.remove('hidden');
657
+ initGame();
658
+ });
659
+
660
+ twoPlayerBtn.addEventListener('click', function() {
661
+ // In a complete implementation, this would set up two-player mode
662
+ showMessage("Two-player mode coming soon! Try single player for now.");
663
+ // For this demo, we'll just use single player
664
+ gameState.mode = 'single';
665
+ phaseSelector.classList.add('hidden');
666
+ placementPhase.classList.remove('hidden');
667
+ initGame();
668
+ });
669
 
670
  // Initialize the game
671
+ initGame();
672
  });
673
  </script>
674
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Chicken117/kids-coding" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
prompts.txt CHANGED
@@ -0,0 +1 @@
 
 
1
+ Create a game of battleships