Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
107 changes: 67 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,84 @@
# OpenDevEd-Wordle
## Requirements:
Your task is to create a web-based Wordle game using React that adheres to the following specifications:
# SSWordle

### User Interface (UI):
**SSWordle** is a word-guessing game inspired by the original **Wordle**, built using TypeScript.

Design a clean and intuitive UI for the game that includes:
## Features

- Input field for guessing words.
- Submit button to submit the guess.
- Display area for previous guesses.
= Indication of correct letters in correct positions (right letter, right position).
- Indication of correct letters in the wrong position.
- Display remaining attempts.
- End game state UI (upon winning or losing).
### User Experience:

### State Management:
- Visual Cues to guide the new players through the game.
- Rewarding visuals for wining the game.
- Support for mobile devices.

Implement a robust state management system to handle:
### User Interface:

- Target word selection (randomly generate a word at the start of the game).
- Storing user guesses and their results.
- Tracking remaining attempts.
- Simple and convenient user interface allowing the user to interact with the game without any disturbance
- Virtual Keyboard that displays incorrect letters also prevents the user from tapping them again.
- Dark background with the legendary wordle logos spread throughout.
- Easy on the eyes and provides clear distinction between game elements and the background elements.
- Ability to restart the game without the need to refresh the page.

### User Interaction:
### Game:

- Capture user input for word guesses.
- Validate input (alphabetic characters, word length, etc.).
- Handle the submission of guesses and update the game state accordingly.
- Sound effects for any event that happens in the game, from tapping the keyboard to either winning or losing the game.
- Hints button providing single letter hints for users who require a bit of assistance in achieving a win.
- Clear definition of incorrect, correct and misplaced characters inside the grid.

## Game Approach

### Game Logic:
Since this is my first time working with react and using typescript i had a bit of a difficulty with it's features since i was accustomed to using **Vanilla js** to preform operations inside the components. Please be wary that this attempt may include some bugs with the correct guesses since i've implemented two different apis to handle dictionary checks and word generation, Thank you!

- Compare the user's guessed word against the target word.
- Provide feedback to the user about the correctness of the guessed word.
- End the game when the correct word is guessed or when the attempts reach zero.
- I've implemented a simple grid box consisting of 6 rows and 5 columns, alongside it i've created two states, one for the attempt string ``string`` that the user is currently typing on and one for the previous attempts ``strings``, this made it so i would access any box from within reach and change it's value also preventing the user from going back to the previous attempts.
- To generate the correct guess ``word`` i has to use a free api that provides common words which i concluded that it would be enough for this project, i had a slight issue with ``useEffect`` first as it was generating the word each time string updated which i then fixed using a simple state change that sets it self after the component updates (Thanks to Charrad).
- Checking for the correct match was done inside the function ``checkValidWord`` this made it so any attempt will be thoroughly inspected for correct guesses, word match or incorrect letters which will then be colored accordingly. If the words match then a ``winState`` event will trigger immediately else the player will try to submit the attempts until there's no more attempts which will then trigger a ``loseState`` event.
- For the correct guesses ``correctLetters`` i've created a simple **array of strings** that would hold each **correct letter** for it to be displayed later, whenever the attempt string ``string`` letters were in the correct order. The array of correct letter guesses **will hold that letter causing it to be displayed to the user**. I am aware that you can do it using one string but i went with this method as i was simply in the learning phase and did not want to cause further confusion during development.
- Sound implementation was made using the **Audio API** that the browser provides, i made a class that loads the audio when the user first visits the site, within it there's a function that plays sounds whenever an event triggers . In the game there's 3 main events:
- When the user triggers ``onKeyDown`` event, which plays a keystroke sound.
- **``WinState``** which plays a sound related to winning the game.
- **``LoseState``** which plays a sound related to losing the game.

## Code Quality:
## Technologies

- Write clean, readable, and maintainable code.
- Implement best practices for React development.
- Ensure error handling for edge cases (invalid input, unexpected behavior).
### Libraries:

## Submission Guidelines:
- React 18

- Fork this [repository](https://github.com/OpenDevEd/OpenDevEd-wordle/)) and create a new branch named `wordle-[YOUR NAME]`.
- Provide clear instructions on how to run the application locally.
- Include a README file explaining your approach, decisions made, and any additional features implemented.
- Open a PR.
### Packages:

## Evaluation Criteria:
- React Confetti Explotion 2.1.2
- React Icons 5.2.1
- React Intersetion Observer 9.13.0
- React Toastify: 10.0.5
- Framer Motion 11.3.24

- UI/UX design and functionality.
- Code quality, structure, and maintainability.
- State management and logic implementation.
- Handling of edge cases and error scenarios.
- Bonus points for additional features or optimizations.
### Development Environment:

- Vite 5.4.0

## Installation

1. Clone this repository

```bash
git clone -b wordle-sarah https://github.com/SilentSarah/OpenDevEd-Wordle.git
```
2. Enter the project directory

```bash
cd OpenDevEd-Wordle
```
3. Install the dependencies/packages

```bash
npm install
```
4. Build the app

```bash
npm run build
```
5. Start the production server:

```bash
npm run start
```
26 changes: 26 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'

export default tseslint.config({
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
ignores: ['dist'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
})
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/Logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SSarah's Wordle</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading