naisu test
parent
39b1a6a1e8
commit
9dd661ecd0
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue