initial commit
This commit is contained in:
commit
428d668537
8 changed files with 525 additions and 0 deletions
12
.editorconfig
Normal file
12
.editorconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
266
.gitignore
vendored
Normal file
266
.gitignore
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### macOS Patch ###
|
||||
# iCloud generated files
|
||||
*.icloud
|
||||
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
### Python Patch ###
|
||||
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
||||
poetry.toml
|
||||
|
||||
# ruff
|
||||
.ruff_cache/
|
||||
|
||||
# LSP config files
|
||||
pyrightconfig.json
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
16
tildagon-app/.vscode/launch.json
vendored
Normal file
16
tildagon-app/.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run simulator",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "/Users/jakew/Projects/badge-2024-software/sim/run.py",
|
||||
"console": "integratedTerminal",
|
||||
"python": "/Users/jakew/.local/share/virtualenvs/sim-Yv4Q9tV7/bin/python"
|
||||
}
|
||||
]
|
||||
}
|
8
tildagon-app/.vscode/settings.json
vendored
Normal file
8
tildagon-app/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"python.autoComplete.extraPaths": [
|
||||
"/Users/jakew/Projects/badge-2024-software/modules"
|
||||
],
|
||||
"python.analysis.extraPaths": [
|
||||
"/Users/jakew/Projects/badge-2024-software/modules"
|
||||
]
|
||||
}
|
24
tildagon-app/LICENSE
Normal file
24
tildagon-app/LICENSE
Normal file
|
@ -0,0 +1,24 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
3
tildagon-app/README.md
Normal file
3
tildagon-app/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
```bash
|
||||
mpremote mip install "github:peterhinch/micropython_ir/ir_rx"
|
||||
```
|
182
tildagon-app/app.py
Normal file
182
tildagon-app/app.py
Normal file
|
@ -0,0 +1,182 @@
|
|||
import time
|
||||
|
||||
from app_components import Menu, clear_background
|
||||
from app_components.tokens import button_labels
|
||||
from events.input import BUTTON_TYPES, Buttons
|
||||
from perf_timer import PerfTimer
|
||||
|
||||
import app
|
||||
|
||||
WHITE_COLOR = (255, 255, 255)
|
||||
BLACK_COLOR = (0, 0, 0)
|
||||
TEAM_A_COLOR = (255, 107, 107)
|
||||
TEAM_B_COLOR = (51, 154, 240)
|
||||
|
||||
BTN_LABEL_MODE = "Mode"
|
||||
BTN_LABEL_RESET = "Reset"
|
||||
BTN_LABEL_TEAM_A = "<-"
|
||||
BTN_LABEL_TEAM_B = "->"
|
||||
BTN_LABEL_SETTINGS = "..."
|
||||
|
||||
MENU_ITEM_SET_WIN_COND_11 = "Win pts = 11"
|
||||
MENU_ITEM_SET_WIN_COND_21 = "Win pts = 21"
|
||||
MENU_ITEM_QUIT = "Quit"
|
||||
|
||||
MODE_INCREMENT = "Increment"
|
||||
MODE_DECREMENT = "Decrement"
|
||||
|
||||
|
||||
class Scoreboard(app.App):
|
||||
win_points = 11
|
||||
a_score = 18
|
||||
b_score = 18
|
||||
mode = MODE_INCREMENT
|
||||
settings_menu = None
|
||||
winner = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.button_states = Buttons(self)
|
||||
|
||||
def select_handler(self, item, index):
|
||||
if item == MENU_ITEM_QUIT:
|
||||
self.back_handler()
|
||||
self.minimise()
|
||||
self.button_states.clear()
|
||||
elif item == MENU_ITEM_SET_WIN_COND_11:
|
||||
self.win_points = 11
|
||||
elif item == MENU_ITEM_SET_WIN_COND_21:
|
||||
self.win_points = 21
|
||||
|
||||
# close menu
|
||||
self.back_handler()
|
||||
|
||||
def back_handler(self):
|
||||
if self.settings_menu is not None:
|
||||
self.settings_menu._cleanup()
|
||||
|
||||
self.settings_menu = None
|
||||
self.button_states.clear()
|
||||
|
||||
async def run(self, render_update):
|
||||
last_time = time.ticks_ms()
|
||||
while True:
|
||||
cur_time = time.ticks_ms()
|
||||
delta_ticks = time.ticks_diff(cur_time, last_time)
|
||||
with PerfTimer(f"Updating {self}"):
|
||||
self.update(delta_ticks)
|
||||
await render_update()
|
||||
last_time = cur_time
|
||||
|
||||
def check_win_condition(self):
|
||||
diff = abs(self.a_score - self.b_score)
|
||||
|
||||
if (
|
||||
self.a_score >= self.win_points
|
||||
and self.a_score > self.b_score
|
||||
and diff >= 2
|
||||
):
|
||||
self.winner = "a"
|
||||
elif (
|
||||
self.b_score >= self.win_points
|
||||
and self.b_score > self.a_score
|
||||
and diff >= 2
|
||||
):
|
||||
self.winner = "b"
|
||||
else:
|
||||
self.winner = None
|
||||
|
||||
def update(self, delta):
|
||||
if self.settings_menu is not None:
|
||||
self.settings_menu.update(delta)
|
||||
return
|
||||
|
||||
if self.button_states.get(BUTTON_TYPES["UP"]):
|
||||
if self.mode == MODE_INCREMENT:
|
||||
self.mode = MODE_DECREMENT
|
||||
else:
|
||||
self.mode = MODE_INCREMENT
|
||||
self.button_states.clear()
|
||||
|
||||
if self.button_states.get(BUTTON_TYPES["DOWN"]):
|
||||
self.a_score = 0
|
||||
self.b_score = 0
|
||||
self.mode = MODE_INCREMENT
|
||||
self.winner = None
|
||||
self.button_states.clear()
|
||||
|
||||
if self.button_states.get(BUTTON_TYPES["LEFT"]):
|
||||
if self.mode == MODE_INCREMENT:
|
||||
self.a_score += 1
|
||||
elif self.mode == MODE_DECREMENT and self.a_score > 0:
|
||||
self.a_score -= 1
|
||||
|
||||
self.check_win_condition()
|
||||
self.button_states.clear()
|
||||
|
||||
if self.button_states.get(BUTTON_TYPES["RIGHT"]):
|
||||
if self.mode == MODE_INCREMENT:
|
||||
self.b_score += 1
|
||||
elif self.mode == MODE_DECREMENT and self.b_score > 0:
|
||||
self.b_score -= 1
|
||||
|
||||
self.check_win_condition()
|
||||
self.button_states.clear()
|
||||
|
||||
if self.button_states.get(BUTTON_TYPES["CONFIRM"]):
|
||||
self.settings_menu = Menu(
|
||||
self,
|
||||
menu_items=[
|
||||
MENU_ITEM_SET_WIN_COND_11,
|
||||
MENU_ITEM_SET_WIN_COND_21,
|
||||
MENU_ITEM_QUIT,
|
||||
],
|
||||
select_handler=self.select_handler,
|
||||
back_handler=self.back_handler,
|
||||
)
|
||||
self.button_states.clear()
|
||||
|
||||
def draw(self, ctx):
|
||||
clear_background(ctx)
|
||||
|
||||
if self.settings_menu is not None:
|
||||
self.settings_menu.draw(ctx)
|
||||
return
|
||||
|
||||
bg_color = BLACK_COLOR
|
||||
fg_color = WHITE_COLOR
|
||||
team_a_fg = TEAM_A_COLOR
|
||||
team_b_fg = TEAM_B_COLOR
|
||||
|
||||
if self.winner is not None:
|
||||
bg_color = TEAM_A_COLOR if self.winner == "a" else TEAM_B_COLOR
|
||||
fg_color = BLACK_COLOR
|
||||
team_a_fg = TEAM_A_COLOR if self.winner == "b" else fg_color
|
||||
team_b_fg = TEAM_B_COLOR if self.winner == "a" else fg_color
|
||||
|
||||
ctx.rgb(*bg_color).rectangle(-120, -120, 240, 240).fill()
|
||||
|
||||
button_labels(
|
||||
ctx,
|
||||
up_label=self.mode,
|
||||
down_label=BTN_LABEL_RESET,
|
||||
left_label=BTN_LABEL_TEAM_A,
|
||||
right_label=BTN_LABEL_TEAM_B,
|
||||
confirm_label=BTN_LABEL_SETTINGS,
|
||||
)
|
||||
|
||||
ctx.text_align = ctx.CENTER
|
||||
|
||||
ctx.font_size = 20
|
||||
ctx.font = "Arimo Bold"
|
||||
ctx.rgb(*fg_color).move_to(0, 60).text(f"w={self.win_points}")
|
||||
|
||||
ctx.font_size = 96
|
||||
ctx.font = "Arimo Bold"
|
||||
ctx.rgb(*team_a_fg).move_to(-50, 0).text(self.a_score)
|
||||
ctx.rgb(*team_b_fg).move_to(50, 0).text(self.b_score)
|
||||
|
||||
self.draw_overlays(ctx)
|
||||
|
||||
|
||||
__app_export__ = Scoreboard
|
14
tildagon-app/tildagon.toml
Normal file
14
tildagon-app/tildagon.toml
Normal file
|
@ -0,0 +1,14 @@
|
|||
[app]
|
||||
name = "Scoreboard"
|
||||
category = "Apps"
|
||||
wifi_preference = false
|
||||
|
||||
[entry]
|
||||
class = "Scoreboard"
|
||||
|
||||
[metadata]
|
||||
author = "jake-walker"
|
||||
license = "Unlicense"
|
||||
url = "https://github.com/jake-walker/tildagon-scoreboard"
|
||||
description = "A simple scoreboard"
|
||||
version = "0.0.1"
|
Loading…
Reference in a new issue