lesson2

package
v0.0.0-...-fc927da Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 19, 2021 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EachPlayerTagName   string = "each-player"
	EachRoundTagName    string = "each-round"
	EachTeamTagName     string = "each-team"
	SelectPlayerTagName string = "select-player"
	SelectRoundTagName  string = "select-round"
	SelectTeamTagName   string = "select-team"
)
View Source
const (
	ByAccumulatedRankingAttribute string = "by-accumulated-ranking"
	ByRankingAttribute            string = "by-ranking"
)

Variables

View Source
var AllowedWhereColumns = map[string]bool{
	"content":  true,
	"header":   true,
	"by_line":  true,
	"tags":     true,
	"group_id": true,
	"owner_id": true,
	"id":       true,
}
View Source
var PresetScoreAccumulatorExprs = map[string]ScoreAccumulatorExpr{

	"sum": "addf .Accumulated.Score .Next.Score",
	"max": "maxf .Accumulated.Score .Next.Score",
}

Functions

This section is empty.

Types

type Act

type Act struct {
	Scenes          []Scene
	ActRepeaterExpr ActRepeaterExpr
}

type ActRepeaterExpr

type ActRepeaterExpr string

func (ActRepeaterExpr) EvalBool

func (expr ActRepeaterExpr) EvalBool(checkpoint Checkpoint) (bool, error)

type Acts

type Acts []Act

type Checkpoint

type Checkpoint struct {
	MaxAccumulatedScores map[ScoreName]float64
	SumAccumulatedScores map[ScoreName]float64
	Round                Round
}

A checkpoint contains summary information about the state of the game currently It is used in eval-ing act repetitions and question sets

type ClientID

type ClientID string

type ClientModel

type ClientModel struct {
	Model
	CurrentPlayer Player
	CurrentRound  Round
}

A small extension specific to a particular client at a particular round

func (*ClientModel) EmptyCopy

func (mdl *ClientModel) EmptyCopy() ClientModel

Makes a client model with the same player and round but no records

func (*ClientModel) Eval

func (mdl *ClientModel) Eval(templateStr string) (string, error)

func (*ClientModel) ForEachPlayer

func (mdl *ClientModel) ForEachPlayer() []ClientModel

Splits the model into many sub ClientModels each with just one ClientID

func (*ClientModel) ForEachPlayerByAccumulatedRank

func (mdl *ClientModel) ForEachPlayerByAccumulatedRank(scoreName ScoreName) []ClientModel

func (*ClientModel) ForEachPlayerByRank

func (mdl *ClientModel) ForEachPlayerByRank(scoreName ScoreName) []ClientModel

func (*ClientModel) ForEachRound

func (mdl *ClientModel) ForEachRound() []ClientModel

Splits the model into many sub models each with just one Round

func (*ClientModel) ForEachTeam

func (mdl *ClientModel) ForEachTeam() []ClientModel

func (*ClientModel) GetEntriesByAct

func (mdl *ClientModel) GetEntriesByAct(act uint64) ClientModel

func (*ClientModel) GetEntriesByActScene

func (mdl *ClientModel) GetEntriesByActScene(act uint64, scene uint64) ClientModel

func (*ClientModel) GetEntriesByClientID

func (mdl *ClientModel) GetEntriesByClientID(clientID string) ClientModel

func (*ClientModel) GetEntriesByCurrentPlayer

func (mdl *ClientModel) GetEntriesByCurrentPlayer() ClientModel

func (*ClientModel) GetEntriesByLastRoundWithQuestion

func (mdl *ClientModel) GetEntriesByLastRoundWithQuestion() ClientModel

func (*ClientModel) GetEntriesByPlayerName

func (mdl *ClientModel) GetEntriesByPlayerName(playerName string) ClientModel

func (*ClientModel) GetEntriesByPreviousRep

func (mdl *ClientModel) GetEntriesByPreviousRep() ClientModel

