initial migration

This commit is contained in:
stryan 2021-10-01 12:43:55 -04:00
commit 50c63067d1
11 changed files with 481 additions and 0 deletions

155
board.go Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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)
}

18
util.go Normal file
View File

@ -0,0 +1,18 @@
package tome_lib
type GameStatus int
const (
StatusLobby = iota
StatusReady
StatusPlaying
StatusStop
StatusSentinalWin
StatusScourgeWin
StatusDraw
)
const (
SentinalID = 1
ScourgeID = 2
)