From c69e6c0770359e2febafcf487eb21c4aa608c3e9 Mon Sep 17 00:00:00 2001 From: ewy Date: Fri, 11 Sep 2026 15:00:48 +0200 Subject: initial commit --- engine/card/attack.go | 11 +++++++ engine/card/card.go | 16 +++++++++ engine/card/damage.go | 5 +++ engine/card/range.go | 11 +++++++ engine/character/character.go | 15 +++++++++ engine/game/game.go | 33 +++++++++++++++++++ engine/player/action.go | 12 +++++++ engine/player/player.go | 34 +++++++++++++++++++ engine/player/vigour.go | 52 +++++++++++++++++++++++++++++ engine/pool/pool.go | 58 +++++++++++++++++++++++++++++++++ engine/pool/pool_test.go | 76 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 323 insertions(+) create mode 100644 engine/card/attack.go create mode 100644 engine/card/card.go create mode 100644 engine/card/damage.go create mode 100644 engine/card/range.go create mode 100644 engine/character/character.go create mode 100644 engine/game/game.go create mode 100644 engine/player/action.go create mode 100644 engine/player/player.go create mode 100644 engine/player/vigour.go create mode 100644 engine/pool/pool.go create mode 100644 engine/pool/pool_test.go (limited to 'engine') diff --git a/engine/card/attack.go b/engine/card/attack.go new file mode 100644 index 0000000..19ad196 --- /dev/null +++ b/engine/card/attack.go @@ -0,0 +1,11 @@ +package card + +type Attack struct { + *Card + + MinDistance RangeValue + MaxDistance RangeValue + + AuraDamage DamageValue + HealthDamage DamageValue +} diff --git a/engine/card/card.go b/engine/card/card.go new file mode 100644 index 0000000..f2dce83 --- /dev/null +++ b/engine/card/card.go @@ -0,0 +1,16 @@ +package card + +type Card struct { + Name string + AllOut bool + Text string + Flavor string +} + +func (c *Card) Base() *Card { + return c +} + +type IsCard interface { + Base() *Card +} diff --git a/engine/card/damage.go b/engine/card/damage.go new file mode 100644 index 0000000..fccb073 --- /dev/null +++ b/engine/card/damage.go @@ -0,0 +1,5 @@ +package card + +type DamageValue int + +const Unselectable = DamageValue(-1) diff --git a/engine/card/range.go b/engine/card/range.go new file mode 100644 index 0000000..3c6a5c9 --- /dev/null +++ b/engine/card/range.go @@ -0,0 +1,11 @@ +package card + +type RangeValue int + +const NoMinimumRange = RangeValue(0) +const NoMaximumRange = RangeValue(10) + +type Range struct { + Min RangeValue + Max RangeValue +} diff --git a/engine/character/character.go b/engine/character/character.go new file mode 100644 index 0000000..66671ae --- /dev/null +++ b/engine/character/character.go @@ -0,0 +1,15 @@ +package character + +import ( + "sakura/engine/card" +) + +type Character struct { + Name string + Cards []card.IsCard + Ultimates []card.IsCard +} + +func (c *Character) String() string { + return c.Name +} diff --git a/engine/game/game.go b/engine/game/game.go new file mode 100644 index 0000000..7f3fa76 --- /dev/null +++ b/engine/game/game.go @@ -0,0 +1,33 @@ +package game + +import ( + "sakura/engine/player" + "sakura/engine/pool" +) + +type Game struct { + Shadow *pool.Pool + Distance *pool.Pool + Yin *player.Player + Yang *player.Player + + Must []player.PlayerAction + May []player.PlayerAction +} + +func (g *Game) propagate() { + g.Distance.OverflowsTo = g.Shadow +} + +func New() *Game { + g := &Game{ + Shadow: pool.New(0, pool.Infinite), + Distance: pool.New(0, 10), + Must: nil, + May: nil, + } + g.Yin = player.New(g) + g.Yang = player.New(g) + g.propagate() + return g +} diff --git a/engine/player/action.go b/engine/player/action.go new file mode 100644 index 0000000..0d8aa58 --- /dev/null +++ b/engine/player/action.go @@ -0,0 +1,12 @@ +package player + +type Action int + +const ( + _ = iota +) + +type PlayerAction struct { + Player *Player + Action Action +} diff --git a/engine/player/player.go b/engine/player/player.go new file mode 100644 index 0000000..9dece55 --- /dev/null +++ b/engine/player/player.go @@ -0,0 +1,34 @@ +package player + +import ( + "sakura/engine/card" + "sakura/engine/game" + "sakura/engine/pool" +) + +type Player struct { + Game *game.Game + Vigour *Vigour + Life *pool.Pool + Aura *pool.Pool + Flare *pool.Pool + MasterDeck []*card.Card + Ultimates []*card.Card +} + +func (p *Player) propagate(g *game.Game) { + p.Game = g + p.Aura.SubtractsTo = g.Shadow + p.Flare.SubtractsTo = g.Shadow + p.Life.SubtractsTo = p.Flare +} + +func New(g *game.Game) *Player { + p := &Player{ + Life: pool.New(pool.Empty, 10), + Aura: pool.New(3, 5), + Flare: pool.New(pool.Empty, pool.Infinite), + } + p.propagate(g) + return p +} diff --git a/engine/player/vigour.go b/engine/player/vigour.go new file mode 100644 index 0000000..1d4022e --- /dev/null +++ b/engine/player/vigour.go @@ -0,0 +1,52 @@ +package player + +import ( + "sakura/engine/pool" +) + +type Vigour int + +type VigorAction struct { + Name string + From func(p *Player) *pool.Pool + To func(p *Player) *pool.Pool +} + +var Actions = []*VigorAction{ + { + Name: "Approach", + From: func(p *Player) *pool.Pool { + return p.Game.Distance + }, + To: func(p *Player) *pool.Pool { + return p.Aura + }, + }, + { + Name: "Retreat", + From: func(p *Player) *pool.Pool { + return p.Aura + }, + To: func(p *Player) *pool.Pool { + return p.Game.Distance + }, + }, + { + Name: "Charge", + From: func(p *Player) *pool.Pool { + return p.Aura + }, + To: func(p *Player) *pool.Pool { + return p.Flare + }, + }, + { + Name: "Recover", + From: func(p *Player) *pool.Pool { + return p.Game.Shadow + }, + To: func(p *Player) *pool.Pool { + return p.Aura + }, + }, +} diff --git a/engine/pool/pool.go b/engine/pool/pool.go new file mode 100644 index 0000000..2179a12 --- /dev/null +++ b/engine/pool/pool.go @@ -0,0 +1,58 @@ +package pool + +const Infinite = -1 +const Empty = 0 + +type Pool struct { + OverflowsTo *Pool + SubtractsTo *Pool + Max int + Value int +} + +func (p *Pool) Add(amount int) { + p.Value += amount + if p.Max == Infinite { + return + } + + if p.Value > p.Max { + overflow := p.Value - p.Max + p.Value = p.Max + p.OverflowsTo.Add(overflow) + } +} + +func (p *Pool) Subtract(amount int) { + if p.SubtractsTo != nil { + forward := amount + if forward > p.Value { + forward = p.Value + } + p.SubtractsTo.Add(forward) + } + + if p.Value == Infinite { + return + } + + p.Value -= amount + if p.Value < 0 { + p.Value = 0 + } +} + +func (p *Pool) Fits(amount int) bool { + return p.Value+amount <= p.Max +} + +func (p *Pool) Has(amount int) bool { + return p.Value >= amount +} + +func New(start, max int) *Pool { + return &Pool{ + Max: max, + Value: start, + } +} diff --git a/engine/pool/pool_test.go b/engine/pool/pool_test.go new file mode 100644 index 0000000..4dd0ea5 --- /dev/null +++ b/engine/pool/pool_test.go @@ -0,0 +1,76 @@ +package pool + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestPool_Add(t *testing.T) { + p := &Pool{ + Max: 10, + Value: 3, + } + p.Add(4) +} + +func TestPool_Add_Overflows(t *testing.T) { + shad := &Pool{ + Max: 5, + Value: 0, + } + dist := &Pool{ + OverflowsTo: shad, + Max: 5, + Value: 0, + } + dist.Add(8) + assert.Equal(t, shad.Value, 3) +} + +func TestPool_Subtract(t *testing.T) { + p := &Pool{ + Max: 10, + Value: 8, + } + p.Subtract(6) + assert.Equal(t, 2, p.Value) +} + +func TestPool_Subtract_Empties(t *testing.T) { + p := &Pool{ + Max: 10, + Value: 4, + } + p.Subtract(8) + assert.Equal(t, 0, p.Value) +} + +func TestPool_Subtract_Flows(t *testing.T) { + dest := &Pool{ + Value: 0, + Max: Infinite, + } + p := &Pool{ + SubtractsTo: dest, + Max: Infinite, + Value: 10, + } + p.Subtract(8) + assert.Equal(t, 8, dest.Value) + assert.Equal(t, 2, p.Value) +} + +func TestPool_Subtract_Flows_Empties(t *testing.T) { + dest := &Pool{ + Value: 0, + Max: Infinite, + } + p := &Pool{ + SubtractsTo: dest, + Max: Infinite, + Value: 5, + } + p.Subtract(8) + assert.Equal(t, 5, dest.Value) + assert.Equal(t, 0, p.Value) +} -- cgit v1.3.1