From 0723811faf2fdfc2ea41cd269170f5d3dacde908 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 23 Jul 2021 18:33:17 -0400 Subject: [PATCH 1/4] create oracle instead of card objects --- internal/game/board.go | 144 ++++++++++++++-------------- internal/game/card.go | 206 +++++----------------------------------- internal/game/deck.go | 41 ++------ internal/game/game.go | 54 ++++++----- internal/game/oracle.go | 38 ++++++++ internal/game/player.go | 59 +----------- 6 files changed, 178 insertions(+), 364 deletions(-) create mode 100644 internal/game/oracle.go diff --git a/internal/game/board.go b/internal/game/board.go index d2a88bf..bd1ff5d 100644 --- a/internal/game/board.go +++ b/internal/game/board.go @@ -1,19 +1,20 @@ package game import ( - "encoding/json" "fmt" + + "github.com/google/uuid" ) type Board struct { - Sentinal [4]Card `json:"sentinal"` - Scourge [4]Card `json:"scourge"` + Sentinal [4]*Card `json:"sentinal"` + Scourge [4]*Card `json:"scourge"` } func NewBoard() *Board { return &Board{ - Sentinal: [4]Card{CreateCard(-1), CreateCard(-1), CreateCard(-1), CreateCard(-1)}, - Scourge: [4]Card{CreateCard(-1), CreateCard(-1), CreateCard(-1), CreateCard(-1)}, + Sentinal: [4]*Card{NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil)}, + Scourge: [4]*Card{NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil)}, } } @@ -21,7 +22,7 @@ func (b *Board) String() string { return fmt.Sprintf("---------\n|%v|%v|%v|%v|\n---------\n|%v|%v|%v|%v|\n---------\n", b.Sentinal[0], b.Sentinal[1], b.Sentinal[2], b.Sentinal[3], b.Scourge[0], b.Scourge[1], b.Scourge[2], b.Scourge[3]) } -func (b *Board) GetRow(id int) []Card { +func (b *Board) GetRow(id int) []*Card { if id == 1 { return b.Sentinal[:] } else { @@ -29,6 +30,14 @@ func (b *Board) GetRow(id int) []Card { } } +func (b *Board) GetCard(id int, pos int) *Card { + if id == SentinalID { + return b.Sentinal[pos] + } else { + return b.Scourge[pos] + } +} + func (b *Board) Empty(id int) bool { res := true if id == SentinalID { @@ -47,9 +56,9 @@ func (b *Board) Empty(id int) bool { return res } -func (b *Board) Move(id, src, dest int) bool { - var brd [4]Card - if id == 1 { +func (b *Board) CanMove(id, src, dest int) bool { + var brd [4]*Card + if id == SentinalID { brd = b.Sentinal } else { brd = b.Scourge @@ -60,13 +69,31 @@ func (b *Board) Move(id, src, dest int) bool { if !brd[dest].Empty() { return false } - if brd[src].Acted() { + if brd[src].Sick { + return false + } + return true +} + +func (b *Board) Move(id, src, dest int) bool { + var brd [4]*Card + if id == SentinalID { + brd = b.Sentinal + } else { + brd = b.Scourge + } + if brd[src].Empty() { + return false + } + if !brd[dest].Empty() { + return false + } + if brd[src].Sick { return false } - brd[dest].Act() brd[dest] = brd[src] - brd[src] = CreateCard(-1) - if id == 1 { + brd[src] = NewCard(-1, uuid.Nil) + if id == SentinalID { b.Sentinal = brd } else { b.Scourge = brd @@ -75,8 +102,8 @@ func (b *Board) Move(id, src, dest int) bool { } func (b *Board) CanPlay(id int, c *Card, dest int) bool { - var brd [4]Card - if id == 1 { + var brd [4]*Card + if id == SentinalID { brd = b.Sentinal } else { brd = b.Scourge @@ -87,9 +114,9 @@ func (b *Board) CanPlay(id int, c *Card, dest int) bool { return true } -func (b *Board) Play(id int, c *Card, dest int) bool { - var brd [4]Card - if id == 1 { +func (b *Board) Play(id int, c *Card, dest int, should bool) bool { + var brd [4]*Card + if id == SentinalID { brd = b.Sentinal } else { brd = b.Scourge @@ -97,8 +124,10 @@ func (b *Board) Play(id int, c *Card, dest int) bool { if !brd[dest].Empty() { return false } - brd[dest] = *c - if id == 1 { + if should { + brd[dest] = c + } + if id == SentinalID { b.Sentinal = brd } else { b.Scourge = brd @@ -106,23 +135,32 @@ func (b *Board) Play(id int, c *Card, dest int) bool { return true } +func (b *Board) CanAttack(id, atk, def int) bool { + var aBrd [4]*Card + if id == SentinalID { + aBrd = b.Sentinal + } else { + aBrd = b.Scourge + } + if aBrd[atk].Empty() || aBrd[atk].Sick || atk != def { + return false + } + return true +} + func (b *Board) Attack(id int, atk, def int) int { - var aBrd [4]Card - var dBrd [4]Card - if id == 1 { + var aBrd [4]*Card + var dBrd [4]*Card + if id == SentinalID { aBrd = b.Sentinal dBrd = b.Scourge } else { aBrd = b.Scourge dBrd = b.Sentinal } - if aBrd[atk].Empty() || !aBrd[atk].CanAttack(atk, def) { - return -1 - } - aBrd[atk].Act() if dBrd[def].Empty() { //health damage - if id == 1 { + if id == SentinalID { b.Sentinal = aBrd b.Scourge = dBrd } else { @@ -132,29 +170,11 @@ func (b *Board) Attack(id int, atk, def int) int { return 1 } //Do actual battle math - attacker := aBrd[atk].Value() - defender := dBrd[def].Value() - dBrd[def].Acted() - //check atk buffs - for i, v := range aBrd { - if v.Value() == Two { - attacker = attacker + 1 - } - if v.Value() == Three && (i == atk-1 || i == atk+1) { - attacker = attacker + 1 - } - } - for i, v := range dBrd { - if v.Value() == Two { - defender = defender + 1 - } - if v.Value() == Three && (i == def-1 || i == def+1) { - defender = defender + 1 - } - } + attacker := aBrd[atk].Power + defender := dBrd[def].Power if attacker > defender { - dBrd[def] = CreateCard(-1) - if id == 1 { + dBrd[def] = NewCard(-1, uuid.Nil) + if id == SentinalID { b.Sentinal = aBrd b.Scourge = dBrd } else { @@ -164,8 +184,8 @@ func (b *Board) Attack(id int, atk, def int) int { return 0 } if attacker == defender { - aBrd[atk] = CreateCard(-1) - dBrd[def] = CreateCard(-1) + aBrd[atk] = NewCard(-1, uuid.Nil) + dBrd[def] = NewCard(-1, uuid.Nil) if id == 1 { b.Sentinal = aBrd b.Scourge = dBrd @@ -178,23 +198,3 @@ func (b *Board) Attack(id int, atk, def int) int { return -1 } - -func (b *Board) MarshalJSON() ([]byte, error) { - res := [][]*PortableCard{{b.Sentinal[0].Port(), b.Sentinal[1].Port(), b.Sentinal[2].Port(), b.Sentinal[3].Port()}, {b.Scourge[0].Port(), b.Scourge[1].Port(), b.Scourge[2].Port(), b.Scourge[3].Port()}} - return json.Marshal(res) -} - -func (b *Board) UnmarshalJSON(data []byte) (err error) { - var ported [][]PortableCard - err = json.Unmarshal(data, &ported) - if err != nil { - return err - } - for i := 0; i < 4; i++ { - b.Sentinal[i] = NewCard(ported[0][i].Type, ported[0][i].ID) - } - for i := 0; i < 4; i++ { - b.Scourge[i] = NewCard(ported[1][i].Type, ported[0][i].ID) - } - return -} diff --git a/internal/game/card.go b/internal/game/card.go index fd5b23e..2aee713 100644 --- a/internal/game/card.go +++ b/internal/game/card.go @@ -6,79 +6,18 @@ import ( "github.com/google/uuid" ) -type Card interface { - Cast(g *Game) *Game - Upkeep(g *Game) *Game - Endstep(g *Game) *Game - Enters(g *Game) *Game - Value() CardValue - Act() - Acted() bool - Empty() bool - String() string - CanAttack(int, int) bool - Port() *PortableCard +type Card struct { + Type CardType `json:"type"` + Power int `json:"power"` + Id uuid.UUID `json:"id"` + Sick bool `json:"sick"` + Counters int `json:"counters"` } -type GenericCard struct { - Val CardValue `json:"value"` - Id uuid.UUID `json:"id"` - Sick bool `json:"sick"` -} - -func (g *GenericCard) Cast(game *Game) *Game { - return nil -} -func (g *GenericCard) Enters(game *Game) *Game { - return nil -} - -func (g *GenericCard) Upkeep(game *Game) *Game { - g.Sick = false - return nil -} -func (g *GenericCard) Endstep(game *Game) *Game { - return nil -} - -func (g *GenericCard) Value() CardValue { - return g.Val -} - -func (g *GenericCard) Acted() bool { - return g.Sick -} - -func (g *GenericCard) Act() { - g.Sick = true -} - -func (g *GenericCard) Empty() bool { - return false -} - -func (g *GenericCard) String() string { - return fmt.Sprintf("%v", g.Val) -} - -func (g *GenericCard) Port() *PortableCard { - return &PortableCard{ - Type: int(g.Val), - ID: g.Id, - } -} - -func (g *GenericCard) CanAttack(x, y int) bool { - if x == y && !g.Sick { - return true - } - return false -} - -type CardValue int +type CardType int const ( - Valk CardValue = iota + Valk CardType = iota Ace Two Three @@ -89,130 +28,33 @@ const ( Eight ) const ( - EmptyValue CardValue = -1 + EmptyValue CardType = -1 ) -func (c CardValue) String() string { +func (c CardType) String() string { if c == -1 { return " " } return []string{"V", "A", "2", "3", "4", "5", "6", "7", "8"}[c] } -func CreateCard(v int) Card { - return NewCard(v, uuid.New()) -} - -func NewCard(v int, id uuid.UUID) Card { - switch v { - case -1: - return &EmptyCard{ - &GenericCard{ - Val: EmptyValue, - Id: id, - Sick: true, - }, - } - case 1: - return &AceCard{ - &GenericCard{ - Val: Ace, - Id: id, - Sick: false, - }, - } - case 4: - return &FourCard{ - &GenericCard{ - Val: Four, - Id: id, - Sick: true, - }, - } - case 8: - return &EightCard{ - &GenericCard{ - Val: Eight, - Id: id, - Sick: true, - }, - 0, - } - case 0: - return &Valkyrie{ - &GenericCard{ - Val: Valk, - Id: id, - Sick: false, - }, - } - default: - return &GenericCard{ - Val: CardValue(v), - Id: id, - Sick: true, - } +func NewCard(v int, id uuid.UUID) *Card { + if id == uuid.Nil { + id = uuid.New() + } + return &Card{ + Type: CardType(v), + Power: OraclePower(CardType(v), nil), + Id: id, + Sick: false, + Counters: 0, } } -type EmptyCard struct { - *GenericCard +func (c *Card) Empty() bool { + return c.Type == EmptyValue } -func (e *EmptyCard) Empty() bool { - return true -} - -type AceCard struct { - *GenericCard -} - -type FourCard struct { - *GenericCard -} - -func (f *FourCard) Enters(g *Game) *Game { - g.CanDraw = true - return g -} - -type EightCard struct { - *GenericCard - Counters int `json:"counters"` -} - -func (e *EightCard) CanAttack(x, y int) bool { - return false -} - -func (e *EightCard) Upkeep(g *Game) *Game { - if e.Counters > 2 { - e = nil - } - return g -} - -func (e *EightCard) Endstep(g *Game) *Game { - e.Counters = e.Counters + 1 - return g -} - -type Valkyrie struct { - *GenericCard -} - -func (v *Valkyrie) Cast(g *Game) *Game { - g.GameBoard.Sentinal = [4]Card{CreateCard(-1), CreateCard(-1), CreateCard(-1), CreateCard(-1)} - g.GameBoard.Scourge = [4]Card{CreateCard(-1), CreateCard(-1), CreateCard(-1), CreateCard(-1)} - return g -} - -func (v *Valkyrie) Enters(g *Game) *Game { - v = nil - return g -} - -type PortableCard struct { - Type int `json:"type"` - ID uuid.UUID `json:"ID"` +func (c *Card) String() string { + return fmt.Sprintf("|%v|", c.Type) } diff --git a/internal/game/deck.go b/internal/game/deck.go index 733c51d..aa732a6 100644 --- a/internal/game/deck.go +++ b/internal/game/deck.go @@ -1,20 +1,21 @@ package game import ( - "encoding/json" "math/rand" "time" + + "github.com/google/uuid" ) type Deck struct { - Cards []Card `json:"cards"` + Cards []*Card `json:"cards"` } func NewDeck() *Deck { - cards := []Card{CreateCard(0)} + cards := []*Card{NewCard(0, uuid.Nil)} for i := 0; i < 3; i++ { for j := 1; j < 9; j++ { - cards = append(cards, Card(CreateCard(j))) + cards = append(cards, NewCard(j, uuid.Nil)) } } return &Deck{ @@ -22,7 +23,7 @@ func NewDeck() *Deck { } } -func DeckFromCards(c []Card) *Deck { +func DeckFromCards(c []*Card) *Deck { return &Deck{ Cards: c, } @@ -38,11 +39,11 @@ func (d *Deck) Shuffle() { d.Cards = cards } -func (d *Deck) Scry(s int) []Card { - seen := []Card{} +func (d *Deck) Scry(s int) []*Card { + seen := []*Card{} if len(d.Cards) < s { seen = d.Cards - d.Cards = []Card{} + d.Cards = []*Card{} return seen } seen = d.Cards[(len(d.Cards) - s):len(d.Cards)] @@ -50,32 +51,10 @@ func (d *Deck) Scry(s int) []Card { return seen } -func (d *Deck) Bottom(result []Card) { +func (d *Deck) Bottom(result []*Card) { d.Cards = append(result, d.Cards...) //Should shuffle result first? } func (d *Deck) Size() int { return len(d.Cards) } - -func (d *Deck) MarshalJSON() ([]byte, error) { - var ported []*PortableCard - for i, _ := range d.Cards { - ported = append(ported, d.Cards[i].Port()) - } - return json.Marshal(ported) -} - -func (d *Deck) UnmarshalJSON(data []byte) (err error) { - var ported []PortableCard - err = json.Unmarshal(data, &ported) - if err != nil { - return err - } - cards := []Card{} - for _, v := range ported { - cards = append(cards, NewCard(v.Type, v.ID)) - } - d.Cards = cards - return -} diff --git a/internal/game/game.go b/internal/game/game.go index abab658..4c4e2dd 100644 --- a/internal/game/game.go +++ b/internal/game/game.go @@ -2,6 +2,7 @@ package game import ( "fmt" + "log" "strconv" "strings" ) @@ -24,7 +25,7 @@ const ( ) func (g GameStatus) String() string { - return []string{"Lobby", "Ready", "Playing", "Stopped"}[g] + return []string{"Lobby", "Ready", "Playing", "Stopped", "SentinalWin", "ScougeWin", "Draw"}[g] } type Game struct { @@ -52,7 +53,7 @@ func NewGame() *Game { SentinalDeck: deckA, ScourgeDeck: deckB, CurrentTurn: 0, //start with no turn - CardBuffer: DeckFromCards([]Card{}), + CardBuffer: DeckFromCards([]*Card{}), CanDraw: false, HasDrawn: false, Status: StatusLobby, @@ -162,11 +163,11 @@ func (g *Game) PlayerStateAct(id int, cmd string) *GameView { } if id == SentinalID { for _, v := range g.GameBoard.Sentinal { - v.Upkeep(g) + OracleUpkeep(v, g) } } else { for _, v := range g.GameBoard.Scourge { - v.Upkeep(g) + OracleUpkeep(v, g) } } case "e": @@ -174,14 +175,14 @@ func (g *Game) PlayerStateAct(id int, cmd string) *GameView { if id != g.CurrentTurn { return nil } - g.CardBuffer = DeckFromCards([]Card{}) + g.CardBuffer = DeckFromCards([]*Card{}) if id == SentinalID { for _, v := range g.GameBoard.Sentinal { - v.Endstep(g) + OracleEndstep(v, g) } } else { for _, v := range g.GameBoard.Scourge { - v.Endstep(g) + OracleEndstep(v, g) } } if g.CurrentTurn == SentinalID { @@ -256,11 +257,12 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck { } x_i, _ := strconv.Atoi(cmd_s[1]) y_i, _ := strconv.Atoi(cmd_s[2]) - res := g.GameBoard.Move(g.CurrentTurn, x_i, y_i) - if res { + if g.GameBoard.CanMove(g.CurrentTurn, x_i, y_i) { + OracleMove(g.GameBoard.GetCard(g.CurrentTurn, x_i), g) + g.GameBoard.Move(g.CurrentTurn, x_i, y_i) return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) } else { - return DeckFromCards([]Card{}) + return DeckFromCards([]*Card{}) } case "a": //attack @@ -272,15 +274,18 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck { } x_i, _ := strconv.Atoi(cmd_s[1]) y_i, _ := strconv.Atoi(cmd_s[2]) - res := g.GameBoard.Attack(g.CurrentTurn, x_i, y_i) - if res == 1 { - opp.Life = opp.Life - 1 - return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) - } else if res == 0 { - return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) + if g.GameBoard.CanAttack(g.CurrentTurn, x_i, y_i) { + OracleAttack(g.GameBoard.GetCard(g.CurrentTurn, x_i), g) + res := g.GameBoard.Attack(g.CurrentTurn, x_i, y_i) + if res == 1 { + opp.Life = opp.Life - 1 + return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) + } else { + return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) + } } else { - fmt.Println("can't attack") - return DeckFromCards([]Card{}) + log.Println("can't attack") + return DeckFromCards([]*Card{}) } case "p": //play: return player boad or [] if invalid @@ -294,17 +299,16 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck { x_i, _ := strconv.Atoi(cmd_s[1]) y_i, _ := strconv.Atoi(cmd_s[2]) card := curr.Hand[x_i] - if g.GameBoard.CanPlay(g.CurrentTurn, &card, y_i) { - curr.Hand[x_i].Cast(g) - } - res := g.GameBoard.Play(g.CurrentTurn, &card, y_i) - if res { - curr.Hand[x_i].Enters(g) + shouldPlace := true + if g.GameBoard.CanPlay(g.CurrentTurn, card, y_i) { + shouldPlace = OracleCast(curr.Hand[x_i], g) + _ = g.GameBoard.Play(g.CurrentTurn, card, y_i, shouldPlace) + OracleEnters(curr.Hand[x_i], g) curr.Hand = append(curr.Hand[:x_i], curr.Hand[x_i+1:]...) return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) } else { fmt.Println("couldn't play") - return DeckFromCards([]Card{}) + return DeckFromCards([]*Card{}) } default: fmt.Println("Invalid act command") diff --git a/internal/game/oracle.go b/internal/game/oracle.go new file mode 100644 index 0000000..a7037d7 --- /dev/null +++ b/internal/game/oracle.go @@ -0,0 +1,38 @@ +package game + +func OracleUpkeep(c *Card, g *Game) { + switch c.Type { + default: + c.Sick = false + } + return +} + +func OracleCast(c *Card, g *Game) bool { + return true +} + +func OracleEnters(c *Card, g *Game) { + c.Sick = true + return +} + +func OracleLeaves(c *Card, g *Game) { + return +} + +func OracleEndstep(c *Card, g *Game) { + return +} + +func OraclePower(c CardType, g *Game) int { + return int(c) +} + +func OracleMove(c *Card, g *Game) { + c.Sick = true +} + +func OracleAttack(c *Card, g *Game) { + c.Sick = true +} diff --git a/internal/game/player.go b/internal/game/player.go index 0ebaa3a..5c227b4 100644 --- a/internal/game/player.go +++ b/internal/game/player.go @@ -1,66 +1,17 @@ package game -import ( - "encoding/json" - "fmt" - "log" - - "github.com/google/uuid" -) - type Player struct { - Name string `json:"name"` - Id int `json:"id"` - Hand []Card `json:"hand"` - Life int `json:"life"` + Name string `json:"name"` + Id int `json:"id"` + Hand []*Card `json:"hand"` + Life int `json:"life"` } func NewPlayer(name string, id int) *Player { return &Player{ Name: name, Id: id, - Hand: []Card{}, + Hand: []*Card{}, Life: 3, } } - -func (p *Player) MarshalJSON() ([]byte, error) { - var ported_hand []*PortableCard - for i, _ := range p.Hand { - ported_hand = append(ported_hand, p.Hand[i].Port()) - } - res := []interface{}{p.Name, p.Id, ported_hand, p.Life} - return json.Marshal(res) -} - -func (p *Player) UnmarshalJSON(data []byte) (err error) { - ported := []interface{}{} - err = json.Unmarshal(data, &ported) - if err != nil { - return err - } - fmt.Println(ported) - p.Name = ported[0].(string) - p.Id = int(ported[1].(float64)) - var tmp []interface{} - if ported[2] != nil { - tmp = ported[2].([]interface{}) - } else { - tmp = []interface{}{} - } - p.Life = int(ported[3].(float64)) - hand := []Card{} - for _, v := range tmp { - m := v.(map[string]interface{}) - t := int(m["type"].(float64)) - i := m["ID"].(string) - uid, err := uuid.Parse(i) - if err != nil { - log.Println("invalid card parse") - } else { - hand = append(hand, NewCard(t, uid)) - } - } - p.Hand = hand - return -} From 22a3e0c8e8a04716d161cbff5f341fef64cdfaa3 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 23 Jul 2021 18:57:39 -0400 Subject: [PATCH 2/4] being actually adding card effects --- internal/game/board.go | 13 +++++++++++++ internal/game/oracle.go | 32 +++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/internal/game/board.go b/internal/game/board.go index bd1ff5d..66320fd 100644 --- a/internal/game/board.go +++ b/internal/game/board.go @@ -38,6 +38,19 @@ func (b *Board) GetCard(id int, pos int) *Card { } } +func (b *Board) Remove(c *Card) { + for k, v := range b.Sentinal { + if v.Id == c.Id { + b.Sentinal[k] = NewCard(-1, uuid.Nil) + } + } + for k, v := range b.Scourge { + if v.Id == c.Id { + b.Scourge[k] = NewCard(-1, uuid.Nil) + } + } +} + func (b *Board) Empty(id int) bool { res := true if id == SentinalID { diff --git a/internal/game/oracle.go b/internal/game/oracle.go index a7037d7..0918b8f 100644 --- a/internal/game/oracle.go +++ b/internal/game/oracle.go @@ -2,6 +2,11 @@ package game func OracleUpkeep(c *Card, g *Game) { switch c.Type { + case Eight: + c.Sick = true + if c.Counters > 3 { + g.GameBoard.Remove(c) + } default: c.Sick = false } @@ -9,11 +14,32 @@ func OracleUpkeep(c *Card, g *Game) { } func OracleCast(c *Card, g *Game) bool { - return true + switch c.Type { + case Valk: + g.GameBoard = NewBoard() + return false + default: + return true + } } func OracleEnters(c *Card, g *Game) { c.Sick = true + switch c.Type { + case Two: + //+1 to all + if g.CurrentTurn == SentinalID { + for _, v := range g.GameBoard.Sentinal { + v.Power = v.Power + 1 + } + } else { + for _, v := range g.GameBoard.Scourge { + v.Power = v.Power + 1 + } + } + case Three: + //+1 around it + } return } @@ -22,6 +48,10 @@ func OracleLeaves(c *Card, g *Game) { } func OracleEndstep(c *Card, g *Game) { + switch c.Type { + case Eight: + c.Counters = c.Counters + 1 + } return } From d1845760fef17636c0e6a8f523b0a7ab5008c6f2 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 25 Jul 2021 13:27:12 -0400 Subject: [PATCH 3/4] actually use GetRow since I can, implement 2 and 3, cards have owners and positions --- internal/game/board.go | 79 +++++++++++------------------------------ internal/game/card.go | 41 +++++++++++++++------ internal/game/deck.go | 6 ++-- internal/game/game.go | 12 ++++--- internal/game/oracle.go | 71 ++++++++++++++++++++++++++++++++++-- 5 files changed, 129 insertions(+), 80 deletions(-) diff --git a/internal/game/board.go b/internal/game/board.go index 66320fd..0c74404 100644 --- a/internal/game/board.go +++ b/internal/game/board.go @@ -2,8 +2,6 @@ package game import ( "fmt" - - "github.com/google/uuid" ) type Board struct { @@ -13,8 +11,8 @@ type Board struct { func NewBoard() *Board { return &Board{ - Sentinal: [4]*Card{NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil)}, - Scourge: [4]*Card{NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil), NewCard(-1, uuid.Nil)}, + Sentinal: [4]*Card{NewEmpty(0), NewEmpty(1), NewEmpty(2), NewEmpty(3)}, + Scourge: [4]*Card{NewEmpty(0), NewEmpty(1), NewEmpty(2), NewEmpty(3)}, } } @@ -23,7 +21,7 @@ func (b *Board) String() string { } func (b *Board) GetRow(id int) []*Card { - if id == 1 { + if id == SentinalID { return b.Sentinal[:] } else { return b.Scourge[:] @@ -31,51 +29,36 @@ func (b *Board) GetRow(id int) []*Card { } func (b *Board) GetCard(id int, pos int) *Card { - if id == SentinalID { - return b.Sentinal[pos] - } else { - return b.Scourge[pos] - } + return b.GetRow(id)[pos] } func (b *Board) Remove(c *Card) { for k, v := range b.Sentinal { if v.Id == c.Id { - b.Sentinal[k] = NewCard(-1, uuid.Nil) + b.Sentinal[k] = NewEmpty(k) } } for k, v := range b.Scourge { if v.Id == c.Id { - b.Scourge[k] = NewCard(-1, uuid.Nil) + b.Scourge[k] = NewEmpty(k) } } } func (b *Board) Empty(id int) bool { res := true - if id == SentinalID { - for _, v := range b.Sentinal { - if !v.Empty() { - res = false - } - } - } else { - for _, v := range b.Scourge { - if !v.Empty() { - res = false - } + row := b.GetRow(id) + for _, v := range row { + if !v.Empty() { + res = false } } + return res } func (b *Board) CanMove(id, src, dest int) bool { - var brd [4]*Card - if id == SentinalID { - brd = b.Sentinal - } else { - brd = b.Scourge - } + brd := b.GetRow(id) if brd[src].Empty() { return false } @@ -105,7 +88,7 @@ func (b *Board) Move(id, src, dest int) bool { return false } brd[dest] = brd[src] - brd[src] = NewCard(-1, uuid.Nil) + brd[src] = NewEmpty(src) if id == SentinalID { b.Sentinal = brd } else { @@ -115,12 +98,7 @@ func (b *Board) Move(id, src, dest int) bool { } func (b *Board) CanPlay(id int, c *Card, dest int) bool { - var brd [4]*Card - if id == SentinalID { - brd = b.Sentinal - } else { - brd = b.Scourge - } + brd := b.GetRow(id) if !brd[dest].Empty() { return false } @@ -128,33 +106,18 @@ func (b *Board) CanPlay(id int, c *Card, dest int) bool { } func (b *Board) Play(id int, c *Card, dest int, should bool) bool { - var brd [4]*Card - if id == SentinalID { - brd = b.Sentinal - } else { - brd = b.Scourge - } - if !brd[dest].Empty() { - return false - } + brd := b.GetRow(id) if should { brd[dest] = c - } - if id == SentinalID { - b.Sentinal = brd + c.Position = dest } else { - b.Scourge = brd + return false } return true } func (b *Board) CanAttack(id, atk, def int) bool { - var aBrd [4]*Card - if id == SentinalID { - aBrd = b.Sentinal - } else { - aBrd = b.Scourge - } + aBrd := b.GetRow(id) if aBrd[atk].Empty() || aBrd[atk].Sick || atk != def { return false } @@ -186,7 +149,7 @@ func (b *Board) Attack(id int, atk, def int) int { attacker := aBrd[atk].Power defender := dBrd[def].Power if attacker > defender { - dBrd[def] = NewCard(-1, uuid.Nil) + dBrd[def] = NewEmpty(def) if id == SentinalID { b.Sentinal = aBrd b.Scourge = dBrd @@ -197,8 +160,8 @@ func (b *Board) Attack(id int, atk, def int) int { return 0 } if attacker == defender { - aBrd[atk] = NewCard(-1, uuid.Nil) - dBrd[def] = NewCard(-1, uuid.Nil) + aBrd[atk] = NewEmpty(atk) + dBrd[def] = NewEmpty(def) if id == 1 { b.Sentinal = aBrd b.Scourge = dBrd diff --git a/internal/game/card.go b/internal/game/card.go index 2aee713..1299132 100644 --- a/internal/game/card.go +++ b/internal/game/card.go @@ -7,11 +7,14 @@ import ( ) type Card struct { - Type CardType `json:"type"` - Power int `json:"power"` - Id uuid.UUID `json:"id"` - Sick bool `json:"sick"` - Counters int `json:"counters"` + Type CardType `json:"type"` + BasePower int `json:"base_power"` + Power int `json:"power"` + Id uuid.UUID `json:"id"` + Sick bool `json:"sick"` + Counters int `json:"counters"` + Owner int `json:"owner"` + Position int `json:"position"` } type CardType int @@ -38,16 +41,32 @@ func (c CardType) String() string { return []string{"V", "A", "2", "3", "4", "5", "6", "7", "8"}[c] } -func NewCard(v int, id uuid.UUID) *Card { +func NewCard(v, o, p int, id uuid.UUID) *Card { if id == uuid.Nil { id = uuid.New() } return &Card{ - Type: CardType(v), - Power: OraclePower(CardType(v), nil), - Id: id, - Sick: false, - Counters: 0, + Type: CardType(v), + BasePower: OraclePower(CardType(v), nil), + Power: OraclePower(CardType(v), nil), + Id: id, + Sick: false, + Counters: 0, + Owner: o, + Position: p, + } +} + +func NewEmpty(p int) *Card { + return &Card{ + Type: EmptyValue, + BasePower: -1, + Power: -1, + Id: uuid.New(), + Sick: false, + Counters: 0, + Owner: -1, + Position: p, } } diff --git a/internal/game/deck.go b/internal/game/deck.go index aa732a6..88e8dea 100644 --- a/internal/game/deck.go +++ b/internal/game/deck.go @@ -11,11 +11,11 @@ type Deck struct { Cards []*Card `json:"cards"` } -func NewDeck() *Deck { - cards := []*Card{NewCard(0, uuid.Nil)} +func NewDeck(owner int) *Deck { + cards := []*Card{NewCard(0, owner, -1, uuid.Nil)} for i := 0; i < 3; i++ { for j := 1; j < 9; j++ { - cards = append(cards, NewCard(j, uuid.Nil)) + cards = append(cards, NewCard(j, owner, -1, uuid.Nil)) } } return &Deck{ diff --git a/internal/game/game.go b/internal/game/game.go index 4c4e2dd..80fc8f3 100644 --- a/internal/game/game.go +++ b/internal/game/game.go @@ -42,8 +42,8 @@ type Game struct { } func NewGame() *Game { - deckA := NewDeck() - deckB := NewDeck() + deckA := NewDeck(SentinalID) + deckB := NewDeck(ScourgeID) deckA.Shuffle() deckB.Shuffle() return &Game{ @@ -258,7 +258,7 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck { x_i, _ := strconv.Atoi(cmd_s[1]) y_i, _ := strconv.Atoi(cmd_s[2]) if g.GameBoard.CanMove(g.CurrentTurn, x_i, y_i) { - OracleMove(g.GameBoard.GetCard(g.CurrentTurn, x_i), g) + OracleMove(g.GameBoard.GetCard(g.CurrentTurn, x_i), x_i, y_i, g) g.GameBoard.Move(g.CurrentTurn, x_i, y_i) return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) } else { @@ -302,8 +302,10 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck { shouldPlace := true if g.GameBoard.CanPlay(g.CurrentTurn, card, y_i) { shouldPlace = OracleCast(curr.Hand[x_i], g) - _ = g.GameBoard.Play(g.CurrentTurn, card, y_i, shouldPlace) - OracleEnters(curr.Hand[x_i], g) + placed := g.GameBoard.Play(g.CurrentTurn, card, y_i, shouldPlace) + if placed { + OracleEnters(curr.Hand[x_i], g) + } curr.Hand = append(curr.Hand[:x_i], curr.Hand[x_i+1:]...) return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) } else { diff --git a/internal/game/oracle.go b/internal/game/oracle.go index 0918b8f..48a97e8 100644 --- a/internal/game/oracle.go +++ b/internal/game/oracle.go @@ -1,5 +1,7 @@ package game +import "log" + func OracleUpkeep(c *Card, g *Game) { switch c.Type { case Eight: @@ -28,22 +30,77 @@ func OracleEnters(c *Card, g *Game) { switch c.Type { case Two: //+1 to all - if g.CurrentTurn == SentinalID { + if c.Owner == SentinalID { for _, v := range g.GameBoard.Sentinal { v.Power = v.Power + 1 } - } else { + } else if c.Owner == ScourgeID { for _, v := range g.GameBoard.Scourge { v.Power = v.Power + 1 } + } else { + log.Println("Trying to lookup an ETB when card not on field") } case Three: //+1 around it + if c.Owner == SentinalID { + if c.Position-1 >= 0 { + g.GameBoard.Sentinal[c.Position-1].Power = g.GameBoard.Sentinal[c.Position-1].Power + 1 + } + if c.Position+1 <= 3 { + g.GameBoard.Sentinal[c.Position+1].Power = g.GameBoard.Sentinal[c.Position+1].Power + 1 + } + + } + if c.Owner == ScourgeID { + if c.Position-1 >= 0 { + g.GameBoard.Scourge[c.Position-1].Power = g.GameBoard.Scourge[c.Position-1].Power + 1 + } + if c.Position+1 <= 3 { + g.GameBoard.Scourge[c.Position+1].Power = g.GameBoard.Scourge[c.Position+1].Power + 1 + } + + } } return } func OracleLeaves(c *Card, g *Game) { + switch c.Type { + case Two: + //remove +1 to all + if c.Owner == SentinalID { + for _, v := range g.GameBoard.Sentinal { + v.Power = v.Power - 1 + } + } else if c.Owner == ScourgeID { + for _, v := range g.GameBoard.Scourge { + v.Power = v.Power - 1 + } + } else { + log.Println("Trying to lookup an LTB when card not on field") + } + case Three: + //+1 around it + if c.Owner == SentinalID { + if c.Position-1 >= 0 { + g.GameBoard.Sentinal[c.Position-1].Power = g.GameBoard.Sentinal[c.Position-1].Power - 1 + } + if c.Position+1 <= 3 { + g.GameBoard.Sentinal[c.Position+1].Power = g.GameBoard.Sentinal[c.Position+1].Power - 1 + } + + } + if c.Owner == ScourgeID { + if c.Position-1 >= 0 { + g.GameBoard.Scourge[c.Position-1].Power = g.GameBoard.Scourge[c.Position-1].Power - 1 + } + if c.Position+1 <= 3 { + g.GameBoard.Scourge[c.Position+1].Power = g.GameBoard.Scourge[c.Position+1].Power - 1 + } + + } + } return } @@ -59,8 +116,16 @@ func OraclePower(c CardType, g *Game) int { return int(c) } -func OracleMove(c *Card, g *Game) { +func OracleMove(c *Card, src, dest int, g *Game) { c.Sick = true + switch c.Type { + case Three: + row := g.GameBoard.GetRow(c.Owner) + row[src-1].Power = row[src-1].Power - 1 + row[src+1].Power = row[src+1].Power - 1 + row[dest-1].Power = row[dest-1].Power + 1 + row[dest+1].Power = row[dest+1].Power + 1 + } } func OracleAttack(c *Card, g *Game) { From 4c37ad270d5adbc085d5ad304ccd4269f9391bc0 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 25 Jul 2021 13:35:49 -0400 Subject: [PATCH 4/4] implement ace, differ between spells (valk) --- internal/game/board.go | 2 +- internal/game/card.go | 2 ++ internal/game/oracle.go | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/internal/game/board.go b/internal/game/board.go index 0c74404..8f9c47e 100644 --- a/internal/game/board.go +++ b/internal/game/board.go @@ -99,7 +99,7 @@ func (b *Board) Move(id, src, dest int) bool { func (b *Board) CanPlay(id int, c *Card, dest int) bool { brd := b.GetRow(id) - if !brd[dest].Empty() { + if !brd[dest].Empty() || !c.Spell { return false } return true diff --git a/internal/game/card.go b/internal/game/card.go index 1299132..af5c3ea 100644 --- a/internal/game/card.go +++ b/internal/game/card.go @@ -15,6 +15,7 @@ type Card struct { Counters int `json:"counters"` Owner int `json:"owner"` Position int `json:"position"` + Spell bool `json:"spell"` } type CardType int @@ -54,6 +55,7 @@ func NewCard(v, o, p int, id uuid.UUID) *Card { Counters: 0, Owner: o, Position: p, + Spell: OracleSpell(CardType(v), nil), } } diff --git a/internal/game/oracle.go b/internal/game/oracle.go index 48a97e8..4cb7652 100644 --- a/internal/game/oracle.go +++ b/internal/game/oracle.go @@ -15,6 +15,15 @@ func OracleUpkeep(c *Card, g *Game) { return } +func OracleSpell(c CardType, g *Game) bool { + switch c { + case Valk: + return true + default: + return false + } +} + func OracleCast(c *Card, g *Game) bool { switch c.Type { case Valk: @@ -28,6 +37,8 @@ func OracleCast(c *Card, g *Game) bool { func OracleEnters(c *Card, g *Game) { c.Sick = true switch c.Type { + case Ace: + c.Sick = false case Two: //+1 to all if c.Owner == SentinalID {