initial migration
This commit is contained in:
commit
50c63067d1
155
board.go
Normal file
155
board.go
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Board struct {
|
||||||
|
Sentinal [4]*Card `json:"sentinal"`
|
||||||
|
Scourge [4]*Card `json:"scourge"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if id == SentinalID {
|
||||||
|
return b.Sentinal[:]
|
||||||
|
} else if id == ScourgeID {
|
||||||
|
return b.Scourge[:]
|
||||||
|
} else {
|
||||||
|
log.Println("asked for invalid row")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Board) GetCard(id int, pos int) *Card {
|
||||||
|
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] = NewEmpty(k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range b.Scourge {
|
||||||
|
if v.Id == c.Id {
|
||||||
|
b.Scourge[k] = NewEmpty(k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Board) Empty(id int) bool {
|
||||||
|
res := true
|
||||||
|
row := b.GetRow(id)
|
||||||
|
for _, v := range row {
|
||||||
|
if !v.Empty() {
|
||||||
|
res = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
if !brd[dest].Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if brd[src].Sick {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Board) Move(id, src, dest int) bool {
|
||||||
|
brd := b.GetRow(id)
|
||||||
|
brd[dest] = brd[src]
|
||||||
|
brd[dest].Position = dest
|
||||||
|
brd[src] = NewEmpty(src)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Board) Play(id int, c *Card, dest int, should bool) bool {
|
||||||
|
brd := b.GetRow(id)
|
||||||
|
if should {
|
||||||
|
c.Position = dest
|
||||||
|
c.Owner = id
|
||||||
|
brd[dest] = c
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
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, atk, def int) int {
|
||||||
|
var aid, did int
|
||||||
|
if id == SentinalID {
|
||||||
|
aid = SentinalID
|
||||||
|
did = ScourgeID
|
||||||
|
} else {
|
||||||
|
aid = ScourgeID
|
||||||
|
did = SentinalID
|
||||||
|
}
|
||||||
|
attacker := b.GetRow(aid)[atk]
|
||||||
|
defender := b.GetRow(did)[def]
|
||||||
|
if defender.Empty() {
|
||||||
|
//health damage
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
//Do actual battle math
|
||||||
|
atkpower := attacker.Power
|
||||||
|
defpower := defender.Power
|
||||||
|
log.Printf("Atk:%v v Def: %v", atkpower, defpower)
|
||||||
|
if atkpower > defpower {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
70
card.go
Normal file
70
card.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Card struct {
|
||||||
|
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"`
|
||||||
|
Spell bool `json:"spell"`
|
||||||
|
Effects []*Effect `json:"effects"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CardType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Valk CardType = iota
|
||||||
|
Ace
|
||||||
|
Two
|
||||||
|
Three
|
||||||
|
Four
|
||||||
|
Five
|
||||||
|
Six
|
||||||
|
Seven
|
||||||
|
Eight
|
||||||
|
)
|
||||||
|
const (
|
||||||
|
EmptyValue CardType = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewEmpty(p int) *Card {
|
||||||
|
return &Card{
|
||||||
|
Type: EmptyValue,
|
||||||
|
BasePower: -1,
|
||||||
|
Power: -1,
|
||||||
|
Id: uuid.New(),
|
||||||
|
Sick: false,
|
||||||
|
Counters: 0,
|
||||||
|
Owner: -1,
|
||||||
|
Position: p,
|
||||||
|
Spell: false,
|
||||||
|
Effects: []*Effect{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c CardType) String() string {
|
||||||
|
if c == -1 {
|
||||||
|
return " "
|
||||||
|
}
|
||||||
|
return []string{"V", "A", "2", "3", "4", "5", "6", "7", "8"}[c]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Card) Empty() bool {
|
||||||
|
return c.Type == EmptyValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Card) String() string {
|
||||||
|
ready := " "
|
||||||
|
if c.Sick {
|
||||||
|
ready = "*"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v%v%v", c.Type, c.Power, ready)
|
||||||
|
}
|
34
cmd.go
Normal file
34
cmd.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type CmdType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActCmd = "a"
|
||||||
|
StateCmd = "s"
|
||||||
|
DebugCmd = "d"
|
||||||
|
InvalidCmd = "e"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Command struct {
|
||||||
|
PlayerID int `json:"player_id"`
|
||||||
|
Type CmdType `json:"type"`
|
||||||
|
Cmd string `json:"cmd"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) String() string {
|
||||||
|
return fmt.Sprintf("%v %v %v", c.PlayerID, c.Type, c.Cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandResult struct {
|
||||||
|
PlayerID int `json:"player_id"`
|
||||||
|
ResultType CmdType `json:"result_type"`
|
||||||
|
StateResult *GameView `json:"state_result,omitempty"`
|
||||||
|
ActionResult *Deck `json:"action_result,omitempty"`
|
||||||
|
DebugResult *interface{} `json:"debug_result,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandResult) String() string {
|
||||||
|
return fmt.Sprintf("%v %v\nState Result: %v\nAction Result: %v\nDebug: %v\n", c.PlayerID, c.ResultType, c.StateResult, c.ActionResult, c.DebugResult)
|
||||||
|
}
|
52
deck.go
Normal file
52
deck.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Deck struct {
|
||||||
|
Cards []*Card `json:"cards"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) String() string {
|
||||||
|
if d == nil {
|
||||||
|
return "||"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("|%v|", d.Cards)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeckFromCards(c []*Card) *Deck {
|
||||||
|
return &Deck{
|
||||||
|
Cards: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Shuffle() {
|
||||||
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
for i := range d.Cards {
|
||||||
|
j := r.Intn(i + 1)
|
||||||
|
d.Cards[i], d.Cards[j] = d.Cards[j], d.Cards[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Scry(s int) []*Card {
|
||||||
|
seen := []*Card{}
|
||||||
|
if len(d.Cards) < s {
|
||||||
|
seen = d.Cards
|
||||||
|
d.Cards = []*Card{}
|
||||||
|
return seen
|
||||||
|
}
|
||||||
|
seen = d.Cards[(len(d.Cards) - s):len(d.Cards)]
|
||||||
|
d.Cards = d.Cards[0 : len(d.Cards)-s]
|
||||||
|
return seen
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
42
effect.go
Normal file
42
effect.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Effect struct {
|
||||||
|
Owner uuid.UUID
|
||||||
|
Target uuid.UUID
|
||||||
|
ID int
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveEffect(source uuid.UUID, c *Card) {
|
||||||
|
if c.Type == EmptyValue {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
if c.Type == EmptyValue {
|
||||||
|
log.Println("Can't add effect to empty card")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c.Position < 0 {
|
||||||
|
log.Println("trying to apply effect to card not on the board")
|
||||||
|
}
|
||||||
|
for _, v := range c.Effects {
|
||||||
|
if v.Owner == e.Owner && v.ID == e.ID && v.Target == e.Target {
|
||||||
|
log.Println("can't stack effects")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("applying %v to %v", e, c)
|
||||||
|
c.Effects = append(c.Effects, e)
|
||||||
|
}
|
20
game_view.go
Normal file
20
game_view.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type GameView struct {
|
||||||
|
Board *Board `json:"board"`
|
||||||
|
Player *Player `json:"player"`
|
||||||
|
DeckSize int `json:"deck_size"`
|
||||||
|
EnemyLife int `json:"enemy_life"`
|
||||||
|
EnemyDeckSize int `json:"enemy_deck_size"`
|
||||||
|
EnemyHandSize int `json:"enemy_hand_size"`
|
||||||
|
CurrentTurn int `json:"current_turn"`
|
||||||
|
CanDraw bool `json:"can_draw"`
|
||||||
|
HasDrawn bool `json:"has_drawn"`
|
||||||
|
Status GameStatus `json:"game_status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *GameView) String() string {
|
||||||
|
return fmt.Sprintf("Enemy Life: %v Enemy Hand Size: %v Enemy DeckSize: %v\n\n%v\n\n%v\nYou Life: %v\nCT:%v CD: %v, HD %v, Status: %v\n", v.EnemyLife, v.EnemyHandSize, v.EnemyDeckSize, v.Board, v.Player.Hand, v.Player.Life, v.CurrentTurn, v.CanDraw, v.HasDrawn, v.Status)
|
||||||
|
}
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module tome_lib
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require github.com/google/uuid v1.3.0 // indirect
|
2
go.sum
Normal file
2
go.sum
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
19
player.go
Normal file
19
player.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Hand []*Card `json:"hand"`
|
||||||
|
Life int `json:"life"`
|
||||||
|
Ready bool `json:"ready"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPlayer(name string, id int) *Player {
|
||||||
|
return &Player{
|
||||||
|
Name: name,
|
||||||
|
Id: id,
|
||||||
|
Hand: []*Card{},
|
||||||
|
Life: 3,
|
||||||
|
Ready: false,
|
||||||
|
}
|
||||||
|
}
|
64
session.go
Normal file
64
session.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package tome_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SessionCmd string
|
||||||
|
type SessionResp string
|
||||||
|
|
||||||
|
const (
|
||||||
|
SessionCmdQuery SessionCmd = "query"
|
||||||
|
SessionCmdJoin = "join"
|
||||||
|
SessionCmdLeave = "leave"
|
||||||
|
SessionCmdPlay = "play"
|
||||||
|
SessionCmdPoll = "poll"
|
||||||
|
SessionCmdReady = "ready"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SessionRespFound SessionResp = "found"
|
||||||
|
SessionRespJoined1 = "joined p1"
|
||||||
|
SessionRespJoined2 = "joined p2"
|
||||||
|
SessionRespReady = "game ready"
|
||||||
|
SessionRespJoinError = "join error"
|
||||||
|
SessionRespLeft = "left"
|
||||||
|
SessionRespPlayed = "played"
|
||||||
|
SessionRespError = "generic error"
|
||||||
|
SessionRespBroadcastSenTurn = "Sentinal turn"
|
||||||
|
SessionRespBroadcastScoTrun = "Scourge turn"
|
||||||
|
SessionRespBroadcastSenWin = "Sentinal wins"
|
||||||
|
SessionRespBroadcastScoWin = "Scourge wins"
|
||||||
|
SessionRespBroadcastUpdate = "update"
|
||||||
|
SessionRespBroadcastSenJoin = "Sentinal joined"
|
||||||
|
SessionRespBroadcastScoJoin = "Scourge joined"
|
||||||
|
SessionRespBroadcastSenReady = "Sentinal player is ready"
|
||||||
|
SessionRespBroadcastScoReady = "Scourge player is ready"
|
||||||
|
SessionRespBroadcastSenLeft = "Sentinal player has left"
|
||||||
|
SessionRespBroadcastScoLeft = "Scourge player has left"
|
||||||
|
SessionRespBroadcastNone = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
type SessionCommand struct {
|
||||||
|
ID uuid.UUID `json:"player_id"`
|
||||||
|
MatchID uuid.UUID `json:"match_id"`
|
||||||
|
Command SessionCmd `json:"command"`
|
||||||
|
GameCommand *Command `json:"game_command,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SessionCommand) String() string {
|
||||||
|
return fmt.Sprintf("%v %v %v\n", s.ID, s.Command, s.GameCommand)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SessionCommandResult struct {
|
||||||
|
ID uuid.UUID `json:"player_id"`
|
||||||
|
MatchID uuid.UUID `json:"match_id"`
|
||||||
|
Result SessionResp `json:"result"`
|
||||||
|
GameResult *CommandResult `json:"game_result,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SessionCommandResult) String() string {
|
||||||
|
return fmt.Sprintf("%v %v %v\n", s.ID, s.Result, s.GameResult)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user