move to effect based system
This commit is contained in:
parent
a623639af3
commit
26a7c137f8
@ -2,6 +2,7 @@ package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Board struct {
|
||||
@ -17,7 +18,7 @@ func NewBoard() *Board {
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -59,6 +60,9 @@ func (b *Board) Empty(id int) bool {
|
||||
|
||||
func (b *Board) CanMove(id, src, dest int) bool {
|
||||
brd := b.GetRow(id)
|
||||
if src < 0 || src > 3 || dest < 0 || dest > 3 {
|
||||
return false
|
||||
}
|
||||
if brd[src].Empty() {
|
||||
return false
|
||||
}
|
||||
@ -72,33 +76,17 @@ func (b *Board) CanMove(id, src, dest int) bool {
|
||||
}
|
||||
|
||||
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 := b.GetRow(id)
|
||||
brd[dest] = brd[src]
|
||||
brd[src] = NewEmpty(src)
|
||||
if id == SentinalID {
|
||||
b.Sentinal = brd
|
||||
} else {
|
||||
b.Scourge = brd
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *Board) CanPlay(id int, c *Card, dest int) bool {
|
||||
brd := b.GetRow(id)
|
||||
if dest < 0 || dest > 3 {
|
||||
return false
|
||||
}
|
||||
if !brd[dest].Empty() && !c.Spell {
|
||||
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 {
|
||||
aBrd := b.GetRow(id)
|
||||
if atk < 0 || atk > 3 || def < 0 || def > 3 {
|
||||
return false
|
||||
}
|
||||
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
|
||||
func (b *Board) Attack(id, atk, def int) int {
|
||||
var aid, did int
|
||||
if id == SentinalID {
|
||||
aBrd = b.Sentinal
|
||||
dBrd = b.Scourge
|
||||
aid = SentinalID
|
||||
did = ScourgeID
|
||||
} else {
|
||||
aBrd = b.Scourge
|
||||
dBrd = b.Sentinal
|
||||
aid = ScourgeID
|
||||
did = SentinalID
|
||||
}
|
||||
if dBrd[def].Empty() {
|
||||
attacker := b.GetRow(aid)[atk]
|
||||
defender := b.GetRow(did)[def]
|
||||
if defender.Empty() {
|
||||
//health damage
|
||||
if id == SentinalID {
|
||||
b.Sentinal = aBrd
|
||||
b.Scourge = dBrd
|
||||
} else {
|
||||
b.Scourge = aBrd
|
||||
b.Sentinal = dBrd
|
||||
}
|
||||
return 1
|
||||
}
|
||||
//Do actual battle math
|
||||
attacker := aBrd[atk].Power
|
||||
defender := dBrd[def].Power
|
||||
if attacker > defender {
|
||||
dBrd[def] = NewEmpty(def)
|
||||
if id == SentinalID {
|
||||
b.Sentinal = aBrd
|
||||
b.Scourge = dBrd
|
||||
} else {
|
||||
b.Scourge = aBrd
|
||||
b.Sentinal = dBrd
|
||||
}
|
||||
return 0
|
||||
atkpower := attacker.Power
|
||||
defpower := defender.Power
|
||||
log.Printf("Atk:%v v Def: %v", atkpower, defpower)
|
||||
if atkpower > defpower {
|
||||
return 2
|
||||
}
|
||||
if attacker == defender {
|
||||
aBrd[atk] = NewEmpty(atk)
|
||||
dBrd[def] = NewEmpty(def)
|
||||
if id == 1 {
|
||||
b.Sentinal = aBrd
|
||||
b.Scourge = dBrd
|
||||
} else {
|
||||
b.Scourge = aBrd
|
||||
b.Sentinal = dBrd
|
||||
}
|
||||
return 0
|
||||
if atkpower == defpower {
|
||||
return 4
|
||||
}
|
||||
if atkpower < defpower {
|
||||
return 3
|
||||
}
|
||||
return -1
|
||||
|
||||
}
|
||||
|
||||
func (b *Board) ResetCards() {
|
||||
for _, v := range b.Sentinal {
|
||||
v.Power = v.BasePower
|
||||
}
|
||||
for _, v := range b.Scourge {
|
||||
v.Power = v.BasePower
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ type Card struct {
|
||||
Owner int `json:"owner"`
|
||||
Position int `json:"position"`
|
||||
Spell bool `json:"spell"`
|
||||
Effects []Effect `json:"effects"`
|
||||
}
|
||||
|
||||
type CardType int
|
||||
@ -56,6 +57,7 @@ func NewCard(v, o, p int, id uuid.UUID) *Card {
|
||||
Owner: o,
|
||||
Position: p,
|
||||
Spell: OracleSpell(CardType(v), nil),
|
||||
Effects: []Effect{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +71,8 @@ func NewEmpty(p int) *Card {
|
||||
Counters: 0,
|
||||
Owner: -1,
|
||||
Position: p,
|
||||
Spell: false,
|
||||
Effects: []Effect{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,5 +81,9 @@ func (c *Card) Empty() bool {
|
||||
}
|
||||
|
||||
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
26
internal/game/effect.go
Normal 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)
|
||||
}
|
@ -125,6 +125,16 @@ func (g *Game) StateChanges() {
|
||||
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
|
||||
//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
|
||||
@ -222,10 +232,12 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck {
|
||||
switch cmd_s[0] {
|
||||
case "s":
|
||||
//scry: return scry options off top of deck
|
||||
if !g.CanDraw || g.CardBuffer.Size() > 0 {
|
||||
if !g.CanDraw {
|
||||
return nil
|
||||
}
|
||||
g.CardBuffer = DeckFromCards(currD.Scry(curr.Life))
|
||||
if g.CardBuffer.Size() <= 0 {
|
||||
g.CardBuffer = DeckFromCards(currD.Scry(curr.Life))
|
||||
}
|
||||
return g.CardBuffer
|
||||
case "d":
|
||||
//draw: return player hand
|
||||
@ -236,6 +248,9 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck {
|
||||
return nil
|
||||
}
|
||||
x_i, err := strconv.Atoi(cmd_s[1])
|
||||
if x_i > 2 || x_i < 0 {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
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) {
|
||||
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))
|
||||
var aid, did int
|
||||
if id == SentinalID {
|
||||
aid = SentinalID
|
||||
did = ScourgeID
|
||||
} 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 {
|
||||
log.Println("can't attack")
|
||||
return DeckFromCards([]*Card{})
|
||||
@ -306,10 +343,10 @@ func (g *Game) PlayerAct(id int, cmd string) *Deck {
|
||||
card := curr.Hand[x_i]
|
||||
shouldPlace := true
|
||||
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)
|
||||
if placed {
|
||||
OracleEnters(curr.Hand[x_i], g)
|
||||
OracleEnters(card, g)
|
||||
}
|
||||
curr.Hand = append(curr.Hand[:x_i], curr.Hand[x_i+1:]...)
|
||||
return DeckFromCards(g.GameBoard.GetRow(g.CurrentTurn))
|
||||
|
@ -1,7 +1,5 @@
|
||||
package game
|
||||
|
||||
import "log"
|
||||
|
||||
func OracleUpkeep(c *Card, g *Game) {
|
||||
switch c.Type {
|
||||
case Eight:
|
||||
@ -39,78 +37,58 @@ func OracleEnters(c *Card, g *Game) {
|
||||
switch c.Type {
|
||||
case Ace:
|
||||
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:
|
||||
//+1 to all
|
||||
if c.Owner == SentinalID {
|
||||
for _, v := range g.GameBoard.Sentinal {
|
||||
v.Power = v.Power + 1
|
||||
for _, v := range row {
|
||||
if v.Id != c.Id {
|
||||
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:
|
||||
//+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.Position-1 >= 0 {
|
||||
v := row[c.Position-1]
|
||||
AddEffect(v, Effect{c.Id, v.Id, 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
|
||||
}
|
||||
if c.Position+1 <= 3 {
|
||||
v := row[c.Position+1]
|
||||
AddEffect(v, Effect{c.Id, v.Id, 1})
|
||||
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func OracleLeaves(c *Card, g *Game) {
|
||||
row := g.GameBoard.GetRow(c.Owner)
|
||||
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")
|
||||
for _, v := range row {
|
||||
RemoveEffect(c.Id, v)
|
||||
}
|
||||
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.Position-1 >= 0 {
|
||||
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
|
||||
}
|
||||
|
||||
if c.Position+1 <= 3 {
|
||||
RemoveEffect(c.Id, row[c.Position+1])
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -132,13 +110,33 @@ func OracleMove(c *Card, src, dest int, g *Game) {
|
||||
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
|
||||
if src-1 >= 0 {
|
||||
RemoveEffect(c.Id, row[src-1])
|
||||
}
|
||||
if src+1 <= 3 {
|
||||
RemoveEffect(c.Id, row[src-1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func OracleAttack(c *Card, g *Game) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user