create-template-html-css 1.9.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/COMPONENTS-GALLERY.html +735 -747
- package/README.md +179 -2
- package/bin/cli.js +15 -3
- package/package.json +1 -1
- package/templates/blackjack/index.html +97 -0
- package/templates/blackjack/script.js +381 -0
- package/templates/blackjack/style.css +452 -0
- package/templates/breakout/index.html +56 -0
- package/templates/breakout/script.js +387 -0
- package/templates/breakout/style.css +239 -0
- package/templates/connect-four/index.html +78 -0
- package/templates/connect-four/script.js +413 -0
- package/templates/connect-four/style.css +426 -0
- package/templates/dice-game/index.html +99 -0
- package/templates/dice-game/script.js +291 -0
- package/templates/dice-game/style.css +403 -0
- package/templates/flappy-bird/index.html +47 -0
- package/templates/flappy-bird/script.js +394 -0
- package/templates/flappy-bird/style.css +243 -0
- package/templates/game-2048/index.html +59 -0
- package/templates/game-2048/script.js +269 -0
- package/templates/game-2048/style.css +281 -0
- package/templates/pong/index.html +90 -0
- package/templates/pong/script.js +364 -0
- package/templates/pong/style.css +371 -0
- package/templates/rock-paper-scissors/index.html +84 -0
- package/templates/rock-paper-scissors/script.js +199 -0
- package/templates/rock-paper-scissors/style.css +295 -0
- package/templates/simon-says/index.html +64 -0
- package/templates/simon-says/script.js +206 -0
- package/templates/simon-says/style.css +250 -0
- package/templates/slot-machine/index.html +112 -0
- package/templates/slot-machine/script.js +238 -0
- package/templates/slot-machine/style.css +464 -0
- package/templates/tetris/index.html +84 -0
- package/templates/tetris/script.js +447 -0
- package/templates/tetris/style.css +286 -0
- package/templates/whack-a-mole/index.html +85 -0
- package/templates/whack-a-mole/script.js +172 -0
- package/{demo-games/snake-game → templates/whack-a-mole}/style.css +114 -97
- package/PUBLISH-GUIDE.md +0 -112
- package/create-template-html-css-1.8.0.tgz +0 -0
- package/demo-games/guess-number/index.html +0 -71
- package/demo-games/guess-number/script.js +0 -216
- package/demo-games/guess-number/style.css +0 -337
- package/demo-games/memory-game/index.html +0 -50
- package/demo-games/memory-game/script.js +0 -216
- package/demo-games/memory-game/style.css +0 -288
- package/demo-games/snake-game/index.html +0 -61
- package/demo-games/snake-game/script.js +0 -360
- package/demo-games/tic-tac-toe/index.html +0 -57
- package/demo-games/tic-tac-toe/script.js +0 -156
- package/demo-games/tic-tac-toe/style.css +0 -244
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
body {
|
|
8
8
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
9
|
-
background: linear-gradient(135deg, #
|
|
9
|
+
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
|
10
10
|
min-height: 100vh;
|
|
11
11
|
display: flex;
|
|
12
12
|
justify-content: center;
|
|
@@ -16,7 +16,7 @@ body {
|
|
|
16
16
|
|
|
17
17
|
.container {
|
|
18
18
|
width: 100%;
|
|
19
|
-
max-width:
|
|
19
|
+
max-width: 600px;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.game-card {
|
|
@@ -33,113 +33,146 @@ body {
|
|
|
33
33
|
font-size: 2.5rem;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
.game-
|
|
36
|
+
.game-stats {
|
|
37
37
|
display: flex;
|
|
38
|
-
justify-content: space-
|
|
38
|
+
justify-content: space-around;
|
|
39
39
|
padding: 15px;
|
|
40
40
|
background: #f3f4f6;
|
|
41
41
|
border-radius: 12px;
|
|
42
42
|
margin-bottom: 20px;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
flex-direction: column;
|
|
48
|
-
align-items: center;
|
|
45
|
+
.stat {
|
|
46
|
+
text-align: center;
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
.label {
|
|
49
|
+
.stat-label {
|
|
52
50
|
font-size: 0.9rem;
|
|
53
51
|
color: #6b7280;
|
|
54
52
|
margin-bottom: 5px;
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
.value {
|
|
58
|
-
font-size: 1.
|
|
55
|
+
.stat-value {
|
|
56
|
+
font-size: 1.5rem;
|
|
59
57
|
font-weight: bold;
|
|
60
58
|
color: #333;
|
|
61
59
|
}
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
margin:
|
|
61
|
+
.difficulty-selector {
|
|
62
|
+
display: flex;
|
|
63
|
+
justify-content: center;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 10px;
|
|
66
|
+
margin-bottom: 20px;
|
|
67
|
+
font-weight: 600;
|
|
68
|
+
color: #555;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#difficulty {
|
|
72
|
+
padding: 8px 15px;
|
|
73
|
+
border: 2px solid #e5e7eb;
|
|
69
74
|
border-radius: 8px;
|
|
70
|
-
|
|
75
|
+
font-size: 1rem;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
background: white;
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
#difficulty:disabled {
|
|
81
|
+
opacity: 0.5;
|
|
82
|
+
cursor: not-allowed;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.game-board {
|
|
86
|
+
display: grid;
|
|
87
|
+
grid-template-columns: repeat(3, 1fr);
|
|
88
|
+
gap: 15px;
|
|
89
|
+
margin: 20px 0;
|
|
90
|
+
padding: 20px;
|
|
91
|
+
background: #f9fafb;
|
|
92
|
+
border-radius: 12px;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.hole {
|
|
96
|
+
aspect-ratio: 1;
|
|
97
|
+
background: linear-gradient(to bottom, #8b4513 0%, #654321 100%);
|
|
98
|
+
border-radius: 50% 50% 0 0;
|
|
99
|
+
position: relative;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
box-shadow: inset 0 -4px 8px rgba(0, 0, 0, 0.3);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.mole {
|
|
106
|
+
position: absolute;
|
|
107
|
+
width: 100%;
|
|
108
|
+
height: 100%;
|
|
109
|
+
bottom: -100%;
|
|
78
110
|
display: flex;
|
|
79
111
|
justify-content: center;
|
|
80
112
|
align-items: center;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
transition: opacity 0.3s ease;
|
|
113
|
+
font-size: 3rem;
|
|
114
|
+
transition: bottom 0.3s ease;
|
|
115
|
+
user-select: none;
|
|
85
116
|
}
|
|
86
117
|
|
|
87
|
-
.
|
|
88
|
-
|
|
89
|
-
animation: pulse 1.5s ease-in-out infinite;
|
|
118
|
+
.mole.up {
|
|
119
|
+
bottom: 0;
|
|
90
120
|
}
|
|
91
121
|
|
|
92
|
-
.
|
|
93
|
-
|
|
94
|
-
font-size: 1.2rem;
|
|
122
|
+
.mole.whacked {
|
|
123
|
+
animation: whack 0.3s ease;
|
|
95
124
|
}
|
|
96
125
|
|
|
97
|
-
@keyframes
|
|
98
|
-
0
|
|
99
|
-
|
|
126
|
+
@keyframes whack {
|
|
127
|
+
0% {
|
|
128
|
+
transform: scale(1) rotate(0deg);
|
|
100
129
|
}
|
|
101
130
|
50% {
|
|
102
|
-
|
|
131
|
+
transform: scale(1.2) rotate(10deg);
|
|
132
|
+
}
|
|
133
|
+
100% {
|
|
134
|
+
transform: scale(0.8) rotate(-10deg);
|
|
135
|
+
bottom: -100%;
|
|
103
136
|
}
|
|
104
137
|
}
|
|
105
138
|
|
|
106
|
-
|
|
107
|
-
|
|
139
|
+
@keyframes shake {
|
|
140
|
+
0%, 100% {
|
|
141
|
+
transform: translateX(0);
|
|
142
|
+
}
|
|
143
|
+
25% {
|
|
144
|
+
transform: translateX(-5px);
|
|
145
|
+
}
|
|
146
|
+
75% {
|
|
147
|
+
transform: translateX(5px);
|
|
148
|
+
}
|
|
108
149
|
}
|
|
109
150
|
|
|
110
|
-
.
|
|
151
|
+
.message {
|
|
152
|
+
text-align: center;
|
|
153
|
+
font-size: 1.2rem;
|
|
154
|
+
font-weight: bold;
|
|
155
|
+
height: 35px;
|
|
111
156
|
display: flex;
|
|
112
|
-
|
|
157
|
+
justify-content: center;
|
|
113
158
|
align-items: center;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.arrow-row {
|
|
118
|
-
display: flex;
|
|
119
|
-
gap: 5px;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.arrow-btn {
|
|
123
|
-
width: 60px;
|
|
124
|
-
height: 60px;
|
|
125
|
-
border: 2px solid #e5e7eb;
|
|
126
|
-
border-radius: 8px;
|
|
127
|
-
background: white;
|
|
128
|
-
font-size: 1.5rem;
|
|
129
|
-
cursor: pointer;
|
|
130
|
-
transition: all 0.2s ease;
|
|
131
|
-
color: #333;
|
|
159
|
+
margin-bottom: 20px;
|
|
160
|
+
color: #10b981;
|
|
132
161
|
}
|
|
133
162
|
|
|
134
|
-
.
|
|
135
|
-
|
|
136
|
-
border-color: #9ca3af;
|
|
137
|
-
transform: scale(1.05);
|
|
163
|
+
.message.show {
|
|
164
|
+
animation: slideDown 0.4s ease;
|
|
138
165
|
}
|
|
139
166
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
167
|
+
@keyframes slideDown {
|
|
168
|
+
from {
|
|
169
|
+
transform: translateY(-20px);
|
|
170
|
+
opacity: 0;
|
|
171
|
+
}
|
|
172
|
+
to {
|
|
173
|
+
transform: translateY(0);
|
|
174
|
+
opacity: 1;
|
|
175
|
+
}
|
|
143
176
|
}
|
|
144
177
|
|
|
145
178
|
.button-group {
|
|
@@ -150,7 +183,7 @@ body {
|
|
|
150
183
|
|
|
151
184
|
.btn {
|
|
152
185
|
flex: 1;
|
|
153
|
-
padding: 12px
|
|
186
|
+
padding: 12px 24px;
|
|
154
187
|
border: none;
|
|
155
188
|
border-radius: 8px;
|
|
156
189
|
font-size: 1rem;
|
|
@@ -184,26 +217,22 @@ body {
|
|
|
184
217
|
box-shadow: 0 5px 15px rgba(245, 158, 11, 0.4);
|
|
185
218
|
}
|
|
186
219
|
|
|
187
|
-
.btn-danger {
|
|
188
|
-
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
|
189
|
-
color: white;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.btn-danger:hover:not(:disabled) {
|
|
193
|
-
transform: translateY(-2px);
|
|
194
|
-
box-shadow: 0 5px 15px rgba(239, 68, 68, 0.4);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
220
|
.instructions {
|
|
198
221
|
background: #f9fafb;
|
|
199
222
|
border-radius: 8px;
|
|
200
223
|
padding: 15px;
|
|
201
|
-
|
|
202
|
-
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.instructions h3 {
|
|
227
|
+
color: #333;
|
|
228
|
+
margin-bottom: 10px;
|
|
229
|
+
font-size: 1.1rem;
|
|
203
230
|
}
|
|
204
231
|
|
|
205
232
|
.instructions p {
|
|
206
|
-
|
|
233
|
+
color: #6b7280;
|
|
234
|
+
font-size: 0.9rem;
|
|
235
|
+
margin-bottom: 5px;
|
|
207
236
|
}
|
|
208
237
|
|
|
209
238
|
.instructions p:last-child {
|
|
@@ -219,28 +248,16 @@ body {
|
|
|
219
248
|
font-size: 2rem;
|
|
220
249
|
}
|
|
221
250
|
|
|
222
|
-
.
|
|
223
|
-
|
|
224
|
-
gap: 10px;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
.info-item {
|
|
228
|
-
flex-direction: row;
|
|
229
|
-
justify-content: space-between;
|
|
230
|
-
width: 100%;
|
|
251
|
+
.mole {
|
|
252
|
+
font-size: 2rem;
|
|
231
253
|
}
|
|
232
254
|
|
|
233
|
-
.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
font-size: 1.2rem;
|
|
255
|
+
.game-board {
|
|
256
|
+
gap: 10px;
|
|
257
|
+
padding: 15px;
|
|
237
258
|
}
|
|
238
259
|
|
|
239
260
|
.button-group {
|
|
240
261
|
flex-direction: column;
|
|
241
262
|
}
|
|
242
|
-
|
|
243
|
-
.instructions {
|
|
244
|
-
font-size: 0.85rem;
|
|
245
|
-
}
|
|
246
263
|
}
|
package/PUBLISH-GUIDE.md
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# Publishing Guide for v1.8.0
|
|
2
|
-
|
|
3
|
-
## Pre-Publish Checklist ✅
|
|
4
|
-
|
|
5
|
-
- [x] Version updated to 1.8.0 in package.json
|
|
6
|
-
- [x] Version updated to 1.8.0 in bin/cli.js
|
|
7
|
-
- [x] README.md updated with all features
|
|
8
|
-
- [x] CHANGELOG.md updated with v1.8.0 features
|
|
9
|
-
- [x] All commits pushed to GitHub
|
|
10
|
-
- [x] Security audit passed (npm audit: 0 vulnerabilities)
|
|
11
|
-
- [x] No Hebrew text in codebase
|
|
12
|
-
- [x] Path traversal protection added
|
|
13
|
-
- [x] Input validation verified
|
|
14
|
-
- [x] All 26 components available and tested
|
|
15
|
-
|
|
16
|
-
## Features in v1.8.0
|
|
17
|
-
|
|
18
|
-
### 🌙 Dark Mode Support
|
|
19
|
-
- Automatic `prefers-color-scheme: dark` detection
|
|
20
|
-
- `--dark-mode` flag to enable dark theme support
|
|
21
|
-
|
|
22
|
-
### 🎨 Color Customizer with Presets
|
|
23
|
-
- 10 preset color schemes: vibrant, pastel, ocean, sunset, forest, purple, minimal, coral, teal, neon
|
|
24
|
-
- `--color-scheme` flag for preset selection
|
|
25
|
-
- Interactive CLI color selection (preset/custom/skip)
|
|
26
|
-
- Hex color validation
|
|
27
|
-
- Automatic RGB conversion for rgba() support
|
|
28
|
-
|
|
29
|
-
### 📊 Interactive Component Gallery
|
|
30
|
-
- Browse all 26 components with descriptions
|
|
31
|
-
- Search and filter by category
|
|
32
|
-
- Live color scheme preview with hex values
|
|
33
|
-
- Copy commands (both npx and local)
|
|
34
|
-
- Dark mode support
|
|
35
|
-
- Print-friendly layout
|
|
36
|
-
- Mobile responsive design
|
|
37
|
-
|
|
38
|
-
### 🎪 Gallery Command
|
|
39
|
-
- `create-template gallery` opens COMPONENTS-GALLERY.html in browser
|
|
40
|
-
- Cross-platform support (Windows, macOS, Linux)
|
|
41
|
-
|
|
42
|
-
### 📦 Package Updates
|
|
43
|
-
- Added `open` dependency for cross-platform file opening
|
|
44
|
-
- Updated .npmignore to exclude development files
|
|
45
|
-
- All dependencies verified and security audited
|
|
46
|
-
|
|
47
|
-
## Publishing Steps
|
|
48
|
-
|
|
49
|
-
### 1. Login to npm (if not already logged in)
|
|
50
|
-
```bash
|
|
51
|
-
npm login
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### 2. Verify package contents
|
|
55
|
-
```bash
|
|
56
|
-
npm pack
|
|
57
|
-
# This creates a .tgz file showing what will be published
|
|
58
|
-
tar -tzf create-template-html-css-1.8.0.tgz | head -20
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### 3. Publish to npm
|
|
62
|
-
```bash
|
|
63
|
-
npm publish
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 4. Verify published package
|
|
67
|
-
```bash
|
|
68
|
-
npm info create-template-html-css
|
|
69
|
-
npm view create-template-html-css@1.8.0
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 5. Test installation from npm
|
|
73
|
-
```bash
|
|
74
|
-
npm install -g create-template-html-css@1.8.0
|
|
75
|
-
create-template --version
|
|
76
|
-
create-template list
|
|
77
|
-
create-template gallery
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### 6. Push commits to GitHub
|
|
81
|
-
```bash
|
|
82
|
-
git push origin main
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Post-Publish Tasks
|
|
86
|
-
|
|
87
|
-
- [ ] Add release tag: `git tag -a v1.8.0 -m "Release v1.8.0"`
|
|
88
|
-
- [ ] Push tags: `git push origin v1.8.0`
|
|
89
|
-
- [ ] Create GitHub Release with changelog
|
|
90
|
-
- [ ] Update social media/documentation sites
|
|
91
|
-
- [ ] Monitor npm page for feedback
|
|
92
|
-
|
|
93
|
-
## Package Statistics
|
|
94
|
-
|
|
95
|
-
- **Version**: 1.8.0
|
|
96
|
-
- **License**: MIT
|
|
97
|
-
- **Repository**: https://github.com/benshabbat/create-template-html-css
|
|
98
|
-
- **NPM**: https://www.npmjs.com/package/create-template-html-css
|
|
99
|
-
- **Components**: 26 total
|
|
100
|
-
- **Color Schemes**: 10 presets
|
|
101
|
-
- **Dependencies**: 3 (chalk, commander, inquirer, open)
|
|
102
|
-
- **DevDependencies**: 1 (prettier)
|
|
103
|
-
|
|
104
|
-
## Security & Quality
|
|
105
|
-
|
|
106
|
-
- ✅ No vulnerabilities (npm audit: 0)
|
|
107
|
-
- ✅ Path traversal protection implemented
|
|
108
|
-
- ✅ Input validation on all user inputs
|
|
109
|
-
- ✅ Component whitelist validation
|
|
110
|
-
- ✅ HTML structure validation
|
|
111
|
-
- ✅ Cross-platform support verified
|
|
112
|
-
- ✅ All code is English (no Hebrew text)
|
|
Binary file
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>{{name}} - Guess Number</title>
|
|
7
|
-
<link rel="stylesheet" href="style.css">
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div class="container">
|
|
11
|
-
<div class="game-card">
|
|
12
|
-
<h1>🎯 Guess the Number</h1>
|
|
13
|
-
|
|
14
|
-
<div class="game-info">
|
|
15
|
-
<div class="info-row">
|
|
16
|
-
<span class="label">Range:</span>
|
|
17
|
-
<span id="rangeDisplay" class="value">1 - 100</span>
|
|
18
|
-
</div>
|
|
19
|
-
<div class="info-row">
|
|
20
|
-
<span class="label">Attempts:</span>
|
|
21
|
-
<span id="attempts" class="value">0</span>
|
|
22
|
-
</div>
|
|
23
|
-
<div class="info-row">
|
|
24
|
-
<span class="label">Best Score:</span>
|
|
25
|
-
<span id="bestScore" class="value">-</span>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
<div class="hint-section">
|
|
30
|
-
<div class="hint-box" id="hintBox">
|
|
31
|
-
<p id="hintText">I'm thinking of a number...</p>
|
|
32
|
-
<p id="hintDetails">Make your first guess!</p>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<div class="input-section">
|
|
37
|
-
<input
|
|
38
|
-
type="number"
|
|
39
|
-
id="guessInput"
|
|
40
|
-
placeholder="Enter your guess"
|
|
41
|
-
min="1"
|
|
42
|
-
max="100"
|
|
43
|
-
/>
|
|
44
|
-
<button id="guessBtn" class="btn btn-primary">Guess</button>
|
|
45
|
-
</div>
|
|
46
|
-
|
|
47
|
-
<div class="history-section">
|
|
48
|
-
<h3>Previous Guesses</h3>
|
|
49
|
-
<div id="guessHistory" class="guess-history">
|
|
50
|
-
<p class="empty-state">No guesses yet</p>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
|
|
54
|
-
<div class="difficulty-section">
|
|
55
|
-
<h3>Difficulty</h3>
|
|
56
|
-
<div class="difficulty-buttons">
|
|
57
|
-
<button class="difficulty-btn active" data-range="100">Easy (1-100)</button>
|
|
58
|
-
<button class="difficulty-btn" data-range="500">Medium (1-500)</button>
|
|
59
|
-
<button class="difficulty-btn" data-range="1000">Hard (1-1000)</button>
|
|
60
|
-
</div>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<div class="button-group">
|
|
64
|
-
<button id="newGameBtn" class="btn btn-success">New Game</button>
|
|
65
|
-
<button id="giveUpBtn" class="btn btn-secondary">Give Up</button>
|
|
66
|
-
</div>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
<script src="script.js"></script>
|
|
70
|
-
</body>
|
|
71
|
-
</html>
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
// Guess the Number Game Logic
|
|
2
|
-
|
|
3
|
-
const guessInput = document.getElementById('guessInput');
|
|
4
|
-
const guessBtn = document.getElementById('guessBtn');
|
|
5
|
-
const newGameBtn = document.getElementById('newGameBtn');
|
|
6
|
-
const giveUpBtn = document.getElementById('giveUpBtn');
|
|
7
|
-
const attemptsDisplay = document.getElementById('attempts');
|
|
8
|
-
const bestScoreDisplay = document.getElementById('bestScore');
|
|
9
|
-
const rangeDisplay = document.getElementById('rangeDisplay');
|
|
10
|
-
const hintBox = document.getElementById('hintBox');
|
|
11
|
-
const hintText = document.getElementById('hintText');
|
|
12
|
-
const hintDetails = document.getElementById('hintDetails');
|
|
13
|
-
const guessHistory = document.getElementById('guessHistory');
|
|
14
|
-
const difficultyBtns = document.querySelectorAll('.difficulty-btn');
|
|
15
|
-
|
|
16
|
-
let targetNumber = 0;
|
|
17
|
-
let attempts = 0;
|
|
18
|
-
let maxRange = 100;
|
|
19
|
-
let guesses = [];
|
|
20
|
-
let bestScores = {
|
|
21
|
-
100: localStorage.getItem('bestScore100') || null,
|
|
22
|
-
500: localStorage.getItem('bestScore500') || null,
|
|
23
|
-
1000: localStorage.getItem('bestScore1000') || null
|
|
24
|
-
};
|
|
25
|
-
let gameActive = true;
|
|
26
|
-
|
|
27
|
-
// Initialize game
|
|
28
|
-
function initGame() {
|
|
29
|
-
targetNumber = Math.floor(Math.random() * maxRange) + 1;
|
|
30
|
-
attempts = 0;
|
|
31
|
-
guesses = [];
|
|
32
|
-
gameActive = true;
|
|
33
|
-
|
|
34
|
-
updateDisplay();
|
|
35
|
-
guessInput.value = '';
|
|
36
|
-
guessInput.disabled = false;
|
|
37
|
-
guessBtn.disabled = false;
|
|
38
|
-
guessInput.focus();
|
|
39
|
-
|
|
40
|
-
hintBox.className = 'hint-box';
|
|
41
|
-
hintText.textContent = "I'm thinking of a number...";
|
|
42
|
-
hintDetails.textContent = 'Make your first guess!';
|
|
43
|
-
|
|
44
|
-
guessHistory.innerHTML = '<p class="empty-state">No guesses yet</p>';
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Make a guess
|
|
48
|
-
function makeGuess() {
|
|
49
|
-
if (!gameActive) return;
|
|
50
|
-
|
|
51
|
-
const guess = parseInt(guessInput.value);
|
|
52
|
-
|
|
53
|
-
// Validate input
|
|
54
|
-
if (isNaN(guess) || guess < 1 || guess > maxRange) {
|
|
55
|
-
showHint('invalid', '⚠️ Invalid Input', `Please enter a number between 1 and ${maxRange}`);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Check if already guessed
|
|
60
|
-
if (guesses.includes(guess)) {
|
|
61
|
-
showHint('duplicate', '🔄 Already Guessed', 'You already tried this number!');
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
attempts++;
|
|
66
|
-
guesses.push(guess);
|
|
67
|
-
updateDisplay();
|
|
68
|
-
addToHistory(guess);
|
|
69
|
-
|
|
70
|
-
// Check if correct
|
|
71
|
-
if (guess === targetNumber) {
|
|
72
|
-
handleWin();
|
|
73
|
-
} else if (guess < targetNumber) {
|
|
74
|
-
const diff = targetNumber - guess;
|
|
75
|
-
if (diff <= 5) {
|
|
76
|
-
showHint('hot', '🔥 Very Hot!', 'You\'re super close! Go higher!');
|
|
77
|
-
} else if (diff <= 10) {
|
|
78
|
-
showHint('warm', '🌡️ Hot!', 'Getting closer! Go higher!');
|
|
79
|
-
} else if (diff <= 20) {
|
|
80
|
-
showHint('cool', '❄️ Warm', 'Go higher!');
|
|
81
|
-
} else {
|
|
82
|
-
showHint('cold', '🧊 Cold', 'Too low! Go much higher!');
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
const diff = guess - targetNumber;
|
|
86
|
-
if (diff <= 5) {
|
|
87
|
-
showHint('hot', '🔥 Very Hot!', 'You\'re super close! Go lower!');
|
|
88
|
-
} else if (diff <= 10) {
|
|
89
|
-
showHint('warm', '🌡️ Hot!', 'Getting closer! Go lower!');
|
|
90
|
-
} else if (diff <= 20) {
|
|
91
|
-
showHint('cool', '❄️ Warm', 'Go lower!');
|
|
92
|
-
} else {
|
|
93
|
-
showHint('cold', '🧊 Cold', 'Too high! Go much lower!');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
guessInput.value = '';
|
|
98
|
-
guessInput.focus();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Handle win
|
|
102
|
-
function handleWin() {
|
|
103
|
-
gameActive = false;
|
|
104
|
-
guessInput.disabled = true;
|
|
105
|
-
guessBtn.disabled = true;
|
|
106
|
-
|
|
107
|
-
showHint('win', '🎉 Congratulations!', `You found it in ${attempts} attempts!`);
|
|
108
|
-
|
|
109
|
-
// Update best score
|
|
110
|
-
if (!bestScores[maxRange] || attempts < bestScores[maxRange]) {
|
|
111
|
-
bestScores[maxRange] = attempts;
|
|
112
|
-
localStorage.setItem(`bestScore${maxRange}`, attempts);
|
|
113
|
-
bestScoreDisplay.textContent = attempts;
|
|
114
|
-
|
|
115
|
-
// Show new record message
|
|
116
|
-
setTimeout(() => {
|
|
117
|
-
hintDetails.textContent = `🏆 New Record: ${attempts} attempts!`;
|
|
118
|
-
}, 1500);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Give up
|
|
123
|
-
function giveUp() {
|
|
124
|
-
if (!gameActive) return;
|
|
125
|
-
|
|
126
|
-
gameActive = false;
|
|
127
|
-
guessInput.disabled = true;
|
|
128
|
-
guessBtn.disabled = true;
|
|
129
|
-
|
|
130
|
-
showHint('give-up', '😔 Game Over', `The number was ${targetNumber}`);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Show hint
|
|
134
|
-
function showHint(type, title, details) {
|
|
135
|
-
hintBox.className = `hint-box ${type}`;
|
|
136
|
-
hintText.textContent = title;
|
|
137
|
-
hintDetails.textContent = details;
|
|
138
|
-
|
|
139
|
-
// Animate
|
|
140
|
-
hintBox.style.animation = 'none';
|
|
141
|
-
setTimeout(() => {
|
|
142
|
-
hintBox.style.animation = 'bounceIn 0.5s ease';
|
|
143
|
-
}, 10);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Add to history
|
|
147
|
-
function addToHistory(guess) {
|
|
148
|
-
if (guesses.length === 1) {
|
|
149
|
-
guessHistory.innerHTML = '';
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const guessItem = document.createElement('div');
|
|
153
|
-
guessItem.className = 'guess-item';
|
|
154
|
-
|
|
155
|
-
let icon = '';
|
|
156
|
-
if (guess === targetNumber) {
|
|
157
|
-
icon = '🎯';
|
|
158
|
-
guessItem.classList.add('correct');
|
|
159
|
-
} else if (Math.abs(guess - targetNumber) <= 5) {
|
|
160
|
-
icon = '🔥';
|
|
161
|
-
} else if (Math.abs(guess - targetNumber) <= 10) {
|
|
162
|
-
icon = '🌡️';
|
|
163
|
-
} else if (Math.abs(guess - targetNumber) <= 20) {
|
|
164
|
-
icon = '❄️';
|
|
165
|
-
} else {
|
|
166
|
-
icon = '🧊';
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
guessItem.innerHTML = `
|
|
170
|
-
<span class="guess-number">${guess}</span>
|
|
171
|
-
<span class="guess-icon">${icon}</span>
|
|
172
|
-
`;
|
|
173
|
-
|
|
174
|
-
guessHistory.prepend(guessItem);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Update display
|
|
178
|
-
function updateDisplay() {
|
|
179
|
-
attemptsDisplay.textContent = attempts;
|
|
180
|
-
bestScoreDisplay.textContent = bestScores[maxRange] || '-';
|
|
181
|
-
rangeDisplay.textContent = `1 - ${maxRange}`;
|
|
182
|
-
guessInput.setAttribute('max', maxRange);
|
|
183
|
-
guessInput.setAttribute('placeholder', `Enter number (1-${maxRange})`);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Change difficulty
|
|
187
|
-
function changeDifficulty(newRange) {
|
|
188
|
-
maxRange = parseInt(newRange);
|
|
189
|
-
|
|
190
|
-
// Update active button
|
|
191
|
-
difficultyBtns.forEach(btn => {
|
|
192
|
-
btn.classList.toggle('active', parseInt(btn.dataset.range) === maxRange);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
initGame();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Event listeners
|
|
199
|
-
guessBtn.addEventListener('click', makeGuess);
|
|
200
|
-
newGameBtn.addEventListener('click', initGame);
|
|
201
|
-
giveUpBtn.addEventListener('click', giveUp);
|
|
202
|
-
|
|
203
|
-
guessInput.addEventListener('keypress', (e) => {
|
|
204
|
-
if (e.key === 'Enter') {
|
|
205
|
-
makeGuess();
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
difficultyBtns.forEach(btn => {
|
|
210
|
-
btn.addEventListener('click', () => {
|
|
211
|
-
changeDifficulty(btn.dataset.range);
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
// Initialize on load
|
|
216
|
-
initGame();
|