Compare commits

...

20 Commits

Author SHA1 Message Date
stryan 93b54b24c4 add rules text 2021-11-30 21:41:11 -05:00
stryan a0ec6430db add card_view for library 2021-11-20 17:24:29 -05:00
stryan 26aff0ecbb more deck util 2021-11-19 14:10:15 -05:00
stryan 8d4e875891 deck func consistency 2021-11-19 13:53:19 -05:00
stryan 354167535a empty cards have owners, clogs and duds should work 2021-11-16 18:07:24 -05:00
stryan c62eff76bb better enums 2021-11-16 16:44:19 -05:00
stryan a17f5bfa95 add Bureaucrats and clog 2021-11-16 15:51:09 -05:00
stryan 0023bc9813 add student and librarian,update protocol 2021-11-14 15:01:18 -05:00
stryan 671f1a059d add diviner,mesmer,hologram,elephant,uuuh probably more things 2021-11-14 14:43:04 -05:00
stryan 59cfb71a5e add player effects, initial support for arbitrary scrying 2021-11-11 15:08:47 -05:00
stryan bfd48cb069 add chupacabra,duelist,vanguard 2021-11-11 12:21:39 -05:00
stryan b16df174ed update game_view to handle targeting 2021-11-10 18:00:43 -05:00
stryan 220f18a75e add enemy card type 2021-11-10 17:50:52 -05:00
stryan e9b81f7ea9 add first targeted affect (ally) 2021-11-10 17:44:54 -05:00
stryan 3648b6ba16 add ally card type 2021-11-10 17:44:42 -05:00
stryan 8f9ee5cfbb more new cards 2021-11-08 16:59:39 -05:00
stryan fa38a05c9d start adding new cards 2021-11-08 15:33:55 -05:00
stryan c24e1aac32 update protocol with load deck options 2021-11-08 15:04:23 -05:00
stryan c588dab2ae custom deck support, card type generation 2021-11-08 15:01:07 -05:00
stryan 3a38ef2252 clean up board util methods 2021-10-07 13:21:46 -04:00
17 changed files with 501 additions and 76 deletions

View File

@ -58,9 +58,11 @@ Action commands return either an empty list of cards or the relevant list of car
s: Look at the top X cards of the current players deck, where x is their Life total. Returns nothing if unable to scry (i.e. the player can not currently draw a card). Otherwise return a list of zero to three cards representing what was seen.
d <x>: Draw the the card at position X in the result return from a Scry. Returns nothing if the player is unable to draw. Otherwise return the current players hand
b <x>: Bottom the the card at position X in the result return from a Scry. Returns nothing if the player is unable to draw. Otherwise return the current players hand
p <x> <y>: Play the card at position X in the current players hand to position Y on the current player's side of the board. Return nothing if the card cannot be played, otherwise return the current players side of the board.
m <x> <y>: Move the card at position X to position Y, with both positions being on the current players side of the board. Return nothing if the card cannot be moved, otherwise return the current players side of the board.
a <x> <y>: Attack with the card at position X on the current players side of the board at position Y on the opponents side of the board. Returns nothing if the attack can not be made, or the current players side of the board.
t <x> <y>: Apply a targeted effect to card on board X (Either SentinalID or ScourgeID) at position Y. Returns the effected board on success and nothing on failure. Requires a card with a targeted effect to be played first
### GameView
@ -103,6 +105,7 @@ Go struct representation:
MatchID uuid.UUID `json:"match_id"`
Command SessionCmd `json:"command"`
GameCommand *game.Command `json:"game_command,omitempty"`
Data string `json:"data,omitempty"`
}
ID is the player ID in standard UUID format. It is generated by the client, however in the future it may be generated by some type of authentication system
@ -117,9 +120,12 @@ Command is a string representing a command from the following list:
poll: Check if the server has any "broadcast" responses. Opts into polling.
play: Attempt to run the attached GameCommand
ready: Check if both players have joined the game with attached MatchID
load_deck: attempt to set the players deck to the information stored in the Data section
GameCommand is a game command following the conventions described above.
Data is a section for miscelaneous arguments
### Session Command results
@ -150,6 +156,8 @@ Result is a string representing the result of the SessionCommand. The following
"played": The server recognized a game command was sent. This does NOT mean the command was succesful; the client should check the GameResult for that information
"game ready": Both players have joined the game and game commands can be sent
"generic error": An error has occured.
"deck loaded": deck loaded succesfully
"load deck error": error either loading the deck or parsing the deck
The following Results are called "Broadcasts" and are sent by the server to ease the work done by the clients. None of them are required to be handled, but it will most likely be useful for clients to handle at least some of them.

