diff --git a/scarytxt/src/game.rs b/scarytxt/src/game.rs new file mode 100644 index 0000000..85e860c --- /dev/null +++ b/scarytxt/src/game.rs @@ -0,0 +1,229 @@ +use std::io::{self, Write}; +use std::process; + +pub struct Game { + encounter: Option, + zone: Zone, + adventurer: Adventurer, + scarers: Vec, +} + +impl Game { + pub fn new() -> Game { + Game { + encounter: None, + zone: Zone { width: 4, depth: 4 }, + adventurer: Adventurer { + name: String::from("adv"), + h: Humors { + health: 1000, + attack: 1, + critical_pct: 10, + }, + l: Location { x: 0, y: 0 }, + }, + scarers: vec![Scarer { + name: String::from("Blue Minotaur"), + description: String::from("Towering half bull with flaming nostrils"), + h: Humors { + health: 4000, + attack: 4, + critical_pct: 2, + }, + l: Location { x: 2, y: 2 }, + }], + } + } + + pub fn play(&mut self) { + loop { + self.step(); + } + } + + fn on(&mut self, event: Event) { + match event { + Event::ApproachEdge => { + println!("// you stand at the edge of the zone"); + } + Event::Encounter(s) => { + println!("// !! you encounter an {}", s.name); + } + Event::Unencounter(s, o) => { + println!("// !! you unencountered an {} with outcome {:?}", s.name, o); + } + Event::Fall => { + println!("// you fall out of the zone"); + process::exit(0); + } + Event::Step(d) => { + println!("// you step {:?}", d); + } + Event::Miss => { + println!("// you brace yourself for the next step"); + } + } + } + + pub fn step(&mut self) { + { + let al = &self.adventurer.l; + + if al.x == 0 + || al.y == 0 + || al.x as u8 == self.zone.width + || al.y as u8 == self.zone.depth + { + self.on(Event::ApproachEdge); + } + } + + let adventurer_loc = Location { + x: self.adventurer.l.x, + y: self.adventurer.l.y, + }; + + let evt: Event = Event::Miss; + + for s in self.scarers.iter() { + if adventurer_loc == s.l { + evt = Event::Encounter(*s); + } + } + + self.on(evt); + + print!("> "); + io::stdout().flush().expect("failed to flush stdout"); + + let mut line = String::new(); + io::stdin() + .read_line(&mut line) + .expect("failed to read line of input"); + line = line.trim().to_string(); + + match &mut self.encounter { + None => { mut self.wandering_step(&line) }, + Some(e) => { mut self.encounter_step(&line, e) }, + } + } + + fn encounter_step(&self, line: &str, enc: &mut Encounter) { + eprintln!( + "// this is not an encounter {:?} from line {:?} OK", + enc, line + ); + } + + fn wandering_step(&mut self, line: &str) { + let v: Vec<&str> = line.split(' ').collect(); + match v.get(0) { + Some(cmd) => { + match *cmd { + "help" => { + println!("// maybe try 'loc'"); + } + "loc" => { + println!( + "// you stand at ({}, {})", + self.adventurer.l.x, self.adventurer.l.y + ); + } + "step" => { + let (mv, dir) = match v.get(1) { + Some(direction) => { + let direction = direction.trim().to_lowercase(); + match direction.as_str() { + "forward" => ((1i8, 0i8), Direction::Forward), + "back" => ((-1i8, 0i8), Direction::Back), + "left" => ((0i8, 1i8), Direction::Left), + "right" => ((0i8, -1i8), Direction::Right), + _ => { + println!("unknown direction {}", direction); + ((0i8, 0i8), Direction::Forward) + } + } + } + None => ((1i8, 0i8), Direction::Forward), + }; + + let loc = &mut self.adventurer.l; + loc.x += mv.0; + loc.y += mv.1; + println!("// you step {:?}", dir); + } + _ => { + println!("// what is this {}?", cmd); + } + }; + } + None => println!("// ..."), + } + } +} + +#[derive(Debug)] +enum Direction { + Forward, + Back, + Left, + Right, +} + +#[derive(Debug)] +enum EncounterOutcome { + Victory, + Defeat, +} + +enum Event { + Fall, + ApproachEdge, + Step(Direction), + Encounter(Scarer), + Unencounter(Scarer, EncounterOutcome), + Miss, +} + +#[derive(Debug)] +struct Encounter { + scarer: Scarer, +} + +#[derive(Debug)] +struct Humors { + health: u16, + attack: u8, + critical_pct: u8, +} + +#[derive(Debug)] +struct Location { + x: i8, + y: i8, +} + +impl PartialEq for Location { + fn eq(&self, other: &Self) -> bool { + self.x == other.x && self.y == other.y + } +} + +struct Adventurer { + name: String, + h: Humors, + l: Location, +} + +#[derive(Debug)] +struct Scarer { + name: String, + description: String, + h: Humors, + l: Location, +} + +struct Zone { + width: u8, + depth: u8, +} diff --git a/scarytxt/src/main.rs b/scarytxt/src/main.rs index 4d8b98d..6d05b11 100644 --- a/scarytxt/src/main.rs +++ b/scarytxt/src/main.rs @@ -1,116 +1,5 @@ -use std::io::{self,Write}; +pub mod game; -fn main() -> io::Result<()> { - let game = build_game(); - - println!("// you enter the zone"); - loop { - print!("> "); - io::stdout().flush(); - - match game.in_battle { - false => { - - let mut line = String::new(); - io::stdin().read_line(&mut line)?; - match line.trim() { - "help" => { - println!("// maybe try 'loc'"); - }, - "loc" => { - println!("// you stand at ({}, {})", game.adventurer.l.x, game.adventurer.l.y); - }, - "step forward" => { - let loc = game.adventurer.l; - loc.x += 1; - println!("// you step forward"); - for s in game.scarers.iter() { - if (loc.x, loc.y) == (s.l.x, s.l.y) { - println!("// oh no it's an {}", s.name) - } - } - }, - _ => { - println!("// what is this {}?", line.trim()) - } - } - }, - true => { - } - } - }; - Ok(()) -} - -fn build_game() -> Game { - Game { - in_battle: false, - zone: Zone { - width: 4, - depth: 4, - }, - adventurer: Adventurer { - name: String::from("adv"), - h: Humors { - health: 1000, - attack: 1, - critical_pct: 10, - }, - l: Location { - x: 0, - y: 0, - } - }, - scarers: vec![ - Scarer { - name: String::from("Blue Minotaur"), - description: String::from("Towering half bull with flaming nostrils"), - h: Humors { - health: 4000, - attack: 4, - critical_pct: 2, - }, - l: Location { - x: 2, - y: 2, - }, - }, - ], - } -} - -struct Humors { - health: u16, - attack: u8, - critical_pct: u8, -} - -struct Location { - x: u8, - y: u8, -} - -struct Adventurer { - name: String, - h: Humors, - l: Location, -} - -struct Scarer { - name: String, - description: String, - h: Humors, - l: Location, -} - -struct Zone { - width: u8, - depth: u8, -} - -struct Game { - in_battle: bool, - zone: Zone, - adventurer: Adventurer, - scarers: Vec, +fn main() { + game::Game::new().play(); }