Added a database, and a /top command
This commit is contained in:
parent
0f5b65586a
commit
4b8e4f8f52
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
|||
.env
|
||||
**/__pycache__
|
||||
tags
|
||||
.ycm_extra_conf.py
|
||||
stats.db
|
||||
|
||||
|
|
490
bot.py
490
bot.py
|
@ -1,11 +1,20 @@
|
|||
# bot.py
|
||||
import os
|
||||
import datetime
|
||||
import time
|
||||
|
||||
import db
|
||||
|
||||
import sqlite3
|
||||
|
||||
import discord
|
||||
from game_logic import connections as con
|
||||
import re
|
||||
from collections import Counter
|
||||
from discord.ext import commands
|
||||
|
||||
import gamelogic as gamlog
|
||||
|
||||
import re
|
||||
|
||||
from collections import Counter
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
WORDLE_CHANNEL = 1317916234863480832
|
||||
|
@ -14,54 +23,94 @@ MISC_GEOGRAPHY = 1317916442342981722
|
|||
|
||||
GLOBLE_CHANNEL = 1320505660701413511
|
||||
|
||||
WHEN_WHERE_CHANNEL = 1320505906592612394
|
||||
|
||||
MISC_CHANNEL = 1317916469660618752
|
||||
|
||||
GENSHINDLE_CHANNEL = 1320505821112832010
|
||||
|
||||
CHANNELS = [
|
||||
WORDLE_CHANNEL,
|
||||
MISC_GEOGRAPHY,
|
||||
GLOBLE_CHANNEL,
|
||||
WHEN_WHERE_CHANNEL,
|
||||
MISC_CHANNEL,
|
||||
GENSHINDLE_CHANNEL
|
||||
]
|
||||
|
||||
possible_games = [
|
||||
"Wordle",
|
||||
"Connections",
|
||||
"Satle",
|
||||
"Globle",
|
||||
"Airport Guessr",
|
||||
"WhereTaken",
|
||||
"WhenTaken",
|
||||
"Flagle",
|
||||
"Genshindle",
|
||||
"Planespottle"
|
||||
]
|
||||
|
||||
chat_limit = 1000
|
||||
|
||||
load_dotenv()
|
||||
TOKEN = os.getenv('DISCORD_TOKEN')
|
||||
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
||||
bot = commands.Bot()
|
||||
bot = commands.Bot(intents=intents)
|
||||
|
||||
db.create_table();
|
||||
|
||||
@bot.slash_command(
|
||||
name="stats",
|
||||
description="Prints out your stats in a daily game, examples include wordle",
|
||||
guild_ids=[261345598987436033]
|
||||
)
|
||||
async def stats(interaction: discord.Interaction, game, user: discord.User = None):
|
||||
async def stats(
|
||||
interaction: discord.Interaction,
|
||||
game : discord.Option(
|
||||
str,
|
||||
choices=possible_games),
|
||||
user: discord.User = None
|
||||
):
|
||||
await interaction.response.defer()
|
||||
match game.lower():
|
||||
case "wordle":
|
||||
channel = bot.get_channel(WORDLE_CHANNEL)
|
||||
|
||||
if user is None:
|
||||
user = interaction.user
|
||||
|
||||
WORDLE_PATTERN = r"^Wordle (\d{1,3}(?:,\d{3})*) (X|\d+)/(\d+)"
|
||||
conn = sqlite3.connect("stats.db")
|
||||
cursor = conn.cursor()
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
if not game in possible_games:
|
||||
|
||||
async for message in channel.history(limit=1000): # Limit can be adjusted
|
||||
if message.author == user:
|
||||
for line in message.content.splitlines():
|
||||
match = re.match(WORDLE_PATTERN, line.strip())
|
||||
if match:
|
||||
total_games += 1
|
||||
guesses = match.group(2)
|
||||
if guesses != 'X':
|
||||
total_guesses += int(guesses)
|
||||
wins += 1
|
||||
break
|
||||
|
||||
|
||||
if total_games == 0:
|
||||
print("SQL Injection???")
|
||||
await interaction.followup.send(
|
||||
"No Wordle results found.",
|
||||
"Sorry, something fucky wucky happened",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
average_guesses = total_guesses / wins
|
||||
win_rate = (wins / total_games) * 100
|
||||
sql = 'SELECT * FROM ' + game.upper().replace(" ", "_") + ' WHERE NAME = ?'
|
||||
cursor.execute(sql, (user.id,))
|
||||
data = cursor.fetchone()
|
||||
conn.close()
|
||||
|
||||
if not data:
|
||||
await interaction.followup.send(
|
||||
"No %s results found." % (game),
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
match game.lower():
|
||||
case "wordle":
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
win_rate = data[3]
|
||||
total_guesses = data[4]
|
||||
average_guesses = data[5]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Wordle stats for {user.mention}:\n"
|
||||
|
@ -71,47 +120,13 @@ async def stats(interaction: discord.Interaction, game, user: discord.User = Non
|
|||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "connections":
|
||||
channel = bot.get_channel(WORDLE_CHANNEL)
|
||||
|
||||
if user is None:
|
||||
user = interaction.user
|
||||
|
||||
CONNECTIONS_PATTERN = r"^Connections\nPuzzle #(\d+)\n((?:[\u2B1B\u2B1C\u2B1D\u2B1E\u2B20]{4}\n?)+)$"
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
perfects = 0
|
||||
|
||||
async for message in channel.history(limit=1000): # Limit can be adjusted
|
||||
if message.author == user:
|
||||
|
||||
color_grid = con.extract_connections_grid( message.content)
|
||||
|
||||
if color_grid:
|
||||
|
||||
guesses = con.check_connections_win(color_grid)
|
||||
|
||||
total_games += 1
|
||||
|
||||
if guesses > 0:
|
||||
total_guesses += guesses
|
||||
wins += 1
|
||||
perfect_game = con.is_perfect_game(color_grid)
|
||||
if perfect_game:
|
||||
perfects += 1
|
||||
|
||||
|
||||
|
||||
if total_games == 0:
|
||||
await interaction.followup.send(
|
||||
"No Connections results found.",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
average_guesses = total_guesses / wins
|
||||
win_rate = (wins / total_games) * 100
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
perfects = data[3]
|
||||
win_rate = data[4]
|
||||
perfect_rate = data[5]
|
||||
total_guesses = data[6]
|
||||
average_guesses = data[7]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Connections stats for {user.mention}:\n"
|
||||
|
@ -123,40 +138,11 @@ async def stats(interaction: discord.Interaction, game, user: discord.User = Non
|
|||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "satle":
|
||||
channel = bot.get_channel(MISC_GEOGRAPHY)
|
||||
|
||||
if user is None:
|
||||
user = interaction.user
|
||||
|
||||
SATLE_PATTERN = r"🛰Satle #[0-9]+ (\d)/6"
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
|
||||
async for message in channel.history(limit=1000): # Limit can be adjusted
|
||||
if message.author == user:
|
||||
lines = message.content.splitlines()
|
||||
for line in lines:
|
||||
match = re.match(SATLE_PATTERN, line.strip())
|
||||
if match:
|
||||
total_games += 1
|
||||
guesses = match.group(1)
|
||||
if lines[lines.index(line)+1].__contains__("🟩"):
|
||||
total_guesses += int(guesses)
|
||||
wins += 1
|
||||
break
|
||||
|
||||
|
||||
if total_games == 0:
|
||||
await interaction.followup.send(
|
||||
"No Satle results found.",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
average_guesses = total_guesses / wins
|
||||
win_rate = (wins / total_games) * 100
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
win_rate = data[3]
|
||||
total_guesses = data[4]
|
||||
average_guesses = data[5]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Satle stats for {user.mention}:\n"
|
||||
|
@ -166,61 +152,9 @@ async def stats(interaction: discord.Interaction, game, user: discord.User = Non
|
|||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "globle":
|
||||
misc_channel = bot.get_channel(MISC_GEOGRAPHY)
|
||||
globle_channel = bot.get_channel(GLOBLE_CHANNEL)
|
||||
|
||||
if user is None:
|
||||
user = interaction.user
|
||||
|
||||
GLOBLE_PATTERN = r"I guessed today’s Globle in ([0-9]+) tries:"
|
||||
BAD_GLOBLE_PATTERN = r".* = ([0-9]+)"
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
|
||||
async for message in misc_channel.history(limit=1000): # Limit can be adjusted
|
||||
if message.author == user:
|
||||
lines = message.content.splitlines()
|
||||
for line in lines:
|
||||
match = re.match(GLOBLE_PATTERN, line.strip())
|
||||
if match:
|
||||
total_games += 1
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses)
|
||||
break
|
||||
match = re.match(BAD_GLOBLE_PATTERN, line.strip())
|
||||
if match:
|
||||
total_games += 1
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses)
|
||||
break
|
||||
|
||||
async for message in globle_channel.history(limit=1000): # Limit can be adjusted
|
||||
if message.author == user:
|
||||
lines = message.content.splitlines()
|
||||
for line in lines:
|
||||
match = re.match(GLOBLE_PATTERN, line.strip())
|
||||
if match:
|
||||
total_games += 1
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses)
|
||||
break
|
||||
match = re.match(BAD_GLOBLE_PATTERN, line.strip())
|
||||
if match:
|
||||
total_games += 1
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses)
|
||||
break
|
||||
|
||||
|
||||
if total_games == 0:
|
||||
await interaction.followup.send(
|
||||
"No Globle results found.",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
average_guesses = total_guesses / total_games
|
||||
total_games = data[1]
|
||||
total_guesses = data[2]
|
||||
average_guesses = data[3]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Globle stats for {user.mention}:\n"
|
||||
|
@ -228,15 +162,251 @@ async def stats(interaction: discord.Interaction, game, user: discord.User = Non
|
|||
f"Average Guesses per Game: {average_guesses:.2f}\n",
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "airport guessr":
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
win_rate = data[3]
|
||||
total_guesses = data[4]
|
||||
average_guesses = data[5]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Airport Guessr stats for {user.mention}:\n"
|
||||
f"Total Games Played: {total_games}\n"
|
||||
f"Average Guesses per Winning Game: {average_guesses:.2f}\n"
|
||||
f"Win Rate: {win_rate:.2f}%\n",
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "whentaken":
|
||||
total_games = data[1]
|
||||
total_distance = data[2]
|
||||
average_distance = data[3]
|
||||
total_points = data[4]
|
||||
average_points = data[5]
|
||||
total_years = data[6]
|
||||
average_years = data[7]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Where Taken stats for {user.mention}:\n"
|
||||
f"Total Games Played: {total_games}\n"
|
||||
f"Average Distance: {average_distance:.2f} km\n"
|
||||
f"Average Time Distance: {average_years:.2f} years\n"
|
||||
f"Average Score: {average_points:.2f}\n",
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "wheretaken":
|
||||
total_games = data[1]
|
||||
total_distance = data[2]
|
||||
average_distance = data[3]
|
||||
total_points = data[4]
|
||||
average_points = data[5]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Where Taken stats for {user.mention}:\n"
|
||||
f"Total Games Played: {total_games}\n"
|
||||
f"Average Distance: {average_distance:.2f} km\n"
|
||||
f"Average Score: {average_points:.2f}\n",
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "flagle":
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
win_rate = data[3]
|
||||
total_guesses = data[4]
|
||||
average_guesses = data[5]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Flagle stats for {user.mention}:\n"
|
||||
f"Total Games Played: {total_games}\n"
|
||||
f"Average Guesses per Winning Game: {average_guesses:.2f}\n"
|
||||
f"Win Rate: {win_rate:.2f}%\n",
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "genshindle":
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
win_rate = data[3]
|
||||
total_guesses = data[4]
|
||||
average_guesses = data[5]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Genshindle stats for {user.mention}:\n"
|
||||
f"Total Games Played: {total_games}\n"
|
||||
f"Average Guesses per Winning Game: {average_guesses:.2f}\n"
|
||||
f"Win Rate: {win_rate:.2f}%\n",
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
case "planespottle":
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
win_rate = data[3]
|
||||
total_guesses = data[4]
|
||||
average_guesses = data[5]
|
||||
|
||||
await interaction.followup.send(
|
||||
f"Planespottle stats for {user.mention}:\n"
|
||||
f"Total Games Played: {total_games}\n"
|
||||
f"Average Guesses per Winning Game: {average_guesses:.2f}\n"
|
||||
f"Win Rate: {win_rate:.2f}%\n",
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
|
||||
case _:
|
||||
await interaction.followup.send(
|
||||
"Not a game.",
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
table_dict = {
|
||||
"games" : "GAMES",
|
||||
"total wins" : "WINS",
|
||||
"win rate" : "WIN_RATE",
|
||||
"average guesses" : "GUESS_AVG",
|
||||
"perfects" : "PERFECTS",
|
||||
"perfect rate" : "PERFECT_RATE",
|
||||
"distance" : "DISTANCE_AVG",
|
||||
"score" : "POINTS_AVG",
|
||||
"time distance" : "YEARS_AVG"
|
||||
}
|
||||
|
||||
async def get_table_options(ctx : discord.AutocompleteContext):
|
||||
game = ctx.options['game']
|
||||
match game.lower():
|
||||
case "wordle":
|
||||
return ["games","total wins","win rate","average guesses"]
|
||||
case "connections":
|
||||
return ["games","total wins","win rate","average guesses","perfects","perfect_rate"]
|
||||
case "satle":
|
||||
return ["games","total wins","win rate","average guesses"]
|
||||
case "globle":
|
||||
return ["games","average guesses"]
|
||||
case "airport guessr":
|
||||
return ["games","total wins","win rate","average guesses"]
|
||||
case "whentaken":
|
||||
return ["games", "distance", "score", "time distance"]
|
||||
case "wheretaken":
|
||||
return ["games", "distance", "score"]
|
||||
case "flagle":
|
||||
return ["games","total wins","win rate","average guesses"]
|
||||
case "genshindle":
|
||||
return ["games","total wins","win rate","average guesses"]
|
||||
case "planespottle":
|
||||
return ["games","total wins","win rate","average guesses"]
|
||||
case _:
|
||||
return ["HOW DID YOU GET HERE? SCREW YOU FOR MESSING WITH MY PROGRAM"]
|
||||
|
||||
|
||||
@bot.slash_command(
|
||||
name="top",
|
||||
description="Prints out the top players of the given game.",
|
||||
guild_ids=[261345598987436033],
|
||||
)
|
||||
async def top(
|
||||
interaction: discord.Interaction,
|
||||
game : discord.Option(
|
||||
str,
|
||||
choices=possible_games),
|
||||
sort_by : discord.Option(str, autocomplete=discord.utils.basic_autocomplete(get_table_options)),
|
||||
count : discord.Option(int) = 3
|
||||
):
|
||||
await interaction.response.defer()
|
||||
|
||||
table_column = table_dict[sort_by]
|
||||
|
||||
conn = sqlite3.connect("stats.db")
|
||||
cursor = conn.cursor()
|
||||
|
||||
if not game in possible_games:
|
||||
|
||||
print("SQL Injection???")
|
||||
await interaction.followup.send(
|
||||
"Sorry, something fucky wucky happened",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
order = "DESC"
|
||||
if table_column in ["GUESS_AVG", "DISTANCE_AVG", "YEARS_AVG"]:
|
||||
order = "ASC"
|
||||
|
||||
sql = 'SELECT NAME,' + table_column + ' FROM ' + game.upper().replace(" ", "_") + ' ORDER BY ' + table_column + '=0, ' + table_column + " " + order
|
||||
cursor.execute(sql)
|
||||
data = cursor.fetchmany(count)
|
||||
conn.close()
|
||||
|
||||
if not data:
|
||||
await interaction.followup.send(
|
||||
"No %s results found." % (game),
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
return_message = "Top " + str(len(data)) + " Players for " + game + " by " + sort_by + "\n"
|
||||
|
||||
for i, stat in enumerate(data):
|
||||
modifier = ''
|
||||
match table_column:
|
||||
case "WIN_RATE" | "PERFECT_RATE":
|
||||
modifier = "%"
|
||||
case "DISTANCE_AVG":
|
||||
modifier = " km"
|
||||
case "YEARS_AVG":
|
||||
modifier = " years"
|
||||
case "GAMES":
|
||||
modifier = " games"
|
||||
case "GUESS_AVG":
|
||||
modifier = " guesses"
|
||||
|
||||
line = f"#{i+1} <@{stat[0]}> Stats: {stat[1]:.2f}{modifier}\n"
|
||||
|
||||
return_message += line
|
||||
|
||||
|
||||
await interaction.followup.send(
|
||||
return_message,
|
||||
ephemeral=False # Send message only to the user who called the command
|
||||
)
|
||||
|
||||
def process_message(message : discord.message, reverse : bool):
|
||||
channel = bot.get_channel(WORDLE_CHANNEL)
|
||||
|
||||
PATTERNS = {
|
||||
gamlog.wordle : r"Wordle (\d{1,3}(?:,\d{3})*) (X|\d+)/(\d+)",
|
||||
gamlog.connections : r"Connections\nPuzzle #",
|
||||
gamlog.satle : r"🛰Satle #[0-9]+ (\d)/6",
|
||||
gamlog.bad_globle: r"🌎 [a-zA-Z]{3} [0-9]+, [0-9]{4} 🌍",
|
||||
gamlog.globle : r"I guessed today’s Globle in ([0-9]+) tries:",
|
||||
gamlog.airport_guessr : r"I (got the|did not guess the) airport (in \d (guess|guesses) )?today:",
|
||||
gamlog.wheretaken : r"#WhereTaken #[0-9]+ \([0-9]{2}\.[0-9]{2}\.[0-9]{4}\)",
|
||||
gamlog.whentaken : r"#WhenTaken #[0-9]+ \([0-9]{2}\.[0-9]{2}\.[0-9]{4}\)",
|
||||
gamlog.flagle : r"#Flagle #[0-9]+ \(.*\) ./6",
|
||||
gamlog.genshindle : r"I (found|couldn't find) today's #Genshindle",
|
||||
gamlog.planespottle : r"Planespottle #[0-9]+ (failed to guess|in \d/5 guesses)!"
|
||||
}
|
||||
|
||||
|
||||
for game, pattern in PATTERNS.items():
|
||||
match = re.search(pattern, message.content.strip())
|
||||
if match:
|
||||
game(message, reverse)
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
|
||||
for channel in CHANNELS:
|
||||
channel = bot.get_channel(channel)
|
||||
async for message in channel.history(limit=chat_limit,oldest_first=True):
|
||||
process_message(message, False)
|
||||
|
||||
print('Ready!')
|
||||
|
||||
@bot.event
|
||||
async def on_message(message : discord.message):
|
||||
process_message(message, False)
|
||||
|
||||
@bot.event
|
||||
async def on_message_delete(message : discord.message):
|
||||
process_message(message, True)
|
||||
|
||||
bot.run(TOKEN)
|
||||
|
||||
|
|
124
db.py
Normal file
124
db.py
Normal file
|
@ -0,0 +1,124 @@
|
|||
import sqlite3
|
||||
import pathlib
|
||||
|
||||
|
||||
def create_table():
|
||||
cnt = None
|
||||
cursor = None
|
||||
|
||||
try:
|
||||
# please remove this later,
|
||||
# it just removes the database for testing
|
||||
pathlib.Path.unlink("./stats.db")
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
print('DB Init')
|
||||
query = 'select sqlite_version();'
|
||||
cursor.execute(query)
|
||||
|
||||
result = cursor.fetchall()
|
||||
print('SQLite Version is {}'.format(result))
|
||||
except sqlite3.Error as error:
|
||||
print('Error occurred - ', error)
|
||||
game_tables = [''' CREATE TABLE IF NOT EXISTS WORDLE(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
WINS INTEGER NOT NULL,
|
||||
WIN_RATE REAL NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS CONNECTIONS(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
WINS INTEGER NOT NULL,
|
||||
PERFECTS INTEGER NOT NULL,
|
||||
WIN_RATE REAL NOT NULL,
|
||||
PERFECT_RATE REAL NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS SATLE(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
WINS INTEGER NOT NULL,
|
||||
WIN_RATE REAL NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS GLOBLE(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS AIRPORT_GUESSR(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
WINS INTEGER NOT NULL,
|
||||
WIN_RATE REAL NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS WHERETAKEN(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
DISTANCE REAL NOT NULL,
|
||||
DISTANCE_AVG REAL NOT NULL,
|
||||
POINTS INTEGER NOT NULL,
|
||||
POINTS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS WHENTAKEN(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
DISTANCE REAL NOT NULL,
|
||||
DISTANCE_AVG REAL NOT NULL,
|
||||
POINTS INTEGER NOT NULL,
|
||||
POINTS_AVG REAL NOT NULL,
|
||||
YEARS INTEGER NOT NULL,
|
||||
YEARS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS FLAGLE(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
WINS INTEGER NOT NULL,
|
||||
WIN_RATE REAL NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS GENSHINDLE(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
WINS INTEGER NOT NULL,
|
||||
WIN_RATE REAL NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); ''',
|
||||
''' CREATE TABLE IF NOT EXISTS PLANESPOTTLE(
|
||||
NAME INTEGER PRIMARY KEY NOT NULL,
|
||||
GAMES INTEGER NOT NULL,
|
||||
WINS INTEGER NOT NULL,
|
||||
WIN_RATE REAL NOT NULL,
|
||||
GUESSES INTEGER NOT NULL,
|
||||
GUESS_AVG REAL NOT NULL,
|
||||
LAST_SYNC INTEGER NOT NULL
|
||||
); '''
|
||||
]
|
||||
|
||||
for table in game_tables:
|
||||
cursor.execute(table)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print("Tables Created")
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -1,50 +0,0 @@
|
|||
from collections import Counter
|
||||
|
||||
def extract_connections_grid(message):
|
||||
message_content = message.strip()
|
||||
if message_content.startswith("Connections") and "Puzzle #" in message_content:
|
||||
# Extract the puzzle number
|
||||
puzzle_number_start = message_content.find("Puzzle #") + len("Puzzle #")
|
||||
puzzle_number_end = message_content.find("\n", puzzle_number_start)
|
||||
puzzle_number = message_content[puzzle_number_start:puzzle_number_end].strip()
|
||||
|
||||
# Extract the grid (assume the grid starts after the first two lines)
|
||||
grid_start = message_content.find("\n", message_content.find("Puzzle #")) + 1
|
||||
grid_content = message_content[grid_start:].strip()
|
||||
|
||||
# Split the grid into lines
|
||||
color_grid = grid_content.split("\n")
|
||||
return color_grid
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def check_connections_win(color_grid):
|
||||
"""
|
||||
Check if the Connections game is a win and return the number of guesses.
|
||||
A win is when there are exactly 4 groups of 4 colors each.
|
||||
"""
|
||||
# Flatten the color grid into a list of colors
|
||||
uniform_rows = [row for row in color_grid if len(set(row)) == 1]
|
||||
|
||||
flattened_grid = ''.join(uniform_rows)
|
||||
|
||||
# Count the occurrences of each color in the grid
|
||||
color_counts = Counter(flattened_grid)
|
||||
|
||||
# Check if there are exactly 4 different colors with 4 squares each
|
||||
if len(color_counts) == 4 and all(count == 4 for count in color_counts.values()):
|
||||
# A win: return the number of guesses (lines in the grid)
|
||||
return len(color_grid)
|
||||
return 0 # Not a win
|
||||
|
||||
def is_perfect_game(color_grid):
|
||||
"""
|
||||
Check if the Connections game is a perfect game (solved in 4 guesses, no mistakes).
|
||||
"""
|
||||
# A perfect game is one where the first 4 lines form perfect groups
|
||||
if len(color_grid) == 4 and all(len(set(line)) == 1 for line in color_grid):
|
||||
return True # It's a perfect game
|
||||
return False
|
||||
|
13
gamelogic/__init__.py
Normal file
13
gamelogic/__init__.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from gamelogic import wheretaken
|
||||
from .wordle import wordle
|
||||
from .connections import connections
|
||||
from .satle import satle
|
||||
from .globle import globle
|
||||
from .globle import bad_globle
|
||||
from .airport_guessr import airport_guessr
|
||||
from .flagle import flagle
|
||||
from .genshindle import genshindle
|
||||
from .planespottle import planespottle
|
||||
from .wheretaken import wheretaken
|
||||
from .wheretaken import whentaken
|
||||
|
61
gamelogic/airport_guessr.py
Normal file
61
gamelogic/airport_guessr.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
|
||||
def airport_guessr(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
PATTERN = r"I got the airport in (\d) guess.*? today:"
|
||||
FAIL_PATTERN = r"I did not guess the airport today:"
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM AIRPORT_GUESSR WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
total_guesses = data[4]
|
||||
sync_time = data[6]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
match = re.search(FAIL_PATTERN, message.content.strip())
|
||||
if not match:
|
||||
match = re.search(PATTERN, message.content.strip())
|
||||
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses) * reverse
|
||||
wins += 1 * reverse
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
if wins != 0:
|
||||
average_guesses = total_guesses / wins
|
||||
else:
|
||||
average_guesses = 0
|
||||
|
||||
|
||||
win_rate = (wins / total_games) * 100
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO AIRPORT_GUESSR VALUES(?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,total_games,wins,win_rate,total_guesses,average_guesses,new_sync_time))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
126
gamelogic/connections.py
Normal file
126
gamelogic/connections.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
from collections import Counter
|
||||
|
||||
import discord
|
||||
import sqlite3
|
||||
import sys
|
||||
import time
|
||||
import re
|
||||
|
||||
def connections(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM CONNECTIONS WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
perfects = 0
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
perfects = data[3]
|
||||
total_guesses = data[6]
|
||||
sync_time = data[8]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
color_grid = extract_connections_grid( message.content)
|
||||
|
||||
if color_grid:
|
||||
|
||||
guesses = check_connections_win(color_grid)
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
if guesses > 0:
|
||||
total_guesses += guesses * reverse
|
||||
wins += 1 * reverse
|
||||
perfect_game = is_perfect_game(color_grid)
|
||||
if perfect_game:
|
||||
perfects += 1 * reverse
|
||||
else:
|
||||
print("Connections: Failed parsing color grid")
|
||||
print(message.content)
|
||||
return
|
||||
|
||||
|
||||
if wins != 0:
|
||||
average_guesses = total_guesses / wins
|
||||
else:
|
||||
average_guesses = 0
|
||||
win_rate = (wins / total_games) * 100
|
||||
perfect_rate = (perfects / total_games) * 100
|
||||
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO CONNECTIONS VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,
|
||||
total_games,
|
||||
wins,
|
||||
perfects,
|
||||
win_rate,
|
||||
perfect_rate,
|
||||
total_guesses,
|
||||
average_guesses,
|
||||
new_sync_time,
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def extract_connections_grid(message):
|
||||
message_content = message.strip()
|
||||
# Extract the puzzle number
|
||||
puzzle_number_start = message_content.find("Puzzle #") + len("Puzzle #")
|
||||
puzzle_number_end = message_content.find("\n", puzzle_number_start)
|
||||
puzzle_number = message_content[puzzle_number_start:puzzle_number_end].strip()
|
||||
|
||||
# Extract the grid (assume the grid starts after the first two lines)
|
||||
grid_start = message_content.find("\n", message_content.find("Puzzle #")) + 1
|
||||
grid_content = message_content[grid_start:].strip()
|
||||
|
||||
# Split the grid into lines
|
||||
color_grid = grid_content.split("\n")
|
||||
return color_grid
|
||||
|
||||
|
||||
|
||||
def check_connections_win(color_grid):
|
||||
"""
|
||||
Check if the Connections game is a win and return the number of guesses.
|
||||
A win is when there are exactly 4 groups of 4 colors each.
|
||||
"""
|
||||
# Flatten the color grid into a list of colors
|
||||
uniform_rows = [row for row in color_grid if len(set(row)) == 1]
|
||||
|
||||
flattened_grid = ''.join(uniform_rows)
|
||||
|
||||
# Count the occurrences of each color in the grid
|
||||
color_counts = Counter(flattened_grid)
|
||||
|
||||
# Check if there are exactly 4 different colors with 4 squares each
|
||||
if len(color_counts) == 4 and all(count == 4 for count in color_counts.values()):
|
||||
# A win: return the number of guesses (lines in the grid)
|
||||
return len(color_grid)
|
||||
return 0 # Not a win
|
||||
|
||||
def is_perfect_game(color_grid):
|
||||
"""
|
||||
Check if the Connections game is a perfect game (solved in 4 guesses, no mistakes).
|
||||
"""
|
||||
# A perfect game is one where the first 4 lines form perfect groups
|
||||
if len(color_grid) == 4 and all(len(set(line)) == 1 for line in color_grid):
|
||||
return True # It's a perfect game
|
||||
return False
|
||||
|
62
gamelogic/flagle.py
Normal file
62
gamelogic/flagle.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
|
||||
def flagle(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
PATTERN = r"#Flagle #[0-9]+ \(.*\) (.)/6"
|
||||
|
||||
|
||||
match = re.match(PATTERN, message.content.strip())
|
||||
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM FLAGLE WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
total_guesses = data[4]
|
||||
sync_time = data[6]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
guesses = match.group(1)
|
||||
if guesses != 'X':
|
||||
total_guesses += int(guesses) * reverse
|
||||
wins += 1 * reverse
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
if wins != 0:
|
||||
average_guesses = total_guesses / wins
|
||||
else:
|
||||
average_guesses = 0
|
||||
|
||||
|
||||
win_rate = (wins / total_games) * 100
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO FLAGLE VALUES(?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,total_games,wins,win_rate,total_guesses,average_guesses,new_sync_time))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
62
gamelogic/genshindle.py
Normal file
62
gamelogic/genshindle.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
|
||||
def genshindle(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
PATTERN = r"I found today's #Genshindle in (\d) tr.*?!"
|
||||
FAIL_PATTERN = r"I couldn't find today's #Genshindle"
|
||||
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM GENSHINDLE WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
total_guesses = data[4]
|
||||
sync_time = data[6]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
match = re.search(FAIL_PATTERN, message.content.strip())
|
||||
if not match:
|
||||
match = re.search(PATTERN, message.content.strip())
|
||||
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses) * reverse
|
||||
wins += 1 * reverse
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
if wins != 0:
|
||||
average_guesses = total_guesses / wins
|
||||
else:
|
||||
average_guesses = 0
|
||||
|
||||
|
||||
win_rate = (wins / total_games) * 100
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO GENSHINDLE VALUES(?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,total_games,wins,win_rate,total_guesses,average_guesses,new_sync_time))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
60
gamelogic/globle.py
Normal file
60
gamelogic/globle.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
|
||||
def globle(message : discord.message, reverse, bad = False):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
if bad:
|
||||
PATTERN = r".* = ([0-9]+)"
|
||||
else:
|
||||
PATTERN = r"I guessed today’s Globle in ([0-9]+) tries:"
|
||||
|
||||
match = re.search(PATTERN, message.content.strip())
|
||||
|
||||
if not match:
|
||||
print("AAAAA")
|
||||
print(message.content)
|
||||
return
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM GLOBLE WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
total_guesses = data[2]
|
||||
sync_time = data[4]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses) * reverse
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
average_guesses = total_guesses / total_games
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO GLOBLE VALUES(?, ?, ?, ?, ?)''',
|
||||
(message.author.id,total_games,total_guesses,average_guesses,new_sync_time))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def bad_globle(message : discord.message, reverse):
|
||||
globle(message, reverse, True)
|
62
gamelogic/planespottle.py
Normal file
62
gamelogic/planespottle.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
|
||||
def planespottle(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
PATTERN = r"Planespottle #[0-9]+ in (\d)/5"
|
||||
FAIL_PATTERN = r"Planespottle #[0-9]+ failed to guess!"
|
||||
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM PLANESPOTTLE WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
total_guesses = data[4]
|
||||
sync_time = data[6]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
match = re.search(FAIL_PATTERN, message.content.strip())
|
||||
if not match:
|
||||
match = re.search(PATTERN, message.content.strip())
|
||||
|
||||
guesses = match.group(1)
|
||||
total_guesses += int(guesses) * reverse
|
||||
wins += 1 * reverse
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
if wins != 0:
|
||||
average_guesses = total_guesses / wins
|
||||
else:
|
||||
average_guesses = 0
|
||||
|
||||
|
||||
win_rate = (wins / total_games) * 100
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO PLANESPOTTLE VALUES(?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,total_games,wins,win_rate,total_guesses,average_guesses,new_sync_time))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
61
gamelogic/satle.py
Normal file
61
gamelogic/satle.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
|
||||
def satle(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
PATTERN = r"🛰Satle #[0-9]+ (\d)/6"
|
||||
|
||||
match = re.match(PATTERN, message.content.strip())
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM SATLE WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
total_guesses = data[4]
|
||||
sync_time = data[6]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
lines = message.content.splitlines()
|
||||
match = re.match(PATTERN, lines[0].strip())
|
||||
guesses = match.group(1)
|
||||
if lines[1].__contains__("🟩"):
|
||||
wins += 1 * reverse
|
||||
total_guesses += int(guesses) * reverse
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
if wins != 0:
|
||||
average_guesses = total_guesses / wins
|
||||
else:
|
||||
average_guesses = 0
|
||||
|
||||
|
||||
win_rate = (wins / total_games) * 100
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO SATLE VALUES(?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,total_games,wins,win_rate,total_guesses,average_guesses,new_sync_time))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
177
gamelogic/wheretaken.py
Normal file
177
gamelogic/wheretaken.py
Normal file
|
@ -0,0 +1,177 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
def wheretaken(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
total_distance = 0
|
||||
total_points = 0
|
||||
total_games = 0
|
||||
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''SELECT * FROM WHERETAKEN WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
total_distance = data[2]
|
||||
total_points = data[4]
|
||||
sync_time = data[6]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
distances, points = parse_distances_and_points(message.content)
|
||||
avg_distance = calculate_average(distances)
|
||||
|
||||
total_distance += avg_distance * reverse
|
||||
total_points += sum(points) * reverse
|
||||
total_games += 1 * reverse
|
||||
|
||||
|
||||
average_distance = total_distance / total_games
|
||||
average_points = total_points / total_games
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO WHERETAKEN VALUES(?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,
|
||||
total_games,
|
||||
total_distance,
|
||||
average_distance,
|
||||
total_points,
|
||||
average_points,
|
||||
new_sync_time
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def whentaken(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
total_distance = 0
|
||||
total_points = 0
|
||||
total_games = 0
|
||||
total_years = 0
|
||||
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''SELECT * FROM WHENTAKEN WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
total_distance = data[2]
|
||||
total_points = data[4]
|
||||
total_years = data[6]
|
||||
sync_time = data[8]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
distances, points, years = parse_distances_points_years(message.content)
|
||||
avg_distance = calculate_average(distances)
|
||||
avg_years = calculate_average(years)
|
||||
|
||||
total_years += avg_years
|
||||
total_distance += avg_distance * reverse
|
||||
total_points += sum(points) * reverse
|
||||
total_games += 1 * reverse
|
||||
|
||||
|
||||
average_distance = total_distance / total_games
|
||||
average_points = total_points / total_games
|
||||
average_years = total_years / total_games
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO WHENTAKEN VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,
|
||||
total_games,
|
||||
total_distance,
|
||||
average_distance,
|
||||
total_points,
|
||||
average_points,
|
||||
total_years,
|
||||
average_years,
|
||||
new_sync_time
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def parse_distances_points_years(message):
|
||||
pattern = r'.{4}([0-9]*\.?[0-9]+)([A-Za-z]?) ([A-Za-z]+) - ..([0-9]+) yrs - .([0-9]+)/200'
|
||||
matches = re.findall(pattern, message)
|
||||
|
||||
converted_distances = []
|
||||
points = []
|
||||
years = []
|
||||
|
||||
for distance, thousands, unit, year, point in matches:
|
||||
# Convert distance to float
|
||||
distance = float(distance)
|
||||
|
||||
# Handle 'K' (thousands) notation
|
||||
if thousands:
|
||||
distance *= 1000 # Convert K to actual kilometers
|
||||
|
||||
# If the unit is meters, convert to kilometers
|
||||
if unit == 'm':
|
||||
distance /= 1000 # Convert meters to kilometers
|
||||
|
||||
# Store the distance and corresponding points
|
||||
converted_distances.append(distance)
|
||||
points.append(int(point))
|
||||
years.append(int(year))
|
||||
|
||||
return converted_distances, points, years
|
||||
|
||||
def parse_distances_and_points(message):
|
||||
# Find all the distances in the format of 'xxx km' or 'xxx m' and their corresponding points
|
||||
pattern = r'(\d+(\.\d+)?)\s*(km|m|K)\s*(km)?\s*[^a-zA-Z0-9]*\s*(\d+)\s*/\s*\d+'
|
||||
matches = re.findall(pattern, message)
|
||||
|
||||
converted_distances = []
|
||||
points = []
|
||||
|
||||
for distance, _, unit, _, point in matches:
|
||||
# Convert distance to float
|
||||
distance = float(distance)
|
||||
|
||||
# Handle 'K' (thousands) notation
|
||||
if unit == 'K':
|
||||
distance *= 1000 # Convert K to actual kilometers
|
||||
|
||||
# If the unit is meters, convert to kilometers
|
||||
elif unit == 'm':
|
||||
distance /= 1000 # Convert meters to kilometers
|
||||
|
||||
# Store the distance and corresponding points
|
||||
converted_distances.append(distance)
|
||||
points.append(int(point))
|
||||
|
||||
return converted_distances, points
|
||||
|
||||
def calculate_average(distances):
|
||||
# Calculate the average of the distances
|
||||
if distances:
|
||||
return sum(distances) / len(distances)
|
||||
return 0
|
61
gamelogic/wordle.py
Normal file
61
gamelogic/wordle.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import sys
|
||||
import time
|
||||
import discord
|
||||
import re
|
||||
|
||||
import sqlite3
|
||||
|
||||
|
||||
def wordle(message : discord.message, reverse):
|
||||
if reverse == True:
|
||||
reverse = -1
|
||||
else:
|
||||
reverse = 1
|
||||
|
||||
conn = sqlite3.connect('stats.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
PATTERN = r"^Wordle (\d{1,3}(?:,\d{3})*) (X|\d+)/(\d+)"
|
||||
|
||||
match = re.match(PATTERN, message.content.strip())
|
||||
|
||||
|
||||
total_guesses = 0
|
||||
total_games = 0
|
||||
wins = 0
|
||||
sync_time = 0
|
||||
new_sync_time = (int)(time.mktime(message.created_at.timetuple()))
|
||||
|
||||
cursor.execute('''SELECT * FROM WORDLE WHERE NAME = ?''', (message.author.id,))
|
||||
|
||||
data = cursor.fetchone()
|
||||
|
||||
|
||||
if data:
|
||||
total_games = data[1]
|
||||
wins = data[2]
|
||||
total_guesses = data[4]
|
||||
sync_time = data[6]
|
||||
if sync_time > new_sync_time and reverse == 1:
|
||||
return
|
||||
|
||||
guesses = match.group(2)
|
||||
if guesses != 'X':
|
||||
total_guesses += int(guesses) * reverse
|
||||
wins += 1 * reverse
|
||||
|
||||
total_games += 1 * reverse
|
||||
|
||||
if wins != 0:
|
||||
average_guesses = total_guesses / wins
|
||||
else:
|
||||
average_guesses = 0
|
||||
|
||||
|
||||
win_rate = (wins / total_games) * 100
|
||||
|
||||
cursor.execute('''INSERT OR REPLACE INTO WORDLE VALUES(?, ?, ?, ?, ?, ?, ?)''',
|
||||
(message.author.id,total_games,wins,win_rate,total_guesses,average_guesses,new_sync_time))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
Loading…
Reference in a new issue