View File

@ -6,8 +6,10 @@ import (
)
type Board struct {
Sentinal [4]*Card `json:"sentinal"`
Scourge [4]*Card `json:"scourge"`
Sentinal [4]*Card `json:"sentinal"`
SentinalSpells [2]int
Scourge [4]*Card `json:"scourge"`
ScourgeSpells [2]int
}
func (b *Board) String() string {
@ -21,27 +23,43 @@ func (b *Board) GetRow(id int) []*Card {
return b.Scourge[:]
} else {
log.Println("asked for invalid row")
panic("bad row")
return nil
}
}
func (b *Board) GetCard(id int, pos int) *Card {
return b.GetRow(id)[pos]
if pos >= 0 && pos <= 3 {
return b.GetRow(id)[pos]
} else {
return nil
}
}
func (b *Board) Remove(c *Card) {
for k, v := range b.Sentinal {
if v.Id == c.Id {
b.Sentinal[k] = NewEmpty(k)
b.Sentinal[k] = NewEmpty(c.Owner, k)
}
}
for k, v := range b.Scourge {
if v.Id == c.Id {
b.Scourge[k] = NewEmpty(k)
b.Scourge[k] = NewEmpty(c.Owner, k)
}
}
}
func (b *Board) Replace(old *Card, neo *Card) {
if old.Owner == SentinalID {
b.Sentinal[old.Position] = neo
} else if old.Owner == ScourgeID {
b.Scourge[old.Position] = neo
} else {
log.Printf("can't replace a card with bad owner:%v", old.Owner)
return
}
}
func (b *Board) Empty(id int) bool {
res := true
row := b.GetRow(id)
@ -75,7 +93,7 @@ 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)
brd[src] = NewEmpty(brd[dest].Owner, src)
return true
}
@ -104,12 +122,16 @@ 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)
dBrd := b.GetRow(flipID(id))
if atk < 0 || atk > 3 || def < 0 || def > 3 {
return false
}
if aBrd[atk].Empty() || aBrd[atk].Sick || atk != def {
return false
}
if aBrd[atk].Phased || dBrd[def].Phased {
return false
}
return true
}

37
card.go
View File

