From bea7a6aa4e903938dd7263dbc028b961f60d245f Mon Sep 17 00:00:00 2001 From: Max Bradbury Date: Sat, 11 Apr 2020 22:40:26 +0100 Subject: [PATCH] game from string and related test --- README.md | 1 - src/main.rs | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 253 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6ecbecc..87e3108 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ a library for parsing Bitsy game data. ### functions -* game from * game to ### tidy up diff --git a/src/main.rs b/src/main.rs index 073e670..b64ee4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -112,6 +112,13 @@ struct Game { version: f64, room_format: u8, palettes: Vec, + rooms: Vec, + tiles: Vec, + avatar: Avatar, + sprites: Vec, + items: Vec, + dialogues: Vec, + endings: Vec, variables: Vec, } @@ -960,13 +967,252 @@ fn test_room_to_string() { assert_eq!(room_to_string(test_room()), test_room_string()); } -// fn game_from_string(game: String ) -> Game { -// // probably needs to split the game data into different segments starting from the end -// // e.g. VAR... then END... then DLG... -// // then split all these up into their individual items -// -// // no - let's try going from the beginning and popping off elements from the start? -// } +fn game_from_string(string: String ) -> Game { + // dialogues and endings can have 2+ line breaks inside, so deal with these separately + // otherwise, everything can be split on a double line break (\n\n) + let mut dialogues: Vec = Vec::new(); + let mut endings: Vec = Vec::new(); + let mut variables: Vec = Vec::new(); + let main_split: Vec<&str> = string.split("\n\nDLG").collect(); + let main = main_split[0].to_string(); + let mut dialogues_endings_variables: String = main_split[1..].join("\n\nDLG"); + // todo handle dialogues_endings_variables + + let variable_segments = dialogues_endings_variables.clone(); + let variable_segments: Vec<&str> = variable_segments.split("\n\nVAR").collect(); + if variable_segments.len() > 0 { + dialogues_endings_variables = variable_segments[0].to_string(); + let variable_segments = variable_segments[1..].to_owned(); + + for segment in variable_segments { + let segment = format!("VAR{}", segment); + variables.push(variable_from_string(segment)); + } + } + + let ending_segments = dialogues_endings_variables.clone(); + let ending_segments: Vec<&str> = ending_segments.split("\n\nEND").collect(); + if ending_segments.len() > 0 { + dialogues_endings_variables = ending_segments[0].to_string(); + let ending_segments = ending_segments[1..].to_owned(); + + for segment in ending_segments { + let segment = format!("END{}", segment); + endings.push(ending_from_string(segment)); + } + } + + + let dialogue_segments = format!("\n\nDLG {}", dialogues_endings_variables.trim()); + let dialogue_segments: Vec<&str> = dialogue_segments.split("\n\nDLG").collect(); + for segment in dialogue_segments[1..].to_owned() { + let segment = format!("DLG{}", segment); + dialogues.push(dialogue_from_string(segment)); + } + + let segments: Vec<&str> = main.split("\n\n").collect(); + + let name = segments[0].to_string(); + let mut version: f64 = 1.0; + let mut room_format: u8 = 1; + let mut palettes: Vec = Vec::new(); + let mut rooms: Vec = Vec::new(); + let mut tiles: Vec = Vec::new(); + let mut avatar : Option = None; // unwrap this later + let mut sprites: Vec = Vec::new(); + let mut items: Vec = Vec::new(); + + for segment in segments[1..].to_owned() { + let segment = segment.to_string(); + + if segment.starts_with("# BITSY VERSION") { + version = segment.replace("# BITSY VERSION ", "").parse().unwrap(); + } else if segment.starts_with("! ROOM_FORMAT") { + room_format = segment.replace("! ROOM_FORMAT ", "").parse().unwrap(); + } else if segment.starts_with("PAL") { + palettes.push(palette_from_string(segment)); + } else if segment.starts_with("ROOM") { + rooms.push(room_from_string(segment)); + } else if segment.starts_with("TIL") { + tiles.push(tile_from_string(segment)); + } else if segment.starts_with("SPR A") { + avatar = Some(avatar_from_string(segment)); + } else if segment.starts_with("SPR") { + sprites.push(sprite_from_string(segment)); + } else if segment.starts_with("ITM") { + items.push(item_from_string(segment)); + } + } + + assert!(avatar.is_some()); + let avatar = avatar.unwrap(); + + Game { + name, + version, + room_format, + palettes, + rooms, + tiles, + avatar, + sprites, + items, + dialogues, + endings, + variables, + } +} + +#[test] +fn test_game_from_string() { + let output = game_from_string( + include_str!["../test/resources/default.bitsy"].to_string() + ); + + let expected = Game { + name: "Write your game's title here".to_string(), + version: 6.5, + room_format: 1, + palettes: vec![ + Palette { + id: "0".to_string(), + name: None, + colours: vec![ + Colour {red: 0, green: 82, blue: 204 }, + Colour {red: 128, green: 159, blue: 255 }, + Colour {red: 255, green: 255, blue: 255 }, + ] + } + ], + rooms: vec![ + Room { + id: "0".to_string(), + palette: "0".to_string(), + name: None, + tiles: vec![ + "0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"a".to_string(),"0".to_string(), + "0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(),"0".to_string(), + ], + items: vec![], + exits: vec![], + endings: vec![] + } + ], + tiles: vec![ + Tile { + id: "a".to_string(), + name: None, + wall: false, + animation_frames: vec![ + Image { + pixels: vec![ + 1,1,1,1,1,1,1,1, + 1,0,0,0,0,0,0,1, + 1,0,0,0,0,0,0,1, + 1,0,0,1,1,0,0,1, + 1,0,0,1,1,0,0,1, + 1,0,0,0,0,0,0,1, + 1,0,0,0,0,0,0,1, + 1,1,1,1,1,1,1,1, + ] + } + ] + } + ], + avatar: Avatar { + animation_frames: vec![ + Image { + pixels: vec![ + 0,0,0,1,1,0,0,0, + 0,0,0,1,1,0,0,0, + 0,0,0,1,1,0,0,0, + 0,0,1,1,1,1,0,0, + 0,1,1,1,1,1,1,0, + 1,0,1,1,1,1,0,1, + 0,0,1,0,0,1,0,0, + 0,0,1,0,0,1,0,0, + ] + } + ], + room: "0".to_string(), + position: Position { x: 4, y: 4 } + }, + sprites: vec![ + Sprite { + id: "a".to_string(), + name: None, + animation_frames: vec![ + Image { + pixels: vec![ + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,1,0,1,0,0,0,1, + 0,1,1,1,0,0,0,1, + 0,1,1,1,0,0,1,0, + 0,1,1,1,1,1,0,0, + 0,0,1,1,1,1,0,0, + 0,0,1,0,0,1,0,0, + ] + } + ], + dialogue: Some("SPR_0".to_string()), + room: "0".to_string(), + position: Position { x: 8, y: 12 } + } + ], + items: vec![ + Item { + id: "0".to_string(), + animation_frames: vec![ + Image { + pixels: vec![ + 0,0,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,1,1,1,0,0, + 0,1,1,0,0,1,0,0, + 0,0,1,0,0,1,0,0, + 0,0,0,1,1,0,0,0, + 0,0,0,0,0,0,0,0, + ] + }, + ], + name: Some("tea".to_string()), + dialogue: Some("ITM_0".to_string()) + }, + ], + dialogues: vec![ + Dialogue { + id: "SPR_0".to_string(), + contents: "I'm a cat".to_string(), + }, + Dialogue { + id: "ITM_0".to_string(), + contents: "You found a nice warm cup of tea".to_string(), + }, + ], + endings: vec![], + variables: vec![ + Variable { id: "a".to_string(), initial_value: "42".to_string() } + ], + }; + + assert_eq!(output, expected); +} // fn game_to_string(game: Game) -> String { //