commit 5294ae2bc94acabb62f7290ba1c96bb5f8002075 Author: Felix Pankratz Date: Thu May 9 14:28:15 2024 +0200 Initial commit - basic bingo field diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ceb386 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +venv diff --git a/bingo.py b/bingo.py new file mode 100644 index 0000000..1f4eec1 --- /dev/null +++ b/bingo.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 + +from textual.app import App, ComposeResult +from textual.widgets import Header, Footer, Button, Label, Switch, Static +from textual.containers import ScrollableContainer +from textual.message import Message +from textual.color import Color + +from asyncio import sleep + +class BingoField(Static): + """A Bingo field widget.""" + + cursor_x, cursor_y = 2 + + class Selected(Message): + """Send message to the board containing clicked field info""" + def __init__(self, num: int, selected: bool) -> None: + self.num = num + self.selected = selected + super().__init__() + + def __init__(self, num, text: str) -> None: + self.text = text + self.num = num + self.selected = False + super().__init__() + + def on_mount(self) -> None: + self.styles.content_align = ("center", "middle") + self.styles.border = ("solid", "green") + self.styles.height = '100%' + self.styles.width = '100%' + + def on_click(self) -> None: + self.selected = not self.selected + if self.selected: + self.styles.animate("background", 'green', duration=0.1) + self.styles.border = ("solid", "black") + else: + self.styles.animate("background", '#1c1c1c', duration=0.1) + self.styles.border = ("solid", "green") + + # The post_message method sends an event to be handled in the DOM + self.post_message(self.Selected(self.num, self.selected)) + + def render(self) -> str: + return str(self.text) + +class BingoApp(App): + """A Textual app to manage stopwatches.""" + CSS_PATH = "bingo.tcss" + + BINDINGS = [("d", "toggle_dark", "Toggle dark mode")] + + fieldstate = [False for _ in range(25)] + + fields = [ + 'Datenelch', + '6 Stunden Schlaf', + 'Tschunk getrunken', + 'Spaß gehabt', + 'Sticker getauscht', + 'DECT genutzt', + 'Hardware gehackt', + 'Kabel vergessen', + 'Halle gesucht', + '$dinge gelötet', + 'an SoS teilgenommen', + 'Neue Leute kennengelernt', + 'Wasser getrunken', + 'Waffel gegessen', + 'Corona Test gemacht', + '2 Mahlzeiten gegessen', + 'Fairydust bewundert', + 'Talk angeschaut', + 'CCC Merch getragen', + 'getrollt', + 'In der Lounge getanzt', + 'Etwas Neues ausprobiert', + 'Maske getragen', + 'geduscht', + 'Gulasch gegessen' + ] + + # todo: prng stuff + import random + random.shuffle(fields) + + def compose(self) -> ComposeResult: + """Create child widgets for the app.""" + yield Header() + + for _ in range(25): + yield BingoField(_, self.fields[_]) + + yield Footer() + + async def on_bingo_field_selected(self, message: BingoField.Selected) -> None: + self.fieldstate[message.num] = message.selected + if self.is_bingo(): + self.screen.styles.animate("background", 'red', duration=0.25) + await sleep(0.25) + self.screen.styles.animate("background", 'orange', duration=0.25) + await sleep(0.25) + self.screen.styles.animate("background", 'yellow', duration=0.25) + await sleep(0.25) + self.screen.styles.animate("background", 'green', duration=0.25) + await sleep(0.25) + self.screen.styles.animate("background", 'lightblue', duration=0.25) + await sleep(0.25) + self.screen.styles.animate("background", 'blue', duration=0.25) + await sleep(0.25) + self.screen.styles.animate("background", 'purple', duration=0.25) + await sleep(0.25) + self.screen.styles.animate("background", '#1c1c1c', duration=0.25) + + def is_bingo(self): + array = [ self.fieldstate[i:i+5] for i in range(0, len(self.fieldstate), 5)] + # check rows + bingo = any( [ all(row) for row in array ] ) + # check cols + bingo = bingo or any([ all(self.fieldstate[num::5]) for num in range(5)]) + # check bottom left to upper right + bingo = bingo or all([ + self.fieldstate[4], + self.fieldstate[8], + self.fieldstate[12], + self.fieldstate[16], + self.fieldstate[20] + ]) + # check top left to bottom right + bingo = bingo or all([ + self.fieldstate[0], + self.fieldstate[6], + self.fieldstate[12], + self.fieldstate[18], + self.fieldstate[24] + ]) + return bingo + + def action_toggle_dark(self) -> None: + """An action to toggle dark mode.""" + self.dark = not self.dark + +if __name__ == "__main__": + app = BingoApp() + app.run() diff --git a/bingo.tcss b/bingo.tcss new file mode 100644 index 0000000..1f8dd44 --- /dev/null +++ b/bingo.tcss @@ -0,0 +1,11 @@ +Screen { + layout: grid; + grid-size: 5 5; +} + +.box { + height: 100%; + border: solid green; + text-align: center; + content-align: center middle; +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a75a51d --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +textual