Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added instructions to Game #5332

Merged
merged 2 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions src/textual/demo/demo_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class DemoApp(App):

CSS = """
.column {
align: center top;
&>*{ max-width: 100; }
align: center top;
&>*{ max-width: 100; }
}
Screen .-maximized {
margin: 1 2;
Expand All @@ -37,25 +37,25 @@ class DemoApp(App):
Binding(
"h",
"app.switch_mode('home')",
"home",
"Home",
tooltip="Show the home screen",
),
Binding(
"g",
"app.switch_mode('game')",
"game",
"Game",
tooltip="Unwind with a Textual game",
),
Binding(
"p",
"app.switch_mode('projects')",
"projects",
"Projects",
tooltip="A selection of Textual projects",
),
Binding(
"w",
"app.switch_mode('widgets')",
"widgets",
"Widgets",
tooltip="Test the builtin widgets",
),
Binding(
Expand Down Expand Up @@ -93,3 +93,13 @@ def action_maximize(self) -> None:
title="Maximize",
severity="warning",
)

def check_action(self, action: str, parameters: tuple[object, ...]) -> bool | None:
"""Disable switching to a mode we are already on."""
if (
action == "switch_mode"
and parameters
and self.current_mode == parameters[0]
):
return None
return True
55 changes: 48 additions & 7 deletions src/textual/demo/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from textual.reactive import reactive
from textual.screen import ModalScreen, Screen
from textual.timer import Timer
from textual.widgets import Button, Digits, Footer, Select, Static
from textual.widgets import Button, Digits, Footer, Markdown, Select, Static


@dataclass
Expand Down Expand Up @@ -447,13 +447,13 @@ def action_move(self, direction: str) -> None:
return
blank = self.get_tile(None).position
if direction == "up":
position = blank + (0, -1)
elif direction == "down":
position = blank + (0, +1)
elif direction == "down":
position = blank + (0, -1)
elif direction == "left":
position = blank + (-1, 0)
elif direction == "right":
position = blank + (+1, 0)
elif direction == "right":
position = blank + (-1, 0)
try:
tile = self.get_tile_at(position)
except IndexError:
Expand Down Expand Up @@ -503,15 +503,54 @@ def on_tile_clicked(self, event: events.Click) -> None:
self.move_tile(tile)


class GameInstructions(containers.VerticalGroup):
DEFAULT_CSS = """\
GameInstructions {
layer: instructions;
width: 60;
background: $panel;
border: thick $primary-darken-2;
Markdown {
background: $panel;
}
}
"""
INSTRUCTIONS = """\
# Instructions
This is an implementation of the *sliding tile puzzle*.
The board consists of a number of tiles and a blank space.
After shuffling, the goal is to restore the original "image" by moving a square either horizontally or vertically into the blank space.
This version is like the physical game, but rather than an image, you need to restore code.
"""

def compose(self) -> ComposeResult:
yield Markdown(self.INSTRUCTIONS)
with containers.Center():
yield Button("New Game", action="screen.new_game", variant="success")


class GameScreen(PageScreen):
"""The screen containing the game."""

DEFAULT_CSS = """
GameScreen{
align: center middle;
layers: instructions game;
}
"""

BINDINGS = [
("s", "shuffle", "Shuffle"),
("n", "new_game", "New Game"),
]

def compose(self) -> ComposeResult:
yield GameInstructions()
yield Game("\n" * 100, "", dimensions=(4, 4), tile_size=(16, 8))
yield Footer()

Expand All @@ -532,8 +571,10 @@ async def new_game(self, new_game: NewGame | None) -> None:
await game.recompose()
game.focus()

def on_mount(self) -> None:
self.action_new_game()
def check_action(self, action: str, parameters: tuple[object, ...]) -> bool | None:
if action == "shuffle" and self.query_one(Game).state == "waiting":
return None
return True


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion src/textual/demo/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class PageScreen(Screen):
Binding(
"c",
"show_code",
"show code",
"Show code",
tooltip="Show the code used to generate this screen",
)
]
Expand Down
Loading