Add config menu, and supoprt for csv input file with word type

This commit is contained in:
Hugo 2022-08-13 22:57:37 +02:00
parent c46f8a809e
commit a5d25ada57
1 changed files with 95 additions and 33 deletions

View File

@ -1,4 +1,6 @@
#!/usr/bin/env python3
import re
import csv
from random import random, randint, choice
from datetime import timedelta
from kivy.app import App
@ -8,17 +10,18 @@ from kivy.uix.label import Label
from kivy.graphics import Color, Ellipse, Line, Rectangle
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.clock import Clock
from kivy.uix.popup import Popup
from kivy.uix.colorpicker import ColorPicker
from kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty, BooleanProperty
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
PASS_PENALTY = 4
DRAWING_TIME = 60
WORDS_FILE = "words.txt"
Builder.load_string('''
<ScrollableLabel>:
@ -35,6 +38,19 @@ class ScrollableLabel(ScrollView):
markup = BooleanProperty(False)
class NumberInput(TextInput):
def __init__(self, init_value, **kwargs):
self.init_value = init_value
kwargs["text"] = str(init_value)
super().__init__(**kwargs)
pat = r"^[0-9]+$"
def insert_text(self, substring, from_undo=False):
if not re.match(self.pat, substring):
s=''
else:
s = substring
super().insert_text(s, from_undo=from_undo)
class MyPaintWidget(Label):
_game_state = {"game_started": False,
@ -43,7 +59,7 @@ class MyPaintWidget(Label):
"word passed": timedelta(0),
"word found": timedelta(0)
}
_game_wordlists = {"possible_wordlist": set(),
_game_wordlists = {"possible_wordlist": dict(),
"found_words": set(),
"unfound_words": set()
}
@ -57,6 +73,26 @@ class MyPaintWidget(Label):
def __init__(self, text="", **kwargs):
super().__init__(**kwargs)
self._keyboard = None
self._get_keyboard()
self._load_words()
self.reset_game()
def _load_words(self):
if WORDS_FILE.endswith(".csv"):
# read a CSV file
with open(WORDS_FILE, "r", newline='') as wordfile:
my_reader = csv.reader(wordfile)
self._game_wordlists["possible_wordlist"] = {line[0]:
line[1] for line in my_reader}
else:
# read a plain text file
with open(WORDS_FILE, "r") as wordfile:
self._wordlist = (word.strip() for word in wordfile.readlines())
self._game_wordlists["possible_wordlist"] = dict.fromkeys(self._wordlist)
def _get_keyboard(self):
if self._keyboard is None:
self._keyboard = Window.request_keyboard(
self._keyboard_closed, self, 'text')
if self._keyboard.widget:
@ -64,10 +100,6 @@ class MyPaintWidget(Label):
# to change the keyboard layout.
pass
self._keyboard.bind(on_key_down=self._on_keyboard_down)
with open("words.txt", "r") as wordfile:
self._wordlist = (word.strip() for word in wordfile.readlines())
self._game_wordlists["possible_wordlist"] = set(self._wordlist)
self.reset_game()
def _keyboard_closed(self):
print('My keyboard has been closed!')
@ -81,6 +113,8 @@ class MyPaintWidget(Label):
if not self._game_state["game_started"]:
if keycode[0] == 32:
self.start_game()
elif keycode[1] == 'c':
self.open_config()
elif keycode[1] == 'p':
self.toggle_pause()
@ -129,26 +163,10 @@ class MyPaintWidget(Label):
self.message_label.text = f'"{self.current_word}" a été trouvé !'
self.current_word = choice(list(self._game_wordlists["possible_wordlist"]))
self._game_wordlists["possible_wordlist"].discard(self.current_word)
self.clear_drawing()
value = self._game_wordlists["possible_wordlist"].pop(self.current_word)
if value:
self.message_label.text += '\n'+f'Le prochain mot est de type: {value}'
def pass_word(self):
self._game_wordlists["unfound_words"].add(self.current_word)
self.next_word(True)
if self.time - timedelta(seconds=PASS_PENALTY) > timedelta(0):
self.time -= timedelta(seconds=PASS_PENALTY)
else:
self.time = timedelta(0)
@property
def is_game_playing(self):
return (self._game_state["game_started"]
and not self._game_state["game_paused"]
and not self._game_state["game_finished"])
self.current_word = choice(list(self._game_wordlists["possible_wordlist"]))
self._game_wordlists["possible_wordlist"].discard(self.current_word)
self.clear_drawing()
def pass_word(self):
@ -191,6 +209,48 @@ class MyPaintWidget(Label):
elif self.collide_point(touch.x, touch.ud['line'].points[-1]):
touch.ud['line'].points += [touch.x, touch.ud['line'].points[-1]]
def open_config(self):
layout = GridLayout()
layout.cols=2
layout.add_widget(Label(text="Chemin vers la liste de mots"))
layout.add_widget(TextInput(text=WORDS_FILE, multiline=False))
layout.add_widget(Label(text="Temps de dessin\n(secondes"))
layout.add_widget(NumberInput(DRAWING_TIME, multiline=False))
layout.add_widget(Label(text="Temps de pénalité\nquand on passe\n(secondes)"))
layout.add_widget(NumberInput(PASS_PENALTY, multiline=False))
conf_popup = Popup(title='Configuration', content=layout, size_hint=(0.5, 0.5))
conf_popup.bind(on_dismiss=self.apply_conf)
conf_popup.open()
def apply_conf(self, obj):
global DRAWING_TIME
global PASS_PENALTY
global WORDS_FILE
try:
drawing_time = int(obj.content.children[2].text)
if drawing_time > 0:
DRAWING_TIME = drawing_time
except ValueError:
Popup(title="Error", content=Label(text="Mauvaise valeur pour temps de dessin")).open()
try:
pass_penalty = int(obj.content.children[0].text)
if pass_penalty > 0 and pass_penalty < drawing_time:
PASS_PENALTY = pass_penalty
except ValueError:
Popup(title="Error", content=Label(text="Mauvaise valeur pour pénalité")).open()
self.reset_game()
if obj.content.children[4].text != WORDS_FILE:
old_file = WORDS_FILE
WORDS_FILE = obj.content.children[4].text
try:
self._load_words()
except OSError:
Popup(title="Error", content=Label(text=f"Erreur de lecture du fichier '{WORDS_FILE}'")).open()
WORDS_FILE = old_file
self._get_keyboard()
def recap(self):
found_words = self._game_wordlists['found_words']
unfound_words =self._game_wordlists['unfound_words']
@ -214,6 +274,8 @@ class MyPaintWidget(Label):
def reset_game(self):
if self._popup:
self._popup.dismiss()
if self.message_label:
self.message_label.text = ""
self.color = (0,0,0,1)
self.text = "Appuyer sur 'espace' pour commencer à jouer"
self.time = timedelta(seconds=DRAWING_TIME)
@ -284,7 +346,7 @@ class MyPaintApp(App):
self.word_label.bind(size=redraw)
self.time_label = Label(text=f"{self.painter.time}", color=[0,0,0,1])
message_label = Label(color=[0,0,0,1])
message_label = Label(color=[0,0,0,1], halign="center")
top_row.add_widget(self.word_label)
top_row.add_widget(message_label)
top_row.add_widget(self.time_label)