Add config menu, and supoprt for csv input file with word type
This commit is contained in:
parent
c46f8a809e
commit
a5d25ada57
|
|
@ -1,4 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
import re
|
||||||
|
import csv
|
||||||
from random import random, randint, choice
|
from random import random, randint, choice
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from kivy.app import App
|
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.graphics import Color, Ellipse, Line, Rectangle
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
|
from kivy.uix.gridlayout import GridLayout
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.uix.popup import Popup
|
from kivy.uix.popup import Popup
|
||||||
from kivy.uix.colorpicker import ColorPicker
|
from kivy.uix.colorpicker import ColorPicker
|
||||||
from kivy.uix.scrollview import ScrollView
|
from kivy.uix.scrollview import ScrollView
|
||||||
from kivy.properties import StringProperty, BooleanProperty
|
from kivy.properties import StringProperty, BooleanProperty
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
|
from kivy.uix.textinput import TextInput
|
||||||
|
|
||||||
PASS_PENALTY = 4
|
PASS_PENALTY = 4
|
||||||
DRAWING_TIME = 60
|
DRAWING_TIME = 60
|
||||||
|
WORDS_FILE = "words.txt"
|
||||||
|
|
||||||
Builder.load_string('''
|
Builder.load_string('''
|
||||||
<ScrollableLabel>:
|
<ScrollableLabel>:
|
||||||
|
|
@ -35,6 +38,19 @@ class ScrollableLabel(ScrollView):
|
||||||
markup = BooleanProperty(False)
|
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):
|
class MyPaintWidget(Label):
|
||||||
_game_state = {"game_started": False,
|
_game_state = {"game_started": False,
|
||||||
|
|
@ -43,7 +59,7 @@ class MyPaintWidget(Label):
|
||||||
"word passed": timedelta(0),
|
"word passed": timedelta(0),
|
||||||
"word found": timedelta(0)
|
"word found": timedelta(0)
|
||||||
}
|
}
|
||||||
_game_wordlists = {"possible_wordlist": set(),
|
_game_wordlists = {"possible_wordlist": dict(),
|
||||||
"found_words": set(),
|
"found_words": set(),
|
||||||
"unfound_words": set()
|
"unfound_words": set()
|
||||||
}
|
}
|
||||||
|
|
@ -57,6 +73,26 @@ class MyPaintWidget(Label):
|
||||||
|
|
||||||
def __init__(self, text="", **kwargs):
|
def __init__(self, text="", **kwargs):
|
||||||
super().__init__(**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 = Window.request_keyboard(
|
||||||
self._keyboard_closed, self, 'text')
|
self._keyboard_closed, self, 'text')
|
||||||
if self._keyboard.widget:
|
if self._keyboard.widget:
|
||||||
|
|
@ -64,10 +100,6 @@ class MyPaintWidget(Label):
|
||||||
# to change the keyboard layout.
|
# to change the keyboard layout.
|
||||||
pass
|
pass
|
||||||
self._keyboard.bind(on_key_down=self._on_keyboard_down)
|
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):
|
def _keyboard_closed(self):
|
||||||
print('My keyboard has been closed!')
|
print('My keyboard has been closed!')
|
||||||
|
|
@ -81,6 +113,8 @@ class MyPaintWidget(Label):
|
||||||
if not self._game_state["game_started"]:
|
if not self._game_state["game_started"]:
|
||||||
if keycode[0] == 32:
|
if keycode[0] == 32:
|
||||||
self.start_game()
|
self.start_game()
|
||||||
|
elif keycode[1] == 'c':
|
||||||
|
self.open_config()
|
||||||
|
|
||||||
elif keycode[1] == 'p':
|
elif keycode[1] == 'p':
|
||||||
self.toggle_pause()
|
self.toggle_pause()
|
||||||
|
|
@ -129,26 +163,10 @@ class MyPaintWidget(Label):
|
||||||
self.message_label.text = f'"{self.current_word}" a été trouvé !'
|
self.message_label.text = f'"{self.current_word}" a été trouvé !'
|
||||||
|
|
||||||
self.current_word = choice(list(self._game_wordlists["possible_wordlist"]))
|
self.current_word = choice(list(self._game_wordlists["possible_wordlist"]))
|
||||||
self._game_wordlists["possible_wordlist"].discard(self.current_word)
|
value = self._game_wordlists["possible_wordlist"].pop(self.current_word)
|
||||||
self.clear_drawing()
|
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()
|
self.clear_drawing()
|
||||||
|
|
||||||
def pass_word(self):
|
def pass_word(self):
|
||||||
|
|
@ -191,6 +209,48 @@ class MyPaintWidget(Label):
|
||||||
elif self.collide_point(touch.x, touch.ud['line'].points[-1]):
|
elif self.collide_point(touch.x, touch.ud['line'].points[-1]):
|
||||||
touch.ud['line'].points += [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):
|
def recap(self):
|
||||||
found_words = self._game_wordlists['found_words']
|
found_words = self._game_wordlists['found_words']
|
||||||
unfound_words =self._game_wordlists['unfound_words']
|
unfound_words =self._game_wordlists['unfound_words']
|
||||||
|
|
@ -214,6 +274,8 @@ class MyPaintWidget(Label):
|
||||||
def reset_game(self):
|
def reset_game(self):
|
||||||
if self._popup:
|
if self._popup:
|
||||||
self._popup.dismiss()
|
self._popup.dismiss()
|
||||||
|
if self.message_label:
|
||||||
|
self.message_label.text = ""
|
||||||
self.color = (0,0,0,1)
|
self.color = (0,0,0,1)
|
||||||
self.text = "Appuyer sur 'espace' pour commencer à jouer"
|
self.text = "Appuyer sur 'espace' pour commencer à jouer"
|
||||||
self.time = timedelta(seconds=DRAWING_TIME)
|
self.time = timedelta(seconds=DRAWING_TIME)
|
||||||
|
|
@ -284,7 +346,7 @@ class MyPaintApp(App):
|
||||||
self.word_label.bind(size=redraw)
|
self.word_label.bind(size=redraw)
|
||||||
|
|
||||||
self.time_label = Label(text=f"{self.painter.time}", color=[0,0,0,1])
|
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(self.word_label)
|
||||||
top_row.add_widget(message_label)
|
top_row.add_widget(message_label)
|
||||||
top_row.add_widget(self.time_label)
|
top_row.add_widget(self.time_label)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue