YAMLabyrinth skeleton v0.0.1

This commit is contained in:
2026-05-21 16:46:14 +03:00
commit aa9cb6ea53
14 changed files with 1650 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.gameplay/

1525
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

25
Cargo.toml Normal file
View File

@@ -0,0 +1,25 @@
[package]
name = "yamlabyrinth"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "go"
path = "src/bin/go.rs"
[lib]
name = "yamlabyrinth"
path = "src/lib.rs"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.9"
tera = "1"
similar = "2"
clap = { version = "4", features = ["derive"] }
rand = "0.8"
rand_chacha = "0.3"
dirs = "5"
anyhow = "1"
ratatui = "0.26"
crossterm = "0.27"

3
src/bin/go.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() -> anyhow::Result<()> {
yamlabyrinth::tui::run()
}

0
src/describe.rs Normal file
View File

7
src/levels/l01.md Normal file
View File

@@ -0,0 +1,7 @@
First level is to open the dungeon door - write a small valid YAML file.
Example game input: A small valid YAML file
Example player response:
---

5
src/levels/l02.md Normal file
View File

@@ -0,0 +1,5 @@
Second level is key-value pairs. The game generates few directions on the dungeon.
left: door
straight: door
right: tunnel

11
src/levels/l03.md Normal file
View File

@@ -0,0 +1,11 @@
Third level is dictionaries. Each direction now leads to a feature with its own properties.
left:
type: door
locked: true
right:
type: tunnel
depth: 10
straight:
type: wall
depth:

9
src/levels/l04.md Normal file
View File

@@ -0,0 +1,9 @@
Fourth level is lists. A chest of loot lies open before you.
chest:
- sword
- torch
- rope
- bread
Randomize the items in the list

0
src/levels/mod.rs Normal file
View File

5
src/lib.rs Normal file
View File

@@ -0,0 +1,5 @@
pub mod describe;
pub mod levels;
pub mod progress;
pub mod similarity;
pub mod tui;

0
src/progress.rs Normal file
View File

0
src/similarity.rs Normal file
View File

59
src/tui.rs Normal file
View File

@@ -0,0 +1,59 @@
use anyhow::Result;
use crossterm::event::{self, Event, KeyCode};
use crossterm::execute;
use crossterm::terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
};
use ratatui::backend::CrosstermBackend;
use ratatui::widgets::{Block, Borders, Paragraph};
use ratatui::Terminal;
use std::io::{stdout, Stdout};
pub fn run() -> Result<()> {
install_panic_hook();
let mut terminal = enter()?;
let result = main_loop(&mut terminal);
leave()?;
result
}
fn install_panic_hook() {
let prev = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
let _ = leave();
prev(info);
}));
}
fn enter() -> Result<Terminal<CrosstermBackend<Stdout>>> {
enable_raw_mode()?;
execute!(stdout(), EnterAlternateScreen)?;
Ok(Terminal::new(CrosstermBackend::new(stdout()))?)
}
fn leave() -> Result<()> {
disable_raw_mode()?;
execute!(stdout(), LeaveAlternateScreen)?;
Ok(())
}
fn main_loop(terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> Result<()> {
loop {
terminal.draw(|frame| {
let block = Block::default()
.borders(Borders::ALL)
.title(" YAMLabyrinth ");
let body = Paragraph::new(
"Welcome to the YAML labyrinth.\n\nPress [q] to flee.",
)
.block(block);
frame.render_widget(body, frame.size());
})?;
if let Event::Key(key) = event::read()? {
if key.code == KeyCode::Char('q') {
return Ok(());
}
}
}
}