Created
February 14, 2016 21:01
-
-
Save agmcleod/637f1ab187355b57a99d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate rand; | |
use std::cmp; | |
use std::collections::HashMap; | |
use rand::distributions::{IndependentSample, Range}; | |
#[derive(Debug)] | |
struct Boss { | |
hp: i32, | |
damage: i32 | |
} | |
#[derive(Debug)] | |
struct Buff<'a> { | |
spell: &'a Spell, | |
duration: i32 | |
} | |
impl<'a> Buff<'a> { | |
fn new(spell: &'a Spell, duration: i32) -> Buff { | |
Buff{ spell: spell, duration: duration } | |
} | |
} | |
#[derive(Debug)] | |
struct Player { | |
damage: i32, | |
armor: i32, | |
hp: i32, | |
mana: i32 | |
} | |
impl Player { | |
fn new() -> Player { | |
Player{ damage: 0, armor: 0, hp: 50, mana: 500 } | |
} | |
} | |
#[derive(Debug)] | |
enum Target { | |
PLAYER, BOSS | |
} | |
#[derive(Debug)] | |
struct Spell { | |
name: String, | |
duration: i32, | |
mana_cost: i32, | |
spell_effects: Vec<SpellEffect> | |
} | |
impl Spell { | |
fn new(name: &str, mana_cost: i32, duration: i32) -> Spell { | |
Spell{ name: String::from(name), duration: duration, mana_cost: mana_cost, spell_effects: Vec::<SpellEffect>::new() } | |
} | |
fn add_spell_effect(self: &mut Spell, spell_effect: SpellEffect) { | |
self.spell_effects.push(spell_effect); | |
} | |
} | |
#[derive(Debug)] | |
struct SpellEffect { | |
target: Target, | |
health: i32, | |
armor: i32, | |
mana: i32 | |
} | |
impl SpellEffect { | |
fn new(target: Target, health: i32) -> SpellEffect { | |
SpellEffect{ target: target, health: health, armor: 0, mana: 0 } | |
} | |
fn new_buff(target: Target, health: i32, armor: i32, mana: i32) -> SpellEffect { | |
SpellEffect{ target: target, health: health, armor: armor, mana: mana } | |
} | |
} | |
fn apply_spell_effect(player: &mut Player, boss: &mut Boss, spell_effect: &SpellEffect) { | |
match spell_effect.target { | |
Target::PLAYER => { | |
player.hp += spell_effect.health; | |
player.armor = spell_effect.armor; | |
player.mana += spell_effect.mana; | |
}, | |
Target::BOSS => { | |
boss.hp += spell_effect.health; | |
} | |
} | |
} | |
fn apply_buffs<'a>(player: &mut Player, boss: &mut Boss, buffs: &mut Vec<Buff<'a>>) { | |
player.armor = 0; | |
for buff in buffs.iter_mut() { | |
buff.duration -= 1; | |
if buff.duration > 0 || buff.spell.name != "shield" { | |
for spell_effect in buff.spell.spell_effects.iter() { | |
apply_spell_effect(player, boss, spell_effect); | |
} | |
} | |
} | |
buffs.retain(|buff| buff.duration > 0); | |
} | |
fn buff_is_active(buffs: &Vec<Buff>, name: &String) -> bool { | |
buffs.iter().filter(|buff| buff.spell.name == *name).collect::<Vec<_>>().len() > 0 | |
} | |
fn choose_spell<'a>(spells: &'a HashMap<String, Spell>, spell_keys: &Vec<String>, player: &Player, boss: &Boss, buffs: &Vec<Buff>) -> &'a Spell { | |
if player.mana < 53 { | |
// return any spell, as we are out of mana anyways | |
spells.get("magic_missle").unwrap() | |
} else { | |
let mut rng = rand::thread_rng(); | |
let mut rand_index; | |
let range = Range::new(0, spells.len()); | |
loop { | |
rand_index = range.ind_sample(&mut rng); | |
let spell = spells.get(&spell_keys[rand_index]).unwrap(); | |
if spell.mana_cost <= player.mana && !buff_is_active(buffs, &spell.name) { | |
break; | |
} | |
} | |
spells.get(&spell_keys[rand_index]).unwrap() | |
} | |
} | |
fn reset(player: &mut Player, boss: &mut Boss, buffs: &mut Vec<Buff>) { | |
player.hp = 50; | |
player.mana = 500; | |
boss.hp = 71; | |
buffs.clear(); | |
} | |
fn main() { | |
let mut boss = Boss{ hp: 71, damage: 10 }; | |
let mut player = Player::new(); | |
let mut min_hp = 10000; | |
let mut magic_missle = Spell::new("magic_missle", 53, 0); | |
magic_missle.add_spell_effect(SpellEffect::new(Target::BOSS, -4)); | |
let mut drain = Spell::new("drain", 73, 0); | |
drain.add_spell_effect(SpellEffect::new(Target::BOSS, -2)); | |
drain.add_spell_effect(SpellEffect::new(Target::PLAYER, 2)); | |
let mut shield = Spell::new("shield", 113, 6); | |
shield.add_spell_effect(SpellEffect::new_buff(Target::PLAYER, 0, 7, 0)); | |
let mut poison = Spell::new("poison", 173, 6); | |
poison.add_spell_effect(SpellEffect::new_buff(Target::BOSS, -3, 0, 0)); | |
let mut recharge = Spell::new("recharge", 229, 5); | |
recharge.add_spell_effect(SpellEffect::new_buff(Target::PLAYER, 0, 0, 101)); | |
let mut spells = HashMap::<String, Spell>::new(); | |
let spell_keys = vec![ | |
magic_missle.name.clone(), drain.name.clone(), shield.name.clone(), poison.name.clone(), recharge.name.clone() | |
]; | |
spells.insert(magic_missle.name.clone(), magic_missle); | |
spells.insert(drain.name.clone(), drain); | |
spells.insert(shield.name.clone(), shield); | |
spells.insert(poison.name.clone(), poison); | |
spells.insert(recharge.name.clone(), recharge); | |
let mut buffs = Vec::<Buff>::new(); | |
let mut mana = 0; | |
loop { | |
if player.hp > 0 { | |
// start player turn | |
apply_buffs(&mut player, &mut boss, &mut buffs); | |
let spell = choose_spell(&spells, &spell_keys, &player, &boss, &buffs); | |
if spell.duration > 0 { | |
buffs.push(Buff::new(spell, spell.duration)); | |
} else { | |
for spell_effect in spell.spell_effects.iter() { | |
apply_spell_effect(&mut player, &mut boss, spell_effect); | |
} | |
} | |
player.mana -= spell.mana_cost; | |
mana += spell.mana_cost; | |
if player.mana < 0 { | |
reset(&mut player, &mut boss, &mut buffs); | |
mana = 0; | |
continue | |
} | |
// start boss turn | |
apply_buffs(&mut player, &mut boss, &mut buffs); | |
if boss.hp > 0 { | |
let mut damage = boss.damage - player.armor; | |
if damage < 1 { | |
damage = 1; | |
} | |
player.hp -= damage; | |
} else { | |
println!("Mana total: {:?}", mana); | |
println!("{:?} {:?}", player.hp, boss.hp); | |
break; | |
} | |
} else { | |
let t = cmp::min(min_hp, boss.hp); | |
if t < min_hp { | |
min_hp = t; | |
println!("{:?}", min_hp); | |
} | |
reset(&mut player, &mut boss, &mut buffs); | |
mana = 0; | |
continue | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment