Feat: mark words [for guessers]

This commit is contained in:
Grail Finder
2025-06-27 15:23:45 +03:00
parent 72053281e2
commit 86063a4f7e
3 changed files with 40 additions and 103 deletions

View File

@ -17,8 +17,12 @@
{{.Word}} {{.Word}}
</div> </div>
<div class="h-6 bg-stone-600 rounded-b flex items-center justify-center text-white text-sm cursor-pointer" <div class="h-6 bg-stone-600 rounded-b flex items-center justify-center text-white text-sm cursor-pointer"
onclick="this.innerHTML = 'X';"> hx-get="/mark-card?word={{.Word}}" hx-trigger="click" hx-swap="outerHTML transition:true swap:.05s">
&nbsp; {{range .Mark}}
{{if .Active}}
<span class="mx-0.5">X</span>
{{end}}
{{end}}
</div> </div>
</div> </div>
{{end}} {{end}}

View File

@ -171,6 +171,7 @@ func HandleMarkCard(w http.ResponseWriter, r *http.Request) {
abortWithError(w, "word is not found") abortWithError(w, "word is not found")
return return
} }
cardword := models.WordCard{}
// check if card already was revealed // check if card already was revealed
for i, card := range fi.Room.Cards { for i, card := range fi.Room.Cards {
if !strings.EqualFold(card.Word, word) { if !strings.EqualFold(card.Word, word) {
@ -180,97 +181,29 @@ func HandleMarkCard(w http.ResponseWriter, r *http.Request) {
abortWithError(w, "cannot mark already revealed") abortWithError(w, "cannot mark already revealed")
return return
} }
fi.Room.Cards[i].Mark = append(card.Mark, models.CardMark{ // Check if the current user already has an active mark on this card
Username: fi.State.Username, found := false
Active: true, var newMarks []models.CardMark
}) for _, mark := range card.Mark {
} if mark.Username == fi.State.Username && mark.Active {
cardword := models.WordCard{ found = true
Word: word, } else {
Color: color, newMarks = append(newMarks, mark)
Revealed: false,
}
fi.Room.RevealSpecificWord(word)
fi.Room.UpdateCounter()
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: string(color),
Action: models.ActionTypeGuess,
Word: word,
}
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
// if opened card is of color of opp team, change turn
oppositeColor := fi.Room.GetOppositeTeamColor()
fi.Room.OpenedThisTurn++
if fi.Room.ThisTurnLimit > 0 {
if fi.Room.ThisTurnLimit >= fi.Room.OpenedThisTurn {
// end turn
fi.Room.TeamTurn = oppositeColor
fi.Room.MimeDone = false
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
}
}
switch string(color) {
case "black":
// game over
fi.Room.IsRunning = false
fi.Room.IsOver = true
fi.Room.TeamWon = oppositeColor
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: models.WordColorBlack,
Action: models.ActionTypeGameOver,
}
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
case "white", string(oppositeColor):
// end turn
fi.Room.TeamTurn = oppositeColor
fi.Room.MimeDone = false
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
// check if no cards left => game over
if fi.Room.BlueCounter == 0 {
// blue won
fi.Room.IsRunning = false
fi.Room.IsOver = true
fi.Room.TeamWon = "blue"
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: models.WordColorBlue,
Action: models.ActionTypeGameOver,
} }
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
} }
if fi.Room.RedCounter == 0 { if !found {
// red won newMarks = append(newMarks, models.CardMark{
fi.Room.IsRunning = false Username: fi.State.Username,
fi.Room.IsOver = true Active: true,
fi.Room.TeamWon = "red" })
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: models.WordColorRed,
Action: models.ActionTypeGameOver,
}
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
} }
fi.Room.Cards[i].Mark = newMarks
cardword = fi.Room.Cards[i]
} }
if err := saveFullInfo(fi); err != nil { if err := saveFullInfo(fi); err != nil {
abortWithError(w, err.Error()) abortWithError(w, err.Error())
return return
} }
// get mime bot for opp team and notify it
notifyBotIfNeeded(fi)
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "") notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
if err := tmpl.ExecuteTemplate(w, "cardword", cardword); err != nil { if err := tmpl.ExecuteTemplate(w, "cardword", cardword); err != nil {
log.Error("failed to execute cardword template", "error", err) log.Error("failed to execute cardword template", "error", err)

View File

@ -1,24 +1,25 @@
### feats ### feats
- auto close room if nothing is going on there (hmm) for ~1h; + - auto close room if nothing is going on there (hmm) for ~1h; +
- words database (file) load and form random 25 words; + - words database (file) load and form random 25 words; +
- different files for each supported lang;
- mark cards (instead of opening them (right click?);
- invite link; + - invite link; +
- login with invite link; + - login with invite link; +
- there three places for bot to check if its its move: start-game; end-turn, after mime gave clue; + - there three places for bot to check if its its move: start-game; end-turn, after mime gave clue; +
- remove bot button (if game is not running, or bot already added); + - remove bot button (if game is not running, or bot already added); +
- show in backlog (and with that in prompt to llm) how many cards are left to open, also additional comment: if guess was right; - show in backlog (and with that in prompt to llm) how many cards are left to open, also additional comment: if guess was right;
- hide clue input for mime when it's not their turn; - hide clue input for mime when it's not their turn; +
- needs resend to llm btn; + - needs resend to llm btn; +
- check if clue word is the same as one of the cards and return err if it is; +
- autoscroll down backlog on update; +
- instead of guessing all words at ones, ask only for 1 word to be open. +
- ways to remove bots from teams; +
- better styles and fluff; - better styles and fluff;
- common auth system between sites; - common auth system between sites;
- autoscroll down backlog on update;
- gameover to backlog; - gameover to backlog;
- cleanup backlog after new game is started;
- ended turn action to backlog; - ended turn action to backlog;
- clear indication that model (llm) is thinking / answered; - clear indication that model (llm) is thinking / answered;
- instead of guessing all words at ones, ask only for 1 word to be open. - different files for each supported lang;
- ways to remove bots from teams; - mark cards (instead of opening them (right click?);
- check if clue word is the same as one of the cards and return err if it is; +
#### sse points #### sse points
- clue sse update; - clue sse update;
@ -31,19 +32,18 @@
### issues ### issues
- after the game started (isrunning) players should be able join guessers, but not switch team, or join as a mime; - after the game started (isrunning) players should be able join guessers, but not switch team, or join as a mime; +
- cleanup backlog after new game is started;
- guessers should not be able to open more cards, than mime gave them +1 (auto end turn); + - guessers should not be able to open more cards, than mime gave them +1 (auto end turn); +
- 0 should mean without limit;
- sse hangs / fails connection which causes to wait for cards to open a few seconds (on local machine);
- after starting a new game (after old one) blue mime has no clue input;
- remove verbs from word file;
- invite link gets cutoff;
- mime rejoined the room: does not see colors; state save in store.json has empty role and team + - mime rejoined the room: does not see colors; state save in store.json has empty role and team +
- restart bot routines after server restart; + - restart bot routines after server restart; +
- remove verbs from word file; +
- if mime joins another role, he stays as mime (before game start); +
- guesser llm makes up words, likely the prompt should be more clear; +
- remove bot does not remove for player roles in the room; +
- 0 should mean without limit;
- sse hangs / fails connection which causes to wait for cards to open a few seconds (on local machine) (did not reoccur so far);
- invite link gets cutoff;
- guesser did not have same number of guesses (move ended after 1 guess); show how much guesses left on the page (red after blue); - guesser did not have same number of guesses (move ended after 1 guess); show how much guesses left on the page (red after blue);
- guesser bot no request after game restart; - guesser bot no request after game restart;
- if mime joins another role, he stays as mime (before game start); - remove join as mime button if there is a mime already on that team (rewrite teampew templ);
- guesser llm makes up words, likely the prompt should be more clear; - openrouter 429 errors;
- remove bot does not remove for player roles in the room; +
- remove join as mime button if there is a mime already on that team;