naisu test
parent
39b1a6a1e8
commit
9dd661ecd0
|
|
@ -5,7 +5,8 @@ import (
|
|||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"math/rand"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
|
|
@ -89,7 +90,7 @@ type (
|
|||
Kill struct {
|
||||
Timestamp time.Time
|
||||
Victim string
|
||||
Public bool
|
||||
KillWord KillWord
|
||||
}
|
||||
|
||||
KillWords struct {
|
||||
|
|
@ -102,23 +103,33 @@ type (
|
|||
}
|
||||
|
||||
Assignment struct {
|
||||
Public []string
|
||||
Private []string
|
||||
Public []KillWord
|
||||
Private []KillWord
|
||||
}
|
||||
|
||||
KillWord struct {
|
||||
Word string
|
||||
Points int
|
||||
}
|
||||
|
||||
EventType int
|
||||
|
||||
EventPlayerJoin struct {
|
||||
ID string
|
||||
Type EventType
|
||||
ID string
|
||||
}
|
||||
EventPlayerLeave struct {
|
||||
ID string
|
||||
Type EventType
|
||||
ID string
|
||||
}
|
||||
EventGameComplete struct {
|
||||
Type EventType
|
||||
}
|
||||
EventGameComplete struct{}
|
||||
EventAssignmentRotation struct {
|
||||
Type EventType
|
||||
Killer string
|
||||
Killed string
|
||||
KillWord string
|
||||
Victim string
|
||||
KillWord KillWord
|
||||
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 {
|
||||
} else if victim, ok := result.Players[assignmentRotation.Killed]; !ok {
|
||||
} else if _, ok := result.Players[assignmentRotation.Victim]; !ok {
|
||||
} else {
|
||||
killer.Kills = append(killer.Kills, Kill{
|
||||
Timestamp: timestamp,
|
||||
Victim: assignmentRotation.Killed,
|
||||
Public: slices.Contains(victim.KillWords.Assignment.Public, assignmentRotation.KillWord),
|
||||
Victim: assignmentRotation.Victim,
|
||||
KillWord: assignmentRotation.KillWord,
|
||||
})
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
// TODO gather current assignees
|
||||
// TODO get victim's target
|
||||
// TODO assign victim's target to killer
|
||||
// TODO randomize everyone else so not the same as before AND not self
|
||||
return io.EOF
|
||||
//return games.createEvent(ctx, id, v)
|
||||
func (games Games) CreateEventAssignmentRotation(ctx context.Context, id string, killer, victim, word string, points int) error {
|
||||
state, err := games.GameState(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
now := time.Now()
|
||||
|
||||
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 {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue