Compare commits
20 Commits
Author | SHA1 | Date |
---|---|---|
stryan | 93b54b24c4 | |
stryan | a0ec6430db | |
stryan | 26aff0ecbb | |
stryan | 8d4e875891 | |
stryan | 354167535a | |
stryan | c62eff76bb | |
stryan | a17f5bfa95 | |
stryan | 0023bc9813 | |
stryan | 671f1a059d | |
stryan | 59cfb71a5e | |
stryan | bfd48cb069 | |
stryan | b16df174ed | |
stryan | 220f18a75e | |
stryan | e9b81f7ea9 | |
stryan | 3648b6ba16 | |
stryan | 8f9ee5cfbb | |
stryan | fa38a05c9d | |
stryan | c24e1aac32 | |
stryan | c588dab2ae | |
stryan | 3a38ef2252 |
|
@ -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.
|
||||
|
||||
|
|
34
board.go
34
board.go
|
@ -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
37
card.go
|
@ -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
|
||||
|
|
|
@ -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"`
|
||||
}
|
|
@ -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
|
||||
)
|
|
@ -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
8
cmd.go
|
@ -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
45
deck.go
|
@ -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{}
|
||||
}
|
||||
|
|
45
effect.go
45
effect.go
|
@ -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)
|
||||
}
|
||||
|
|
22
game_view.go
22
game_view.go
|
@ -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 {
|
||||
|
|
|
@ -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
5
go.mod
|
@ -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
11
go.sum
|
@ -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=
|
||||
|
|
11
player.go
11
player.go
|
@ -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
|
||||
}
|
||||
|
|
18
session.go
18
session.go
|
@ -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 {
|
||||
|
|
|
@ -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
27
util.go
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue