Enha: bot guesser

This commit is contained in:
Grail Finder
2025-05-29 11:46:40 +03:00
parent 9ebce0a7d0
commit 7fab000d20
4 changed files with 64 additions and 28 deletions

View File

@ -74,9 +74,6 @@ func saveFullInfo(fi *models.FullInfo) error {
if err := saveState(fi.State.Username, fi.State); err != nil {
return err
}
// if fi.Room == nil { // can be null on exit
// return nil
// }
if err := saveRoom(fi.Room); err != nil {
return err
}
@ -85,14 +82,6 @@ func saveFullInfo(fi *models.FullInfo) error {
func notifyBotIfNeeded(fi *models.FullInfo) {
if botName := fi.Room.WhichBotToMove(); botName != "" {
// // get bot from memcache
// bot, err := loadBot(botName, fi.Room.ID)
// if err != nil {
// log.Error("failed to load bot", "bot_name", botName, "room_id", fi.Room.ID)
// // abortWithError(w, err.Error())
// // return
// }
// send signal to bot
llmapi.SignalChanMap[botName] <- true
}
log.Debug("no bot", "room_id", fi.Room.ID)

View File

@ -2,6 +2,7 @@ package handlers
import (
"errors"
"fmt"
"golias/llmapi"
"golias/models"
"html/template"
@ -147,7 +148,8 @@ func HandleAddBot(w http.ResponseWriter, r *http.Request) {
}
// TODO: what if bot exists already?
// control number and names of bots
bot, err := llmapi.NewBot(role, team, "bot1", fi.Room.ID, cfg)
botname := fmt.Sprintf("bot_%d", len(llmapi.SignalChanMap)+1) // what if many rooms?
bot, err := llmapi.NewBot(role, team, botname, fi.Room.ID, cfg)
if err != nil {
abortWithError(w, err.Error())
return

View File

@ -27,8 +27,8 @@ var (
SignalChanMap = make(map[string]chan bool)
DoneChanMap = make(map[string]chan bool)
// got prompt: control character (\\u0000-\\u001F) found while parsing a string at line 4 column 0
MimePrompt = `we are playing alias;\nyou are a mime (player who gives a clue of one noun word and number of cards you expect them to open) of the red team (people who would guess by your clue want open the red cards);\nplease return your clue, number of cards to open and what words you mean them to find using that clue in json like:\n{\n\"clue\": \"one-word-noun\",\n\"number\": \"number-from-0-to-9\",\n\"words_I_mean_my_team_to_open\": [\"this\", \"that\", ...]\n}\nthe team who openes all their cards first wins.\nplease return json only.\nunopen Blue cards left: %d;\nunopen Red cards left: %d;\nhere is the game info in json:\n%s`
GuesserPrompt = `we are playing alias;\nyou are to guess words of the red team (people who would guess by your clue want open the red cards) by given clue and a number of meant guesses;\nplease return your guesses and words that you did not wish to open, but think that they could be also meant by the clue in json like:\n{\n\"guesses\": [\"word1\", \"word2\", ...],\n\"could_be\": [\"this\", \"that\", ...]\n}\nthe team who openes all their cards first wins.\nplease return json only.\nunopen Blue cards left: %d;\nunopen Red cards left: %d;\nhere is the game info in json:\n%s`
MimePrompt = `we are playing alias;\nyou are a mime (player who gives a clue of one noun word and number of cards you expect them to open) of the %s team (people who would guess by your clue want open the %s cards);\nplease return your clue, number of cards to open and what words you mean them to find using that clue in json like:\n{\n\"clue\": \"one-word-noun\",\n\"number\": \"number-from-0-to-9\",\n\"words_I_mean_my_team_to_open\": [\"this\", \"that\", ...]\n}\nthe team who openes all their cards first wins.\nplease return json only.\nunopen Blue cards left: %d;\nunopen Red cards left: %d;\nhere is the game info in json:\n%s`
GuesserPrompt = `we are playing alias;\nyou are to guess words of the %s team (people who would guess by your clue want open the %s cards) by given clue and a number of meant guesses;\nplease return your guesses and words that you did not wish to open, but think that they could be also meant by the clue in json like:\n{\n\"guesses\": [\"word1\", \"word2\", ...],\n\"could_be\": [\"this\", \"that\", ...]\n}\nthe team who openes all their cards first wins.\nplease return json only.\nunopen Blue cards left: %d;\nunopen Red cards left: %d;\nhere is the game info in json:\n%s`
// notifier =
)
@ -142,12 +142,57 @@ func (b *Bot) StartBot() {
room.MimeDone = true
eventPayload = mimeResp.Clue + mimeResp.Number
case models.UserRoleGuesser:
gr := GusserResp{}
if err := json.Unmarshal([]byte(sj), &gr); err != nil {
b.log.Error("failed to unmarshal guesser resp", "error", err)
return
for _, word := range tempMap["guesses"].([]string) {
color, exists := room.WCMap[word]
b.log.Debug("bot trying to open card", "word", word, "color",
color, "exists", exists)
if !exists {
return
}
room.RevealSpecificWord(word)
room.UpdateCounter()
action := models.Action{
Actor: b.BotName,
ActorColor: b.Team,
WordColor: string(color),
Action: "guessed",
Word: word,
}
room.ActionHistory = append(room.ActionHistory, action)
// if opened card is of color of opp team, change turn
oppositeColor := room.GetOppositeTeamColor()
switch string(color) {
case "black":
// game over
room.IsRunning = false
room.IsOver = true
room.TeamWon = oppositeColor
case "white", string(oppositeColor):
// end turn
room.TeamTurn = oppositeColor
room.MimeDone = false
}
// check if no cards left => game over
if room.BlueCounter == 0 {
// blue won
room.IsRunning = false
room.IsOver = true
room.TeamWon = "blue"
}
if room.RedCounter == 0 {
// red won
room.IsRunning = false
room.IsOver = true
room.TeamWon = "red"
}
if err := saveRoom(room); err != nil {
b.log.Error("failed to save room", "room", room)
return
}
}
b.log.Info("mime resp log", "guesserResp", gr)
b.log.Info("mime resp log", "guesserResp", tempMap)
eventName = models.NotifyRoomUpdatePrefix + room.ID
eventPayload = ""
default:
b.log.Error("unexpected role", "role", b.Role, "llmResp", sj)
return
@ -157,6 +202,9 @@ func (b *Bot) StartBot() {
b.log.Error("failed to save room", "error", err)
return
}
if botName := room.WhichBotToMove(); botName != "" {
SignalChanMap[botName] <- true
}
broker.Notifier.Notifier <- broker.NotificationEvent{
EventName: eventName,
Payload: eventPayload,
@ -291,11 +339,10 @@ func (b *Bot) BuildPrompt(room *models.Room) string {
// Escape the JSON string for inclusion in another JSON field
escapedData := strings.ReplaceAll(string(data), `"`, `\"`)
if b.Role == models.UserRoleMime {
return fmt.Sprintf(MimePrompt, room.BlueCounter, room.RedCounter, escapedData)
return fmt.Sprintf(MimePrompt, b.Team, b.Team, room.BlueCounter, room.RedCounter, escapedData)
}
if b.Role == models.UserRoleMime {
// TODO:
return ""
if b.Role == models.UserRoleGuesser {
return fmt.Sprintf(GuesserPrompt, b.Team, b.Team, room.BlueCounter, room.RedCounter, escapedData)
}
return ""
}

View File

@ -11,10 +11,9 @@ import (
func ListenToRequests(port string) error {
mux := http.NewServeMux()
server := &http.Server{
Handler: handlers.LogRequests(handlers.GetSession(mux)),
Addr: port,
ReadTimeout: time.Second * 5,
// WriteTimeout: time.Second * 5,
Handler: handlers.LogRequests(handlers.GetSession(mux)),
Addr: port,
ReadTimeout: time.Second * 5,
WriteTimeout: 0, // sse streaming
}
fs := http.FileServer(http.Dir("assets/"))
@ -23,7 +22,6 @@ func ListenToRequests(port string) error {
mux.HandleFunc("GET /ping", handlers.HandlePing)
mux.HandleFunc("GET /", handlers.HandleHome)
mux.HandleFunc("POST /login", handlers.HandleFrontLogin)
// mux.HandleFunc("GET /room", handlers.HandleRoomEnter)
mux.HandleFunc("POST /join-team", handlers.HandleJoinTeam)
mux.HandleFunc("GET /end-turn", handlers.HandleEndTurn)
mux.HandleFunc("POST /room-create", handlers.HandleCreateRoom)