move to effect based system

This commit is contained in:
stryan 2021-07-25 15:33:47 -04:00
parent a623639af3
commit 26a7c137f8
5 changed files with 174 additions and 124 deletions

View File

@ -2,6 +2,7 @@ package game
import ( import (
"fmt" "fmt"
"log"
) )
type Board struct { type Board struct {
@ -17,7 +18,7 @@ func NewBoard() *Board {
} }
func (b *Board) String() string { 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]) 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 {
@ -59,6 +60,9 @@ func (b *Board) Empty(id int) bool {
func (b *Board) CanMove(id, src, dest int) bool { func (b *Board) CanMove(id, src, dest int) bool {
brd := b.GetRow(id) brd := b.GetRow(id)
if src < 0 || src > 3 || dest < 0 || dest > 3 {
return false
}
if brd[src].Empty() { if brd[src].Empty() {
return false return false
} }
@ -72,33 +76,17 @@ func (b *Board) CanMove(id, src, dest int) bool {
} }
func (b *Board) Move(id, src, dest int) bool { func (b *Board) Move(id, src, dest int) bool {
var brd [4]*Card brd := b.GetRow(id)
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] = brd[src] brd[dest] = brd[src]
brd[src] = NewEmpty(src) brd[src] = NewEmpty(src)
if id == SentinalID {
b.Sentinal = brd
} else {
b.Scourge = brd
}
return true return true
} }
func (b *Board) CanPlay(id int, c *Card, dest int) bool { func (b *Board) CanPlay(id int, c *Card, dest int) bool {
brd := b.GetRow(id) brd := b.GetRow(id)
if dest < 0 || dest > 3 {
return false
}
if !brd[dest].Empty() && !c.Spell { if !brd[dest].Empty() && !c.Spell {
return false return false
} }
@ -118,59 +106,52 @@ func (b *Board) Play(id int, c *Card, dest int, should bool) bool {
func (b *Board) CanAttack(id, atk, def int) bool { func (b *Board) CanAttack(id, atk, def int) bool {
aBrd := b.GetRow(id) aBrd := b.GetRow(id)
if atk < 0 || atk > 3 || def < 0 || def > 3 {
return false
}
if aBrd[atk].Empty() || aBrd[atk].Sick || atk != def { if aBrd[atk].Empty() || aBrd[atk].Sick || atk != def {
return false return false
} }
return true return true
} }
func (b *Board) Attack(id int, atk, def int) int { func (b *Board) Attack(id, atk, def int) int {
var aBrd [4]*Card var aid, did int
var dBrd [4]*Card
if id == SentinalID { if id == SentinalID {
aBrd = b.Sentinal aid = SentinalID
dBrd = b.Scourge did = ScourgeID
} else { } else {
aBrd = b.Scourge aid = ScourgeID
dBrd = b.Sentinal did = SentinalID
} }
if dBrd[def].Empty() { attacker := b.GetRow(aid)[atk]
defender := b.GetRow(did)[def]
if defender.Empty() {
//health damage //health damage
if id == SentinalID {
b.Sentinal = aBrd
b.Scourge = dBrd
} else {
b.Scourge = aBrd
b.Sentinal = dBrd
}
return 1 return 1
} }
//Do actual battle math //Do actual battle math
attacker := aBrd[atk].Power atkpower := attacker.Power
defender := dBrd[def].Power defpower := defender.Power
if attacker > defender { log.Printf("Atk:%v v Def: %v", atkpower, defpower)
dBrd[def] = NewEmpty(def) if atkpower > defpower {
if id == SentinalID { return 2
b.Sentinal = aBrd
b.Scourge = dBrd
} else {
b.Scourge = aBrd
b.Sentinal = dBrd
} }
return 0 if atkpower == defpower {
return 4
} }
if attacker == defender { if atkpower < defpower {
aBrd[atk] = NewEmpty(atk) return 3
dBrd[def] = NewEmpty(def)
if id == 1 {
b.Sentinal = aBrd
b.Scourge = dBrd
} else {
b.Scourge = aBrd
b.Sentinal = dBrd
}
return 0
} }
return -1 return -1
} }
func (b *Board) ResetCards() {
for _, v := range b.Sentinal {
v.Power = v.BasePower
}
for _, v := range b.Scourge {
v.Power = v.BasePower
}
}

View File

@ -16,6 +16,7 @@ type Card struct {
Owner int `json:"owner"` Owner int `json:"owner"`
Position int `json:"position"` Position int `json:"position"`
Spell bool `json:"spell"` Spell bool `json:"spell"`
Effects []Effect `json:"effects"`
} }
type CardType int type CardType int
@ -56,6 +57,7 @@ func NewCard(v, o, p int, id uuid.UUID) *Card {
Owner: o, Owner: o,
Position: p, Position: p,
Spell: OracleSpell(CardType(v), nil), Spell: OracleSpell(CardType(v), nil),
Effects: []Effect{},
} }
} }
@ -69,6 +71,8 @@ func NewEmpty(p int) *Card {
Counters: 0, Counters: 0,
Owner: -1, Owner: -1,
Position: p, Position: p,
Spell: false,
Effects: []Effect{},
} }
} }
@ -77,5 +81,9 @@ func (c *Card) Empty() bool {
} }
func (c *Card) String() string { func (c *Card) String() string {
return fmt.Sprintf("|%v|", c.Type) ready := " "
if c.Sick {
ready = "*"
}
return fmt.Sprintf("%v%v%v", c.Type, c.Power, ready)
} }

