diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2023-01-24 00:27:50 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-01-27 16:43:44 +0100 |
| commit | 73d40903aecad3efcf7c6055c133f0db86558203 (patch) | |
| tree | e9c8f00fb186e270da92f273f570579f2d0b0d95 /go/game/state.go | |
| parent | fbba48698d8f8b83dfd7d914b0e37338e0d4e2ef (diff) | |
| download | muhqs-game-73d40903aecad3efcf7c6055c133f0db86558203.tar.gz muhqs-game-73d40903aecad3efcf7c6055c133f0db86558203.zip | |
intermediate commit
Diffstat (limited to 'go/game/state.go')
| -rw-r--r-- | go/game/state.go | 187 |
1 files changed, 164 insertions, 23 deletions
diff --git a/go/game/state.go b/go/game/state.go index 5cab9458..1a6ae093 100644 --- a/go/game/state.go +++ b/go/game/state.go @@ -2,21 +2,25 @@ package game import ( "image/color" + "log" "math/rand" + "strconv" + "strings" ) type State struct { - Decks []*Deck - Stores []*Store - Map *Map - Stack *Stack - Hands []*Hand - DiscardPiles []*DiscardPile - Players []*Player - Permanents []Permanent - Units []*Unit - Artifacts []*Artifact - Rand rand.Rand + Decks []*Deck + Stores []*Store + Map *Map + Stack *Stack + Hands []*Hand + DiscardPiles []*DiscardPile + Players []*Player + ActivePlayerId int + Permanents []Permanent + Units []*Unit + Artifacts []*Artifact + Rand rand.Rand } func NewState() *State { @@ -25,15 +29,138 @@ func NewState() *State { return s } -func (s *State) AddNewPlayer(name string, deck *Deck, color color.Color) { - p := NewPlayer(len(s.Players), name, deck, s, color) +func (s *State) AddNewPlayer(name string, deck *Deck, store *Store, color color.Color) { + p := NewPlayer(len(s.Players)+1, name, deck, store, s, color) s.Players = append(s.Players, p) } -func (s *State) AddNewUnit(card string, pos Position, owner *Player) { - unit := NewUnit(card, s.Map.TileAt(pos), owner) - s.Permanents = append(s.Permanents, unit) - s.Units = append(s.Units, unit) +func (s *State) Loop() []*Player { + winners := []*Player{} + for len(winners) == 0 { + for i, p := range s.Players { + log.Printf("Starting %s turn %d\n", p.Name, p.Turn) + s.ActivePlayerId = i + p.Turn++ + + if p.Deck.IsEmpty() { + log.Printf("Shuffle %s pile into the deck\n", p.Name) + p.DiscardPile.MoveInto(p.Deck) + p.Deck.Shuffle() + } + + log.Printf("%s draw\n", p.Name) + p.Draw() + + log.Printf("%s Upkeep\n", p.Name) + p.Upkeep() + s.PhaseChange(i) + + log.Printf("%s Actions\n", p.Name) + p.ActionPhase() + s.PhaseChange(i) + + log.Printf("%s Buystep\n", p.Name) + p.BuyStep() + s.PhaseChange(i) + + log.Printf("%s Discard\n", p.Name) + p.DiscardStep() + + winners = s.Map.WinCondition(s) + } + } + + return winners +} + +func (s *State) PushAction(a Action) { + if !a.PayCosts(s) { + log.Fatalf("Cost for a could not be paid") + } + s.Stack.Push(a) +} + +func (s *State) DeclareAction(a Action) { + if !s.Stack.IsEmpty() { + log.Fatalf("Slow action can not be declared while other actions are on the stack") + } + s.PushAction(a) +} + +func (s *State) DeclareFastAction(a Action) { + s.PushAction(a) +} + +func (s *State) AllPassing() bool { + nPlayers := len(s.Players) + for i := 0; i < nPlayers; i++ { + p := s.Players[(i+s.ActivePlayerId)%nPlayers] + p.Ctrl.SendNotification(NewPriorityNotification()) + a := p.Ctrl.RecvAction() + switch a.(type) { + case *PassPriorityAction: + log.Printf("%s passed %d/%d\n", p.Name, i, nPlayers) + default: + s.Stack.Push(a) + return false + } + } + return true +} + +func (s *State) PhaseChange(activePlaerId int) { + log.Println("Phase change") + for !s.AllPassing() { + s.Stack.Resolve() + } +} + +func (s *State) broadcastNotification(n PlayerNotification) { + log.Printf("broadcasting %v\n", n) + for _, p := range s.Players { + p.Ctrl.SendNotification(n) + } +} + +func (s *State) Upkeep(p *Player) { + p.Ressource += s.Map.RessourceGain + // TODO: handle upkeep trigger + for _, unit := range s.Units { + if unit.Controller != p { + continue + } + + // TODO: let players decide if they want to pay the upkeep + p.Ressource -= unit.Upkeep + } +} + +func (s *State) AddPermanent(perm Permanent) { + s.Permanents = append(s.Permanents, perm) + switch p := perm.(type) { + case *Unit: + s.Units = append(s.Units, p) + case *Artifact: + s.Artifacts = append(s.Artifacts, p) + } +} + +func (s *State) AddNewUnit(card *Card, pos Position, owner *Player) { + s.AddPermanent(NewUnit(card, s.Map.TileAt(pos), owner)) +} + +func (s *State) AddNewArtifact(card *Card, pos Position, owner *Player) { + s.AddPermanent(NewArtifact(card, s.Map.TileAt(pos), owner)) +} + +func (s *State) AddNewPermFromPath(cardPath string, pos Position, owner *Player) { + card := NewCard(cardPath) + switch card.Type { + case UnitType: + s.AddNewUnit(card, pos, owner) + case ArtifactType: + s.AddNewArtifact(card, pos, owner) + } } func (s *State) removePermanent(p Permanent) { @@ -66,12 +193,6 @@ func (s *State) DestroyPermanent(p Permanent) { } } -func (s *State) AddNewArtifact(card string, pos Position, owner *Player) { - artifact := NewArtifact(card, s.Map.TileAt(pos), owner) - s.Permanents = append(s.Permanents, artifact) - s.Artifacts = append(s.Artifacts, artifact) -} - func (s *State) Fight(p1, p2 Permanent) { p1.Fight(p2) p2.Fight(p1) @@ -97,3 +218,23 @@ func (s *State) EnemyUnits(player *Player) []*Unit { } return enemyUnits } + +func (s *State) ResolvePlay(p *Player, c *Card, targets interface{}) { + switch c.Type { + case UnitType: + s.AddNewUnit(c, targets.(Position), p) + } + p.DiscardPile.AddCard(c) +} + +func (s *State) SpawnTiles(p *Player) []*Tile { + spawns := s.Map.FilterTiles(func(t *Tile) bool { + if t.Type != TileTypes.Spawn { + return false + } + + return strings.HasSuffix(t.Raw, strconv.Itoa(p.Id)) || t.Raw == "player spawn" + }) + + return spawns +} |
