├── .config
└── configstore
│ ├── update-notifier-npm.json.2701252402
│ └── update-notifier-npm.json
├── .gitattributes
├── gifs
├── 01_Run.gif
├── 02_Remix.gif
└── 03_Publish.gif
├── .tutorial
├── gifs
│ ├── 01_Run.gif
│ ├── 02_Remix.gif
│ └── 03_Publish.gif
└── README.md
├── replit.nix
├── reference.md
├── targetWords.js
├── LICENSE
├── README.md
├── index.html
├── .cache
└── replit
│ └── nix
│ └── env.json
├── styles.css
├── script.js
└── .replit
/.config/configstore/update-notifier-npm.json.2701252402:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/gifs/01_Run.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akshat-jn-crypto/Wordle-clone/HEAD/gifs/01_Run.gif
--------------------------------------------------------------------------------
/gifs/02_Remix.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akshat-jn-crypto/Wordle-clone/HEAD/gifs/02_Remix.gif
--------------------------------------------------------------------------------
/gifs/03_Publish.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akshat-jn-crypto/Wordle-clone/HEAD/gifs/03_Publish.gif
--------------------------------------------------------------------------------
/.config/configstore/update-notifier-npm.json:
--------------------------------------------------------------------------------
1 | {
2 | "optOut": false,
3 | "lastUpdateCheck": 1661606148651
4 | }
--------------------------------------------------------------------------------
/.tutorial/gifs/01_Run.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akshat-jn-crypto/Wordle-clone/HEAD/.tutorial/gifs/01_Run.gif
--------------------------------------------------------------------------------
/.tutorial/gifs/02_Remix.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akshat-jn-crypto/Wordle-clone/HEAD/.tutorial/gifs/02_Remix.gif
--------------------------------------------------------------------------------
/.tutorial/gifs/03_Publish.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akshat-jn-crypto/Wordle-clone/HEAD/.tutorial/gifs/03_Publish.gif
--------------------------------------------------------------------------------
/replit.nix:
--------------------------------------------------------------------------------
1 | { pkgs }: {
2 | deps = [
3 | pkgs.nodePackages.vscode-langservers-extracted
4 | pkgs.nodePackages.typescript-language-server
5 | ];
6 | }
--------------------------------------------------------------------------------
/reference.md:
--------------------------------------------------------------------------------
1 | - Source: https://github.com/WebDevSimplified/wordle-clone
2 | - Modified CSS slightly to get it to fit in the output window.
3 | - Modifed JS logic to join targetWords + dictionary to form a list of all words - targetWords no longer need to be in the dictionary.
4 |
--------------------------------------------------------------------------------
/targetWords.js:
--------------------------------------------------------------------------------
1 | const targetWords = [
2 | "rebut",
3 | "humph",
4 | "awake",
5 | "blush",
6 | "focal",
7 | "evade",
8 | "naval",
9 | "serve",
10 | "heath",
11 | "dwarf",
12 | "model",
13 | "karma",
14 | "stink",
15 | "grade",
16 | "quiet",
17 | "adieu",
18 | "alert",
19 | "alien",
20 | "atone",
21 | "audio",
22 | "blind",
23 | "canoe",
24 | "fraud",
25 | "haunt",
26 | "media",
27 | "minor",
28 | "odium",
29 | "orate",
30 | "pause",
31 | "plane",
32 | "raise",
33 | "resin",
34 | "rouse",
35 | "route",
36 | "shade"
37 | ];
38 |
39 | export default targetWords;
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2022 WebDevSimplified
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/.tutorial/README.md:
--------------------------------------------------------------------------------
1 | # Make Your Own Wordle Game
2 |
3 | ### Step 1: Run
4 |
5 | Check out the "Output" panel to see your game in action.
6 |
7 | 
8 |
9 | ### Step 2: Customize
10 |
11 | Look at the left hand side vertical panel with the icons
12 | - You are currently in the `Tutorial` (the icon with the open book)
13 | - Below this is the `Files` icon (page with the corner folded)
14 | - You can switch back and forth through this panel of icons
15 |
16 | To modify a file you will need to go to the `Files` icon (the page with the folded corner)
17 | - Here right click on `targetWords.json` file and choose "Open Tab"
18 | - This will open the file side by side with `index.html`
19 | - Modify `targetwords.json` to customize which words could show up as the randomly choosen word for a round of the game.
20 | - Refresh the browser or hit the "run" button and test it out.
21 |
22 | 
23 |
24 | ## Step 3: Share
25 |
26 | Share your game with the community.
27 |
28 | 
29 |
30 | ## Step 4: Remix
31 |
32 | Dig into web development [here](https://docs.replit.com/tutorials/building-a-game-with-pygame) and remix the rules of the game to create your own word puzzle.
33 |
34 | # 🎉 Good job!
35 |
36 | # Challenge!
37 | - Can you make a 6-letter wordle game?
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Wordle clone
2 | Hackoberfest repo
3 | Hacktoberfest-2022🔥
4 |
5 |
6 |
7 |
8 |
9 |
10 | ## This repository aims to help code beginners with their first successful pull request and open source contribution. :partying_face:
11 |
12 | :star: Feel free to use this project to make your first contribution to an open-source project on GitHub. Practice making your first pull request to a public repository before doing the real thing!
13 |
14 | :star: Make sure to grab some cool swags during Hacktoberfest by getting involved in the open-source community.
15 |
16 | ### This repository is open to all members of the GitHub community. Any member can contribute to this project!
17 | # Guidelines
18 |
19 | # Steps For Contribution
20 |
21 | 0. Star
22 |
23 | 1. Fork
24 |
25 | 2. Clone the forked repository.
26 | ```css
27 | git clone https://github.com//Wordle-clone
28 | ```
29 |
30 | 3. Navigate to the project directory.
31 | ```py
32 | cd Wordle-clone
33 | ```
34 |
35 | 4. Create a new branch.
36 | ```css
37 | git checkout -b
38 | ```
39 |
40 | 5. Make changes.
41 |
42 | 6. Stage your changes and commit
43 | ```css
44 | git add -A
45 |
46 | git commit -m ""
47 | ```
48 |
49 | 7. Push your local commits to the remote repo.
50 | ```css
51 | git push -u origin ""
52 | ```
53 |
54 | 8. Create a Pull Request.
55 |
56 | 9. Congratulations! 🎉 you've made your contribution.
57 |
58 |
59 | ---
60 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Wordle Clone
10 |
11 |
12 |
13 |
WORDLE CLONE
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 |
Q
50 |
W
51 |
E
52 |
R
53 |
T
54 |
Y
55 |
U
56 |
I
57 |
O
58 |
P
59 |
60 |
A
61 |
S
62 |
D
63 |
F
64 |
G
65 |
H
66 |
J
67 |
K
68 |
L
69 |
70 |
Enter
71 |
Z
72 |
X
73 |
C
74 |
V
75 |
B
76 |
N
77 |
M
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
88 | New game?
89 |
90 |
91 |
--------------------------------------------------------------------------------
/.cache/replit/nix/env.json:
--------------------------------------------------------------------------------
1 | {"entries":{"replit.nix":{"env":{"AR":"ar","AS":"as","CC":"gcc","CONFIG_SHELL":"/nix/store/bm7jr70d9ghn5cczb3q0w90apsm05p54-bash-5.1-p8/bin/bash","CXX":"g++","HOST_PATH":"/nix/store/mj9madzlh0xwcccb30qsnsclfjxr5k1s-vscode-langservers-extracted-3.0.1/bin:/nix/store/rszcnphk27fvfr2hq5pcr07jccf2dqy1-typescript-language-server-0.9.6/bin:/nix/store/jd1y449cf66yx5d1hwyjvc4562b1p1am-coreutils-9.0/bin:/nix/store/jjvw20r6pz3ff7pn91yhvfx8s7izsqan-findutils-4.8.0/bin:/nix/store/ndd6gh8zigjy0j68arj7nyrbcw4kcw01-diffutils-3.8/bin:/nix/store/bpg0ia8nkavzw7s66avi1f9nz72i1p3r-gnused-4.8/bin:/nix/store/df3ff57sbkgbdhc4ar19zs4y0hrhggii-gnugrep-3.7/bin:/nix/store/4fv981732jqzirah3h2y6ynmlsfbxb37-gawk-5.1.1/bin:/nix/store/k5ifa08z0qlkknnb8s1bdh2kdrx0qmd0-gnutar-1.34/bin:/nix/store/dcird3wn9xywy49w3qq1hpjwvjfn3lph-gzip-1.11/bin:/nix/store/s85iyc3p9nbinwvwx9rcqirf1m68zpmm-bzip2-1.0.6.0.2-bin/bin:/nix/store/msncxcf5lgy5by9cqjyxchxd26x47d64-gnumake-4.3/bin:/nix/store/bm7jr70d9ghn5cczb3q0w90apsm05p54-bash-5.1-p8/bin:/nix/store/gi3psbgxbf2fmvgi36pmw77nnh58vq3l-patch-2.7.6/bin:/nix/store/sqb20f4rk80lw21j4is85qwljlphmn3g-xz-5.2.5-bin/bin","LD":"ld","LOCALE_ARCHIVE":"/usr/lib/locale/locale-archive","NIX_BINTOOLS":"/nix/store/spm7d6ncyx2k5w8yl6clzynv2s4wf1kp-binutils-wrapper-2.35.2","NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu":"1","NIX_BUILD_CORES":"16","NIX_BUILD_TOP":"/tmp","NIX_CC":"/nix/store/2qwnn6lizc9d119kp3zig3q19gbfm4n6-gcc-wrapper-10.3.0","NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu":"1","NIX_CFLAGS_COMPILE":" -frandom-seed=qfbj2w45kl","NIX_ENFORCE_NO_NATIVE":"1","NIX_HARDENING_ENABLE":"fortify stackprotector pic strictoverflow format relro bindnow","NIX_INDENT_MAKE":"1","NIX_LDFLAGS":"-rpath /nix/store/qfbj2w45kliilxjmvsvz3iqm4mxk1qf1-nix-shell/lib64 -rpath /nix/store/qfbj2w45kliilxjmvsvz3iqm4mxk1qf1-nix-shell/lib ","NIX_STORE":"/nix/store","NM":"nm","OBJCOPY":"objcopy","OBJDUMP":"objdump","PATH":"/nix/store/bccsypsvjskpzsgzww8bzjgqmck4bjbf-bash-interactive-5.1-p8/bin:/nix/store/bqmg7l0jn6nhgjlfc981g1imzb6ny8xl-patchelf-0.13/bin:/nix/store/2qwnn6lizc9d119kp3zig3q19gbfm4n6-gcc-wrapper-10.3.0/bin:/nix/store/6r5h4h7nqx73m87j5b9sjwy2x9kyri0k-gcc-10.3.0/bin:/nix/store/csz8v8xi2f644j26n84i20dnqmq43sih-glibc-2.33-117-bin/bin:/nix/store/jd1y449cf66yx5d1hwyjvc4562b1p1am-coreutils-9.0/bin:/nix/store/spm7d6ncyx2k5w8yl6clzynv2s4wf1kp-binutils-wrapper-2.35.2/bin:/nix/store/h19zwlkrp6b0hp3ypbqdcggnyarn3af6-binutils-2.35.2/bin:/nix/store/mj9madzlh0xwcccb30qsnsclfjxr5k1s-vscode-langservers-extracted-3.0.1/bin:/nix/store/rszcnphk27fvfr2hq5pcr07jccf2dqy1-typescript-language-server-0.9.6/bin:/nix/store/jd1y449cf66yx5d1hwyjvc4562b1p1am-coreutils-9.0/bin:/nix/store/jjvw20r6pz3ff7pn91yhvfx8s7izsqan-findutils-4.8.0/bin:/nix/store/ndd6gh8zigjy0j68arj7nyrbcw4kcw01-diffutils-3.8/bin:/nix/store/bpg0ia8nkavzw7s66avi1f9nz72i1p3r-gnused-4.8/bin:/nix/store/df3ff57sbkgbdhc4ar19zs4y0hrhggii-gnugrep-3.7/bin:/nix/store/4fv981732jqzirah3h2y6ynmlsfbxb37-gawk-5.1.1/bin:/nix/store/k5ifa08z0qlkknnb8s1bdh2kdrx0qmd0-gnutar-1.34/bin:/nix/store/dcird3wn9xywy49w3qq1hpjwvjfn3lph-gzip-1.11/bin:/nix/store/s85iyc3p9nbinwvwx9rcqirf1m68zpmm-bzip2-1.0.6.0.2-bin/bin:/nix/store/msncxcf5lgy5by9cqjyxchxd26x47d64-gnumake-4.3/bin:/nix/store/bm7jr70d9ghn5cczb3q0w90apsm05p54-bash-5.1-p8/bin:/nix/store/gi3psbgxbf2fmvgi36pmw77nnh58vq3l-patch-2.7.6/bin:/nix/store/sqb20f4rk80lw21j4is85qwljlphmn3g-xz-5.2.5-bin/bin","RANLIB":"ranlib","READELF":"readelf","SIZE":"size","SOURCE_DATE_EPOCH":"315532800","STRINGS":"strings","STRIP":"strip","XDG_DATA_DIRS":"/nix/store/bqmg7l0jn6nhgjlfc981g1imzb6ny8xl-patchelf-0.13/share","_":"/nix/store/jd1y449cf66yx5d1hwyjvc4562b1p1am-coreutils-9.0/bin/env","__ETC_PROFILE_SOURCED":"1","buildInputs":"/nix/store/mj9madzlh0xwcccb30qsnsclfjxr5k1s-vscode-langservers-extracted-3.0.1 /nix/store/rszcnphk27fvfr2hq5pcr07jccf2dqy1-typescript-language-server-0.9.6","builder":"/nix/store/bm7jr70d9ghn5cczb3q0w90apsm05p54-bash-5.1-p8/bin/bash","configureFlags":"","depsBuildBuild":"","depsBuildBuildPropagated":"","depsBuildTarget":"","depsBuildTargetPropagated":"","depsHostHost":"","depsHostHostPropagated":"","depsTargetTarget":"","depsTargetTargetPropagated":"","doCheck":"","doInstallCheck":"","name":"nix-shell","nativeBuildInputs":"","nobuildPhase":"echo\necho \"This derivation is not meant to be built, aborting\";\necho\nexit 1\n","out":"/nix/store/qfbj2w45kliilxjmvsvz3iqm4mxk1qf1-nix-shell","outputs":"out","patches":"","phases":"nobuildPhase","propagatedBuildInputs":"","propagatedNativeBuildInputs":"","shell":"/nix/store/bm7jr70d9ghn5cczb3q0w90apsm05p54-bash-5.1-p8/bin/bash","shellHook":"","stdenv":"/nix/store/z7wz8q1i0j4jmfpn87wpakwma6q0k90n-stdenv-linux","strictDeps":"","system":"x86_64-linux"},"dependencies":[{"path":"replit.nix","mod_time":"2022-03-14T23:31:45.35298035Z"}],"channel":"stable-21_11","channel_nix_path":"/nix/store/1m2fssfawvn6krbv3rc6hmq7xaa45v5a-nixpkgs-stable-21_11-21.11.tar.gz/nixpkgs-stable-21_11"}}}
--------------------------------------------------------------------------------
/styles.css:
--------------------------------------------------------------------------------
1 | *, *::after, *::before {
2 | box-sizing: border-box;
3 | font-family: Arial;
4 | }
5 |
6 | body {
7 | background-color: hsl(240, 3%, 7%);
8 | display: flex;
9 | flex-direction: column;
10 | min-height: 100vh;
11 | margin: 0;
12 | padding: 3em 10em 10em 10em;
13 | font-size: clamp(.5rem, 2.5vmin, 1.5rem);
14 | }
15 | .heading {
16 | display: flex;
17 | justify-content: center;
18 | align-items: center;
19 | margin-bottom: 1em;
20 | }
21 |
22 | .title {
23 | color: hsl(204, 7%, 85%);
24 | }
25 |
26 | .keyboard {
27 | display: grid;
28 | grid-template-columns: repeat(20, minmax(auto, 1em));
29 | grid-auto-rows: 3em;
30 | gap: .25em;
31 | justify-content: center;
32 | }
33 |
34 | .key {
35 | font-size: inherit;
36 | grid-column: span 2;
37 | border: none;
38 | padding: 0;
39 | display: flex;
40 | justify-content: center;
41 | align-items: center;
42 | background-color: hsl(
43 | var(--hue, 200),
44 | var(--saturation, 1%),
45 | calc(var(--lightness-offset, 0%) + var(--lightness, 51%))
46 | );
47 | color: white;
48 | fill: white;
49 | text-transform: uppercase;
50 | border-radius: .25em;
51 | cursor: pointer;
52 | user-select: none;
53 | }
54 | .key:hover{
55 | background-color: hsl(
56 | var(--hue, 198),
57 | var(--saturation, 1%),
58 | calc(var(--lightness-offset, 0%) + var(--lightness, 52%))
59 | );
60 | }
61 |
62 | .key.large {
63 | grid-column: span 3;
64 | }
65 |
66 | .key > svg {
67 | width: 1.75em;
68 | height: 1.75em;
69 | }
70 |
71 | .key:hover, .key:focus {
72 | --lightness-offset: 10%;
73 | }
74 |
75 | .key.wrong {
76 | --lightness: 23%;
77 | }
78 |
79 | .key.wrong-location {
80 | --hue: 49;
81 | --saturation: 51%;
82 | --lightness: 47%;
83 | }
84 |
85 | .key.correct {
86 | --hue: 115;
87 | --saturation: 29%;
88 | --lightness: 43%;
89 | }
90 |
91 | .guess-grid {
92 | display: grid;
93 | justify-content: center;
94 | align-content: start;
95 | grid-template-columns: repeat(5, 2em);
96 | grid-template-rows: repeat(6, 2em);
97 | gap: .25em;
98 | margin-bottom: 1em;
99 | }
100 |
101 | .tile {
102 | font-size: 1em;
103 | color: white;
104 | border: .05em solid hsl(240, 2%, 23%);
105 | text-transform: uppercase;
106 | font-weight: bold;
107 | display: flex;
108 | justify-content: center;
109 | align-items: center;
110 | user-select: none;
111 | transition: transform 250ms linear;
112 | }
113 |
114 | .tile[data-state="active"] {
115 | border-color: hsl(200, 1%, 34%);
116 | }
117 |
118 | .tile[data-state="wrong"] {
119 | border: none;
120 | background-color: hsl(240, 2%, 23%);
121 | }
122 |
123 | .tile[data-state="wrong-location"] {
124 | border: none;
125 | background-color: hsl(49, 51%, 47%);
126 | }
127 |
128 | .tile[data-state="correct"] {
129 | border: none;
130 | background-color: hsl(115, 29%, 43%);
131 | }
132 |
133 | .tile.shake {
134 | animation: shake 250ms ease-in-out;
135 | }
136 |
137 | .tile.dance {
138 | animation: dance 500ms ease-in-out;
139 | }
140 |
141 | .tile.flip {
142 | transform: rotateX(90deg);
143 | }
144 |
145 | @keyframes shake {
146 | 10% {
147 | transform: translateX(-5%);
148 | }
149 |
150 | 30% {
151 | transform: translateX(5%);
152 | }
153 |
154 | 50% {
155 | transform: translateX(-7.5%);
156 | }
157 |
158 | 70% {
159 | transform: translateX(7.5%);
160 | }
161 |
162 | 90% {
163 | transform: translateX(-5%);
164 | }
165 |
166 | 100% {
167 | transform: translateX(0);
168 | }
169 | }
170 |
171 | @keyframes dance {
172 | 20% {
173 | transform: translateY(-50%);
174 | }
175 |
176 | 40% {
177 | transform: translateY(5%);
178 | }
179 |
180 | 60% {
181 | transform: translateY(-25%);
182 | }
183 |
184 | 80% {
185 | transform: translateY(2.5%);
186 | }
187 |
188 | 90% {
189 | transform: translateY(-5%);
190 | }
191 |
192 | 100% {
193 | transform: translateY(0);
194 | }
195 | }
196 |
197 | .alert-container {
198 | position: fixed;
199 | top: 6vh;
200 | left: 50vw;
201 | transform: translateX(-50%);
202 | z-index: 1;
203 | display: flex;
204 | flex-direction: column;
205 | align-items: center;
206 | }
207 |
208 | .alert {
209 | pointer-events: none;
210 | background-color: hsl(204, 7%, 85%);
211 | padding: .75em;
212 | border-radius: .25em;
213 | opacity: 1;
214 | transition: opacity 500ms ease-in-out;
215 | margin-bottom: .5em;
216 | }
217 |
218 | .alert:last-child {
219 | margin-bottom: 0;
220 | }
221 |
222 | .alert.hide {
223 | opacity: 0;
224 | }
225 |
226 |
227 | .footer {
228 | display: flex;
229 | justify-content: center;
230 | align-items: center;
231 | margin-top: 1.5em;
232 | color: white;
233 | }
234 |
235 | .footer a {
236 | color: hsl(197, 59%, 64%);
237 | text-decoration: none;
238 | .new-game {
239 | width: 10%;
240 | margin: 5% auto 0;
241 | padding: 8px;
242 | transition: display 500ms ease-in-out;
243 | background-color: hsl(115, 29%, 43%);
244 | }
245 |
246 | .new-game.hidden {
247 | display: none;
248 | }
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | import targetWords from "./targetWords.js";
2 | import dictionary from "./dictionary.js";
3 |
4 | const WORD_LENGTH = 5;
5 | const FLIP_ANIMATION_DURATION = 500;
6 | const DANCE_ANIMATION_DURATION = 500;
7 | const keyboard = document.querySelector("[data-keyboard]");
8 | const alertContainer = document.querySelector("[data-alert-container]");
9 | const guessGrid = document.querySelector("[data-guess-grid]");
10 | const newGameButton = document.getElementById("newGameButton");
11 | const offsetFromDate = new Date(2022, 0, 1);
12 | const msOffset = Date.now() - offsetFromDate;
13 | const dayOffset = msOffset / 1000 / 60 / 60 / 24;
14 | let targetWord = targetWords[Math.floor(dayOffset) % targetWords.length];
15 | const allWords = Array.from(new Set([...targetWords, ...dictionary]));
16 |
17 | startInteraction();
18 |
19 | function startInteraction() {
20 | newGameButton.classList.add("hidden");
21 | document.addEventListener("click", handleMouseClick);
22 | document.addEventListener("keydown", handleKeyPress);
23 | }
24 |
25 | function stopInteraction() {
26 | document.removeEventListener("click", handleMouseClick);
27 | document.removeEventListener("keydown", handleKeyPress);
28 | }
29 |
30 | function handleMouseClick(e) {
31 | if (e.target.matches("[data-key]")) {
32 | pressKey(e.target.dataset.key);
33 | return;
34 | }
35 |
36 | if (e.target.matches("[data-enter]")) {
37 | submitGuess();
38 | return;
39 | }
40 |
41 | if (e.target.matches("[data-delete]")) {
42 | deleteKey();
43 | return;
44 | }
45 | }
46 |
47 | function handleKeyPress(e) {
48 | if (e.key === "Enter") {
49 | submitGuess();
50 | return;
51 | }
52 |
53 | if (e.key === "Backspace" || e.key === "Delete") {
54 | deleteKey();
55 | return;
56 | }
57 |
58 | if (e.key.match(/^[a-z]|[A-Z]$/)) {
59 | pressKey(e.key.toLowerCase());
60 | return;
61 | }
62 | }
63 |
64 | function pressKey(key) {
65 | const activeTiles = getActiveTiles();
66 | if (activeTiles.length >= WORD_LENGTH) return;
67 | const nextTile = guessGrid.querySelector(":not([data-letter])");
68 | nextTile.dataset.letter = key.toLowerCase();
69 | nextTile.textContent = key;
70 | nextTile.dataset.state = "active";
71 | }
72 |
73 | function deleteKey() {
74 | const activeTiles = getActiveTiles();
75 | const lastTile = activeTiles[activeTiles.length - 1];
76 | if (lastTile == null) return;
77 | lastTile.textContent = "";
78 | delete lastTile.dataset.state;
79 | delete lastTile.dataset.letter;
80 | }
81 |
82 | function submitGuess() {
83 | const activeTiles = [...getActiveTiles()];
84 | if (activeTiles.length !== WORD_LENGTH) {
85 | showAlert("Not enough letters");
86 | shakeTiles(activeTiles);
87 | return;
88 | }
89 |
90 | const guess = activeTiles.reduce((word, tile) => {
91 | return word + tile.dataset.letter;
92 | }, "");
93 |
94 | if (!allWords.includes(guess)) {
95 | showAlert("Not in word list");
96 | shakeTiles(activeTiles);
97 | return;
98 | }
99 |
100 | stopInteraction();
101 | let used = [0, 0, 0, 0, 0];
102 | let marker = [0, 0, 0, 0, 0];
103 | activeTiles.forEach((...params) => markCorrect(...params, used, marker));
104 | activeTiles.forEach((...params) =>
105 | markWrongLocation(...params, used, marker)
106 | );
107 | activeTiles.forEach((...params) => flipTile(...params, guess, marker));
108 | }
109 |
110 | function markCorrect(tile, index, array, used, marker) {
111 | const letter = tile.dataset.letter;
112 | if (targetWord[index] === letter) {
113 | marker[index] = 1;
114 | used[index] = 1;
115 | }
116 | }
117 |
118 | function markWrongLocation(tile, index, array, used, marker) {
119 | const letter = tile.dataset.letter;
120 | for (let i = 0; i < 5; i++) {
121 | if (targetWord[i] === letter && used[i] === 0) {
122 | marker[index] = 2;
123 | used[i] = 1;
124 | break;
125 | }
126 | }
127 | }
128 |
129 | function flipTile(tile, index, array, guess, marker) {
130 | const letter = tile.dataset.letter;
131 | const key = keyboard.querySelector(`[data-key="${letter}"i]`);
132 | setTimeout(() => {
133 | tile.classList.add("flip");
134 | }, (index * FLIP_ANIMATION_DURATION) / 2);
135 |
136 | tile.addEventListener(
137 | "transitionend",
138 | () => {
139 | tile.classList.remove("flip");
140 | if (marker[index] === 1) {
141 | tile.dataset.state = "correct";
142 | key.classList.add("correct");
143 | } else if (marker[index] === 2) {
144 | tile.dataset.state = "wrong-location";
145 | key.classList.add("wrong-location");
146 | } else {
147 | tile.dataset.state = "wrong";
148 | key.classList.add("wrong");
149 | }
150 |
151 | if (index === array.length - 1) {
152 | tile.addEventListener(
153 | "transitionend",
154 | () => {
155 | startInteraction();
156 | checkWinLose(guess, array);
157 | },
158 | { once: true }
159 | );
160 | }
161 | },
162 | { once: true }
163 | );
164 | }
165 |
166 | function getActiveTiles() {
167 | return guessGrid.querySelectorAll('[data-state="active"]');
168 | }
169 |
170 | function showAlert(message, duration = 1000) {
171 | const alert = document.createElement("div");
172 | alert.textContent = message;
173 | alert.classList.add("alert");
174 | alertContainer.prepend(alert);
175 | if (duration == null) return;
176 |
177 | setTimeout(() => {
178 | alert.classList.add("hide");
179 | alert.addEventListener("transitionend", () => {
180 | alert.remove();
181 | });
182 | }, duration);
183 | }
184 |
185 | function shakeTiles(tiles) {
186 | tiles.forEach((tile) => {
187 | tile.classList.add("shake");
188 | tile.addEventListener(
189 | "animationend",
190 | () => {
191 | tile.classList.remove("shake");
192 | },
193 | { once: true }
194 | );
195 | });
196 | }
197 |
198 | function checkWinLose(guess, tiles) {
199 | if (guess === targetWord) {
200 | showAlert("You Win", 5000);
201 | danceTiles(tiles);
202 | newGameButton.classList.remove("hidden");
203 | stopInteraction();
204 | return;
205 | }
206 |
207 | const remainingTiles = guessGrid.querySelectorAll(":not([data-letter])");
208 | if (remainingTiles.length === 0) {
209 | showAlert(targetWord.toUpperCase(), null);
210 | stopInteraction();
211 | newGameButton.classList.remove("hidden");
212 | }
213 | }
214 |
215 | function danceTiles(tiles) {
216 | tiles.forEach((tile, index) => {
217 | setTimeout(() => {
218 | tile.classList.add("dance");
219 | tile.addEventListener(
220 | "animationend",
221 | () => {
222 | tile.classList.remove("dance");
223 | },
224 | { once: true }
225 | );
226 | }, (index * DANCE_ANIMATION_DURATION) / 5);
227 | });
228 | }
229 |
230 | newGameButton.addEventListener("click", startNewGame);
231 |
232 | function startNewGame() {
233 | const tiles = Array.from(document.getElementsByClassName("tile"));
234 | tiles.forEach((e) => {
235 | setTimeout(() => {
236 | e.classList.add("flip");
237 | }, FLIP_ANIMATION_DURATION / 2);
238 | e.addEventListener(
239 | "transitionend",
240 | () => {
241 | e.classList.remove("flip");
242 | e.textContent = "";
243 | delete e.dataset.state;
244 | delete e.dataset.letter;
245 | },
246 | { once: true }
247 | );
248 | });
249 | const keys = Array.from(document.getElementsByClassName("key"));
250 | keys.forEach((e) => {
251 | e.classList.remove("correct");
252 | e.classList.remove("wrong-location");
253 | e.classList.remove("wrong");
254 | });
255 |
256 | targetWord = allWords[Math.floor(Math.random() * allWords.length)];
257 | startInteraction();
258 | }
259 |
--------------------------------------------------------------------------------
/.replit:
--------------------------------------------------------------------------------
1 | hidden=[".config", ".tutorial", "reference.md"]
2 |
3 | entrypoint="README.md"
4 |
5 | # hosting is currently hardcoded for this language
6 | # [hosting]
7 | # route = "/"
8 | # directory= "/"
9 |
10 | [nix]
11 | channel = "stable-21_11"
12 |
13 | [languages.html]
14 | pattern = "**/*.html"
15 | [languages.html.languageServer]
16 | start = ["vscode-html-language-server", "--stdio"]
17 | [languages.html.languageServer.initializationOptions]
18 | provideFormatter = true
19 | [languages.html.languageServer.configuration.html]
20 | customData = [ ]
21 | autoCreateQuotes = true
22 | autoClosingTags = true
23 | mirrorCursorOnMatchingTag = false
24 |
25 | [languages.html.languageServer.configuration.html.completion]
26 | attributeDefaultValue = "doublequotes"
27 |
28 | [languages.html.languageServer.configuration.html.format]
29 | enable = true
30 | wrapLineLength = 120
31 | unformatted = "wbr"
32 | contentUnformatted = "pre,code,textarea"
33 | indentInnerHtml = false
34 | preserveNewLines = true
35 | indentHandlebars = false
36 | endWithNewline = false
37 | extraLiners = "head, body, /html"
38 | wrapAttributes = "auto"
39 | templating = false
40 | unformattedContentDelimiter = ""
41 |
42 | [languages.html.languageServer.configuration.html.suggest]
43 | html5 = true
44 |
45 | [languages.html.languageServer.configuration.html.validate]
46 | scripts = true
47 | styles = true
48 |
49 | [languages.html.languageServer.configuration.html.hover]
50 | documentation = true
51 | references = true
52 |
53 | [languages.html.languageServer.configuration.html.trace]
54 | server = "off"
55 |
56 | [languages.javascript]
57 | pattern = "**/{*.js,*.jsx,*.ts,*.tsx,*.mjs,*.cjs}"
58 | [languages.javascript.languageServer]
59 | start = ["typescript-language-server", "--stdio"]
60 |
61 | # TODO autocomplete relies on snippet support, which we don't advertise to LSP servers.
62 | # For now CSS autocomplete will use built-in codemirror, which is not perfect but good enough
63 | [languages.css]
64 | pattern = "**/{*.less,*.scss,*.css}"
65 | [languages.css.languageServer]
66 | start = ["vscode-css-language-server", "--stdio"]
67 | [languages.css.languageServer.configuration.css]
68 | customData = [ ]
69 | validate = true
70 |
71 | [languages.css.languageServer.configuration.css.completion]
72 | triggerPropertyValueCompletion = true
73 | completePropertyWithSemicolon = true
74 |
75 | [languages.css.languageServer.configuration.css.hover]
76 | documentation = true
77 | references = true
78 |
79 | [languages.css.languageServer.configuration.css.lint]
80 | # Configure linting
81 | # ignore = don't show any warning or error
82 | # warning = show yellow underline
83 | # error = show red underline
84 | argumentsInColorFunction = "error" # Invalid number of parameters
85 | boxModel = "ignore" # Do not use width or height when using padding or border
86 | compatibleVendorPrefixes = "ignore" # When using a vendor-specific prefix make sure to also include all other vendor-specific properties"
87 | duplicateProperties = "warning" # Do not use duplicate style definitions
88 | emptyRules = "warning" # Do not use empty rulesets
89 | float = "ignore" # Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.
90 | fontFaceProperties = "warning" # @font-face rule must define 'src' and 'font-family' properties
91 | hexColorLength = "error" # Hex colors must consist of three, four, six or eight hex numbers
92 | idSelector = "ignore" # Selectors should not contain IDs because these rules are too tightly coupled with the HTML.
93 | ieHack = "ignore" # IE hacks are only necessary when supporting IE7 and older
94 | important = "ignore" # Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.
95 | importStatement = "ignore" # Import statements do not load in parallel
96 | propertyIgnoredDueToDisplay = "warning" # Property is ignored due to the display
97 | universalSelector = "ignore" # The universal selector (*) is known to be slow
98 | unknownAtRules = "warning" # Unknown at-rule
99 | unknownProperties = "warning" # Unknown property.
100 | validProperties = [ ] # add some properties that the linter doesn't know about
101 | unknownVendorSpecificProperties = "ignore" # Unknown vendor specific property.
102 | vendorPrefix = "warning" # When using a vendor-specific prefix also include the standard property
103 | zeroUnits = "ignore" # No unit for zero needed
104 |
105 | [languages.css.languageServer.configuration.css.trace]
106 | server = "off"
107 |
108 | [languages.css.languageServer.configuration.scss]
109 | validate = true
110 |
111 | [languages.css.languageServer.configuration.scss.completion]
112 | triggerPropertyValueCompletion = true
113 | completePropertyWithSemicolon = true
114 |
115 | [languages.css.languageServer.configuration.scss.hover]
116 | documentation = true
117 | references = true
118 |
119 | [languages.css.languageServer.configuration.scss.lint]
120 | # Configure linting
121 | # ignore = don't show any warning or error
122 | # warning = show yellow underline
123 | # error = show red underline
124 | argumentsInColorFunction = "error" # Invalid number of parameters
125 | boxModel = "ignore" # Do not use width or height when using padding or border
126 | compatibleVendorPrefixes = "ignore" # When using a vendor-specific prefix make sure to also include all other vendor-specific properties"
127 | duplicateProperties = "warning" # Do not use duplicate style definitions
128 | emptyRules = "warning" # Do not use empty rulesets
129 | float = "ignore" # Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.
130 | fontFaceProperties = "warning" # @font-face rule must define 'src' and 'font-family' properties
131 | hexColorLength = "error" # Hex colors must consist of three, four, six or eight hex numbers
132 | idSelector = "ignore" # Selectors should not contain IDs because these rules are too tightly coupled with the HTML.
133 | ieHack = "ignore" # IE hacks are only necessary when supporting IE7 and older
134 | important = "ignore" # Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.
135 | importStatement = "ignore" # Import statements do not load in parallel
136 | propertyIgnoredDueToDisplay = "warning" # Property is ignored due to the display
137 | universalSelector = "ignore" # The universal selector (*) is known to be slow
138 | unknownAtRules = "warning" # Unknown at-rule
139 | unknownProperties = "warning" # Unknown property.
140 | validProperties = [ ] # add some properties that the linter doesn't know about
141 | unknownVendorSpecificProperties = "ignore" # Unknown vendor specific property.
142 | vendorPrefix = "warning" # When using a vendor-specific prefix also include the standard property
143 | zeroUnits = "ignore" # No unit for zero needed"
144 |
145 | [languages.css.languageServer.configuration.less]
146 | validate = true
147 |
148 | [languages.css.languageServer.configuration.less.completion]
149 | triggerPropertyValueCompletion = true
150 | completePropertyWithSemicolon = true
151 |
152 | [languages.css.languageServer.configuration.less.hover]
153 | documentation = true
154 | references = true
155 |
156 | [languages.css.languageServer.configuration.less.lint]
157 | # Configure linting
158 | # ignore = don't show any warning or error
159 | # warning = show yellow underline
160 | # error = show red underline
161 | argumentsInColorFunction = "error" # Invalid number of parameters
162 | boxModel = "ignore" # Do not use width or height when using padding or border
163 | compatibleVendorPrefixes = "ignore" # When using a vendor-specific prefix make sure to also include all other vendor-specific properties"
164 | duplicateProperties = "warning" # Do not use duplicate style definitions
165 | emptyRules = "warning" # Do not use empty rulesets
166 | float = "ignore" # Avoid using 'float'. Floats lead to fragile CSS that is easy to break if one aspect of the layout changes.
167 | fontFaceProperties = "warning" # @font-face rule must define 'src' and 'font-family' properties
168 | hexColorLength = "error" # Hex colors must consist of three, four, six or eight hex numbers
169 | idSelector = "ignore" # Selectors should not contain IDs because these rules are too tightly coupled with the HTML.
170 | ieHack = "ignore" # IE hacks are only necessary when supporting IE7 and older
171 | important = "ignore" # Avoid using !important. It is an indication that the specificity of the entire CSS has gotten out of control and needs to be refactored.
172 | importStatement = "ignore" # Import statements do not load in parallel
173 | propertyIgnoredDueToDisplay = "warning" # Property is ignored due to the display
174 | universalSelector = "ignore" # The universal selector (*) is known to be slow
175 | unknownAtRules = "warning" # Unknown at-rule
176 | unknownProperties = "warning" # Unknown property.
177 | validProperties = [ ] # add some properties that the linter doesn't know about
178 | unknownVendorSpecificProperties = "ignore" # Unknown vendor specific property.
179 | vendorPrefix = "warning" # When using a vendor-specific prefix also include the standard property
180 | zeroUnits = "ignore" # No unit for zero needed"
181 |
--------------------------------------------------------------------------------