26
internal/game/effect.go Normal file
View File

@ -0,0 +1,26 @@
package game
import "github.com/google/uuid"
type Effect struct {
Owner uuid.UUID
Target uuid.UUID
ID int
}
func RemoveEffect(source uuid.UUID, c *Card) {
for i, e := range c.Effects {
if e.Owner == source {
c.Effects = append(c.Effects[:i], c.Effects[i+1:]...)
}
}
}
func AddEffect(c *Card, e Effect) {
for _, v := range c.Effects {
if v.Owner == e.Owner && v.ID == e.ID {
return
}
}
c.Effects = append(c.Effects, e)
}

View File

@ -125,6 +125,16 @@ func (g *Game) StateChanges() {
g.Status = StatusSentinalWin g.Status = StatusSentinalWin
} }
} }
//reapply card effects
g.GameBoard.ResetCards()
for _, v := range g.GameBoard.Sentinal {
OracleTick(v, g) //apply effect stacks first
OracleEffect(v, g) //actually activate effects
}
for _, v := range g.GameBoard.Scourge {
OracleTick(v, g)
OracleEffect(v, g)
}
//check life //check life
//this is second on purpose so that it shadows deck out win conditions //this is second on purpose so that it shadows deck out win conditions
//if you use your last action to win the game, you should actually win //if you use your last action to win the game, you should actually win
@ -222,10 +232,12 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck {
switch cmd_s[0] { switch cmd_s[0] {
case "s": case "s":
//scry: return scry options off top of deck //scry: return scry options off top of deck
if !g.CanDraw || g.CardBuffer.Size() > 0 { if !g.CanDraw {
return nil return nil
} }
if g.CardBuffer.Size() <= 0 {
g.CardBuffer = DeckFromCards(currD.Scry(curr.Life)) g.CardBuffer = DeckFromCards(currD.Scry(curr.Life))
}
return g.CardBuffer return g.CardBuffer
case "d": case "d":
//draw: return player hand //draw: return player hand
@ -236,6 +248,9 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck {
return nil return nil
} }
x_i, err := strconv.Atoi(cmd_s[1]) x_i, err := strconv.Atoi(cmd_s[1])
if x_i > 2 || x_i < 0 {
return nil
}
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -282,12 +297,34 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck {
if g.GameBoard.CanAttack(g.CurrentTurn, x_i, y_i) { if g.GameBoard.CanAttack(g.CurrentTurn, x_i, y_i) {
OracleAttack(g.GameBoard.GetCard(g.CurrentTurn, x_i), g) OracleAttack(g.GameBoard.GetCard(g.CurrentTurn, x_i), g)
res := g.GameBoard.Attack(g.CurrentTurn, x_i, y_i) res := g.GameBoard.Attack(g.CurrentTurn, x_i, y_i)
if res == 1 { var aid, did int
opp.Life = opp.Life - 1 if id == SentinalID {
return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) aid = SentinalID
did = ScourgeID
} else { } else {
return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) aid = ScourgeID
did = SentinalID
} }
attacker := g.GameBoard.GetRow(aid)[x_i]
defender := g.GameBoard.GetRow(did)[y_i]
switch res {
case 1:
opp.Life = opp.Life - 1
case 2:
OracleLeaves(defender, g)
g.GameBoard.Remove(defender)
case 3:
OracleLeaves(attacker, g)
g.GameBoard.Remove(attacker)
case 4:
OracleLeaves(attacker, g)
OracleLeaves(defender, g)
g.GameBoard.Remove(attacker)
g.GameBoard.Remove(defender)
}
return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn))
} else { } else {
log.Println("can't attack") log.Println("can't attack")
return DeckFromCards([]*Card{}) return DeckFromCards([]*Card{})
@ -306,10 +343,10 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck {
card := curr.Hand[x_i] card := curr.Hand[x_i]
shouldPlace := true shouldPlace := true
if g.GameBoard.CanPlay(g.CurrentTurn, card, y_i) { if g.GameBoard.CanPlay(g.CurrentTurn, card, y_i) {
shouldPlace = OracleCast(curr.Hand[x_i], g) shouldPlace = OracleCast(card, g)
placed := g.GameBoard.Play(g.CurrentTurn, card, y_i, shouldPlace) placed := g.GameBoard.Play(g.CurrentTurn, card, y_i, shouldPlace)
if placed { if placed {
OracleEnters(curr.Hand[x_i], g) OracleEnters(card, g)
} }
curr.Hand = append(curr.Hand[:x_i], curr.Hand[x_i+1:]...) curr.Hand = append(curr.Hand[:x_i], curr.Hand[x_i+1:]...)
return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn)) return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn))

