add bounding area score to solution results
This commit is contained in:
parent
997297ab68
commit
157ee0de51
5 changed files with 60 additions and 7 deletions
|
@ -3,9 +3,11 @@ Game store page: https://crispypin.itch.io/marble-machinations
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### added
|
### added
|
||||||
|
- score number: bounding area
|
||||||
- configurable key bindings for many editor actions
|
- configurable key bindings for many editor actions
|
||||||
- QWERTY+ASDFGH keybindings for the tile tools
|
- QWERTY+ASDFGH keybindings for the tile tools
|
||||||
- OS clipboard copy/paste, with fallback to old behavior when copying
|
- OS clipboard copy/paste, with fallback to old behavior when copying
|
||||||
|
- cut selection
|
||||||
- in-grid text comments (not yet editable in-game)
|
- in-grid text comments (not yet editable in-game)
|
||||||
- changelog file
|
- changelog file
|
||||||
- (dev) sub-tick visualisation in debug mode
|
- (dev) sub-tick visualisation in debug mode
|
||||||
|
|
|
@ -18,7 +18,6 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
|
||||||
- background colour setting
|
- background colour setting
|
||||||
- hotkeys for everything (no mouse needed to play)
|
- hotkeys for everything (no mouse needed to play)
|
||||||
- more levels
|
- more levels
|
||||||
- footprint and bounding box stats (instead of area)
|
|
||||||
- scroll output bytes
|
- scroll output bytes
|
||||||
- timestamps in solutions and blueprints
|
- timestamps in solutions and blueprints
|
||||||
- lock tile types for early levels to make it less overwhelming
|
- lock tile types for early levels to make it less overwhelming
|
||||||
|
@ -31,6 +30,7 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
|
||||||
- show histograms
|
- show histograms
|
||||||
- author name in solutions and blueprints
|
- author name in solutions and blueprints
|
||||||
#### undecided
|
#### undecided
|
||||||
|
- footprint score (tiles that were non-empty at any point in the run)
|
||||||
- option to use 8-bit marbles?
|
- option to use 8-bit marbles?
|
||||||
- blueprint rotation?
|
- blueprint rotation?
|
||||||
- settable marble start direction?
|
- settable marble start direction?
|
||||||
|
|
|
@ -24,7 +24,7 @@ const HEADER_HEIGHT: i32 = 40;
|
||||||
const FOOTER_HEIGHT: i32 = 95;
|
const FOOTER_HEIGHT: i32 = 95;
|
||||||
const SIDEBAR_WIDTH: i32 = 200 + 32 * 2 + 5 * 4;
|
const SIDEBAR_WIDTH: i32 = 200 + 32 * 2 + 5 * 4;
|
||||||
const END_POPUP_WIDTH: i32 = 320;
|
const END_POPUP_WIDTH: i32 = 320;
|
||||||
const END_POPUP_HEIGHT: i32 = 165;
|
const END_POPUP_HEIGHT: i32 = 225;
|
||||||
|
|
||||||
const MAX_ZOOM: f32 = 8.;
|
const MAX_ZOOM: f32 = 8.;
|
||||||
const MIN_ZOOM: f32 = 0.25;
|
const MIN_ZOOM: f32 = 0.25;
|
||||||
|
@ -335,6 +335,7 @@ impl Editor {
|
||||||
self.score = Some(Score {
|
self.score = Some(Score {
|
||||||
cycles: self.total_steps + self.machine.step_count(),
|
cycles: self.total_steps + self.machine.step_count(),
|
||||||
tiles: self.source_board.grid.count_tiles(),
|
tiles: self.source_board.grid.count_tiles(),
|
||||||
|
bounds_area: self.source_board.grid.used_bounds_area(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if !stage.output().as_bytes().starts_with(self.machine.output()) {
|
} else if !stage.output().as_bytes().starts_with(self.machine.output()) {
|
||||||
|
@ -744,11 +745,14 @@ impl Editor {
|
||||||
if self.popup == Popup::Success {
|
if self.popup == Popup::Success {
|
||||||
d.draw_text("Level Complete!", x + 45, y + 10, 30, Color::LIME);
|
d.draw_text("Level Complete!", x + 45, y + 10, 30, Color::LIME);
|
||||||
if let Some(score) = &self.score {
|
if let Some(score) = &self.score {
|
||||||
d.draw_text("cycles", x + 15, y + 45, 20, Color::WHITE);
|
d.draw_text("cycles", x + 15, y + 40, 20, Color::WHITE);
|
||||||
draw_usize(d, textures, score.cycles, (x + 10, y + 70), 9, 2);
|
draw_usize(d, textures, score.cycles, (x + 110, y + 40), 9, 2);
|
||||||
d.draw_text("tiles", x + 215, y + 45, 20, Color::WHITE);
|
d.draw_text("tiles", x + 15, y + 80, 20, Color::WHITE);
|
||||||
draw_usize(d, textures, score.tiles, (x + 210, y + 70), 5, 2);
|
draw_usize(d, textures, score.tiles, (x + 110, y + 80), 9, 2);
|
||||||
|
d.draw_text("bounds", x + 15, y + 120, 20, Color::WHITE);
|
||||||
|
draw_usize(d, textures, score.bounds_area, (x + 110, y + 120), 9, 2);
|
||||||
}
|
}
|
||||||
|
let y = y + 60;
|
||||||
if simple_button((d, &self.mouse), x + 10, y + 110, 140, 45) {
|
if simple_button((d, &self.mouse), x + 10, y + 110, 140, 45) {
|
||||||
self.popup = Popup::None;
|
self.popup = Popup::None;
|
||||||
self.dismissed_end = true;
|
self.dismissed_end = true;
|
||||||
|
|
|
@ -123,6 +123,48 @@ impl Grid {
|
||||||
sum
|
sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn used_bounds_area(&self) -> usize {
|
||||||
|
let row_clear = |a, max, f: fn(usize, usize) -> (usize, usize)| {
|
||||||
|
for b in 0..max {
|
||||||
|
if !self.get_unchecked(f(a, b).into()).is_blank() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
};
|
||||||
|
let mut height = self.height;
|
||||||
|
for y in 0..self.height {
|
||||||
|
if row_clear(y, self.width, |y, x| (x, y)) {
|
||||||
|
height -= 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for y in (0..self.height).rev() {
|
||||||
|
if row_clear(y, self.width, |y, x| (x, y)) {
|
||||||
|
height -= 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut width = self.width;
|
||||||
|
for x in 0..self.width {
|
||||||
|
if row_clear(x, self.height, |x, y| (x, y)) {
|
||||||
|
width -= 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for x in (0..self.width).rev() {
|
||||||
|
if row_clear(x, self.width, |x, y| (x, y)) {
|
||||||
|
width -= 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width * height
|
||||||
|
}
|
||||||
|
|
||||||
fn in_bounds(&self, p: Pos) -> bool {
|
fn in_bounds(&self, p: Pos) -> bool {
|
||||||
p.x >= 0 && p.y >= 0 && p.x < self.width as PosInt && p.y < self.height as PosInt
|
p.x >= 0 && p.y >= 0 && p.x < self.width as PosInt && p.y < self.height as PosInt
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ pub struct Solution {
|
||||||
pub struct Score {
|
pub struct Score {
|
||||||
pub cycles: usize,
|
pub cycles: usize,
|
||||||
pub tiles: usize,
|
pub tiles: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub bounds_area: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Solution {
|
impl Solution {
|
||||||
|
@ -68,7 +70,10 @@ impl Solution {
|
||||||
|
|
||||||
pub fn score_text(&self) -> String {
|
pub fn score_text(&self) -> String {
|
||||||
if let Some(score) = &self.score {
|
if let Some(score) = &self.score {
|
||||||
format!("C: {} T: {}", score.cycles, score.tiles)
|
format!(
|
||||||
|
"C: {} T: {} B: {}",
|
||||||
|
score.cycles, score.tiles, score.bounds_area
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
"unsolved".into()
|
"unsolved".into()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue