replace tile ID with string

This commit is contained in:
Max Bradbury 2020-06-18 17:47:54 +01:00
parent bf5b3a8d20
commit 168f3559e0
4 changed files with 24 additions and 24 deletions

View File

@ -58,7 +58,7 @@ some more practical uses would be things like:
* implement Result return types on ::from functions so we can handle errors * implement Result return types on ::from functions so we can handle errors
* replace Image with Vec<u8> or something. seems like a pointless abstraction * replace Image with Vec<u8> 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 ### tidy up

View File

@ -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 std::error::Error;
use loe::TransformMode; use loe::TransformMode;
use std::str::FromStr; use std::str::FromStr;
@ -316,8 +316,8 @@ impl ToString for Game {
impl Game { impl Game {
#[inline] #[inline]
pub fn tile_ids(&self) -> Vec<u64> { pub fn tile_ids(&self) -> Vec<String> {
self.tiles.iter().map(|tile| tile.id).collect() self.tiles.iter().map(|tile| tile.id.clone()).collect()
} }
/// first available tile ID. /// first available tile ID.
@ -325,28 +325,28 @@ impl Game {
/// if current tile IDs are [0, 1, 2] the result will be `3` /// 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 /// todo this needs to be a generic function that takes a vec of string IDs and returns a new base64 string ID
#[inline] #[inline]
pub fn new_tile_id(&self) -> u64 { pub fn new_tile_id(&self) -> String {
let mut new_id = 0; let mut new_id = 0;
let mut ids = self.tile_ids(); let mut ids = self.tile_ids();
ids.sort(); ids.sort();
for id in ids { for id in ids {
if new_id == id { if new_id == from_base36(id.as_ref()) {
new_id += 1; new_id += 1;
} else { } 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 /// adds a tile safely and returns the new tile ID
#[inline] #[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(); let new_id = self.new_tile_id();
tile.id = new_id; tile.id = new_id.clone();
self.tiles.push(tile); self.tiles.push(tile);
new_id new_id
} }
@ -430,13 +430,13 @@ mod test {
#[test] #[test]
fn test_tile_ids() { 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] #[test]
fn test_new_tile_id() { fn test_new_tile_id() {
// default tile has an id of 10 ("a"), so 0 is available // 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 game = crate::mock::game_default();
let mut tiles: Vec<Tile> = Vec::new(); let mut tiles: Vec<Tile> = Vec::new();
@ -444,32 +444,32 @@ mod test {
for n in 0..9 { for n in 0..9 {
if n != 4 { if n != 4 {
let mut new_tile = crate::mock::tile_default(); let mut new_tile = crate::mock::tile_default();
new_tile.id = n; new_tile.id = format!("{}", n).to_string();
tiles.push(new_tile); tiles.push(new_tile);
} }
} }
game.tiles = tiles; 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 // fill in the space created above, and test that tile IDs get sorted
let mut new_tile = crate::mock::tile_default(); let mut new_tile = crate::mock::tile_default();
new_tile.id = 4; new_tile.id = "4".to_string();
game.tiles.push(new_tile); game.tiles.push(new_tile);
assert_eq!(game.new_tile_id(), 10); assert_eq!(game.new_tile_id(), "a".to_string());
} }
#[test] #[test]
fn test_add_tile() { fn test_add_tile() {
let mut game = crate::mock::game_default(); let mut game = crate::mock::game_default();
let new_id = game.add_tile(crate::mock::tile_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); assert_eq!(game.tiles.len(), 2);
let new_id = game.add_tile(crate::mock::tile_default()); 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); assert_eq!(game.tiles.len(), 3);
} }

View File

@ -113,7 +113,7 @@ pub fn avatar() -> Sprite {
#[inline] #[inline]
pub fn tile_default() -> Tile { pub fn tile_default() -> Tile {
Tile { Tile {
id: 10, id: "a".to_string(),
name: None, name: None,
wall: None, wall: None,
animation_frames: vec![Image { animation_frames: vec![Image {

View File

@ -3,7 +3,7 @@ use crate::image::animation_frames_from_string;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct Tile { pub struct Tile {
pub id: u64, pub id: String,
pub name: Option<String>, pub name: Option<String>,
pub wall: Option<bool>, // this is "optional" in that a tile can have `WAL true|false` or neither pub wall: Option<bool>, // this is "optional" in that a tile can have `WAL true|false` or neither
pub animation_frames: Vec<Image>, pub animation_frames: Vec<Image>,
@ -40,7 +40,7 @@ impl From<String> for Tile {
fn from(string: String) -> Tile { fn from(string: String) -> Tile {
let mut lines: Vec<&str> = string.lines().collect(); 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 wall = None;
let mut name = None; let mut name = None;
@ -80,7 +80,7 @@ impl ToString for Tile {
fn to_string(&self) -> String { fn to_string(&self) -> String {
format!( format!(
"TIL {}\n{}{}{}{}", "TIL {}\n{}{}{}{}",
self.id.to_base36(), self.id,
self.animation_frames.to_string(), self.animation_frames.to_string(),
self.name_line(), self.name_line(),
self.wall_line(), self.wall_line(),
@ -100,7 +100,7 @@ mod test {
let output = Tile::from(include_str!("test-resources/tile").to_string()); let output = Tile::from(include_str!("test-resources/tile").to_string());
let expected = Tile { let expected = Tile {
id: 35, id: "z".to_string(),
name: Some("concrete 1".to_string()), name: Some("concrete 1".to_string()),
wall: Some(true), wall: Some(true),
animation_frames: vec![Image { animation_frames: vec![Image {
@ -115,7 +115,7 @@ mod test {
#[test] #[test]
fn test_tile_to_string() { fn test_tile_to_string() {
let output = Tile { let output = Tile {
id: 262, id: "7a".to_string(),
name: Some("chequers".to_string()), name: Some("chequers".to_string()),
wall: None, wall: None,
animation_frames: vec![ animation_frames: vec![