naisu test

main
Bel LaPointe 2024-12-15 01:41:22 -07:00
parent 39b1a6a1e8
commit 9dd661ecd0
2 changed files with 109 additions and 23 deletions

View File

@ -5,7 +5,8 @@ import (
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "maps"
"math/rand"
"slices" "slices"
"time" "time"
@ -89,7 +90,7 @@ type (
Kill struct { Kill struct {
Timestamp time.Time Timestamp time.Time
Victim string Victim string
Public bool KillWord KillWord
} }
KillWords struct { KillWords struct {
@ -102,23 +103,33 @@ type (
} }
Assignment struct { Assignment struct {
Public []string Public []KillWord
Private []string Private []KillWord
}
KillWord struct {
Word string
Points int
} }
EventType int EventType int
EventPlayerJoin struct { EventPlayerJoin struct {
Type EventType
ID string ID string
} }
EventPlayerLeave struct { EventPlayerLeave struct {
Type EventType
ID string ID string
} }
EventGameComplete struct{} EventGameComplete struct {
Type EventType
}
EventAssignmentRotation struct { EventAssignmentRotation struct {
Type EventType
Killer string Killer string
Killed string Victim string
KillWord string KillWord KillWord
KillWords map[string]KillWords KillWords map[string]KillWords
} }
) )
@ -176,12 +187,12 @@ func (games Games) GameState(ctx context.Context, id string) (GameState, error)
} }
if killer, ok := result.Players[assignmentRotation.Killer]; !ok { if killer, ok := result.Players[assignmentRotation.Killer]; !ok {
} else if victim, ok := result.Players[assignmentRotation.Killed]; !ok { } else if _, ok := result.Players[assignmentRotation.Victim]; !ok {
} else { } else {
killer.Kills = append(killer.Kills, Kill{ killer.Kills = append(killer.Kills, Kill{
Timestamp: timestamp, Timestamp: timestamp,
Victim: assignmentRotation.Killed, Victim: assignmentRotation.Victim,
Public: slices.Contains(victim.KillWords.Assignment.Public, assignmentRotation.KillWord), KillWord: assignmentRotation.KillWord,
}) })
result.Players[assignmentRotation.Killer] = killer result.Players[assignmentRotation.Killer] = killer
} }
@ -238,24 +249,99 @@ func (games Games) CreateGame(ctx context.Context, name string) (string, error)
} }
func (games Games) CreateEventPlayerJoin(ctx context.Context, id string, player string) error { func (games Games) CreateEventPlayerJoin(ctx context.Context, id string, player string) error {
return games.createEvent(ctx, id, EventPlayerJoin{ID: player}) if err := games.db.Exec(ctx, `
INSERT INTO players (
game_uuid,
user_uuid
) VALUES (?, ?)
`, id, player); err != nil {
return err
}
return games.createEvent(ctx, id, EventPlayerJoin{Type: PlayerJoin, ID: player})
} }
func (games Games) CreateEventPlayerLeave(ctx context.Context, id string, player string) error { func (games Games) CreateEventPlayerLeave(ctx context.Context, id string, player string) error {
return games.createEvent(ctx, id, EventPlayerLeave{ID: player}) return games.createEvent(ctx, id, EventPlayerLeave{Type: PlayerLeave, ID: player})
} }
func (games Games) CreateEventAssignmentRotation(ctx context.Context, id string, killer, killed, killWord string) error { func (games Games) CreateEventAssignmentRotation(ctx context.Context, id string, killer, victim, word string, points int) error {
// TODO gather current assignees state, err := games.GameState(ctx, id)
// TODO get victim's target if err != nil {
// TODO assign victim's target to killer return err
// TODO randomize everyone else so not the same as before AND not self }
return io.EOF now := time.Now()
//return games.createEvent(ctx, id, v)
event := EventAssignmentRotation{
Type: AssignmentRotation,
Killer: killer,
Victim: victim,
KillWord: KillWord{
Word: word,
Points: points,
},
KillWords: map[string]KillWords{},
}
toAssign := []string{}
doNotAssign := map[string]string{}
for k, v := range state.Players {
v := v.KillWords
toAssign = append(toAssign, k)
doNotAssign[k] = v.Assignee
event.KillWords[k] = KillWords{
Global: v.Global,
Assigned: now,
Assignee: "",
Assignment: v.Assignment,
}
}
if killerState, ok := state.Players[killer]; !ok {
} else if victimState, ok := state.Players[victim]; !ok {
} else {
event.KillWords[killer] = KillWords{
Global: killerState.KillWords.Global,
Assigned: now,
Assignee: victimState.KillWords.Assignee,
Assignment: killerState.KillWords.Assignment,
}
toAssign = slices.DeleteFunc(toAssign, func(s string) bool { return s == event.KillWords[killer].Assignee })
}
for !func() bool {
toAssign := slices.Clone(toAssign)
doNotAssign := maps.Clone(doNotAssign)
eventKillWords := maps.Clone(event.KillWords)
for i := range toAssign {
j := rand.Intn(i + 1)
toAssign[i], toAssign[j] = toAssign[j], toAssign[i]
}
for k, v := range eventKillWords {
if k == toAssign[0] || doNotAssign[k] == toAssign[0] {
return false
}
eventKillWords[k] = KillWords{
Global: v.Global,
Assigned: now,
Assignee: toAssign[0],
Assignment: v.Assignment,
}
toAssign = toAssign[1:]
}
event.KillWords = eventKillWords
return true
}() {
}
return games.createEvent(ctx, id, event)
} }
func (games Games) CreateEventGameComplete(ctx context.Context, id string) error { func (games Games) CreateEventGameComplete(ctx context.Context, id string) error {
return games.createEvent(ctx, id, EventGameComplete{}) return games.createEvent(ctx, id, EventGameComplete{Type: GameComplete})
} }
func (games Games) createEvent(ctx context.Context, id string, v any) error { func (games Games) createEvent(ctx context.Context, id string, v any) error {

View File

@ -66,7 +66,7 @@ func TestGames(t *testing.T) {
} }
} }
if err := games.CreateEventAssignmentRotation(ctx, id, "", "", ""); err != nil { if err := games.CreateEventAssignmentRotation(ctx, id, "", "", "", 1); err != nil {
t.Fatal("err creating rotation:", err) t.Fatal("err creating rotation:", err)
} }