Documentation ¶
Index ¶
- Constants
- Variables
- func DeterministicUsername(uuid string) string
- func RelevantRating(ratings Ratings, ratingKey VariantKey) string
- func TotalTimeEstimate(gamereq *pb.GameRequest) int32
- func VariantFromGameReq(gamereq *pb.GameRequest) (TimeControl, Variant, error)
- type EventAudienceType
- type EventWrapper
- type FakeNower
- type Game
- func (g *Game) CachedTimeRemaining(idx int) int
- func (g *Game) ChallengeRule() macondopb.ChallengeRule
- func (g *Game) CreationRequest() *pb.GameRequest
- func (g *Game) GameID() string
- func (g *Game) GetWinnerIdx() int
- func (g *Game) HistoryRefresherEvent() *pb.GameHistoryRefresher
- func (g *Game) RatingKey() (VariantKey, error)
- func (g *Game) RatingMode() pb.RatingMode
- func (g *Game) RecordTimeOfMove(idx int)
- func (g *Game) RegisterChangeHook(eventChan chan<- *EventWrapper) error
- func (g *Game) ResetTimersAndStart()
- func (g *Game) SendChange(e *EventWrapper)
- func (g *Game) SetGameEndReason(r pb.GameEndReason)
- func (g *Game) SetLoserIdx(pidx int)
- func (g *Game) SetTimerModule(n Nower)
- func (g *Game) SetWinnerIdx(pidx int)
- func (g *Game) TimeRanOut(idx int) bool
- func (g *Game) TimeRemaining(idx int) int
- func (g *Game) TimeStarted() int64
- func (g *Game) WinnerWasSet() bool
- type GameTimer
- type IncrementType
- type ListDatum
- type ListItem
- type MistakeMagnitude
- type MistakeType
- type Nower
- type PoolMember
- type Profile
- type ProfileStats
- type Quickdata
- type Ratings
- type Session
- type SingleRating
- type SoughtGame
- type SoughtGameType
- type StatItem
- type StatItemType
- type Stats
- type TimeControl
- type Timers
- type User
- type Variant
- type VariantKey
Constants ¶
const ( AudGame EventAudienceType = "game" AudGameTV = "gametv" AudUser = "user" AudLobby = "lobby" )
const ( KnowledgeMistakeType = "knowledge" FindingMistakeType = "finding" VisionMistakeType = "vision" TacticsMistakeType = "tactics" StrategyMistakeType = "strategy" TimeMistakeType = "time" EndgameMistakeType = "endgame" )
const ( LargeMistakeMagnitude = "large" MediumMistakeMagnitude = "medium" SmallMistakeMagnitude = "small" SaddestMistakeMagnitude = "saddest" SadderMistakeMagnitude = "sadder" SadMistakeMagnitude = "sad" UnspecifiedMistakeMagnitude = "unspecified" )
const ( ALL_TRIPLE_LETTERS_COVERED_STAT string = "All Triple Letter Squares Covered" ALL_TRIPLE_WORDS_COVERED_STAT string = "All Triple Word Squares Covered" BINGOS_STAT string = "Bingos" CHALLENGED_PHONIES_STAT string = "Challenged Phonies" CHALLENGES_LOST_STAT string = "Challenges Lost" CHALLENGES_WON_STAT string = "Challenges Won" COMMENTS_STAT string = "Comments" DRAWS_STAT string = "Draws" EXCHANGES_STAT string = "Exchanges" FIRSTS_STAT string = "Firsts" GAMES_STAT string = "Games" HIGH_GAME_STAT string = "High Game" HIGH_TURN_STAT string = "High Turn" LOSSES_STAT string = "Losses" LOW_GAME_STAT string = "Low Game" NO_BINGOS_STAT string = "Games with no Bingos" MANY_DOUBLE_LETTERS_COVERED_STAT string = "Many Double Letter Squares Covered" MANY_DOUBLE_WORDS_COVERED_STAT string = "Many Double Word Squares Covered" MISTAKES_STAT string = "Mistakes" SCORE_STAT string = "Score" RATINGS_STAT string = "Ratings" TILES_PLAYED_STAT string = "Tiles Played" TIME_STAT string = "Time Taken" TRIPLE_TRIPLES_STAT string = "Triple Triples" TURNS_STAT string = "Turns" TURNS_WITH_BLANK_STAT string = "Turns With Blank" UNCHALLENGED_PHONIES_STAT string = "Unchallenged Phonies" VALID_PLAYS_THAT_WERE_CHALLENGED_STAT string = "Valid Plays That Were Challenged" VERTICAL_OPENINGS_STAT string = "Vertical Openings" WINS_STAT string = "Wins" NO_BLANKS_PLAYED_STAT string = "No Blanks Played" HIGH_SCORING_STAT string = "High Scoring" COMBINED_HIGH_SCORING_STAT string = "Combined High Scoring" COMBINED_LOW_SCORING_STAT string = "Combined Low Scoring" ONE_PLAYER_PLAYS_EVERY_POWER_TILE_STAT string = "One Player Plays Every Power Tile" ONE_PLAYER_PLAYS_EVERY_E_STAT string = "One Player Plays Every E" MANY_CHALLENGES_STAT string = "Many Challenges" FOUR_OR_MORE_CONSECUTIVE_BINGOS_STAT string = "Four or More Consecutive Bingos" )
const ( VarClassic Variant = "classic" VarAWorth100 = "a-is-worth-100" VarDogworms = "dogworms" // OMGWords scrambled = dogworms? VarSuper = "superomg" )
const ( TCRegular TimeControl = "regular" // > 14/0 TCRapid = "rapid" // 6/0 to <= 14/0 TCBlitz = "blitz" // > 2/0 to < 6/0 TCUltraBlitz = "ultrablitz" // 2/0 and under TCCorres = "corres" )
const ( // Cutoffs in seconds for different time controls. CutoffUltraBlitz = 2 * 60 CutoffBlitz = 6 * 60 CutoffRapid = 14 * 60 )
const (
CrosswordGame string = "CrosswordGame"
)
const (
// MaxNameLength is the maximum length that a proto message can be.
MaxNameLength = 64
)
const MaxNotableInt = 1000000000
const RatingDeviationConfidence = 150
If the RD is <= this number, the rating is "known"
const ( // SessionExpiration - Expire a session after this much time. SessionExpiration = time.Hour * 24 * 30 )
Variables ¶
var MistakeMagnitudeAliases = map[string]string{LargeMistakeMagnitude: LargeMistakeMagnitude, MediumMistakeMagnitude: MediumMistakeMagnitude, SmallMistakeMagnitude: SmallMistakeMagnitude, UnspecifiedMistakeMagnitude: UnspecifiedMistakeMagnitude, "saddest": LargeMistakeMagnitude, "sadder": MediumMistakeMagnitude, "sad": SmallMistakeMagnitude, }
var MistakeMagnitudeMapping = map[string]int{LargeMistakeMagnitude: 1, MediumMistakeMagnitude: 2, SmallMistakeMagnitude: 3, UnspecifiedMistakeMagnitude: 0, }
var MistakeTypeMapping = map[string]int{KnowledgeMistakeType: 0, FindingMistakeType: 1, VisionMistakeType: 2, TacticsMistakeType: 3, StrategyMistakeType: 4, TimeMistakeType: 5, EndgameMistakeType: 6}
var StatName_value = map[string]int{ ALL_TRIPLE_LETTERS_COVERED_STAT: 0, ALL_TRIPLE_WORDS_COVERED_STAT: 1, BINGOS_STAT: 2, CHALLENGED_PHONIES_STAT: 3, CHALLENGES_LOST_STAT: 4, CHALLENGES_WON_STAT: 5, COMMENTS_STAT: 6, DRAWS_STAT: 7, EXCHANGES_STAT: 8, FIRSTS_STAT: 9, GAMES_STAT: 10, HIGH_GAME_STAT: 11, HIGH_TURN_STAT: 12, LOSSES_STAT: 13, LOW_GAME_STAT: 14, NO_BINGOS_STAT: 15, MANY_DOUBLE_LETTERS_COVERED_STAT: 16, MANY_DOUBLE_WORDS_COVERED_STAT: 17, MISTAKES_STAT: 18, SCORE_STAT: 19, RATINGS_STAT: 20, TILES_PLAYED_STAT: 21, TIME_STAT: 22, TRIPLE_TRIPLES_STAT: 23, TURNS_STAT: 24, TURNS_WITH_BLANK_STAT: 25, UNCHALLENGED_PHONIES_STAT: 26, VALID_PLAYS_THAT_WERE_CHALLENGED_STAT: 27, VERTICAL_OPENINGS_STAT: 28, WINS_STAT: 29, NO_BLANKS_PLAYED_STAT: 30, HIGH_SCORING_STAT: 31, COMBINED_HIGH_SCORING_STAT: 32, COMBINED_LOW_SCORING_STAT: 33, ONE_PLAYER_PLAYS_EVERY_POWER_TILE_STAT: 34, ONE_PLAYER_PLAYS_EVERY_E_STAT: 35, MANY_CHALLENGES_STAT: 36, FOUR_OR_MORE_CONSECUTIVE_BINGOS_STAT: 37, }
Functions ¶
func DeterministicUsername ¶
func RelevantRating ¶
func RelevantRating(ratings Ratings, ratingKey VariantKey) string
RelevantRating returns the rating from a Ratings object given a rating key.
func TotalTimeEstimate ¶ added in v0.1.2
func TotalTimeEstimate(gamereq *pb.GameRequest) int32
TotalTimeEstimate estimates the amount of time this game will take, per side.
func VariantFromGameReq ¶
func VariantFromGameReq(gamereq *pb.GameRequest) (TimeControl, Variant, error)
Types ¶
type EventAudienceType ¶
type EventAudienceType string
type EventWrapper ¶
type EventWrapper struct { Type pb.MessageType // The actual event should therefore be a proto object Event proto.Message // contains filtered or unexported fields }
An EventWrapper is a real-time update, whether it is a played move, a challenged move, or the game ending, a seek beginning, etc.
func EventFromByteArray ¶
func EventFromByteArray(arr []byte) (*EventWrapper, error)
EventFromByteArray takes in a serialized event and deserializes it.
func WrapEvent ¶
func WrapEvent(event proto.Message, messageType pb.MessageType) *EventWrapper
WrapEvent wraps a protobuf event.
func (*EventWrapper) AddAudience ¶
func (e *EventWrapper) AddAudience(audType EventAudienceType, suffix string)
AddAudience sets the audience(s) for this event. It is in the form of a NATS channel name. This is not required to be set in order to deliver a message, but certain functions will use it in the gameplay/entity module.
func (*EventWrapper) AddExcludedUsers ¶ added in v0.1.2
func (e *EventWrapper) AddExcludedUsers(ids []string)
AddExcludedUsers excludes the given users from receiving this message
func (*EventWrapper) Audience ¶
func (e *EventWrapper) Audience() []string
Audience gets the audience(s) for this event, in the form of NATS channel names.
func (*EventWrapper) Serialize ¶
func (e *EventWrapper) Serialize() ([]byte, error)
Serialize serializes the event to a byte array. Our encoding inserts a two byte big-endian number indicating the length of the coming bytes, then a byte representing the message type to the start of the event.
func (*EventWrapper) SetSerializationProtocol ¶
func (e *EventWrapper) SetSerializationProtocol(protocol string)
SetSerializationProtocol sets the serialization protocol of the protobuf object.
type FakeNower ¶ added in v0.1.2
type FakeNower struct {
// contains filtered or unexported fields
}
FakeNower uses a fake timer. It is used for tests so we don't actually sleep.
func NewFakeNower ¶ added in v0.1.2
type Game ¶
type Game struct { sync.RWMutex game.Game PlayerDBIDs [2]uint PlayersReady [2]bool GameReq *pb.GameRequest // started is set when the game actually starts (when the game timers start). // Note that the internal game.Game may have started a few seconds before, // but there should be no information about it given until _this_ started // is true. Started bool Timers Timers GameEndReason pb.GameEndReason // if 0 or 1, that player won // if -1, it was a tie! WinnerIdx int LoserIdx int Stats *Stats ChangeHook chan<- *EventWrapper Quickdata *Quickdata CreatedAt time.Time // contains filtered or unexported fields }
A Game should be saved to the database or store. It wraps a macondo.Game, and we should save most of the included fields here, especially the macondo.game.History (which can be exported as GCG, etc in the future)
func NewGame ¶
func NewGame(mcg *game.Game, req *pb.GameRequest) *Game
NewGame takes in a Macondo game that was just "started". Note that Macondo games when they start do not log any time, they just deal tiles. The time of start must be logged later, when both players are in the table and ready.
func (*Game) CachedTimeRemaining ¶
func (*Game) ChallengeRule ¶
func (g *Game) ChallengeRule() macondopb.ChallengeRule
func (*Game) CreationRequest ¶
func (g *Game) CreationRequest() *pb.GameRequest
func (*Game) GetWinnerIdx ¶
func (*Game) HistoryRefresherEvent ¶
func (g *Game) HistoryRefresherEvent() *pb.GameHistoryRefresher
func (*Game) RatingKey ¶
func (g *Game) RatingKey() (VariantKey, error)
func (*Game) RatingMode ¶
func (g *Game) RatingMode() pb.RatingMode
func (*Game) RecordTimeOfMove ¶
func (*Game) RegisterChangeHook ¶
func (g *Game) RegisterChangeHook(eventChan chan<- *EventWrapper) error
RegisterChangeHook registers a channel with the game. Events will be sent down this channel.
func (*Game) ResetTimersAndStart ¶
func (g *Game) ResetTimersAndStart()
Reset timers to _now_. The game is actually starting.
func (*Game) SendChange ¶
func (g *Game) SendChange(e *EventWrapper)
SendChange sends an event via the registered hook.
func (*Game) SetGameEndReason ¶
func (g *Game) SetGameEndReason(r pb.GameEndReason)
func (*Game) SetLoserIdx ¶
func (*Game) SetTimerModule ¶ added in v0.1.2
SetTimerModule sets the timer for a game to the given Nower.
func (*Game) SetWinnerIdx ¶
func (*Game) TimeRanOut ¶
TimeRanOut calculates if time ran out for the given player. Assumes player is on turn, otherwise it always returns false.
func (*Game) TimeRemaining ¶
TimeRemaining calculates the time remaining, but does NOT update it.
func (*Game) TimeStarted ¶
func (*Game) WinnerWasSet ¶
type GameTimer ¶ added in v0.1.2
type GameTimer struct{}
GameTimer uses the standard library's `time` package to determine how much time has elapsed in a game.
type IncrementType ¶
type IncrementType int
const ( EventType IncrementType = iota GameType FinalType )
type ListDatum ¶ added in v0.1.2
type ListDatum struct { // Used for words Word string `json:"w,omitempty"` Probability int `json:"p,omitempty"` // Used for words or games: Score int `json:"s,omitempty"` // Used for comments: Comment string `json:"c,omitempty"` // Used for mistakes: MistakeType int `json:"t,omitempty"` MistakeSize int `json:"z,omitempty"` // Used for ratings: Rating int `json:"r,omitempty"` Variant string `json:"v,omitempty"` }
A ListDatum is the individual datum that is stored in a list. It is a sort of "union" of various struct types. Depending on the type of stat, only some of thees fields will be filled in.
type MistakeMagnitude ¶
type MistakeMagnitude string
type MistakeType ¶
type MistakeType string
type Nower ¶ added in v0.1.2
type Nower interface { // Now returns a timestamp in milliseconds Now() int64 }
Nower is an interface for determining the current time
type PoolMember ¶
func NewPoolMember ¶
type Profile ¶
type Profile struct { FirstName string LastName string CountryCode string Title string About string Ratings Ratings Stats ProfileStats }
Profile is a user profile. It might not be defined for anonymous users.
type ProfileStats ¶
type ProfileStats struct {
Data map[VariantKey]*Stats
}
type Quickdata ¶ added in v0.1.2
type Quickdata struct { OriginalRequestId string `json:"o"` FinalScores []int32 `json:"s"` PlayerInfo []*gameservicepb.PlayerInfo `json:"pi"` }
Quickdata represents data that we might need quick access to, for the purposes of aggregating large numbers of games rapidly. This should get saved in its own blob in the store, as opposed to being buried within a game history.
type Ratings ¶
type Ratings struct {
Data map[VariantKey]SingleRating
}
Ratings gets stored into a PostgreSQL database.
type SingleRating ¶
type SingleRating struct { Rating float64 `json:"r"` RatingDeviation float64 `json:"rd"` Volatility float64 `json:"v"` // This is the last game timestamp for this user for THIS variant: LastGameTimestamp int64 `json:"ts"` }
SingleRating encodes a whole Glicko-225 rating object.
type SoughtGame ¶
type SoughtGame struct { // A sought game has either of these two fields set SeekRequest *pb.SeekRequest MatchRequest *pb.MatchRequest }
func NewMatchRequest ¶
func NewMatchRequest(matchRequest *pb.MatchRequest) *SoughtGame
func NewSoughtGame ¶
func NewSoughtGame(seekRequest *pb.SeekRequest) *SoughtGame
func (*SoughtGame) ConnID ¶ added in v0.1.2
func (sg *SoughtGame) ConnID() string
func (*SoughtGame) ID ¶
func (sg *SoughtGame) ID() string
func (*SoughtGame) Seeker ¶
func (sg *SoughtGame) Seeker() string
func (*SoughtGame) Type ¶
func (sg *SoughtGame) Type() SoughtGameType
type SoughtGameType ¶
type SoughtGameType int
const ( TypeSeek SoughtGameType = iota TypeMatch TypeNone )
type StatItemType ¶
type StatItemType int
const ( SingleType StatItemType = iota ListType MinimumType MaximumType )
type TimeControl ¶
type TimeControl string
type Timers ¶
type Timers struct { // TimeOfLastUpdate is the timestamp of the last update, in milliseconds. // If no update has been made, this defaults to timeStarted. TimeOfLastUpdate int64 `json:"lu"` // TimeStarted is a unix timestamp, in milliseconds. TimeStarted int64 `json:"ts"` // TimeRemaining is an array of remaining time per player, in milliseconds. TimeRemaining []int `json:"tr"` // MaxOvertime is in minutes. All others are in milliseconds. MaxOvertime int `json:"mo"` }
type User ¶
type User struct { sync.RWMutex Anonymous bool // ID is the database ID. Since this increases monotonically, we should // not expose it to the user ID uint // UUID is the "user-exposed" ID, in any APIs. UUID string Username string Password string Email string Profile *Profile // CurrentChannel tracks presence; where is the user currently? CurrentChannel string IsBot bool IsAdmin bool }
User - the db-specific details are in the store package.
func (*User) GetRating ¶
func (u *User) GetRating(ratingKey VariantKey) (*SingleRating, error)
GetRating gets a full Glicko-225 rating for this user, based on the passed-in rating key.
func (*User) GetRelevantRating ¶
func (u *User) GetRelevantRating(ratingKey VariantKey) string
GetRelevantRating gets a displayable rating for this user, based on the passed-in rating key (encoding variant, time control, etc)
type VariantKey ¶
type VariantKey string
func ToVariantKey ¶
func ToVariantKey(lexiconName string, variantName Variant, timeControl TimeControl) VariantKey