merge both repos! atempt 1 by making the file system the same!

This commit is contained in:
RezHackXYZ 2025-05-29 13:11:49 +05:30
parent badb303ea6
commit 2fe58ee6be
No known key found for this signature in database
128 changed files with 2320 additions and 4285 deletions

View file

@ -0,0 +1,132 @@
<script>
import Keyboard from "./game/keyboard.svelte";
import Display from "./game/display.svelte";
import { onMount } from "svelte";
import { handleKey } from "./logic.svelte.js";
import Right from "./InfoAndSetings/main.svelte";
import { OpenTab } from "./InfoAndSetings/main.svelte";
onMount(() => {
window.addEventListener("keydown", handleKey);
});
</script>
<div id="nav">
<div></div>
<div>
<button
aria-label="Back to main menu"
onclick={() => OpenTab("WordLength")}
><span class="front"
><svg
xmlns="http://www.w3.org/2000/svg"
height="24px"
viewBox="0 -960 960 960"
width="24px"
fill="#FFFFFF"
><path
d="M320-80 160-240l160-160 57 56-64 64h334l-63-64 56-56 160 160L640-80l-57-56 64-64H313l63 64-56 56ZM200-480v-400h80v400h-80Zm240 0v-400h80v400h-80Zm240 0v-400h80v400h-80Z"
/></svg
> Change word legnth
</span></button
>
<button aria-label="Back to main menu" onclick={() => OpenTab("Stats")}
><span class="front"
><svg
xmlns="http://www.w3.org/2000/svg"
height="24px"
viewBox="0 -960 960 960"
width="24px"
fill="#FFFFFF"
><path
d="m105-399-65-47 200-320 120 140 160-260 120 180 135-214 65 47-198 314-119-179-152 247-121-141-145 233Zm475 159q42 0 71-29t29-71q0-42-29-71t-71-29q-42 0-71 29t-29 71q0 42 29 71t71 29ZM784-80 676-188q-21 14-45.5 21t-50.5 7q-75 0-127.5-52.5T400-340q0-75 52.5-127.5T580-520q75 0 127.5 52.5T760-340q0 26-7 50.5T732-244l108 108-56 56Z"
/></svg
> Stats
</span></button
>
</div>
</div>
<div id="root">
<div id="left">
<Display />
<Keyboard />
</div>
<Right />
</div>
<style>
#nav {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #121212;
color: white;
}
button {
background: #292929;
border-radius: 12px;
border: none;
margin: 10px;
padding: 2px 0px;
cursor: pointer;
outline-offset: 4px;
max-width: 400px;
}
button:hover .front {
transform: translateY(-7px);
}
button:active .front {
transform: translateY(-2px);
}
.front {
display: flex;
text-align: center;
align-items: center;
padding: 5px;
border-radius: 12px;
background: #4d4d4d;
color: white;
transform: translateY(-4px);
transition: all 0.1s ease-in-out;
font-family: "JetBrains Mono", monospace;
font-size: 25px;
}
#root {
height: 90%;
display: flex;
margin: 0;
font-family: "Sour Gummy", sans-serif;
background-color: #121212;
color: white;
}
#left {
width: 100%;
height: 100%;
border-radius: 20px;
margin: 20px;
margin-top: 5px;
border: 2px solid #444;
font-family: "JetBrains Mono", monospace;
}
h1 {
text-align: center;
margin: 5px 0px;
text-decoration: underline #444;
position: fixed;
top: 0;
left: 50%;
transform: translate(-50%, 0);
}
span {
font-size: 0.5em;
text-decoration: none;
color: #444;
}
</style>

View file

@ -0,0 +1,39 @@
<script>
import { newGame, WordLegnth } from "../logic.svelte.js";
import { TabOpen } from "./main.svelte";
let LetersSelected = WordLegnth.v;
</script>
<div id="root">
<h4>Select The Word legnth (between 3 and 10 letters)</h4>
<input type="range" id="vol" name="vol" min="3" max="10" bind:value={LetersSelected} />
<button
onclick={() => {
WordLegnth.v = LetersSelected;
newGame();
TabOpen.v = "none";
}}
class="btn"
>Start New Game with Word legnth of {LetersSelected} letters
</button>
</div>
<style>
#root {
display: flex;
flex-direction: column;
gap: 5px;
margin: 10px;
justify-content: center;
background-color: #303030;
padding: 10px;
margin: 20px;
border-radius: 10px;
width: 400px;
}
h4 {
text-align: center;
margin: 0px;
}
</style>

View file

@ -0,0 +1,58 @@
<script module>
import { newGame, WordLegnth } from "../logic.svelte.js";
import WordLegnthSetings from "./WordLegnthSetings.svelte";
import Stats from "./stats.svelte";
export let TabOpen = $state({ v: "none" });
export function OpenTab(type) {
TabOpen.v = type;
}
</script>
{#if TabOpen.v !== "none"}
<div id="UperLayer">
<div id="wrap">
{#if TabOpen.v == "WordLength"}
<WordLegnthSetings />
{:else if TabOpen.v == "Stats"}
<Stats />
{/if}
<button
class="close"
onclick={() => (TabOpen.v = "none")}
aria-label="close">CLOSE</button
>
</div>
</div>
{/if}
<style>
#UperLayer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
backdrop-filter: blur(5px);
background-color: rgba(0, 0, 0, 0.5);
z-index: 1;
display: grid;
place-items: center;
}
#wrap {
display: flex;
flex-direction: column;
}
.close {
background-color: #2b2b2b;
color: #888;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
align-self: center;
}
</style>

View file

@ -0,0 +1,155 @@
<script>
import { data, WordLegnth } from "../logic.svelte.js";
// svelte-ignore non_reactive_update
let LetersSelected = JSON.stringify(WordLegnth.v);
let dataPoints = data.value[LetersSelected];
import { onMount } from "svelte";
import Chart from "chart.js/auto";
let canvas;
let chart;
onMount(() => {
const ctx = canvas.getContext("2d");
chart = new Chart(ctx, {
type: "line",
data: {
labels: dataPoints.map((_, i) => `Game ${i + 1}`),
datasets: [
{
label: "Number Of Guesses Taken to Win",
data: $state.snapshot(dataPoints),
borderColor: "rgba(75, 192, 192, 1)",
backgroundColor: "rgba(75, 192, 192, 0.2)",
fill: true,
tension: 0.3,
},
],
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
},
},
},
});
});
let Avgguesses = $state(
(
dataPoints.reduce((acc, val) => acc + val, 0) / dataPoints.length
).toFixed(2)
);
let TotalWins = $state(dataPoints.length);
$effect(() => {
const snapshot = JSON.stringify(data.value);
UpdateChart(data.value);
});
function UpdateChart(val) {
dataPoints = data.value[LetersSelected];
if (chart) {
chart.data.labels = dataPoints.map((_, i) => `Game ${i + 1}`);
chart.data.datasets[0].data = $state.snapshot(dataPoints);
chart.update();
}
Avgguesses = (
dataPoints.reduce((acc, val) => acc + val, 0) / dataPoints.length
).toFixed(2);
TotalWins = dataPoints.length;
}
</script>
<div id="root">
<p>
Stats For:
<select
bind:value={LetersSelected}
onchange={() => {
dataPoints = data.value[LetersSelected];
if (chart) {
chart.data.labels = dataPoints.map(
(_, i) => `Point ${i + 1}`
);
chart.data.datasets[0].data = $state.snapshot(dataPoints);
chart.update();
}
Avgguesses = (
dataPoints.reduce((acc, val) => acc + val, 0) /
dataPoints.length
).toFixed(2);
TotalWins = dataPoints.length;
}}
>
<option value="3">3 Letters</option>
<option value="4">4 Letters</option>
<option value="5" selected>5 Letters</option>
<option value="6">6 Letters</option>
<option value="7">7 Letters</option>
<option value="8">8 Letters</option>
<option value="9">9 Letters</option>
<option value="10">10 Letters</option>
</select>
</p>
<div id="toprow">
<div class="toprow">
<h2>Total WINS</h2>
<h1>{TotalWins}</h1>
</div>
<div class="toprow">
<h2>Avg No. of guesses</h2>
<h1>{Avgguesses}</h1>
</div>
</div>
<canvas bind:this={canvas}></canvas>
</div>
<style>
#root {
display: flex;
flex-direction: column;
gap: 5px;
margin: 10px;
justify-content: center;
background-color: #303030;
padding: 10px;
margin: 20px;
border-radius: 10px;
width: 700px;
}
h2,
h1,
p {
text-align: center;
margin: 0px;
}
h2 {
font-size: 20px;
color: #888;
}
#toprow {
display: inline-flex;
gap: 20px;
}
.toprow {
background-color: #3f3f3f;
border-radius: 10px;
}
.toprow:nth-child(1n) {
min-width: 35%;
}
.toprow:nth-child(2n) {
width: 100%;
}
</style>

