group levels into chapters
This commit is contained in:
parent
ff69b967dd
commit
42dfe4fac7
22 changed files with 236 additions and 210 deletions
7
build.rs
7
build.rs
|
@ -1,6 +1,9 @@
|
||||||
use std::{fs::File, io::Write};
|
use std::{fs::File, io::Write};
|
||||||
|
|
||||||
fn main(){
|
fn main() {
|
||||||
let version = concat!("v", env!("CARGO_PKG_VERSION"));
|
let version = concat!("v", env!("CARGO_PKG_VERSION"));
|
||||||
File::create("version.txt").unwrap().write_all(version.as_bytes()).unwrap();
|
File::create("version.txt")
|
||||||
|
.unwrap()
|
||||||
|
.write_all(version.as_bytes())
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"id": "output",
|
|
||||||
"sort_order": 11,
|
|
||||||
"name": "Zero",
|
|
||||||
"description": "learn how to output data",
|
|
||||||
"init_board": "\n o \n\n I\n\n",
|
|
||||||
"stages": [{
|
|
||||||
"input": [],
|
|
||||||
"output": [0]
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"id": "digits",
|
|
||||||
"sort_order": 12,
|
|
||||||
"name": "Digits",
|
|
||||||
"description": "place digits and use number keys to assign them values",
|
|
||||||
"stages": [{
|
|
||||||
"input": [],
|
|
||||||
"output": [4, 8, 16]
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"id": "loop",
|
|
||||||
"sort_order": 13,
|
|
||||||
"name": "Loop",
|
|
||||||
"description": "repeated output",
|
|
||||||
"init_board": "\n \n o\n\n\n\n ^ \n\n",
|
|
||||||
"stages": [{
|
|
||||||
"input": [],
|
|
||||||
"output": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"id": "copy_input",
|
|
||||||
"sort_order": 14,
|
|
||||||
"name": "Copy Cat",
|
|
||||||
"description": "read input and output the same thing",
|
|
||||||
"stages": [{
|
|
||||||
"input": "Hello, world!",
|
|
||||||
"output": "Hello, world!"
|
|
||||||
},{
|
|
||||||
"input": "Meow!",
|
|
||||||
"output": "Meow!"
|
|
||||||
},{
|
|
||||||
"input": "there really isn't much point to more than 2 stages, but here we are",
|
|
||||||
"output": "there really isn't much point to more than 2 stages, but here we are"
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "copy_odd",
|
|
||||||
"sort_order": 15,
|
|
||||||
"name": "Odd Cat",
|
|
||||||
"description": "copy only the odd numbers from the input",
|
|
||||||
"stages": [{
|
|
||||||
"input": [1, 2, 3, 4, 5, 6, 7],
|
|
||||||
"output": [1, 3, 5, 7]
|
|
||||||
},{
|
|
||||||
"input": [112, 92, 51, 79, 112, 96, 84, 59, 195, 208, 137, 196, 68, 204, 82, 148, 251, 56, 105, 38, 63, 204, 240, 220, 180, 54, 211, 17, 82, 17, 181, 43],
|
|
||||||
"output": [51, 79, 59, 195, 137, 251, 105, 63, 211, 17, 17, 181, 43]
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "count_fives",
|
|
||||||
"sort_order": 23,
|
|
||||||
"name": "Fives",
|
|
||||||
"description": "count how many fives are in the input",
|
|
||||||
"stages": [{
|
|
||||||
"input": [6, 5, 5, 3, 5, 0],
|
|
||||||
"output": [3]
|
|
||||||
},{
|
|
||||||
"input": [182, 236, 71, 5, 5, 242, 29, 99, 19, 230, 217, 5, 67, 5, 223, 224, 70, 243, 3, 74, 242, 5, 171, 31, 96, 5, 169, 70, 5, 163, 72, 5, 172, 148, 5, 208, 28, 220, 17, 184, 172, 238, 5, 105, 119, 5, 106, 100, 73, 53, 42, 221, 155, 5, 74, 100, 161, 36, 16, 239, 193, 164, 64, 162, 222, 155, 107, 14, 45, 52, 159, 31, 199, 124, 129, 0],
|
|
||||||
"output": [12]
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "list_length",
|
|
||||||
"sort_order": 22,
|
|
||||||
"name": "Length",
|
|
||||||
"description": "count how many numbers are in the input, until the first zero",
|
|
||||||
"stages": [{
|
|
||||||
"input": [1, 87, 9, 0],
|
|
||||||
"output": [3]
|
|
||||||
},{
|
|
||||||
"input": [182, 236, 71, 5, 5, 242, 29, 99, 19, 230, 217, 5, 67, 5, 223, 224, 70, 243, 3, 74, 242, 5, 171, 31, 96, 5, 169, 70, 5, 163, 72, 5, 172, 148, 5, 208, 28, 220, 17, 184, 172, 0],
|
|
||||||
"output": [41]
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "null_separation",
|
|
||||||
"sort_order": 21,
|
|
||||||
"name": "Null Separation",
|
|
||||||
"description": "output everything after the first zero in the input data",
|
|
||||||
"stages": [{
|
|
||||||
"input": "9834726\u0000Hello, worlg!",
|
|
||||||
"output": "Hello, worlg!"
|
|
||||||
},{
|
|
||||||
"input": "aonmbgoirf\u0000this is just to make sure you don't hardcode the output for a better score",
|
|
||||||
"output": "this is just to make sure you don't hardcode the output for a better score"
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "reverse_input",
|
|
||||||
"sort_order": 24,
|
|
||||||
"name": "Reverse",
|
|
||||||
"description": "read input until zero and output the same thing in reverse",
|
|
||||||
"stages": [{
|
|
||||||
"input": "woem\u0000",
|
|
||||||
"output": "meow"
|
|
||||||
},{
|
|
||||||
"input": "tnropmi yrev\u0000",
|
|
||||||
"output": "very impornt"
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "ascii_to_lower",
|
|
||||||
"sort_order": 35,
|
|
||||||
"name": "Lowercase",
|
|
||||||
"description": "Convert text to lowercase",
|
|
||||||
"stages": [{
|
|
||||||
"input": "FROM THE MOMENT I UNDERSTOOD THE WEAKNESS OF MY FLESH, IT DISGUSTED ME",
|
|
||||||
"output": "from the moment i understood the weakness of my flesh, it disgusted me"
|
|
||||||
},{
|
|
||||||
"input": "I CraVeD tHE strEnGTH AND CerTAinTy oF STeeL",
|
|
||||||
"output": "i craved the strength and certainty of steel"
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "output_decimal",
|
|
||||||
"sort_order": 31,
|
|
||||||
"name": "Numbers",
|
|
||||||
"description": "Convert input numbers to text, separated by spaces (32)\n'0' = 48, '1' = 49, '2' = 50, and so on",
|
|
||||||
"stages": [{
|
|
||||||
"input": [8, 7, 1],
|
|
||||||
"output": "8 7 1"
|
|
||||||
},{
|
|
||||||
"input": [85, 114, 32, 103, 97, 121, 58, 51],
|
|
||||||
"output": "85 114 32 103 97 121 58 51"
|
|
||||||
}]
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"id": "parse_decimal",
|
|
||||||
"sort_order": 33,
|
|
||||||
"name": "Numbers 2",
|
|
||||||
"description": "Convert input numbers from text, separated by spaces (32)\n'0' = 48, '1' = 49, '2' = 50, and so on",
|
|
||||||
"stages": [{
|
|
||||||
"input": "1 2 3",
|
|
||||||
"output": [1, 2, 3]
|
|
||||||
},{
|
|
||||||
"input": "85 114 32 103 97 121 58 51",
|
|
||||||
"output": [85, 114, 32, 103, 97, 121, 58, 51]
|
|
||||||
}]
|
|
||||||
}
|
|
62
levels/chapter_01.json
Normal file
62
levels/chapter_01.json
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{
|
||||||
|
"title": "1. Introduction",
|
||||||
|
"levels": [
|
||||||
|
{
|
||||||
|
"id": "output",
|
||||||
|
"name": "Zero",
|
||||||
|
"description": "learn how to output data",
|
||||||
|
"init_board": "\n o \n\n I\n\n",
|
||||||
|
"stages": [{
|
||||||
|
"input": [],
|
||||||
|
"output": [0]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "digits",
|
||||||
|
"name": "Digits",
|
||||||
|
"description": "place digits and use number keys to assign them values",
|
||||||
|
"stages": [{
|
||||||
|
"input": [],
|
||||||
|
"output": [4, 8, 16]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "loop",
|
||||||
|
"name": "Loop",
|
||||||
|
"description": "repeated output",
|
||||||
|
"init_board": "\n \n o\n\n\n\n ^ \n\n",
|
||||||
|
"stages": [{
|
||||||
|
"input": [],
|
||||||
|
"output": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "copy_input",
|
||||||
|
"name": "Copy Cat",
|
||||||
|
"description": "read input and output the same thing",
|
||||||
|
"stages": [{
|
||||||
|
"input": "Hello, world!",
|
||||||
|
"output": "Hello, world!"
|
||||||
|
},{
|
||||||
|
"input": "Meow!",
|
||||||
|
"output": "Meow!"
|
||||||
|
},{
|
||||||
|
"input": "there really isn't much point to more than 2 stages, but here we are",
|
||||||
|
"output": "there really isn't much point to more than 2 stages, but here we are"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "copy_odd",
|
||||||
|
"sort_order": 15,
|
||||||
|
"name": "Odd Cat",
|
||||||
|
"description": "copy only the odd numbers from the input",
|
||||||
|
"stages": [{
|
||||||
|
"input": [1, 2, 3, 4, 5, 6, 7],
|
||||||
|
"output": [1, 3, 5, 7]
|
||||||
|
},{
|
||||||
|
"input": [112, 92, 51, 79, 112, 96, 84, 59, 195, 208, 137, 196, 68, 204, 82, 148, 251, 56, 105, 38, 63, 204, 240, 220, 180, 54, 211, 17, 82, 17, 181, 43],
|
||||||
|
"output": [51, 79, 59, 195, 137, 251, 105, 63, 211, 17, 17, 181, 43]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
53
levels/chapter_02.json
Normal file
53
levels/chapter_02.json
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"title": "2. List machines",
|
||||||
|
"levels": [
|
||||||
|
{
|
||||||
|
"id": "null_separation",
|
||||||
|
"name": "Null Separation",
|
||||||
|
"description": "output everything after the first zero in the input data",
|
||||||
|
"stages": [{
|
||||||
|
"input": "9834726\u0000Hello, worlg!",
|
||||||
|
"output": "Hello, worlg!"
|
||||||
|
},{
|
||||||
|
"input": "aonmbgoirf\u0000this is just to make sure you don't hardcode the output for a better score",
|
||||||
|
"output": "this is just to make sure you don't hardcode the output for a better score"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "count_fives",
|
||||||
|
"name": "Fives",
|
||||||
|
"description": "count how many fives are in the input",
|
||||||
|
"stages": [{
|
||||||
|
"input": [6, 5, 5, 3, 5, 0],
|
||||||
|
"output": [3]
|
||||||
|
},{
|
||||||
|
"input": [182, 236, 71, 5, 5, 242, 29, 99, 19, 230, 217, 5, 67, 5, 223, 224, 70, 243, 3, 74, 242, 5, 171, 31, 96, 5, 169, 70, 5, 163, 72, 5, 172, 148, 5, 208, 28, 220, 17, 184, 172, 238, 5, 105, 119, 5, 106, 100, 73, 53, 42, 221, 155, 5, 74, 100, 161, 36, 16, 239, 193, 164, 64, 162, 222, 155, 107, 14, 45, 52, 159, 31, 199, 124, 129, 0],
|
||||||
|
"output": [12]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "list_length",
|
||||||
|
"name": "Length",
|
||||||
|
"description": "count how many numbers are in the input, until the first zero",
|
||||||
|
"stages": [{
|
||||||
|
"input": [1, 87, 9, 0],
|
||||||
|
"output": [3]
|
||||||
|
},{
|
||||||
|
"input": [182, 236, 71, 5, 5, 242, 29, 99, 19, 230, 217, 5, 67, 5, 223, 224, 70, 243, 3, 74, 242, 5, 171, 31, 96, 5, 169, 70, 5, 163, 72, 5, 172, 148, 5, 208, 28, 220, 17, 184, 172, 0],
|
||||||
|
"output": [41]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "reverse_input",
|
||||||
|
"name": "Reverse",
|
||||||
|
"description": "read input until zero and output the same thing in reverse",
|
||||||
|
"stages": [{
|
||||||
|
"input": "woem\u0000",
|
||||||
|
"output": "meow"
|
||||||
|
},{
|
||||||
|
"input": "tnropmi yrev\u0000",
|
||||||
|
"output": "very impornt"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
41
levels/chapter_03.json
Normal file
41
levels/chapter_03.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"title": "3. Text processing",
|
||||||
|
"levels": [
|
||||||
|
{
|
||||||
|
"id": "ascii_to_lower",
|
||||||
|
"name": "Lowercase",
|
||||||
|
"description": "Convert text to lowercase",
|
||||||
|
"stages": [{
|
||||||
|
"input": "FROM THE MOMENT I UNDERSTOOD THE WEAKNESS OF MY FLESH, IT DISGUSTED ME",
|
||||||
|
"output": "from the moment i understood the weakness of my flesh, it disgusted me"
|
||||||
|
},{
|
||||||
|
"input": "I CraVeD tHE strEnGTH AND CerTAinTy oF STeeL",
|
||||||
|
"output": "i craved the strength and certainty of steel"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "output_decimal",
|
||||||
|
"name": "Numbers",
|
||||||
|
"description": "Convert input numbers to text, separated by spaces (32)\n'0' = 48, '1' = 49, '2' = 50, and so on",
|
||||||
|
"stages": [{
|
||||||
|
"input": [8, 7, 1],
|
||||||
|
"output": "8 7 1"
|
||||||
|
},{
|
||||||
|
"input": [85, 114, 32, 103, 97, 121, 58, 51],
|
||||||
|
"output": "85 114 32 103 97 121 58 51"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "parse_decimal",
|
||||||
|
"name": "Numbers 2",
|
||||||
|
"description": "Convert input numbers from text, separated by spaces (32)\n'0' = 48, '1' = 49, '2' = 50, and so on",
|
||||||
|
"stages": [{
|
||||||
|
"input": "1 2 3",
|
||||||
|
"output": [1, 2, 3]
|
||||||
|
},{
|
||||||
|
"input": "85 114 32 103 97 121 58 51",
|
||||||
|
"output": [85, 114, 32, 103, 97, 121, 58, 51]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
{
|
{
|
||||||
|
"title": "Sandbox",
|
||||||
|
"levels": [
|
||||||
|
{
|
||||||
"id": "sandbox",
|
"id": "sandbox",
|
||||||
"sort_order": 100000,
|
|
||||||
"name": "Sandbox",
|
"name": "Sandbox",
|
||||||
"description": "make whatever you want here"
|
"description": "make whatever you want here"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -281,7 +281,6 @@ impl Editor {
|
||||||
match self.sim_state {
|
match self.sim_state {
|
||||||
SimState::Editing => {
|
SimState::Editing => {
|
||||||
self.init_sim();
|
self.init_sim();
|
||||||
// self.step();
|
|
||||||
}
|
}
|
||||||
SimState::Running => (),
|
SimState::Running => (),
|
||||||
SimState::Stepping => self.step(),
|
SimState::Stepping => self.step(),
|
||||||
|
|
11
src/level.rs
11
src/level.rs
|
@ -1,9 +1,14 @@
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Chapter {
|
||||||
|
pub title: String,
|
||||||
|
pub levels: Vec<Level>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct Level {
|
pub struct Level {
|
||||||
id: String,
|
id: String,
|
||||||
sort_order: i32,
|
|
||||||
name: String,
|
name: String,
|
||||||
description: String,
|
description: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -44,10 +49,6 @@ impl Level {
|
||||||
&self.id
|
&self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sort_order(&self) -> i32 {
|
|
||||||
self.sort_order
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -11,11 +11,11 @@ mod level;
|
||||||
mod marble_engine;
|
mod marble_engine;
|
||||||
mod solution;
|
mod solution;
|
||||||
mod theme;
|
mod theme;
|
||||||
mod util;
|
|
||||||
mod ui;
|
mod ui;
|
||||||
|
mod util;
|
||||||
|
|
||||||
use editor::{Editor, ExitState};
|
use editor::{Editor, ExitState};
|
||||||
use level::Level;
|
use level::{Chapter, Level};
|
||||||
use solution::Solution;
|
use solution::Solution;
|
||||||
use theme::*;
|
use theme::*;
|
||||||
use ui::{simple_button, simple_option_button, text_input, ShapedText};
|
use ui::{simple_button, simple_option_button, text_input, ShapedText};
|
||||||
|
@ -26,7 +26,7 @@ const TITLE_TEXT: &str = concat!("Marble Machinations v", env!("CARGO_PKG_VERSIO
|
||||||
pub const TILE_TEXTURE_SIZE: f32 = 16.0;
|
pub const TILE_TEXTURE_SIZE: f32 = 16.0;
|
||||||
|
|
||||||
struct Game {
|
struct Game {
|
||||||
levels: Vec<Level>,
|
levels: Vec<LevelListEntry>,
|
||||||
level_scroll: usize,
|
level_scroll: usize,
|
||||||
solutions: HashMap<String, Vec<Solution>>,
|
solutions: HashMap<String, Vec<Solution>>,
|
||||||
open_editor: Option<Editor>,
|
open_editor: Option<Editor>,
|
||||||
|
@ -37,6 +37,12 @@ struct Game {
|
||||||
level_desc_text: ShapedText,
|
level_desc_text: ShapedText,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum LevelListEntry {
|
||||||
|
Level(Level),
|
||||||
|
ChapterTitle(String),
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (mut rl, thread) = raylib::init().resizable().title(TITLE_TEXT).build();
|
let (mut rl, thread) = raylib::init().resizable().title(TITLE_TEXT).build();
|
||||||
rl.set_target_fps(60);
|
rl.set_target_fps(60);
|
||||||
|
@ -58,12 +64,7 @@ impl Game {
|
||||||
|
|
||||||
let levels = get_levels();
|
let levels = get_levels();
|
||||||
let solutions = get_solutions();
|
let solutions = get_solutions();
|
||||||
let mut selected_solution = 0;
|
let selected_solution = 0;
|
||||||
|
|
||||||
// select the last solution of the first level, if there is one
|
|
||||||
if let Some(s) = levels.first().and_then(|l| solutions.get(l.id())) {
|
|
||||||
selected_solution = s.len().saturating_sub(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
levels,
|
levels,
|
||||||
|
@ -145,6 +146,12 @@ impl Game {
|
||||||
width: level_list_width as f32 - 10.,
|
width: level_list_width as f32 - 10.,
|
||||||
height: level_entry_height as f32 - 5.,
|
height: level_entry_height as f32 - 5.,
|
||||||
};
|
};
|
||||||
|
match level {
|
||||||
|
LevelListEntry::ChapterTitle(title) => {
|
||||||
|
d.draw_rectangle_rec(bounds, BG_DARK);
|
||||||
|
d.draw_text(title, 10, y, 30, FG_CHAPTER_TITLE);
|
||||||
|
}
|
||||||
|
LevelListEntry::Level(level) => {
|
||||||
if clicked
|
if clicked
|
||||||
&& bounds.check_collision_point_rec(mouse_pos)
|
&& bounds.check_collision_point_rec(mouse_pos)
|
||||||
&& self.selected_level != index
|
&& self.selected_level != index
|
||||||
|
@ -179,8 +186,10 @@ impl Game {
|
||||||
};
|
};
|
||||||
d.draw_text(&subtext, 10, y + 30, 20, subtext_color);
|
d.draw_text(&subtext, 10, y + 30, 20, subtext_color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(level) = self.levels.get(self.selected_level) {
|
if let Some(LevelListEntry::Level(level)) = self.levels.get(self.selected_level) {
|
||||||
d.draw_text(level.name(), level_list_width + 10, 10, 40, Color::CYAN);
|
d.draw_text(level.name(), level_list_width + 10, 10, 40, Color::CYAN);
|
||||||
d.draw_text(level.id(), level_list_width + 10, 50, 10, Color::GRAY);
|
d.draw_text(level.id(), level_list_width + 10, 50, 10, Color::GRAY);
|
||||||
|
|
||||||
|
@ -280,15 +289,15 @@ impl Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_levels() -> Vec<Level> {
|
fn get_levels() -> Vec<LevelListEntry> {
|
||||||
let mut levels = Vec::<Level>::new();
|
let mut chapters = Vec::<Chapter>::new();
|
||||||
let mut add_level = |path| {
|
let mut add_level = |path| {
|
||||||
let l = read_to_string(path)
|
let l = read_to_string(path)
|
||||||
.ok()
|
.ok()
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.and_then(|s| serde_json::from_str(s).ok());
|
.and_then(|s| serde_json::from_str(s).ok());
|
||||||
if let Some(level) = l {
|
if let Some(level) = l {
|
||||||
levels.push(level);
|
chapters.push(level);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for d in read_dir("levels").unwrap().flatten() {
|
for d in read_dir("levels").unwrap().flatten() {
|
||||||
|
@ -300,7 +309,13 @@ fn get_levels() -> Vec<Level> {
|
||||||
add_level(d.path());
|
add_level(d.path());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
levels.sort_unstable_by_key(Level::sort_order);
|
chapters.sort_unstable_by_key(|c| c.title.clone());
|
||||||
|
|
||||||
|
let mut levels = Vec::new();
|
||||||
|
for c in chapters {
|
||||||
|
levels.push(LevelListEntry::ChapterTitle(c.title));
|
||||||
|
levels.extend(c.levels.into_iter().map(LevelListEntry::Level));
|
||||||
|
}
|
||||||
levels
|
levels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use board::Board;
|
||||||
use pos::*;
|
use pos::*;
|
||||||
use tile::*;
|
use tile::*;
|
||||||
|
|
||||||
use crate::{ ui::draw_usize_small, Textures, TILE_TEXTURE_SIZE};
|
use crate::{ui::draw_usize_small, Textures, TILE_TEXTURE_SIZE};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub const BG_LIGHT: Color = gray(64);
|
||||||
pub const BG_WIDGET: Color = gray(64);
|
pub const BG_WIDGET: Color = gray(64);
|
||||||
pub const BG_WIDGET_ACTIVE: Color = rgb(80, 120, 180);
|
pub const BG_WIDGET_ACTIVE: Color = rgb(80, 120, 180);
|
||||||
pub const FG_MARBLE_VALUE: Color = rgb(255, 80, 40);
|
pub const FG_MARBLE_VALUE: Color = rgb(255, 80, 40);
|
||||||
pub const FG_TOGGLE_ENABLED: Color = gray(200);
|
pub const FG_CHAPTER_TITLE: Color = rgb(255, 160, 40);
|
||||||
|
|
||||||
pub const fn widget_bg(highlight: bool) -> Color {
|
pub const fn widget_bg(highlight: bool) -> Color {
|
||||||
if highlight {
|
if highlight {
|
||||||
|
|
Loading…
Reference in a new issue