@ -2,6 +2,7 @@ package tome_lib
import (
"fmt"
"log"
"github.com/google/uuid"
)
@ -16,27 +17,17 @@ type Card struct {
Owner int `json:"owner"`
Position int `json:"position"`
Spell bool `json:"spell"`
Token bool `json:"token"`
Phased bool `json:"phased"`
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 {
func NewEmpty(o, p int) *Card {
if o != ScourgeID && o != SentinalID {
log.Printf("Need valid owner for empty card:%v", o)
panic("err")
return nil
}
return &Card{
Type: EmptyValue,
BasePower: -1,
@ -44,18 +35,14 @@ func NewEmpty(p int) *Card {
Id: uuid.New(),
Sick: false,
Counters: 0,
Owner: -1,
Owner: o,
Position: p,
Spell: false,
Token: false,
Phased: 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

10
card_view.go Normal file
View File

@ -0,0 +1,10 @@
package tome_lib
type CardView struct {
Name string `json:"name"`
Type int `json:"type"`
Rank int `json:"rank"`
ImageURI string `json:"image_uri"`
Flavour string `json:"flavour"`
Rules string `json:"rules_text"`
}

55
cardtype.go Normal file
View File

@ -0,0 +1,55 @@
package tome_lib
//go:generate enumer -type=CardType -json
type CardType int
const (
Valk CardType = iota
Speedster //ace, has haste
Commander //2, buffs row
Paladin //3, buffs neighbours
Scholar //4, draws card
Warrior //5, nothing
Fighter //6, nothing
Seven //7, seven
ShieldWall //8, only blocks
//new cards
//Rank 1
HealthPotion //both players get +1 health
Tree //grows to 8 after five turns
Goblin //adds two other 1 strength units
Chupacabra //Destroy target creature
//Rank 2
Ally //puts +1 token on allied unit
Enemy //puts -1 token on enemy unit
//Rank 3
Duelist //puts +0/+1 on allied unit
Bureaucrat //creates a Clog token on any open space
//Rank 4
Vanguard //puts +1/+0 on allied unit
Student //scry 2, draw 1
Librarian //scry life, draw 1
//Rank 5
Elephant //Created a dud on enemy board
//Rank 6
Mesmerist //Shuffles enemy deck
Diviner //Peek top 3, bottom 2
//Rank 8
Hologram //Can't deal HP damage, disapears after 3 turns
//Tokens,etc
GoblinSpawn //1 power goblin token
Dud //0 power token
Clog //0 power token that disapears after one turn
)
const (
EmptyValue CardType = -1
)

95
cardtype_enumer.go Normal file
View File

@ -0,0 +1,95 @@
// Code generated by "enumer -type=CardType -json"; DO NOT EDIT.
//
package tome_lib
import (
"encoding/json"
"fmt"
)
const _CardTypeName = "EmptyValueValkSpeedsterCommanderPaladinScholarWarriorFighterSevenShieldWallHealthPotionTreeGoblinChupacabraAllyEnemyDuelistBureaucratVanguardStudentLibrarianElephantMesmeristDivinerHologramGoblinSpawnDudClog"
var _CardTypeIndex = [...]uint8{0, 10, 14, 23, 32, 39, 46, 53, 60, 65, 75, 87, 91, 97, 107, 111, 116, 123, 133, 141, 148, 157, 165, 174, 181, 189, 200, 203, 207}
func (i CardType) String() string {
i -= -1
if i < 0 || i >= CardType(len(_CardTypeIndex)-1) {
return fmt.Sprintf("CardType(%d)", i+-1)
}
return _CardTypeName[_CardTypeIndex[i]:_CardTypeIndex[i+1]]
}
var _CardTypeValues = []CardType{-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}
var _CardTypeNameToValueMap = map[string]CardType{
_CardTypeName[0:10]: -1,
_CardTypeName[10:14]: 0,
_CardTypeName[14:23]: 1,
_CardTypeName[23:32]: 2,
_CardTypeName[32:39]: 3,
_CardTypeName[39:46]: 4,
_CardTypeName[46:53]: 5,
_CardTypeName[53:60]: 6,
_CardTypeName[60:65]: 7,
_CardTypeName[65:75]: 8,
_CardTypeName[75:87]: 9,
_CardTypeName[87:91]: 10,
_CardTypeName[91:97]: 11,
_CardTypeName[97:107]: 12,
_CardTypeName[107:111]: 13,
_CardTypeName[111:116]: 14,
_CardTypeName[116:123]: 15,
_CardTypeName[123:133]: 16,
_CardTypeName[133:141]: 17,
_CardTypeName[141:148]: 18,
_CardTypeName[148:157]: 19,
_CardTypeName[157:165]: 20,
_CardTypeName[165:174]: 21,
_CardTypeName[174:181]: 22,
_CardTypeName[181:189]: 23,
_CardTypeName[189:200]: 24,
_CardTypeName[200:203]: 25,
_CardTypeName[203:207]: 26,
}
// CardTypeString retrieves an enum value from the enum constants string name.
// Throws an error if the param is not part of the enum.
func CardTypeString(s string) (CardType, error) {
if val, ok := _CardTypeNameToValueMap[s]; ok {
return val, nil
}
return 0, fmt.Errorf("%s does not belong to CardType values", s)
}
// CardTypeValues returns all values of the enum
func CardTypeValues() []CardType {
return _CardTypeValues
}
// IsACardType returns "true" if the value is listed in the enum definition. "false" otherwise
func (i CardType) IsACardType() bool {
for _, v := range _CardTypeValues {
if i == v {
return true
}
}
return false
}
// MarshalJSON implements the json.Marshaler interface for CardType
func (i CardType) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
// UnmarshalJSON implements the json.Unmarshaler interface for CardType
func (i *CardType) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return fmt.Errorf("CardType should be a string, got %s", data)
}
var err error
*i, err = CardTypeString(s)
return err
}

8
cmd.go
View File

@ -5,10 +5,10 @@ import "fmt"
type CmdType string
const (
ActCmd = "a"
StateCmd = "s"
DebugCmd = "d"
InvalidCmd = "e"
ActCmd CmdType = "a"
StateCmd = "s"
DebugCmd = "d"
InvalidCmd = "e"
)
type Command struct {

45
deck.go
View File

@ -22,7 +22,16 @@ func DeckFromCards(c []*Card) *Deck {
Cards: c,
}
}
func DeckFromCard(c *Card) *Deck {
if c == nil {
return &Deck{
Cards: []*Card{},
}
}
return &Deck{
Cards: []*Card{c},
}
}
func (d *Deck) Shuffle() {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := range d.Cards {
@ -31,22 +40,34 @@ func (d *Deck) Shuffle() {
}
}
func (d *Deck) Scry(s int) []*Card {
seen := []*Card{}
if len(d.Cards) < s {
seen = d.Cards
d.Cards = []*Card{}
return seen
func (d *Deck) Scry(s int) *Deck {
var seen []*Card
if len(d.Cards) == 0 {
return DeckFromCard(nil)
} else if len(d.Cards) < s {
seen := make([]*Card, len(d.Cards))
copy(seen, d.Cards)
d.Reset()
} else {
seen = make([]*Card, s)
scrybox := d.Cards[(len(d.Cards) - s):len(d.Cards)]
res := copy(seen, scrybox)
if res == 0 {
panic("Error copy scrybox")
}
d.Cards = d.Cards[0 : len(d.Cards)-s]
}
seen = d.Cards[(len(d.Cards) - s):len(d.Cards)]
d.Cards = d.Cards[0 : len(d.Cards)-s]
return seen
return DeckFromCards(seen)
}
func (d *Deck) Bottom(result []*Card) {
d.Cards = append(result, d.Cards...) //Should shuffle result first?
func (d *Deck) Bottom(bot *Deck) {
d.Cards = append(bot.Cards, d.Cards...) //Should shuffle result first?
}
func (d *Deck) Size() int {
return len(d.Cards)
}
func (d *Deck) Reset() {
d.Cards = []*Card{}
}

View File

@ -7,9 +7,11 @@ import (
)
type Effect struct {
Owner uuid.UUID
Target uuid.UUID
ID int
Owner uuid.UUID
Target uuid.UUID
ID int
Modifier int
NeedsCard bool
}
func RemoveEffect(source uuid.UUID, c *Card) {
@ -22,14 +24,28 @@ func RemoveEffect(source uuid.UUID, c *Card) {
}
}
}
func RemovePlayerEffect(source uuid.UUID, p *Player) {
if p == nil {
return
}
for i, e := range p.Effects {
if e.Owner == source {
p.Effects = append(p.Effects[:i], p.Effects[i+1:]...)
}
}
}
func AddEffect(c *Card, e *Effect) {
if c.Type == EmptyValue {
if c.Type == EmptyValue && e.NeedsCard {
//can't apply effect to empty card
return
}
if e.Target == uuid.Nil {
log.Println("trying to apply targeted effect before target set")
return
}
if c.Position < 0 || c.Position > 3 {
log.Println("trying to apply effect to card not on the board")
return
}
for _, v := range c.Effects {
if v.Owner == e.Owner && v.ID == e.ID && v.Target == e.Target {
@ -40,3 +56,22 @@ func AddEffect(c *Card, e *Effect) {
log.Printf("applying %v to %v", e, c)
c.Effects = append(c.Effects, e)
}
func AddPlayerEffect(p *Player, e *Effect) {
if p == nil || e == nil {
log.Println("adding nil player efect")
return
}
if e.Target != uuid.Nil {
log.Println("trying to apply targeted effect to player set")
return
}
for _, v := range p.Effects {
if v.Owner == e.Owner && v.ID == e.ID {
//can't stack effects
return
}
}
log.Printf("applying %v to player %v", e, p)
p.Effects = append(p.Effects, e)
}

View File

@ -3,16 +3,18 @@ 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"`
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"`
QueuedEffect *Effect `json:"queued_effect"`
TargetReq TargetStatus `json:"target_required"`
Status GameStatus `json:"game_status"`
}
func (v *GameView) String() string {

73
gamestatus_enumer.go Normal file
View File

@ -0,0 +1,73 @@
// Code generated by "enumer -type=GameStatus -json"; DO NOT EDIT.
//
package tome_lib
import (
"encoding/json"
"fmt"
)
const _GameStatusName = "StatusLobbyStatusReadyStatusPlayingStatusStopStatusSentinalWinStatusScourgeWinStatusDraw"
var _GameStatusIndex = [...]uint8{0, 11, 22, 35, 45, 62, 78, 88}
func (i GameStatus) String() string {
if i < 0 || i >= GameStatus(len(_GameStatusIndex)-1) {
return fmt.Sprintf("GameStatus(%d)", i)
}
return _GameStatusName[_GameStatusIndex[i]:_GameStatusIndex[i+1]]
}
var _GameStatusValues = []GameStatus{0, 1, 2, 3, 4, 5, 6}
var _GameStatusNameToValueMap = map[string]GameStatus{
_GameStatusName[0:11]: 0,
_GameStatusName[11:22]: 1,
_GameStatusName[22:35]: 2,
_GameStatusName[35:45]: 3,
_GameStatusName[45:62]: 4,
_GameStatusName[62:78]: 5,
_GameStatusName[78:88]: 6,
}
// GameStatusString retrieves an enum value from the enum constants string name.
// Throws an error if the param is not part of the enum.
func GameStatusString(s string) (GameStatus, error) {
if val, ok := _GameStatusNameToValueMap[s]; ok {
return val, nil
}
return 0, fmt.Errorf("%s does not belong to GameStatus values", s)
}
// GameStatusValues returns all values of the enum
func GameStatusValues() []GameStatus {
return _GameStatusValues
}
// IsAGameStatus returns "true" if the value is listed in the enum definition. "false" otherwise
func (i GameStatus) IsAGameStatus() bool {
for _, v := range _GameStatusValues {
if i == v {
return true
}
}
return false
}
// MarshalJSON implements the json.Marshaler interface for GameStatus
func (i GameStatus) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
// UnmarshalJSON implements the json.Unmarshaler interface for GameStatus
func (i *GameStatus) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return fmt.Errorf("GameStatus should be a string, got %s", data)
}
var err error
*i, err = GameStatusString(s)
return err
}

5
go.mod
View File

@ -2,4 +2,7 @@ module git.saintnet.tech/tomecraft/tome_lib
go 1.16
require github.com/google/uuid v1.3.0
require (
github.com/alvaroloes/enumer v1.1.2 // indirect
github.com/google/uuid v1.3.0
)

11
go.sum
View File

@ -1,2 +1,13 @@
github.com/alvaroloes/enumer v1.1.2 h1:5khqHB33TZy1GWCO/lZwcroBFh7u+0j40T83VUbfAMY=
github.com/alvaroloes/enumer v1.1.2/go.mod h1:FxrjvuXoDAx9isTJrv4c+T410zFi0DtXIT0m65DJ+Wo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1 h1:/I3lTljEEDNYLho3/FUB7iD/oc2cEFgVmbHzV+O0PtU=
github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1/go.mod h1:eD5JxqMiuNYyFNmyY9rkJ/slN8y59oEu4Ei7F8OoKWQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190524210228-3d17549cdc6b h1:iEAPfYPbYbxG/2lNN4cMOHkmgKNsCuUwkxlDCK46UlU=
golang.org/x/tools v0.0.0-20190524210228-3d17549cdc6b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=

View File

@ -1,9 +1,10 @@
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"`
Name string `json:"name"`
Id int `json:"id"`
Hand []*Card `json:"hand"`
Life int `json:"life"`
Ready bool `json:"ready"`
Effects []*Effect
}

View File

@ -10,12 +10,13 @@ type SessionCmd string
type SessionResp string
const (
SessionCmdQuery SessionCmd = "query"
SessionCmdJoin = "join"
SessionCmdLeave = "leave"
SessionCmdPlay = "play"
SessionCmdPoll = "poll"
SessionCmdReady = "ready"
SessionCmdQuery SessionCmd = "query"
SessionCmdJoin = "join"
SessionCmdLeave = "leave"
SessionCmdPlay = "play"
SessionCmdPoll = "poll"
SessionCmdReady = "ready"
SessionCmdLoadDeck = "load_deck"
)
const (
@ -26,7 +27,9 @@ const (
SessionRespJoinError = "join error"
SessionRespLeft = "left"
SessionRespPlayed = "played"
SessionRespDeckLoaded = "deck loaded"
SessionRespError = "generic error"
SessionRespLoadDeckError = "load deck error"
SessionRespBroadcastSenTurn = "Sentinal turn"
SessionRespBroadcastScoTrun = "Scourge turn"
SessionRespBroadcastSenWin = "Sentinal wins"
@ -46,10 +49,11 @@ type SessionCommand struct {
MatchID uuid.UUID `json:"match_id"`
Command SessionCmd `json:"command"`
GameCommand *Command `json:"game_command,omitempty"`
Data string `json:"data,omitempty"`
}
func (s *SessionCommand) String() string {
return fmt.Sprintf("%v %v %v\n", s.ID, s.Command, s.GameCommand)
return fmt.Sprintf("%v %v %v %v\n", s.ID, s.Command, s.GameCommand, s.Data)
}
type SessionCommandResult struct {

73
targetstatus_enumer.go Normal file
View File

@ -0,0 +1,73 @@
// Code generated by "enumer -type=TargetStatus -json"; DO NOT EDIT.
//
package tome_lib
import (
"encoding/json"
"fmt"
)
const _TargetStatusName = "TargetSelfTargetOwnTargetOwnEmptyTargetOppTargetOppEmptyTargetAnyTargetNone"
var _TargetStatusIndex = [...]uint8{0, 10, 19, 33, 42, 56, 65, 75}
func (i TargetStatus) String() string {
if i < 0 || i >= TargetStatus(len(_TargetStatusIndex)-1) {
return fmt.Sprintf("TargetStatus(%d)", i)
}
return _TargetStatusName[_TargetStatusIndex[i]:_TargetStatusIndex[i+1]]
}
var _TargetStatusValues = []TargetStatus{0, 1, 2, 3, 4, 5, 6}
var _TargetStatusNameToValueMap = map[string]TargetStatus{
_TargetStatusName[0:10]: 0,
_TargetStatusName[10:19]: 1,
_TargetStatusName[19:33]: 2,
_TargetStatusName[33:42]: 3,
_TargetStatusName[42:56]: 4,
_TargetStatusName[56:65]: 5,
_TargetStatusName[65:75]: 6,
}
// TargetStatusString retrieves an enum value from the enum constants string name.
// Throws an error if the param is not part of the enum.
func TargetStatusString(s string) (TargetStatus, error) {
if val, ok := _TargetStatusNameToValueMap[s]; ok {
return val, nil
}
return 0, fmt.Errorf("%s does not belong to TargetStatus values", s)
}
// TargetStatusValues returns all values of the enum
func TargetStatusValues() []TargetStatus {
return _TargetStatusValues
}
// IsATargetStatus returns "true" if the value is listed in the enum definition. "false" otherwise
func (i TargetStatus) IsATargetStatus() bool {
for _, v := range _TargetStatusValues {
if i == v {
return true
}
}
return false
}
// MarshalJSON implements the json.Marshaler interface for TargetStatus
func (i TargetStatus) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
// UnmarshalJSON implements the json.Unmarshaler interface for TargetStatus
func (i *TargetStatus) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return fmt.Errorf("TargetStatus should be a string, got %s", data)
}
var err error
*i, err = TargetStatusString(s)
return err
}

27
util.go
View File

@ -1,9 +1,10 @@
package tome_lib
//go:generate enumer -type=GameStatus -json
type GameStatus int
const (
StatusLobby = iota
StatusLobby GameStatus = iota
StatusReady
StatusPlaying
StatusStop
@ -12,7 +13,31 @@ const (
StatusDraw
)
//go:generate enumer -type=TargetStatus -json
type TargetStatus int
const (
TargetSelf TargetStatus = iota
TargetOwn
TargetOwnEmpty
TargetOpp
TargetOppEmpty
TargetAny
TargetNone
)
const (
SentinalID = 1
ScourgeID = 2
)
func flipID(i int) int {
if i == SentinalID {
return ScourgeID
} else if i == ScourgeID {
return SentinalID
} else {
return -1
}
}