View file

@ -0,0 +1,73 @@
<script>
import { CurrentWord, words, WordLegnth } from "../logic.svelte.js";
</script>
<div id="DisplayOfWords">
{#each words.v as word}
<div class="word">
{#each word as letter}
<span class={letter[1]}>{letter[0]}</span>
{/each}
</div>
{/each}
<div class="word">
{#each Array(WordLegnth.v) as _, i}
<span>{CurrentWord.v[i] || ""}</span>
{/each}
</div>
</div>
<style>
#DisplayOfWords {
height: calc(100% - 320px);
border: 2px solid #202020;
margin: 20px;
border-radius: 10px;
overflow-y: auto;
}
.word {
display: flex;
gap: 5px;
margin: 10px;
justify-content: center;
}
span {
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
font-size: 50px;
border: 2px solid #444;
}
.c {
background-color: #2b5f2d;
}
.d {
background-color: #804d00;
}
.w {
background-color: #2b2b2b;
}
/* width */
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
border: 1px solid #5c5c5c;
border-radius: 10px;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #3f3f3f;
border-radius: 10px;
}
</style>

View file

@ -0,0 +1,71 @@
<script>
import { keys, ButtonPressed } from "../logic.svelte.js";
</script>
<div id="root">
<div class="word">
{#each keys.v.slice(0, 10) as key}
<button on:click={() => ButtonPressed(key[0])} class={key[1]}
>{key[0]}</button
>
{/each}
</div>
<div class="word">
{#each keys.v.slice(10, 19) as key}
<button on:click={() => ButtonPressed(key[0])} class={key[1]}
>{key[0]}</button
>
{/each}
</div>
<div class="word">
{#each keys.v.slice(19) as key}
<button on:click={() => ButtonPressed(key[0])} class={key[1]}
>{key[0]}</button
>
{/each}
</div>
</div>
<style>
#root {
height: 255px;
margin: 20px;
border-radius: 10px;
border: 2px solid #202020;
}
.word {
display: flex;
gap: 5px;
margin: 10px;
justify-content: center;
}
button {
background: none;
font-family: "JetBrains Mono", monospace;
color: #888;
width: 80px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
font-size: 50px;
border: 2px solid #444;
}
.c {
background-color: #2b5f2d;
}
.d {
background-color: #804d00;
}
.w {
background-color: #2b2b2b;
}
.o {
background-color: #00202c;
}
</style>

View file

@ -0,0 +1,222 @@
import wordExists from "word-exists";
import { generate } from "random-words";
import toast from "svelte-5-french-toast";
export let WordLegnth = $state({ v: 5 });
let CorrectWord = generate({
minLength: WordLegnth.v,
maxLength: WordLegnth.v,
});
console.log("CorrectWord: ", CorrectWord);
export let words = $state({ v: [] });
export let CurrentWord = $state({ v: [] });
export let keys = $state({
v: [
["Q", "n"],
["W", "n"],
["E", "n"],
["R", "n"],
["T", "n"],
["Y", "n"],
["U", "n"],
["I", "n"],
["O", "n"],
["P", "n"],
["A", "n"],
["S", "n"],
["D", "n"],
["F", "n"],
["G", "n"],
["H", "n"],
["J", "n"],
["K", "n"],
["L", "n"],
["⌫", "o"],
["Z", "n"],
["X", "n"],
["C", "n"],
["V", "n"],
["B", "n"],
["N", "n"],
["M", "n"],
["⏎", "o"],
],
});
export function newGame() {
CorrectWord = generate({
minLength: WordLegnth.v,
maxLength: WordLegnth.v,
});
console.log("CorrectWord: ", CorrectWord);
words.v = [];
CurrentWord.v = [];
keys.v = [
["Q", "n"],
["W", "n"],
["E", "n"],
["R", "n"],
["T", "n"],
["Y", "n"],
["U", "n"],
["I", "n"],
["O", "n"],
["P", "n"],
["A", "n"],
["S", "n"],
["D", "n"],
["F", "n"],
["G", "n"],
["H", "n"],
["J", "n"],
["K", "n"],
["L", "n"],
["⌫", "o"],
["Z", "n"],
["X", "n"],
["C", "n"],
["V", "n"],
["B", "n"],
["N", "n"],
["M", "n"],
["⏎", "o"],
];
}
function GameWin() {
ShowAlert("You win!", "success");
toast.success("You win!");
data.value[WordLegnth.v].push(words.v.length);
localStorage.setItem("WordleGamesData", JSON.stringify(data.value));
newGame();
}
function SendWord(word) {
let result = Array(word.length).fill(null);
let used = Array(CorrectWord.length).fill(false);
// First pass: exact matches
for (let i = 0; i < word.length; i++) {
if (word[i].toLowerCase() === CorrectWord[i].toLowerCase()) {
result[i] = [word[i].toUpperCase(), "c"];
used[i] = true;
}
}
// Second pass: wrong place but correct letter
for (let i = 0; i < word.length; i++) {
if (result[i]) continue;
let found = false;
for (let j = 0; j < CorrectWord.length; j++) {
if (!used[j] && word[i].toLowerCase() === CorrectWord[j].toLowerCase()) {
found = true;
used[j] = true;
break;
}
}
result[i] = found ? [word[i].toUpperCase(), "d"] : [word[i].toUpperCase(), "w"];
}
words.v.push(result);
setTimeout(() => {
document.getElementById("DisplayOfWords").scrollTo({
top: document.getElementById("DisplayOfWords").scrollHeight,
behavior: "smooth",
});
}, 100);
// Update keyboard status
for (let [letter, status] of result) {
let keyIndex = keys.v.findIndex((k) => k[0].toLowerCase() === letter.toLowerCase());
if (keyIndex !== -1) {
let current = keys.v[keyIndex][1];
if (status === "c") {
keys.v[keyIndex][1] = "c";
} else if (status === "d" && current === "n") {
keys.v[keyIndex][1] = "d";
} else if (status === "w" && current === "n") {
keys.v[keyIndex][1] = "w";
}
}
}
// Check for win
if (result.every(([_, status]) => status === "c")) {
GameWin();
}
}
export function ButtonPressed(key) {
document.getElementById("DisplayOfWords").scrollTo({
top: document.getElementById("DisplayOfWords").scrollHeight,
behavior: "smooth",
});
if (key === "⏎") {
if (CurrentWord.v.length === WordLegnth.v) {
let word = CurrentWord.v.join("").toUpperCase();
if (wordExists(word)) {
SendWord(CurrentWord.v);
CurrentWord.v = [];
} else {
ShowAlert("Not a valid word", "error");
}
}
return;
} else if (key === "⌫") {
CurrentWord.v.pop();
return;
}
if (CurrentWord.v.length === WordLegnth.v) {
return;
}
CurrentWord.v.push(key);
}
export function handleKey(event) {
const key = event.key.toLowerCase();
if (key === "enter") {
ButtonPressed("⏎");
} else if (key === "backspace") {
ButtonPressed("⌫");
} else if (/^[a-z]$/.test(key)) {
ButtonPressed(key.toUpperCase());
}
}
export let data = $state({
value: {
3: [],
4: [],
5: [],
6: [],
7: [],
8: [],
9: [],
10: [],
},
});
let WordleGamesData = localStorage.getItem("WordleGamesData") || "";
if (WordleGamesData != "") {
data.value = JSON.parse(WordleGamesData);
} else {
data.value = {
3: [],
4: [],
5: [],
6: [],
7: [],
8: [],
9: [],
10: [],
};
}