View File

@ -1,7 +1,5 @@
package game package game
import "log"
func OracleUpkeep(c *Card, g *Game) { func OracleUpkeep(c *Card, g *Game) {
switch c.Type { switch c.Type {
case Eight: case Eight:
@ -39,79 +37,59 @@ func OracleEnters(c *Card, g *Game) {
switch c.Type { switch c.Type {
case Ace: case Ace:
c.Sick = false c.Sick = false
return
case Four:
AddEffect(c, Effect{c.Id, c.Id, 2})
case Eight:
c.Counters = 0
}
}
func OracleTick(c *Card, g *Game) {
row := g.GameBoard.GetRow(c.Owner)
switch c.Type {
case Two: case Two:
//+1 to all //+1 to all
if c.Owner == SentinalID { for _, v := range row {
for _, v := range g.GameBoard.Sentinal { if v.Id != c.Id {
v.Power = v.Power + 1 v.Effects = append(v.Effects, Effect{c.Id, v.Id, 1})
AddEffect(v, Effect{c.Id, v.Id, 1})
} }
} 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: case Three:
//+1 around it //+1 around it
if c.Owner == SentinalID {
if c.Position-1 >= 0 { if c.Position-1 >= 0 {
g.GameBoard.Sentinal[c.Position-1].Power = g.GameBoard.Sentinal[c.Position-1].Power + 1 v := row[c.Position-1]
} AddEffect(v, Effect{c.Id, v.Id, 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 { if c.Position+1 <= 3 {
g.GameBoard.Scourge[c.Position+1].Power = g.GameBoard.Scourge[c.Position+1].Power + 1 v := row[c.Position+1]
} AddEffect(v, Effect{c.Id, v.Id, 1})
} }
} }
return
} }
func OracleLeaves(c *Card, g *Game) { func OracleLeaves(c *Card, g *Game) {
row := g.GameBoard.GetRow(c.Owner)
switch c.Type { switch c.Type {
case Two: case Two:
//remove +1 to all //remove +1 to all
if c.Owner == SentinalID { for _, v := range row {
for _, v := range g.GameBoard.Sentinal { RemoveEffect(c.Id, v)
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: case Three:
//+1 around it //+1 around it
if c.Owner == SentinalID {
if c.Position-1 >= 0 { if c.Position-1 >= 0 {
g.GameBoard.Sentinal[c.Position-1].Power = g.GameBoard.Sentinal[c.Position-1].Power - 1 RemoveEffect(c.Id, row[c.Position-1])
} }
if c.Position+1 <= 3 { if c.Position+1 <= 3 {
g.GameBoard.Sentinal[c.Position+1].Power = g.GameBoard.Sentinal[c.Position+1].Power - 1 RemoveEffect(c.Id, row[c.Position+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 return
} }
@ -132,13 +110,33 @@ func OracleMove(c *Card, src, dest int, g *Game) {
switch c.Type { switch c.Type {
case Three: case Three:
row := g.GameBoard.GetRow(c.Owner) row := g.GameBoard.GetRow(c.Owner)
row[src-1].Power = row[src-1].Power - 1 if src-1 >= 0 {
row[src+1].Power = row[src+1].Power - 1 RemoveEffect(c.Id, row[src-1])
row[dest-1].Power = row[dest-1].Power + 1 }
row[dest+1].Power = row[dest+1].Power + 1 if src+1 <= 3 {
RemoveEffect(c.Id, row[src-1])
}
} }
} }
func OracleAttack(c *Card, g *Game) { func OracleAttack(c *Card, g *Game) {
c.Sick = true c.Sick = true
} }
func OracleEffect(c *Card, g *Game) {
for _, e := range c.Effects {
switch e.ID {
case 1:
c.Power = c.Power + 1
case 2:
if c.Owner == SentinalID {
g.CardBuffer = DeckFromCards(g.SentinalDeck.Scry(1))
} else {
g.CardBuffer = DeckFromCards(g.SentinalDeck.Scry(1))
}
g.CanDraw = true
g.HasDrawn = false
RemoveEffect(e.Owner, c)
}
}
}