Fixme: I'm not sure semantically a Round is a Round as much as a Rep?

func (*ClientModel) GetEntriesByPreviousScene

func (mdl *ClientModel) GetEntriesByPreviousScene() ClientModel

If there is no previous scene in the act

func (*ClientModel) GetEntriesByRound

func (mdl *ClientModel) GetEntriesByRound(act uint64, scene uint64, repeat uint64) ClientModel

func (*ClientModel) GetEntriesByTeam

func (mdl *ClientModel) GetEntriesByTeam(teamName string) ClientModel

func (*ClientModel) GetPlayers

func (mdl *ClientModel) GetPlayers() []Player

func (*ClientModel) GetQuestions

func (mdl *ClientModel) GetQuestions() []Question

func (*ClientModel) GetScoreCards

func (mdl *ClientModel) GetScoreCards() []ScoreCards

func (*ClientModel) GetScores

func (mdl *ClientModel) GetScores(scoreName string) []ScoreCard

type Controller

type Controller struct {
	//Note: Controller doesn't own the current round any more - event loop does that
	PlanID   uuid.UUID
	Plan     *Plan // This is the fixed recipe for the lesson
	Model    Model // This is the dynamically evaluated model as questions are answered etc.
	LeaderID uuid.UUID
	Leader   *account.User //Runs the show
	Players  map[ClientID]Player
	Teams    map[ClientID]TeamName
	Rounds   []Round
	Draw     Draw
	// contains filtered or unexported fields
}

Controller runs on the EventLoop go routine mostly, except a number of Async methods that take a channel to sync back with (with optional error!)

func NewController

func NewController(planID uuid.UUID, leaderID uuid.UUID) *Controller

func (*Controller) AddPlayer

func (ctrl *Controller) AddPlayer(player Player)

func (*Controller) CreateRound

func (ctrl *Controller) CreateRound(round Round, drawChan *chan<- Draw) (bool, error)

TODO need to pass through a draw channel Returns whether or not a round was created - i.e. false if the round already exists

func (*Controller) DealDraw

func (ctrl *Controller) DealDraw(draw Draw) error

TODO we need a DealDraw(Draw) which should extend draw map and try to pre-resolve as much as possible

func (*Controller) FetchQuestions

func (ctrl *Controller) FetchQuestions(round Round, drawChan chan<- Draw) error

Note - let's just get rid of the idea that question filters have templates Turn a question set into a list of questions and resolve those questions using a client model

func (*Controller) GetPlayerTeam

func (ctrl *Controller) GetPlayerTeam(player Player) TeamName

func (*Controller) LoadPlan

func (ctrl *Controller) LoadPlan() error

func (*Controller) NumPlayers

func (ctrl *Controller) NumPlayers() int

func (*Controller) NumTeams

func (ctrl *Controller) NumTeams() int

func (*Controller) NumberRequired

func (ctrl *Controller) NumberRequired(qs *QuestionSet) int

func (*Controller) PutPlayersInTeams

func (ctrl *Controller) PutPlayersInTeams() error

func (*Controller) UsedQuestionCount

func (ctrl *Controller) UsedQuestionCount() int

type Draw

type Draw map[*QuestionSet]map[Round][]Question

type EventLoop

type EventLoop struct {
	Ctrl               Controller
	CurrentRound       Round
	ConsoleInChannel   <-chan EventLoopEvent
	TheatreInChannel   <-chan EventLoopEvent
	CtrlInChannel      <-chan EventLoopEvent //TODO rarely used - really just for serious async
	ConsoleOutChannels map[ClientID]chan<- EventLoopEvent
	TheatreOutChannels map[ClientID]chan<- EventLoopEvent
}

type EventLoopEvent

type EventLoopEvent interface {
	HandleFromConsole(*EventLoop, string) error //Second argument is clientID
	HandleFromTheatre(*EventLoopEvent) error
}

type LessonServer

type LessonServer struct {
	Opts struct {
		// contains filtered or unexported fields
	}
	//TODO I'm very convinced now that controller shouldn't have it's
	//TODO own go-routine. Should just listen on event loop
	//TODO then controller should have async channels made out that we can listen to
	//TODO (or be passed to!) TODO TODO
	Controller Controller
	Register   struct {
		// contains filtered or unexported fields
	}
	EventLoop EventLoop
	// contains filtered or unexported fields
}

func NewLessonServer

func NewLessonServer() *LessonServer

func (*LessonServer) Run

func (srv *LessonServer) Run() error

type Model

type Model map[Round]map[TeamName]map[Player]Record

Note that this can naturally be grouped just by inspecting ... the single, grouped upon key

func (*Model) AddRecord

func (mdl *Model) AddRecord(rec Record)

func (*Model) Eval

func (mdl *Model) Eval(currentPlayer Player, currentRound Round, templateStr string) (string, error)

func (*Model) Records

func (mdl *Model) Records() []Record

type Plan

type Plan struct {
	account.UserObject
	Name             string
	Description      string
	Tags             Tags             //TODO jsonify
	TeamRules        TeamRules        //TODO embed
	ScoreDefinitions ScoreDefinitions //TODO jsonify
	Acts             Acts             //TODO jsonify
}

type Player

type Player struct {
	ClientID ClientID
	Name     string
}

type Question

type Question struct {
	account.UserObject
	Content          string         `json:"content" gorm:"column:content"`
	Header           string         `json:"header,omitempty" gorm:"column:header"`
	Media            string         `json:"media,omitempty" gorm:"column:media"`
	MediaContentType string         `json:"mediaContentType,omitempty" gorm:"column:media_content_type"`
	ByLine           string         `json:"byline,omitempty" gorm:"column:by_line"`
	Tags             pq.StringArray `json:"tags" gorm:"type:varchar(64)[];column:tags"`
	Rules            QuestionRules  `json:"rules" gorm:"column:rules"`
}

func (*Question) Resolve

func (question *Question) Resolve(mdl *ClientModel) error

type QuestionLogic

type QuestionLogic string

Note: Vote here means "vote for person"- it's up to the slide designer ... to dress this up as "vote for their answer"

const (
	SingleInput              QuestionLogic = "Single Input"
	SingleInputOpen          QuestionLogic = "Single Input No Right Answer"
	MultipleInput            QuestionLogic = "Multiple Input"
	MultipleInputOpen        QuestionLogic = "Multiple Input No Right Answer"
	SingleMultipleChoice     QuestionLogic = "Single Answer Multiple Choice"
	SingleMultipleChoiceOpen QuestionLogic = "Single Answer Multiple Choice No Right Answer"
	MultiMultipleChoice      QuestionLogic = "Multiple Answer Multiple Choice"
	MultiMultipleChoiceOpen  QuestionLogic = "Multiple Answer Multiple Choice No Right Answer"
	MultiBestMultipleChoice  QuestionLogic = "Multiple Answer Multiple Choice With Best Answer"
	ApproximateSingleInput   QuestionLogic = "Approximate Single Input"
	ApproximateMultipleInput QuestionLogic = "Approximate Multiple Inputs"
	VoteForPlayerFPTP        QuestionLogic = "Vote For Player (First Past The Post)"
	VoteForPlayerSTV         QuestionLogic = "Vote For Player (Single Transferable Vote)"
	VoteForPlayerAV          QuestionLogic = "Vote For Player (Alternative Vote)"
)

type QuestionRules

type QuestionRules struct {
	Logic       QuestionLogic       `json:"logic,omitempty"`
	ContentType ResponseContentType `json:"contentType,omitempty"`
	Data        datatypes.JSON      `json:"data,omitempty"` //Extra data - e.g. best answer plus multiple choices
}

func (*QuestionRules) Scan

func (qr *QuestionRules) Scan(src interface{}) error

func (*QuestionRules) Value

func (qr *QuestionRules) Value() (driver.Value, error)

type QuestionSet

type QuestionSet struct {
	Logic          QuestionSetLogic `json:"logic"`
	WhereCondition WhereCondition   `json:"whereCondition,omitempty"`
}

type QuestionSetLogic

type QuestionSetLogic string
const (
	QuestionSetLogicOneQuestionForEverybody QuestionSetLogic = "one-question-for-everbody"
	QuestionSetLogicOneQuestionPerPlayer    QuestionSetLogic = "one-question-per-player"
	QuestionSetLogicOneQuestionPerTeam      QuestionSetLogic = "one-question-per-team"
)

type Record

type Record struct {
	Player     Player
	Round      Round
	ScoreCards ScoreCards
	Question   *Question //Optional
	Team       TeamName
	Response   *Response //TODO need to fold this through model
}

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

func NewRenderer

func NewRenderer(mdl *ClientModel, slideTemplate string) *Renderer

func (*Renderer) Render

func (renderer *Renderer) Render() (string, error)

type Response

type Response struct {
	Player      Player
	ContentType ResponseContentType
	Data        interface{}
	Logic       QuestionLogic
}

func (*Response) Validate

func (response *Response) Validate() bool

TODO need to connect event loop up with websocket channels before understanding how this looks

type ResponseContentType

type ResponseContentType string
const (
	ContentTypeText    ResponseContentType = "text"
	ContentTypeCanvas  ResponseContentType = "canvas"
	ContentTypeImage   ResponseContentType = "image"
	ContentTypeVideo   ResponseContentType = "video"
	ContentTypeNumber  ResponseContentType = "number"
	ContentTypeEmoji   ResponseContentType = "emoji"
	ContentTypeBoolean ResponseContentType = "boolean"
	ContentTypeMathjax ResponseContentType = "mathjax"
	ContentTypeAudio   ResponseContentType = "audio"
	ContentTypeChart   ResponseContentType = "chart"
)

type Round

type Round struct {
	Act   uint
	Scene uint
	Rep   uint
}

func (*Round) LessThan

func (round *Round) LessThan(rhs Round) bool

type RoundScore

type RoundScore struct {
	ScoreName ScoreName
	Score     float64
	Ranking   uint64
}

type Scene

type Scene struct {
	Template     string
	ScoresActive []ScoreName
	QuestionSet  *QuestionSet //TODO add these filters across.
}

type ScoreAccumulatorExpr

type ScoreAccumulatorExpr string

func (ScoreAccumulatorExpr) Eval

func (expr ScoreAccumulatorExpr) Eval(score RoundScore, card ScoreCard) float64

type ScoreCard

type ScoreCard struct {
	RoundScore
	AccumulatedScore   float64
	AccumulatedRanking uint64
}

type ScoreCards

type ScoreCards map[ScoreName]ScoreCard

type ScoreDefinitions

type ScoreDefinitions map[ScoreName]ScoreAccumulatorExpr

type ScoreName

type ScoreName string

type Tags

type Tags []string

type TeamLogic

type TeamLogic string
const (
	TeamLogicNoTeams    TeamLogic = "No Teams"
	TeamLogicBySize     TeamLogic = "By Size"
	TeamLogicByNumberOf TeamLogic = "By Number Of"
)

type TeamName

type TeamName string
const DefaultTeamName TeamName = "default"

type TeamRules

type TeamRules struct {
	TeamLogic TeamLogic
	Count     int
}

type WebsocketMessage

type WebsocketMessage struct {
	Type     string
	ClientID ClientID
	Data     json.RawMessage
}

type WhereCondition

type WhereCondition map[string]interface{}

func (*WhereCondition) CleanseAndValidate

func (wc *WhereCondition) CleanseAndValidate() error

Should remove any conditions that aren't queryable Should check that all the types are right

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL