OA2SY6VNE4QSCQJ5PUNJ42RB7BK5PE26CWBAOYNGDVGIBWPHCGOAC pub struct Support;pub struct Supports;
pub struct Summon;pub struct Summons;
use enum_dispatch::enum_dispatch;#[enum_dispatch(StatusTrait)]pub enum Status {}#[enum_dispatch]pub trait StatusTrait {}pub struct Statuses;pub struct EquipmentStatuses;pub enum Preprocessables {Swap,Skill,Card,DmgElement,DmgReaction,DmgAmountPlus,DmgAmountMinus,DmgAmountMul,RollChances,}pub enum Informables {DmgDelt,SkillUsage,CharacterDeath,}
use enumset::EnumSetType;use Reaction::*;#[repr(u8)]#[derive(EnumSetType, Debug)]pub enum Reaction {BLOOM,BURNING,CRYSTALLIZE,ELECTROCHARGED,FROZEN,MELT,OVERLOADED,QUICKEN,SUPERCONDUCT,SWIRL,VAPORIZE,}use crate::element::Element::{self, *};use crate::element::ElementSet;use crate::element::{elem_set, ElementalAura};macro_rules! test {($fst:expr, $snd:expr; $value:path, $($rest:path),* $(,)*) => {if $value.test_reaction($fst, $snd) { return Some($value) };$(if $rest.test_reaction($fst, $snd) { return Some($value) });*}}macro_rules! test_detail {($fst:expr, $snd:expr; $value:path, $($rest:path),* $(,)*) => {if $value.test_reaction($fst, $snd) { return Some(ReactionDetail::new($value, $fst, $snd)) };$(if $rest.test_reaction($fst, $snd) { return Some(ReactionDetail::new($value, $fst, $snd)) });*}}impl Reaction {pub const fn reaction_elems(self) -> (ElementSet, ElementSet) {use elem_set as S;match self {BLOOM => (S!(DENDRO), S!(HYDRO)),BURNING => (S!(DENDRO), S!(PYRO)),CRYSTALLIZE => (S!(PYRO, HYDRO, CRYO, ELECTRO), S!(GEO)),ELECTROCHARGED => (S!(HYDRO), S!(ELECTRO)),FROZEN => (S!(HYDRO), S!(CRYO)),MELT => (S!(PYRO), S!(CRYO)),OVERLOADED => (S!(PYRO), S!(ELECTRO)),QUICKEN => (S!(DENDRO), S!(ELECTRO)),SUPERCONDUCT => (S!(CRYO), S!(ELECTRO)),SWIRL => (S!(PYRO, HYDRO, CRYO, ELECTRO), S!(ANEMO)),VAPORIZE => (S!(HYDRO), S!(PYRO)),}}pub const fn damage_boost(self) -> usize {match self {BLOOM => 1,BURNING => 1,CRYSTALLIZE => 1,ELECTROCHARGED => 1,FROZEN => 1,MELT => 2,OVERLOADED => 2,QUICKEN => 1,SUPERCONDUCT => 1,SWIRL => 0,VAPORIZE => 2,}}fn test_reaction(self, fst: Element, snd: Element) -> bool {let (x, y) = self.reaction_elems();x.contains(fst) && y.contains(snd) || y.contains(fst) && x.contains(snd)}pub fn consult_reaction(fst: Element, snd: Element) -> Option<Reaction> {test!(fst, snd;BURNING,CRYSTALLIZE,ELECTROCHARGED,FROZEN,MELT,OVERLOADED,QUICKEN,SUPERCONDUCT,SWIRL,VAPORIZE,);None}pub fn consult_reaction_detail(fst: Element, snd: Element) -> Option<ReactionDetail> {test_detail!(fst, snd;BURNING,CRYSTALLIZE,ELECTROCHARGED,FROZEN,MELT,OVERLOADED,QUICKEN,SUPERCONDUCT,SWIRL,VAPORIZE,);None}pub fn consult_reaction_with_aura(aura: ElementalAura, snd: Element) -> Option<ReactionDetail> {aura.consult_reaction(snd)}}pub struct ReactionDetail {reaction: Reaction,fst: Element,snd: Element,}impl ReactionDetail {pub const fn new(reaction: Reaction, fst: Element, snd: Element) -> Self {Self { reaction, fst, snd }}pub fn elem_reaction(self, elem: Element) -> bool {self.fst == elem || self.snd == elem}}
use crate::{act::Act, card::Cards, character::Characters, dice::ActualDices, status::Statuses,summon::Summons, support::Supports,};pub struct PlayerState {pub phase: Act,pub conset_action: bool,pub charcters: Characters,pub hidden_statuses: Statuses,pub combat_statuses: Statuses,pub summons: Summons,pub supports: Supports,pub card_redraw_chances: usize,pub dice_reroll_chances: usize,pub dices: ActualDices,pub hand_cards: Cards,pub deck_cards: Cards,pub publicly_used_cards: Cards,pub publicly_gained_cards: Cards,}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]pub enum Pid {Player1,Player2,}impl std::ops::Not for Pid {type Output = Pid;fn not(self) -> Self::Output {match self {Pid::Player1 => Pid::Player2,Pid::Player2 => Pid::Player1,}}}
use enum_dispatch::enum_dispatch;use crate::{game_state::GameState, pid::Pid, act::Act, action_generator::ActionGenerator};#[enum_dispatch(PhaseTrait)]pub enum Phase {CardsSelectPhase,}#[enum_dispatch]trait PhaseTrait {fn step(&self, state: &GameState) -> GameState;fn step_action(&self, state: &GameState, pid: Pid) -> GameState;fn waiting_for(&self, state: &GameState) -> Option<Pid>;fn action_generator(&self, state: &GameState, pid: Pid) -> ActionGenerator;}struct CardsSelectPhase;impl PhaseTrait for CardsSelectPhase {fn step(&self, state: &GameState) -> GameState {let ref p1 = state.player1;let ref p2 = state.player2;todo!()}fn step_action(&self, state: &GameState, pid: Pid) -> GameState {todo!()}fn waiting_for(&self, state: &GameState) -> Option<Pid> {todo!()}fn action_generator(&self, state: &GameState, pid: Pid) -> ActionGenerator {todo!()}}
use crate::{dice::{AbstractDices, Dices},element::Element,event::EventSpeed,};use once_cell::sync::Lazy;const CARD_REDRAW_CHANCES: usize = 1;const DECK_CARDS_REQUIREMENT: usize = 30;const DECK_CARD_LIMIT_PER_KIND: usize = 2;const DECK_CHARS_REQUIREMENT: usize = 3;const DECK_CHAR_LIMIT_PER_KIND: usize = 1;const DICE_LIMIT: usize = 16;const DICE_REROLL_CHANCES: usize = 1;const HAND_CARD_LIMIT: usize = 10;const MAX_CARDS_PER_KIND: usize = 2;const ROUND_LIMIT: usize = 15;const SUMMONS_LIMIT: usize = 4;const SUPPORTS_LIMIT: usize = 4;const SWAP_COST: Lazy<AbstractDices> = Lazy::new(|| AbstractDices::new_from_element_iter([Element::ANY; 1].into_iter()));const SWAP_SPEED: EventSpeed = EventSpeed::Combat;pub struct Mode {card_redraw_chances: usize,deck_cards_requirement: usize,deck_card_limit_per_kind: usize,deck_chars_requirement: usize,deck_char_limit_per_kind: usize,dice_limit: usize,dice_reroll_chances: usize,hand_card_limit: usize,max_cards_per_kind: usize,round_limit: usize,summons_limit: usize,supports_limit: usize,swap_cost: AbstractDices,swap_speed: EventSpeed,}impl Default for Mode {fn default() -> Self {Self {card_redraw_chances: CARD_REDRAW_CHANCES,deck_cards_requirement: DECK_CARDS_REQUIREMENT,deck_card_limit_per_kind: DECK_CARD_LIMIT_PER_KIND,deck_chars_requirement: DECK_CHARS_REQUIREMENT,deck_char_limit_per_kind: DECK_CHAR_LIMIT_PER_KIND,dice_limit: DICE_LIMIT,dice_reroll_chances: DICE_REROLL_CHANCES,hand_card_limit: HAND_CARD_LIMIT,max_cards_per_kind: MAX_CARDS_PER_KIND,round_limit: ROUND_LIMIT,summons_limit: SUMMONS_LIMIT,supports_limit: SUPPORTS_LIMIT,swap_cost: SWAP_COST.clone(),swap_speed: SWAP_SPEED,}}}
fn main() {println!("Hello, world!");}
#![allow(dead_code)]mod act;mod action;mod action_generator;mod agent;mod card;mod character;mod deck;mod dice;mod effect;mod element;mod event;mod game_state_machine;mod game_state;mod mode;mod phase;mod pid;mod player_state;mod reaction;mod status;mod summon;mod support;
use typed_arena::Arena;use crate::{game_state::GameState, action::PlayerAction, agent::PlayerAgent};pub struct GameStateMachine<'a> {pub state_arena: Arena<GameState>,pub action_arena: Arena<PlayerAction>,pub history: Vec<&'a GameState>,pub action_history: Vec<&'a PlayerAction>,pub current_state: &'a GameState,pub player_agent1: PlayerAgent,pub player_agent2: PlayerAgent,}
use crate::{effect::EffectStack, mode::Mode, phase::Phase, pid::Pid, player_state::PlayerState};pub struct GameState {pub mode: Mode,pub phase: Phase,pub round: usize,pub active_player: Pid,pub player1: PlayerState,pub player2: PlayerState,pub effect_stack: EffectStack,}
use enum_map::Enum;use enumset::EnumSetType;#[derive(Enum, EnumSetType, Debug)]pub enum EventSpeed {Fast,Combat,}#[derive(Enum, EnumSetType, Debug)]pub enum EventType {Normal,ElementalSkill1,ElementalSkill2,ElementalBurst,Swap,}
use crate::reaction::{Reaction, ReactionDetail};use enum_map::Enum;use enumset::{enum_set, EnumSet, EnumSetType};use Element::*;#[repr(u8)]#[derive(Enum, EnumSetType, Debug)]pub enum Element {OMNI,PYRO,HYDRO,ANEMO,ELECTRO,DENDRO,CRYO,GEO,PHYSICAL,PIERCING,ANY,}impl Element {pub fn is_pure(self) -> bool {!matches!(self, OMNI | PHYSICAL | PIERCING | ANY)}}pub const PURE_ELEMENTS: ElementSet = elem_set!(PYRO, HYDRO, ANEMO, ELECTRO, DENDRO, CRYO, GEO);pub const ORDERED_AURA_ELEMENTS: [Element; 5] = [PYRO, HYDRO, ELECTRO, CRYO, DENDRO];pub const AURA_ELEMENTS: ElementSet = elem_set!(PYRO, HYDRO, ELECTRO, CRYO, DENDRO);pub const ORDERED_LEGAL_ACTUAL_DICE_ELEMENTS: [Element; 8] =[OMNI, CRYO, HYDRO, PYRO, ELECTRO, GEO, DENDRO, ANEMO];pub const LEGAL_ACTUAL_DICE_ELEMENTS: ElementSet =elem_set!(OMNI, PYRO, HYDRO, ANEMO, ELECTRO, DENDRO, CRYO, GEO);pub const LEGAL_ABSTRACT_DICE_ELEMENTS: ElementSet =elem_set!(OMNI, PYRO, HYDRO, ANEMO, ELECTRO, DENDRO, CRYO, GEO, ANY);#[derive(Clone, Copy, PartialEq, Debug)]pub struct ElementalAura(ElementSet);impl ElementalAura {pub fn aurable(elem: Element) -> bool {AURA_ELEMENTS.contains(elem)}pub fn peek(self) -> Option<Element> {for elem in ORDERED_AURA_ELEMENTS.iter() {if self.0.contains(*elem) {return Some(*elem);}}None}pub fn remove(self, elem: Element) -> ElementalAura {assert!(Self::aurable(elem));ElementalAura(self.0 - elem)}pub fn add(self, elem: Element) -> ElementalAura {assert!(Self::aurable(elem));ElementalAura(self.0 | elem)}pub fn contains(self, elem: Element) -> bool {assert!(Self::aurable(elem));self.0.contains(elem)}pub fn has_aura(self) -> bool {!self.0.is_empty()}pub fn elem_auras(self) -> ElementSet {self.0}pub fn consult_reaction(self, income: Element) -> Option<ReactionDetail> {for elem in ORDERED_AURA_ELEMENTS.into_iter() {if self.contains(elem) {if let Some(detail) = Reaction::consult_reaction_detail(elem, income) {return Some(detail);}}}None}}pub type ElementSet = EnumSet<Element>;#[macro_export]macro_rules! _elem_set {($(|)*) => { { use enumset::enum_set; enum_set!() } };($value:path $(,)*) => { { use enumset::enum_set; enum_set!($value) } };($value:path , $($rest:path),* $(,)*) => { { use enumset::enum_set; enum_set!($value $(| $rest)*) } };}pub(crate) use _elem_set as elem_set;
pub enum Zone {Characters,Summons,Supports,HiddenStatuses,CombatStatuses,}
use enum_dispatch::enum_dispatch;#[enum_dispatch(TriggerrableEffectTrait)]pub enum TriggerrableEffect {AllStatusTriggererEffect,PlayerStatusTriggererEffect,PersonalStatusTriggerEffect,TriggerStatusEffect,TriggerHiddenStatusEffect,TriggerCombatStatusEffect,TriggerSummonEffect,TriggerSupportEffect,}#[enum_dispatch]pub trait TriggerrableEffectTrait {}pub struct AllStatusTriggererEffect;pub struct PlayerStatusTriggererEffect;pub struct PersonalStatusTriggerEffect;pub struct TriggerStatusEffect;pub struct TriggerHiddenStatusEffect;pub struct TriggerCombatStatusEffect;pub struct TriggerSummonEffect;pub struct TriggerSupportEffect;
pub enum TriggeringSignal {FastAction,CombatAction,DeathEvent,TriggerRevival,SwapEvent1,SwapEvent2,PostReaction,PostDmg,GameStart,RoundStart,PreAction,ActPreSkill,SelfDeclareEndRound,OppoDeclareEndRound,EndRoundCheckOut,RoundEnd,}
use crate::pid::Pid;use super::zone::Zone;pub enum DynamicCharacterTarget {SelfSelf,SelfActive,SelfOffField,SelfAll,SelfAbs,OppoActive,OppoOffField,}pub struct StaticTarget {pid: Pid,zone: Zone,id: usize,}
use enum_dispatch::enum_dispatch;#[enum_dispatch(PhaseEffectTrait)]pub enum PhaseEffect {DeathSwapPhaseStartEffect,DeathSwapPhaseEndEffect,EndPhaseCheckoutEffect,EndRoundEffect,RollPhaseStartEffect,SetBothPlayerPhaseEffect,TurnEndEffect,}#[enum_dispatch]pub trait PhaseEffectTrait {}pub struct DeathSwapPhaseStartEffect;pub struct DeathSwapPhaseEndEffect;pub struct EndPhaseCheckoutEffect;pub struct EndRoundEffect;pub struct RollPhaseStartEffect;pub struct SetBothPlayerPhaseEffect;pub struct TurnEndEffect;
use enum_dispatch::enum_dispatch;pub mod damage_type;pub mod target;pub mod triggering_signal;pub mod zone;pub mod triggerrable_effect;pub mod phase_effect;pub mod checker_effect;pub mod direct_effect;#[enum_dispatch(EffectTrait)]pub enum Effect {TriggerrableEffect,PhaseEffect,CheckerEffect,DirectEffect,}#[enum_dispatch]pub trait EffectTrait {}type TriggerrableEffect = triggerrable_effect::TriggerrableEffect;type PhaseEffect = phase_effect::PhaseEffect;type CheckerEffect = checker_effect::CheckerEffect;type DirectEffect = direct_effect::DirectEffect;pub struct EffectStack {pub effects: Vec<Effect>,}
use enum_dispatch::enum_dispatch;#[enum_dispatch(DirectEffectTrait)]pub enum DirectEffect {ConsecutiveActionEffect,SwapCharacterEffect,BackwardSwapCharacterEffect,ForwardSwapCharacterEffect,ForwardSwapCharacterCheckEffect,ApplyElementalAuraEffect,SpecificDamageEffect,ReferredDamageEffect,EnergyRechargeEffect,EnergyDrainEffect,RecoverHPEffect,ReviveRecoverHPEffect,PublicAddCardEffect,PublicRemoveCardEffect,PublicRemoveAllCardEffect,AddDiceEffect,RemoveDiceEffect,AddCharacterStatusEffect,RemoveCharacterStatusEffect,UpdateCharacterStatusEffect,OverrideCharacterStatusEffect,AddHiddenStatusEffect,RemoveHiddenStatusEffect,UpdateHiddenStatusEffect,OverrideHiddenStatusEffect,AddCombatStatusEffect,RemoveCombatStatusEffect,UpdateCombatStatusEffect,OverrideCombatStatusEffect,AddSummonEffect,RemoveSummonEffect,UpdateSummonEffect,OverrideSummonEffect,AllSummonIncreaseUsage,OneSummonDecreaseUsage,OneSummonIncreaseUsage,AddSupportEffect,RemoveSupportEffect,UpdateSupportEffect,OverrideSupportEffect,CastSkillEffect,BroadCastSkillInfoEffect,}#[enum_dispatch]pub trait DirectEffectTrait {}pub struct ConsecutiveActionEffect;pub struct SwapCharacterEffect;pub struct BackwardSwapCharacterEffect;pub struct ForwardSwapCharacterEffect;pub struct ForwardSwapCharacterCheckEffect;pub struct ApplyElementalAuraEffect;pub struct SpecificDamageEffect;pub struct ReferredDamageEffect;pub struct EnergyRechargeEffect;pub struct EnergyDrainEffect;pub struct RecoverHPEffect;pub struct ReviveRecoverHPEffect;pub struct PublicAddCardEffect;pub struct PublicRemoveCardEffect;pub struct PublicRemoveAllCardEffect;pub struct AddDiceEffect;pub struct RemoveDiceEffect;pub struct AddCharacterStatusEffect;pub struct RemoveCharacterStatusEffect;pub struct UpdateCharacterStatusEffect;pub struct OverrideCharacterStatusEffect;pub struct AddHiddenStatusEffect;pub struct RemoveHiddenStatusEffect;pub struct UpdateHiddenStatusEffect;pub struct OverrideHiddenStatusEffect;pub struct AddCombatStatusEffect;pub struct RemoveCombatStatusEffect;pub struct UpdateCombatStatusEffect;pub struct OverrideCombatStatusEffect;pub struct AddSummonEffect;pub struct RemoveSummonEffect;pub struct UpdateSummonEffect;pub struct OverrideSummonEffect;pub struct AllSummonIncreaseUsage;pub struct OneSummonDecreaseUsage;pub struct OneSummonIncreaseUsage;pub struct AddSupportEffect;pub struct RemoveSupportEffect;pub struct UpdateSupportEffect;pub struct OverrideSupportEffect;pub struct CastSkillEffect;pub struct BroadCastSkillInfoEffect;
use enumset::{EnumSetType, EnumSet};#[derive(EnumSetType, Debug)]pub enum DamageKind {NormalAttack,ChargedAttack,PlungeAttack,ElementalSkill,ElementalBurst,Status,Summon,Reaction,NoBoost,}pub type DamageType = EnumSet<DamageKind>;
use enum_dispatch::enum_dispatch;#[enum_dispatch(CheckerEffectTrait)]pub enum CheckerEffect {AliveMarkCheckerEffect,SwapCharacterCheckerEffect,DeathCheckCheckerEffect,DefeatedCheckerEffect,}#[enum_dispatch]pub trait CheckerEffectTrait {}pub struct AliveMarkCheckerEffect;pub struct SwapCharacterCheckerEffect;pub struct DeathCheckCheckerEffect;pub struct DefeatedCheckerEffect;
use std::ops::Index;use crate::element::{Element::{*, self}, ElementSet, LEGAL_ABSTRACT_DICE_ELEMENTS, LEGAL_ACTUAL_DICE_ELEMENTS, PURE_ELEMENTS,};use enum_map::EnumMap;use rand::{seq::IteratorRandom, thread_rng};pub trait Dices<Rhs = Self> {type Output;fn empty() -> Self;fn new_from_counter_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = (Element, i8)>;fn new_from_element_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = Element>;fn add_mut(&mut self, other: &Rhs);fn add(&self, other: &Rhs) -> Self::Output;fn sub_mut(&mut self, other: &Rhs);fn sub(&self, other: &Rhs) -> Self::Output;fn add_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>;fn add_elements<T>(&self, other: T) -> Self::OutputwhereT: Iterator<Item = Element>;fn sub_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>;fn sub_elements<T>(&self, other: T) -> Self::OutputwhereT: Iterator<Item = Element>;fn num_dices(&self) -> usize;fn is_even(&self) -> bool;fn is_odd(&self) -> bool;fn is_empty(&self) -> bool;fn is_legal(&self) -> bool;fn elem_set(&self) -> ElementSet;fn elems(&self) -> impl Iterator<Item = Element>;fn values(&self) -> impl Iterator<Item = i8>;fn elem_values(&self) -> impl Iterator<Item = (Element, i8)>;fn legal_elems() -> ElementSet;fn extract_with(&self, eset: ElementSet) -> Self::Output;fn pick_random(&self, x: usize) -> (Self, Self)whereSelf: Sized;fn contains(&self, elem: Element) -> bool;}fn check_is_legal(dices: &impl Dices, legal_elements: ElementSet) -> bool {dices.elem_values().all(|(elem, count)| count > 0 && legal_elements.contains(elem) || count == 0)}impl ActualDices {fn satisfy(&self, requirement: &AbstractDices) -> bool {assert!(self.is_legal() && requirement.is_legal());let upgraded: AbstractDices = self.clone().into();let pure_deducted = upgraded.sub(requirement).extract_with(PURE_ELEMENTS);let omni_required = pure_deducted.values().filter(|x| *x < 0).sum::<i8>();if self[OMNI] < omni_required {return false;}let omni_remained = self[OMNI] - omni_required;let most_pure = pure_deducted.values().max().unwrap();if omni_remained + most_pure < requirement[OMNI] {return false;}true}fn loosely_satify(&self, requirement: &AbstractDices) -> bool {self.num_dices() >= requirement.num_dices() && self.satisfy(requirement)}fn just_satisfy(&self, requirement: &AbstractDices) -> bool {self.num_dices() == requirement.num_dices() && self.satisfy(requirement)}}impl ActualDices {pub const fn new_from_raw(x: EnumMap<Element, i8>) -> Self {ActualDices(x)}}impl AbstractDices {pub const fn new_from_raw(x: EnumMap<Element, i8>) -> Self {AbstractDices(x)}}impl Dices for EnumMap<Element, i8> {type Output = Self;fn empty() -> Self {EnumMap::default()}fn new_from_counter_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = (Element, i8)>,{let mut dices = dices;let mut map = EnumMap::default();while let Some((elem, count)) = dices.next() {map[elem] += count;}map}fn new_from_element_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = Element>,{let mut dices = dices;let mut map = EnumMap::default();while let Some(elem) = dices.next() {map[elem] += 1;}map}fn add_mut(&mut self, other: &Self) {for (elem, count) in other {self[elem] += count;}}fn add(&self, other: &Self) -> Self::Output {let mut new = self.clone();new.add_mut(other);new}fn sub_mut(&mut self, other: &Self) {for (elem, count) in other {self[elem] -= count;}}fn sub(&self, other: &Self) -> Self::Output {let mut new = self.clone();new.sub_mut(other);new}fn add_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>,{for elem in other {self[elem] += 1;}}fn add_elements<T>(&self, other: T) -> Self::OutputwhereT: Iterator<Item = Element>,{let mut new = self.clone();new.add_elements_mut(other);new}fn sub_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>,{for elem in other {self[elem] -= 1;}}fn sub_elements<T>(&self, other: T) -> Self::OutputwhereT: Iterator<Item = Element>,{let mut new = self.clone();new.sub_elements_mut(other);new}fn num_dices(&self) -> usize {assert!(self.is_legal());self.values().sum::<i8>() as usize}fn is_even(&self) -> bool {self.num_dices() % 2 == 0}fn is_odd(&self) -> bool {!self.is_even()}fn is_empty(&self) -> bool {self.num_dices() == 0}fn is_legal(&self) -> bool {unreachable!("EnumMap is always legal")}fn elem_set(&self) -> ElementSet {let mut es = ElementSet::empty();for (elem, count) in self {if *count > 0 {es.insert(elem);}}es}fn elems(&self) -> impl Iterator<Item = Element> {let mut es = Vec::new();for (elem, count) in self {let mut n = *count as usize;while n > 0 {es.push(elem);n -= 1;}}es.into_iter()}fn values(&self) -> impl Iterator<Item = i8> {let mut vs = Vec::new();for (_, count) in self {vs.push(*count);}vs.into_iter()}fn elem_values(&self) -> impl Iterator<Item = (Element, i8)> {self.into_iter().map(|(elem, count)| (elem, *count))}fn legal_elems() -> ElementSet {ElementSet::all()}fn extract_with(&self, eset: ElementSet) -> Self::Output {Self::new_from_counter_iter(self.elem_values().filter(|x| eset.contains(x.0)))}fn pick_random(&self, n: usize) -> (Self, Self) {let m = n.min(self.num_dices());if m == 0 {(self.clone(), Self::empty())} else {let mut trng = thread_rng();let dices = self.elems();let choosen = dices.into_iter().choose_multiple(&mut trng, m);let picked = Self::new_from_element_iter(choosen.into_iter());let new_dices = self.sub(&picked);(new_dices, picked)}}fn contains(&self, elem: Element) -> bool {self[elem] > 0}}#[derive(Debug, Clone, Copy, PartialEq)]pub struct ActualDices(EnumMap<Element, i8>);impl From<EnumMap<Element, i8>> for ActualDices {fn from(map: EnumMap<Element, i8>) -> Self {Self(map)}}impl Dices for ActualDices {type Output = Self;fn empty() -> Self {Self(EnumMap::empty())}fn new_from_counter_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = (Element, i8)>,{EnumMap::new_from_counter_iter(dices).into()}fn new_from_element_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = Element>,{EnumMap::new_from_element_iter(dices).into()}fn add_mut(&mut self, other: &Self) {self.0.add_mut(&other.0)}fn add(&self, other: &Self) -> Self {self.0.add(&other.0).into()}fn sub_mut(&mut self, other: &Self) {self.0.sub_mut(&other.0)}fn sub(&self, other: &Self) -> Self {self.0.sub(&other.0).into()}fn add_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>,{self.0.add_elements_mut(other);}fn add_elements<T>(&self, other: T) -> SelfwhereT: Iterator<Item = Element>,{self.0.add_elements(other).into()}fn sub_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>,{self.0.sub_elements_mut(other);}fn sub_elements<T>(&self, other: T) -> SelfwhereT: Iterator<Item = Element>,{self.0.sub_elements(other).into()}fn num_dices(&self) -> usize {assert!(self.is_legal());self.0.num_dices()}fn is_even(&self) -> bool {self.0.is_even()}fn is_odd(&self) -> bool {self.0.is_odd()}fn is_empty(&self) -> bool {self.0.is_empty()}fn is_legal(&self) -> bool {check_is_legal(self, Self::legal_elems())}fn elem_set(&self) -> ElementSet {self.0.elem_set()}fn elems(&self) -> impl Iterator<Item = Element> {Dices::elems(&self.0)}fn values(&self) -> impl Iterator<Item = i8> {Dices::values(&self.0)}fn elem_values(&self) -> impl Iterator<Item = (Element, i8)> {Dices::elem_values(&self.0)}fn legal_elems() -> ElementSet {LEGAL_ACTUAL_DICE_ELEMENTS}fn extract_with(&self, eset: ElementSet) -> Self::Output {self.0.extract_with(eset).into()}fn pick_random(&self, x: usize) -> (Self, Self)whereSelf: Sized,{let (a, b) = self.0.pick_random(x);(a.into(), b.into())}fn contains(&self, elem: Element) -> bool {self.0.contains(elem)}}#[derive(Debug, Clone, Copy, PartialEq)]pub struct AbstractDices(EnumMap<Element, i8>);impl From<EnumMap<Element, i8>> for AbstractDices {fn from(map: EnumMap<Element, i8>) -> Self {Self(map)}}impl From<ActualDices> for AbstractDices {fn from(dices: ActualDices) -> Self {AbstractDices::new_from_counter_iter(dices.elem_values())}}impl Dices for AbstractDices {type Output = Self;fn empty() -> Self {Self(EnumMap::empty())}fn new_from_counter_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = (Element, i8)>,{EnumMap::new_from_counter_iter(dices).into()}fn new_from_element_iter<T>(dices: T) -> SelfwhereT: Iterator<Item = Element>,{EnumMap::new_from_element_iter(dices).into()}fn add_mut(&mut self, other: &Self) {self.0.add_mut(&other.0)}fn add(&self, other: &Self) -> Self {self.0.add(&other.0).into()}fn sub_mut(&mut self, other: &Self) {self.0.sub_mut(&other.0)}fn sub(&self, other: &Self) -> Self::Output {self.0.sub(&other.0).into()}fn add_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>,{self.0.add_elements_mut(other);}fn add_elements<T>(&self, other: T) -> Self::OutputwhereT: Iterator<Item = Element>,{self.0.add_elements(other).into()}fn sub_elements_mut<T>(&mut self, other: T)whereT: Iterator<Item = Element>,{self.0.sub_elements_mut(other);}fn sub_elements<T>(&self, other: T) -> Self::OutputwhereT: Iterator<Item = Element>,{self.0.sub_elements(other).into()}fn num_dices(&self) -> usize {assert!(self.is_legal());self.0.num_dices()}fn is_even(&self) -> bool {self.0.is_even()}fn is_odd(&self) -> bool {self.0.is_odd()}fn is_empty(&self) -> bool {self.0.is_empty()}fn is_legal(&self) -> bool {check_is_legal(self, Self::legal_elems())}fn elem_set(&self) -> ElementSet {self.0.elem_set()}fn elems(&self) -> impl Iterator<Item = Element> {Dices::elems(&self.0)}fn values(&self) -> impl Iterator<Item = i8> {Dices::values(&self.0)}fn elem_values(&self) -> impl Iterator<Item = (Element, i8)> {Dices::elem_values(&self.0)}fn legal_elems() -> ElementSet {LEGAL_ABSTRACT_DICE_ELEMENTS}fn extract_with(&self, eset: ElementSet) -> Self::Output {self.0.extract_with(eset).into()}fn pick_random(&self, x: usize) -> (Self, Self)whereSelf: Sized,{let (a, b) = self.0.pick_random(x);(a.into(), b.into())}fn contains(&self, elem: Element) -> bool {self.0.contains(elem)}}impl Index<Element> for ActualDices {type Output = i8;fn index(&self, elem: Element) -> &Self::Output {&self.0[elem]}}impl Index<Element> for AbstractDices {type Output = i8;fn index(&self, elem: Element) -> &Self::Output {&self.0[elem]}}
use enum_map::EnumMap;use crate::{card::Cards, character::Character};pub struct Deck {characters: Vec<Character>,cards: Cards,}
use enum_dispatch::enum_dispatch;use crate::{element::{ElementalAura, Element}, event::EventType, status::{Statuses, EquipmentStatuses}, dice::AbstractDices};#[derive(Hash, Eq, PartialEq, Debug)]#[enum_dispatch(CharacterTrait)]pub enum Character {Klee,}#[enum_dispatch]pub trait CharacterTrait {fn status(&self) -> &CharacterStatus;}struct Klee(CharacterInfo, CharacterStatus);impl CharacterTrait for Klee {fn status(&self) -> &CharacterStatus {&self.1}}pub struct CharacterInfo {element: Element,weapon: WeaponType,normal_attack_cost: AbstractDices,elemental_skill1_cost: AbstractDices,elemental_skill2_cost: AbstractDices,elemental_burst_cost: AbstractDices,}pub struct CharacterStatus {id: u8,alive: bool,hp: u8,max_hp: u8,energy: u8,max_energy: u8,hiddens: Statuses,equipments: EquipmentStatuses,statuses: Statuses,elemental_aura: ElementalAura,}pub struct Characters {pub inner: Vec<Character>,pub active: Option<u32>,}impl Characters {fn characters(&self) -> &[Character] {&self.inner}fn characters_in_activity_order(&self) -> Vec<Character> {todo!()}}pub enum CharacterSkill {Normal,ElementalSkill1,ElementalSkill2,ElementalBurst,}impl From<CharacterSkill> for EventType {fn from(skill: CharacterSkill) -> Self {match skill {CharacterSkill::Normal => EventType::Normal,CharacterSkill::ElementalSkill1 => EventType::ElementalSkill1,CharacterSkill::ElementalSkill2 => EventType::ElementalSkill2,CharacterSkill::ElementalBurst => EventType::ElementalBurst,}}}pub enum WeaponType {Bow,Catalyst,Claymore,Polearm,Sword,None,}
use std::collections::HashMap;use enum_dispatch::enum_dispatch;#[enum_dispatch]#[derive(Hash, Eq, PartialEq, Debug)]pub enum Card {}#[enum_dispatch(Card)]pub trait CardTrait {}struct OmniCard;pub struct Cards {pub inner: HashMap<Card, u8>,}
use enum_dispatch::enum_dispatch;#[enum_dispatch(PlayerAgentTrait)]pub enum PlayerAgent {CustomChoiceAgent,LazyAgent,NoneAgent,PuppetAgent,RandomAgent,}#[enum_dispatch]pub trait PlayerAgentTrait {}pub struct CustomChoiceAgent;pub struct LazyAgent;pub struct NoneAgent;pub struct PuppetAgent;pub struct RandomAgent;
pub struct ActionGenerator {}
use enum_dispatch::enum_dispatch;use crate::{card::{Card, Cards},character::CharacterSkill,dice::ActualDices,effect::target::StaticTarget,element::Element,};pub enum ActionType {SelectCards,SelectActiveCharacter,SelectDices,PlayCard,CastSkill,SwapCharacter,ElementalTuning,EndRound,}#[enum_dispatch(PlayerActionTrait)]pub enum PlayerAction {CardsSelectAction,DicesSelectAction,CharacterSelectAction,EndRoundAction,}#[enum_dispatch]pub trait PlayerActionTrait {}pub struct CardsSelectAction {pub cards: Cards,}pub struct DicesSelectAction {pub dices: ActualDices,}pub struct CharacterSelectAction {pub character: usize,}pub struct EndRoundAction;#[enum_dispatch(GameActionTrait)]pub enum GameAction {ElementalTuningAction,CardAction,SkillAction,SwapAction,DeathSwapAction,}#[enum_dispatch]pub trait GameActionTrait {}pub struct ElementalTuningAction {pub card: Card,pub elem: Element,}pub struct CardAction {pub card: Card,pub instruction: Instruction,}pub struct SkillAction {pub character_skill: CharacterSkill,pub instruction: DiceOnlyInstruction,}pub struct SwapAction {pub character: usize,pub instruction: Instruction,}pub struct DeathSwapAction {pub character: usize,}#[enum_dispatch(InstructionTrait)]pub enum Instruction {DiceOnlyInstruction,StaticTargetInstruction,SourceTargetInstruction,}#[enum_dispatch]pub trait InstructionTrait {}pub struct DiceOnlyInstruction {}pub struct StaticTargetInstruction {pub target: StaticTarget,}pub struct SourceTargetInstruction {pub source: StaticTarget,pub target: StaticTarget,}
pub enum Act {ActionPhase,PassiveWaitPhase,ActiveWaitPhase,EndPhase,}
tab_spaces = 2
[package]name = "tcg"version = "0.1.0"edition = "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]enum-map = "2.7.3"enum_dispatch = "0.3.12"enumset = "1.1.3"once_cell = "1.19.0"rand = "0.8.5"typed-arena = "2.0.2"
# This file is automatically @generated by Cargo.# It is not intended for manual editing.version = 3[[package]]name = "cfg-if"version = "1.0.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"[[package]]name = "darling"version = "0.20.3"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"dependencies = ["darling_core","darling_macro",][[package]]name = "darling_core"version = "0.20.3"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"dependencies = ["fnv","ident_case","proc-macro2","quote","syn",][[package]]name = "darling_macro"version = "0.20.3"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"dependencies = ["darling_core","quote","syn",][[package]]name = "enum-map"version = "2.7.3"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9"dependencies = ["enum-map-derive",][[package]]name = "enum-map-derive"version = "0.17.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"dependencies = ["proc-macro2","quote","syn",][[package]]name = "enum_dispatch"version = "0.3.12"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e"dependencies = ["once_cell","proc-macro2","quote","syn",][[package]]name = "enumset"version = "1.1.3"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d"dependencies = ["enumset_derive",][[package]]name = "enumset_derive"version = "0.8.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"dependencies = ["darling","proc-macro2","quote","syn",][[package]]name = "fnv"version = "1.0.7"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"[[package]]name = "getrandom"version = "0.2.11"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"dependencies = ["cfg-if","libc","wasi",][[package]]name = "ident_case"version = "1.0.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"[[package]]name = "libc"version = "0.2.151"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"[[package]]name = "once_cell"version = "1.19.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"[[package]]name = "ppv-lite86"version = "0.2.17"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"[[package]]name = "proc-macro2"version = "1.0.75"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708"dependencies = ["unicode-ident",][[package]]name = "quote"version = "1.0.35"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"dependencies = ["proc-macro2",][[package]]name = "rand"version = "0.8.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"dependencies = ["libc","rand_chacha","rand_core",][[package]]name = "rand_chacha"version = "0.3.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"dependencies = ["ppv-lite86","rand_core",][[package]]name = "rand_core"version = "0.6.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"dependencies = ["getrandom",][[package]]name = "syn"version = "2.0.48"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"dependencies = ["proc-macro2","quote","unicode-ident",][[package]]name = "tcg"version = "0.1.0"dependencies = ["enum-map","enum_dispatch","enumset","once_cell","rand","typed-arena",][[package]]name = "typed-arena"version = "2.0.2"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"[[package]]name = "unicode-ident"version = "1.0.12"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"[[package]]name = "wasi"version = "0.11.0+wasi-snapshot-preview1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
.git.DS_Store.vscode# Added by cargo/target