diff --git a/README.md b/README.md index e195490..e134ce1 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ some more practical uses would be things like: * implement Result return types on ::from functions so we can handle errors * replace Image with Vec or something. seems like a pointless abstraction -* convert integer IDs to strings and just use base36 when creating new IDs; test games with arbitrary IDs +* replace game avatar with a helper function to get the sprite with an ID of A ### tidy up diff --git a/src/game.rs b/src/game.rs index 19d3e7d..1df6a8a 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,4 +1,4 @@ -use crate::{Dialogue, Ending, Font, Item, Palette, Room, Sprite, TextDirection, Tile, ToBase36, Variable, transform_line_endings, segments_from_string, is_string_numeric}; +use crate::{Dialogue, Ending, Font, Item, Palette, Room, Sprite, TextDirection, Tile, ToBase36, Variable, transform_line_endings, segments_from_string, is_string_numeric, to_base36, from_base36}; use std::error::Error; use loe::TransformMode; use std::str::FromStr; @@ -316,8 +316,8 @@ impl ToString for Game { impl Game { #[inline] - pub fn tile_ids(&self) -> Vec { - self.tiles.iter().map(|tile| tile.id).collect() + pub fn tile_ids(&self) -> Vec { + self.tiles.iter().map(|tile| tile.id.clone()).collect() } /// first available tile ID. @@ -325,28 +325,28 @@ impl Game { /// if current tile IDs are [0, 1, 2] the result will be `3` /// todo this needs to be a generic function that takes a vec of string IDs and returns a new base64 string ID #[inline] - pub fn new_tile_id(&self) -> u64 { + pub fn new_tile_id(&self) -> String { let mut new_id = 0; let mut ids = self.tile_ids(); ids.sort(); for id in ids { - if new_id == id { + if new_id == from_base36(id.as_ref()) { new_id += 1; } else { - return new_id; + return to_base36(new_id); } } - new_id + 1 + to_base36(new_id + 1) } /// adds a tile safely and returns the new tile ID #[inline] - pub fn add_tile(&mut self, mut tile: Tile) -> u64 { + pub fn add_tile(&mut self, mut tile: Tile) -> String { let new_id = self.new_tile_id(); - tile.id = new_id; + tile.id = new_id.clone(); self.tiles.push(tile); new_id } @@ -430,13 +430,13 @@ mod test { #[test] fn test_tile_ids() { - assert_eq!(crate::mock::game_default().tile_ids(), vec![10]); + assert_eq!(crate::mock::game_default().tile_ids(), vec!["a".to_string()]); } #[test] fn test_new_tile_id() { // default tile has an id of 10 ("a"), so 0 is available - assert_eq!(crate::mock::game_default().new_tile_id(), 0); + assert_eq!(crate::mock::game_default().new_tile_id(), "0".to_string()); let mut game = crate::mock::game_default(); let mut tiles: Vec = Vec::new(); @@ -444,32 +444,32 @@ mod test { for n in 0..9 { if n != 4 { let mut new_tile = crate::mock::tile_default(); - new_tile.id = n; + new_tile.id = format!("{}", n).to_string(); tiles.push(new_tile); } } game.tiles = tiles; - assert_eq!(game.new_tile_id(), 4); + assert_eq!(game.new_tile_id(), "4".to_string()); // fill in the space created above, and test that tile IDs get sorted let mut new_tile = crate::mock::tile_default(); - new_tile.id = 4; + new_tile.id = "4".to_string(); game.tiles.push(new_tile); - assert_eq!(game.new_tile_id(), 10); + assert_eq!(game.new_tile_id(), "a".to_string()); } #[test] fn test_add_tile() { let mut game = crate::mock::game_default(); let new_id = game.add_tile(crate::mock::tile_default()); - assert_eq!(new_id, 0); + assert_eq!(new_id, "0".to_string()); assert_eq!(game.tiles.len(), 2); let new_id = game.add_tile(crate::mock::tile_default()); - assert_eq!(new_id, 1); + assert_eq!(new_id, "1".to_string()); assert_eq!(game.tiles.len(), 3); } diff --git a/src/mock.rs b/src/mock.rs index eebfa5a..8aeae59 100644 --- a/src/mock.rs +++ b/src/mock.rs @@ -113,7 +113,7 @@ pub fn avatar() -> Sprite { #[inline] pub fn tile_default() -> Tile { Tile { - id: 10, + id: "a".to_string(), name: None, wall: None, animation_frames: vec![Image { diff --git a/src/tile.rs b/src/tile.rs index 381882e..09b747a 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -3,7 +3,7 @@ use crate::image::animation_frames_from_string; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Tile { - pub id: u64, + pub id: String, pub name: Option, pub wall: Option, // this is "optional" in that a tile can have `WAL true|false` or neither pub animation_frames: Vec, @@ -40,7 +40,7 @@ impl From for Tile { fn from(string: String) -> Tile { let mut lines: Vec<&str> = string.lines().collect(); - let id = from_base36(&lines[0].replace("TIL ", "")); + let id = lines[0].replace("TIL ", ""); let mut wall = None; let mut name = None; @@ -80,7 +80,7 @@ impl ToString for Tile { fn to_string(&self) -> String { format!( "TIL {}\n{}{}{}{}", - self.id.to_base36(), + self.id, self.animation_frames.to_string(), self.name_line(), self.wall_line(), @@ -100,7 +100,7 @@ mod test { let output = Tile::from(include_str!("test-resources/tile").to_string()); let expected = Tile { - id: 35, + id: "z".to_string(), name: Some("concrete 1".to_string()), wall: Some(true), animation_frames: vec![Image { @@ -115,7 +115,7 @@ mod test { #[test] fn test_tile_to_string() { let output = Tile { - id: 262, + id: "7a".to_string(), name: Some("chequers".to_string()), wall: None, animation_frames: vec![