use context::{CharacterKind, Context};
use loot::{Loot, LootKind};
use gametools::GameResult;
use gametools::refilling_pool::RefillingPool;
fn main() -> GameResult<()> {
use LootKind::*;
let loot_items = [
(Weapon, "Longsword"),
(Weapon, "Shortsword +1"),
(Weapon, "Halberd"),
(HealthPotion, "Blue Health +10"),
(HealthPotion, "Violet Health +20"),
(MagicItem, "Amulet of Protection +1"),
(MagicItem, "Boots of Speed +1"),
(ManaPotion, "Wizard's Flask"),
(ManaPotion, "Alchemist's Ale"),
(SpellBook, "Magic Missile"),
(SpellBook, "Conjure Familiar"),
(SpellBook, "Levitation"),
]
.into_iter()
.map(Loot::from)
.collect::<Vec<_>>();
let mut infinite_chest = RefillingPool::new(loot_items)?;
let loot_matcher = |context: &Context, loot: &Loot| match loot.kind {
HealthPotion => context.current_hp < 10,
MagicItem => true,
ManaPotion => context.class == CharacterKind::Wizard,
SpellBook => context.class == CharacterKind::Wizard,
Weapon => context.class == CharacterKind::Fighter,
};
let mut character_kinds = RefillingPool::new([CharacterKind::Fighter, CharacterKind::Wizard])?;
let mut hp_configs = RefillingPool::new([5, 8, 12, 20])?;
let character_count = 100;
println!(
"{character_count} characters drawing from the infinite chest with refill pool of {} items...",
infinite_chest.full_size()
);
for _ in 0..character_count {
let context = Context::new(character_kinds.draw(), hp_configs.draw());
let loot = infinite_chest.draw_with_context_or_any(&context, loot_matcher);
println!("Character [{context}] → {loot}");
}
Ok(())
}
mod context {
#[derive(Debug, Clone, Copy, PartialEq)]
pub(super) struct Context {
pub(super) class: CharacterKind,
pub(super) current_hp: u64,
}
impl Context {
pub(super) fn new(character: CharacterKind, current_hp: u64) -> Self {
Self {
class: character,
current_hp,
}
}
}
impl std::fmt::Display for Context {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{} ({} hp)",
match self.class {
CharacterKind::Fighter => "Fighter",
CharacterKind::Wizard => "Wizard",
},
self.current_hp
)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub(super) enum CharacterKind {
Fighter,
Wizard,
}
}
mod loot {
#[derive(Debug, Clone, PartialEq)]
pub(super) struct Loot {
pub(super) name: String,
pub(super) kind: LootKind,
}
impl From<(LootKind, &str)> for Loot {
fn from(value: (LootKind, &str)) -> Self {
Self {
kind: value.0,
name: value.1.to_string(),
}
}
}
impl std::fmt::Display for Loot {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({:?})", self.name, self.kind)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub(super) enum LootKind {
Weapon,
HealthPotion,
MagicItem,
ManaPotion,
SpellBook,
}
}