Skip to content

Commit

Permalink
feat: color highlighting is now accurate for duplicate characters. Cr…
Browse files Browse the repository at this point in the history
…eated a new database table for the word of the day. The api wasn't effective.
  • Loading branch information
JaredIsaacs committed Mar 11, 2024
1 parent b701090 commit e002d5f
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 47 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# WORDLE!

The ability to play Wordle with your friends in Discord!
Simply type in /wordle 'word' and the bot will display a board for you to play the game with!

![image](https://github.com/JaredIsaacs/worlde-bot/assets/45950689/99eb2724-4ed3-4a4f-ac34-a88c57697b26)


## Features

- Automatically construct the board behind the scenes.
- Checks with the [Wordle API](https://github.com/petergeorgas/Wordle-API) for correct answers.
- Can Play with multiple friends at once.

## Todo

- Implement a single player mode.
- Make the word generate after each successful playthrough.
- Keep track of player stats.
8 changes: 6 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ async def setup_hook(self) -> None:
@client.event
async def on_ready():
wordle_db.init_db()
print(wordle_db.get_word())
print(f'App running. Logged on as {client.user.id}!')


Expand All @@ -44,8 +45,9 @@ async def on_guild_join(guild: discord.guild.Guild):
@client.tree.command()
async def wordle(interaction: discord.Interaction, word: str):
guild_id = interaction.guild_id
secret_word = wordle_db.get_word()

if wordle_db.check_exists(guild_id):
if wordle_db.check_guild_exists(guild_id):
accuracy_board, letter_board = wordle_db.get_wordle_progress(guild_id)
board = wordleboard.WordleBoard(accuracy_board=accuracy_board, letter_board=letter_board)
else:
Expand All @@ -55,8 +57,9 @@ async def wordle(interaction: discord.Interaction, word: str):
await interaction.response.send_message(f'Sorry, {interaction.user.mention}. But the wordle of the day has already been completed.\nTo see the board, type /board.')
return


try:
board.process_word(word)
board.process_word(word, secret_word)

board_file = convert_to_image(board)
embed = create_embed(interaction)
Expand Down Expand Up @@ -101,5 +104,6 @@ def convert_to_image(board):
for line in open_file:
WORD_LIST.add(line.strip())


handler = logging.FileHandler(filename='logs/debug.log', encoding='utf-8', mode='w')
client.run(os.getenv('BOT_TOKEN'), log_handler=handler, log_level=logging.DEBUG)
2 changes: 0 additions & 2 deletions globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
2 : CORRECT_CHAR
}

WORDLE_URL = 'https://wordle-api.vercel.app/api/wordle'

DB_PATH = 'db/wordle.db'

WORD_LIST = set()
56 changes: 29 additions & 27 deletions wordleboard.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from globals import *
from PIL import Image, ImageDraw, ImageFont
from wordlerequest import get_wordle_info


class WordleBoard():
Expand Down Expand Up @@ -33,49 +32,52 @@ def __init__(self, accuracy_board: list = None, letter_board: list = None):
self.letter_board = letter_board


def process_word(self, word: str):
assert len(word) == 5, f'{word} is not 5 characters long!' #Check if word is correct length
assert word.lower() in WORD_LIST, f'{word} is not in the word list!' #Check if word is in the word list. Can maybe combine this with previous check.
def process_word(self, guess: str, word: str):
assert len(guess) == 5, f'{guess} is not 5 characters long!' #Check if guess is correct length
assert guess.lower() in WORD_LIST, f'{guess} is not in the guess list!' #Check if guess is in the guess list. Can maybe combine this with previous check.

self.correct_chars = 0
word = word.upper()
wordle_info = get_wordle_info(word)
guess = guess.upper()
unmatched = {}

letter_row = next(row for row in self.letter_board if None in row)
for i, char in enumerate(word):
for i, char in enumerate(guess):
letter_row[i] = char

accuracy_row = next(row for row in self.accuracy_board if None in row)
if wordle_info['was_correct']:
for i, char in enumerate(word):
for i in range(len(word)):
if word[i] == guess[i]:
accuracy_row[i] = 2
self.isWinner = True
else:
i = 0
accuracy = 0

while len(wordle_info['character_info']) != 0:
character_scoring = wordle_info['character_info'].pop(0)['scoring']

if character_scoring['in_word'] and character_scoring['correct_idx']:
accuracy = 2
self.correct_chars += 1
elif character_scoring['in_word'] and not character_scoring['correct_idx']:
accuracy = 1
self.correct_chars += 1
else:
unmatched[word[i]] = unmatched.get(word[i], 0) + 1

for i in range(len(guess)):
if guess[i] != word[i]:
if unmatched.get(guess[i], 0) > 0:
accuracy_row[i] = 1
unmatched[guess[i]] -= 1
else:
accuracy = 0
accuracy_row[i] = 0


if self.check_for_win(accuracy_row):
self.isWinner = True

accuracy_row[i] = accuracy
i += 1

if self.check_for_loss():
self.isWinner = False


def check_for_loss(self):
if None not in self.accuracy_board[5] and self.isWinner != True:
return True


def check_for_win(self, row):
for i in range(len(row)):
if row[i] != 2:
return False
return True



def create_wordle_square(self, char: str, x: int, y: int) -> Image:
Expand Down
47 changes: 41 additions & 6 deletions wordledb.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sqlite3, datetime, pickle
import sqlite3, datetime, pickle, random
from os import path, makedirs
from globals import *

Expand All @@ -19,10 +19,13 @@ def init_db(self) -> None:
self.cur.execute('''CREATE TABLE IF NOT EXISTS wordle
(date TEXT NOT NULL, guild_id INTEGER NOT NULL, completed TEXT,
won TEXT, accuracy_board BINARY NOT NULL, letter_board BINARY NOT NULL)''')

self.cur.execute('''CREATE TABLE IF NOT EXISTS wordle_word (date TEXT NOT NULL, word TEXT NOT NULL)''')

self.conn.commit()


def check_exists(self, guild_id: int) -> bool:
def check_guild_exists(self, guild_id: int) -> bool:
today = datetime.date.today()
guild = self.cur.execute('''SELECT * FROM wordle
WHERE guild_id = ? AND date = ?''', (guild_id, today))
Expand Down Expand Up @@ -63,7 +66,7 @@ def update_wordle_progress(self, guild_id: int, accuracy_board: list, letter_boa
p_accuracy = pickle.dumps(accuracy_board, protocol=pickle.HIGHEST_PROTOCOL)
p_letter = pickle.dumps(letter_board, protocol=pickle.HIGHEST_PROTOCOL)

if self.check_exists(guild_id):
if self.check_guild_exists(guild_id):
self.cur.execute('''UPDATE wordle
SET completed = ?, won = ?, accuracy_board = ?, letter_board = ?
WHERE guild_id = ? AND date = ?''', (completed, won, p_accuracy, p_letter, guild_id, today))
Expand All @@ -83,11 +86,43 @@ def get_wordle_progress(self, guild_id: int):
accuracy_board = pickle.loads(boards[0])
letter_board = pickle.loads(boards[1])

return accuracy_board, letter_board

return accuracy_board, letter_board


def update_word(self) -> str:
today = datetime.date.today()
word = random.choice(list(WORD_LIST))

self.cur.execute('''INSERT INTO wordle_word (date, word) values (?, ?)''', (today, word))
self.conn.commit()

return word


def check_word_exists(self):
today = datetime.date.today()

guild = self.cur.execute('''SELECT * FROM wordle_word
WHERE date = ?''', (today,))

if guild.fetchone():
return True
return False


def get_word(self) -> str:
today = datetime.date.today()

if self.check_word_exists():
word = self.cur.execute("SELECT word FROM wordle_word WHERE date = ?", (today,)).fetchone()[0]
else:
word = self.update_word()

return word.upper()


def get_all_wordles(self):
# For Debug purposes
self.cur.execute('SELECT date, guild_id, completed, won FROM wordle')
for e in self.cur:
print(e)
print(e)
9 changes: 0 additions & 9 deletions wordlerequest.py

This file was deleted.

0 comments on commit e002d5f

Please sign in to comment.