package models import ( "golias/utils" "time" "github.com/rs/xid" ) type WordColor string const ( WordColorWhite = "white" WordColorBlue = "blue" WordColorRed = "red" WordColorBlack = "black" WordColorUknown = "beige" ) func StrToWordColor(s string) WordColor { switch s { case "white": return WordColorWhite case "blue": return WordColorBlue case "red": return WordColorRed case "black": return WordColorBlack default: return WordColorUknown } } type Team struct { Guessers []string Mime string Color string } type Action struct { Actor string ActorColor string Action WordColor // clue | guess Word string WordColor string Number string // for clue } type BotPlayer struct { Role UserRole // gueeser | mime Team UserTeam } type Room struct { ID string `json:"id" db:"id"` CreatedAt time.Time `json:"created_at" db:"created_at"` // RoomName string `json:"room_name"` RoomPass string `json:"room_pass"` RoomLink string CreatorName string `json:"creator_name"` PlayerList []string `json:"player_list"` ActionHistory []Action TeamTurn UserTeam RedTeam Team BlueTeam Team Cards []WordCard WCMap map[string]WordColor BotMap map[string]BotPlayer // key is bot name Result uint8 // 0 for unknown; 1 is win for red; 2 if for blue; BlueCounter uint8 RedCounter uint8 RedTurn bool // false is blue turn MimeDone bool IsPublic bool // GameSettings *GameSettings `json:"settings"` IsRunning bool `json:"is_running"` Language string `json:"language" example:"en" form:"language"` RoundTime int32 `json:"round_time"` // ProgressPct uint32 `json:"progress_pct"` IsOver bool TeamWon UserTeam // blue | red } // WhichBotToMove returns bot name that have to move or empty string func (r *Room) WhichBotToMove() string { if !r.IsRunning { return "" } switch r.TeamTurn { case UserTeamBlue: if !r.MimeDone { _, ok := r.BotMap[r.BlueTeam.Mime] if ok { return r.BlueTeam.Mime } } // check gussers case UserTeamRed: if !r.MimeDone { _, ok := r.BotMap[r.RedTeam.Mime] if ok { return r.RedTeam.Mime } } // check gussers default: // how did we got here? return "" } return "" } func (r *Room) GetOppositeTeamColor() UserTeam { switch r.TeamTurn { case "red": return UserTeamBlue case "blue": return UserTeamRed } return UserTeamNone } func (r *Room) UpdateCounter() { redCounter := uint8(0) blueCounter := uint8(0) for _, card := range r.Cards { if card.Revealed { continue } switch card.Color { case WordColorRed: redCounter++ case WordColorBlue: blueCounter++ } } r.RedCounter = redCounter r.BlueCounter = blueCounter } // func (r *Room) LoadTestCards() { // // TODO: pass room settings // // TODO: map language to path // wl := wordloader.InitDefaultLoader("assets/words/en_nouns.txt") // cards, err := wl.Load() // if err != nil { // // no logger // fmt.Println("failed to load cards", "error", err) // } // r.Cards = cards // // cards := []WordCard{ // // {Word: "hamster", Color: "blue"}, // // {Word: "child", Color: "red"}, // // {Word: "wheel", Color: "white"}, // // {Word: "condition", Color: "black"}, // // {Word: "test", Color: "white"}, // // {Word: "ball", Color: "blue"}, // // {Word: "violin", Color: "red"}, // // {Word: "rat", Color: "white"}, // // {Word: "perplexity", Color: "blue"}, // // {Word: "notion", Color: "red"}, // // {Word: "guitar", Color: "blue"}, // // {Word: "ocean", Color: "blue"}, // // {Word: "moon", Color: "blue"}, // // {Word: "coffee", Color: "blue"}, // // {Word: "mountain", Color: "blue"}, // // {Word: "book", Color: "blue"}, // // {Word: "camera", Color: "blue"}, // // {Word: "apple", Color: "red"}, // // {Word: "fire", Color: "red"}, // // {Word: "rose", Color: "red"}, // // {Word: "sun", Color: "red"}, // // {Word: "cherry", Color: "red"}, // // {Word: "heart", Color: "red"}, // // {Word: "tomato", Color: "red"}, // // {Word: "cloud", Color: "white"}, // // } // // r.Cards = cards // } func (r *Room) ChangeTurn() { switch r.TeamTurn { case "blue": r.TeamTurn = "red" case "red": r.TeamTurn = "blue" default: r.TeamTurn = "blue" } } func (r *Room) RevealAllCards() { for i := range r.Cards { r.Cards[i].Revealed = true } } func (r *Room) RevealSpecificWord(word string) { for i, card := range r.Cards { if card.Word == word { r.Cards[i].Revealed = true } } } type WordCard struct { Word string `json:"word"` Color WordColor `json:"color"` Revealed bool `json:"revealed"` } type GameSettings struct { IsRunning bool `json:"is_running"` Language string `json:"language" example:"en" form:"language"` RoundTime int32 `json:"round_time"` ProgressPct uint32 `json:"progress_pct"` IsOver bool } // ===== type RoomReq struct { // is not user or not unique RoomPass string `json:"room_pass" form:"room_pass"` RoomName string `json:"room_name" form:"room_name"` // GameSettings } func (rr *RoomReq) CreateRoom(creator string) *Room { roomID := xid.New().String() return &Room{ // RoomName: , RoomPass: rr.RoomPass, ID: roomID, CreatedAt: time.Now(), PlayerList: []string{creator}, CreatorName: creator, BotMap: make(map[string]BotPlayer), } } // ==== type FullInfo struct { State *UserState Room *Room List []*Room LinkLogin string // room_id } func (f *FullInfo) ExitRoom() *Room { f.Room.PlayerList = utils.RemoveFromSlice(f.State.Username, f.Room.PlayerList) f.Room.RedTeam.Guessers = utils.RemoveFromSlice(f.State.Username, f.Room.RedTeam.Guessers) f.Room.BlueTeam.Guessers = utils.RemoveFromSlice(f.State.Username, f.Room.BlueTeam.Guessers) if f.Room.RedTeam.Mime == f.State.Username { f.Room.RedTeam.Mime = "" } if f.Room.BlueTeam.Mime == f.State.Username { f.Room.BlueTeam.Mime = "" } f.State.ExitRoom() resp := f.Room f.Room = nil return resp }