tests pass but LOTS of todos

main
Bel LaPointe 2024-12-16 17:29:27 -07:00
parent 421331eb71
commit d2fa707628
1 changed files with 52 additions and 18 deletions

View File

@ -216,7 +216,7 @@ type (
Trial struct { Trial struct {
Prosecutor string Prosecutor string
Killer string Defendant string
Word string Word string
} }
@ -253,7 +253,7 @@ type (
Type EventType Type EventType
Timestamp time.Time Timestamp time.Time
Prosecutor string Prosecutor string
Killer string Defendant string
Word string Word string
} }
EventCodenameTrial struct { EventCodenameTrial struct {
@ -261,6 +261,12 @@ type (
Timestamp time.Time Timestamp time.Time
Guilty bool Guilty bool
} }
EventNotification struct {
Type EventType
Timestamp time.Time
Recipient string
Message string
}
AllKillWords map[string]KillWords AllKillWords map[string]KillWords
) )
@ -272,6 +278,7 @@ const (
GameReset GameReset
CodenameAccusal CodenameAccusal
CodenameTrial CodenameTrial
Notification
) )
type Event interface{ event() } type Event interface{ event() }
@ -283,6 +290,7 @@ func (EventAssignmentRotation) event() {}
func (EventGameReset) event() {} func (EventGameReset) event() {}
func (EventCodenameAccusal) event() {} func (EventCodenameAccusal) event() {}
func (EventCodenameTrial) event() {} func (EventCodenameTrial) event() {}
func (EventNotification) event() {}
func EventWithTime(event Event, t time.Time) Event { func EventWithTime(event Event, t time.Time) Event {
switch e := event.(type) { switch e := event.(type) {
@ -307,6 +315,9 @@ func EventWithTime(event Event, t time.Time) Event {
case EventCodenameTrial: case EventCodenameTrial:
e.Timestamp = t e.Timestamp = t
event = e event = e
case EventNotification:
e.Timestamp = t
event = e
} }
return event return event
} }
@ -369,6 +380,10 @@ func parseEvent(b []byte, timestamp time.Time) (Event, error) {
var v EventCodenameTrial var v EventCodenameTrial
err := json.Unmarshal(b, &v) err := json.Unmarshal(b, &v)
return EventWithTime(v, timestamp), err return EventWithTime(v, timestamp), err
case Notification:
var v EventNotification
err := json.Unmarshal(b, &v)
return EventWithTime(v, timestamp), err
} }
return nil, fmt.Errorf("unknown event type %d: %s", peek.Type, b) return nil, fmt.Errorf("unknown event type %d: %s", peek.Type, b)
} }
@ -415,27 +430,29 @@ func (games Games) GameState(ctx context.Context, id string) (GameState, error)
result.Players[k] = player result.Players[k] = player
} }
case EventCodenameAccusal: case EventCodenameAccusal:
if actual := result.Players[e.Killer].KillWords.Codename; !actual.Consumed { if actual := result.Players[e.Defendant].KillWords.Codename; !actual.Consumed {
result.Trial.Prosecutor = e.Prosecutor result.Trial.Prosecutor = e.Prosecutor
result.Trial.Killer = e.Killer result.Trial.Defendant = e.Defendant
result.Trial.Word = e.Word result.Trial.Word = e.Word
guessed := e.Word if !basicallyTheSame(actual.KillWord.Word, e.Word) {
if !basicallyTheSame(actual, guessed) { } else if err := games.CreateEventCodenameTrial(ctx, id, true); err != nil { // TODO cannot be in State loop
} else if err := games.CreateEventCodenameTrial(ctx, true); err != nil { return GameState{}, err
return err
} }
} }
case EventCodenameTrial: case EventCodenameTrial:
if result.Trial == (Trial{}) { if result.Trial == (Trial{}) {
} else if e.Guilty { } else if e.Guilty {
if err := games.CreateEventNotification(ctx, id, fmt.Sprintf(`%s revealed %s is %s and collected %s's bounty.`, result.Trial.Prosecutor, result.Trial.Defendant, result.Trial.Word, result.Trial.Defendant)); err != nil { // TODO not in this loop
return GameState{}, err
}
return GameState{}, fmt.Errorf("not impl: trial: guilty: %+v", e) return GameState{}, fmt.Errorf("not impl: trial: guilty: %+v", e)
} else { } else {
v := result.Players[result.Trial.Prosecutor] v := result.Players[result.Trial.Prosecutor]
v.Killwords.Codename.Consumed = true v.KillWords.Codename.Consumed = true
v.Kills = append(v.Kills, Kill{ v.Kills = append(v.Kills, Kill{
Timestamp: e.Timestamp, Timestamp: e.Timestamp,
Victim: result.Trial.Killer, Victim: result.Trial.Defendant,
KillWord: KillWord{ KillWord: KillWord{
Word: result.Trial.Word, Word: result.Trial.Word,
Points: -200, Points: -200,
@ -443,12 +460,12 @@ func (games Games) GameState(ctx context.Context, id string) (GameState, error)
}) })
result.Players[result.Trial.Prosecutor] = v result.Players[result.Trial.Prosecutor] = v
v = result.Players[result.Trial.Killer] v = result.Players[result.Trial.Defendant]
v.KillWords.Codename.KillWord.Word = TODO v.KillWords.Codename.KillWord.Word = "" // TODO
return fmt.Errorf("creating state CANNOT create events because it will eval every loop") return GameState{}, fmt.Errorf("creating state CANNOT create events because it will eval every loop")
if err := games.CreateEventNotification(ctx, fmt.Sprintf(`%s accused the innocent %s of being %s. %s will get a new codename.`, prosecutorName, killerName, result.Trial.Word, killerName)); err != nil { if err := games.CreateEventNotification(ctx, id, fmt.Sprintf(`%s accused the innocent %s of being %s. %s will get a new codename.`, result.Trial.Prosecutor, result.Trial.Defendant, result.Trial.Word, result.Trial.Defendant)); err != nil {
return err return GameState{}, err
} }
} }
result.Trial = Trial{} result.Trial = Trial{}
@ -537,7 +554,7 @@ func (games Games) CreateEventAssignmentRotation(ctx context.Context, id string,
}, },
} }
prevAllKillWords := games.AllKillWords() prevAllKillWords := state.AllKillWords()
event.AllKillWords = prevAllKillWords.ShuffleAssignees(killer, victim, word) event.AllKillWords = prevAllKillWords.ShuffleAssignees(killer, victim, word)
event.AllKillWords = event.AllKillWords.FillKillWords() event.AllKillWords = event.AllKillWords.FillKillWords()
@ -545,12 +562,12 @@ func (games Games) CreateEventAssignmentRotation(ctx context.Context, id string,
return games.createEvent(ctx, id, event) return games.createEvent(ctx, id, event)
} }
func (playerState PlayerState) AllKillWords() AllKillWords { func (state GameState) AllKillWords() AllKillWords {
m := make(AllKillWords) m := make(AllKillWords)
for k, v := range state.Players { for k, v := range state.Players {
m[k] = v.KillWords m[k] = v.KillWords
} }
return m return m
} }
func (games Games) CreateEventGameReset(ctx context.Context, gid string) error { func (games Games) CreateEventGameReset(ctx context.Context, gid string) error {
@ -794,6 +811,23 @@ func (games Games) CreateEventGameComplete(ctx context.Context, id string) error
return games.createEvent(ctx, id, EventGameComplete{Type: GameComplete}) return games.createEvent(ctx, id, EventGameComplete{Type: GameComplete})
} }
func (games Games) CreateEventCodenameAccusal(ctx context.Context, gid, prosecutor, defendant, codename string) error {
return fmt.Errorf("not impl: x accused y")
return fmt.Errorf("not impl: x caught by y")
}
func (games Games) CreateEventCodenameTrial(ctx context.Context, gid string, guilty bool) error {
return fmt.Errorf("not impl: x found guilty/notguilty")
}
func (games Games) CreateEventNotification(ctx context.Context, gid, msg string) error {
return games.CreateEventNotificationTo(ctx, gid, "", msg)
}
func (games Games) CreateEventNotificationTo(ctx context.Context, gid, uid, msg string) error {
return fmt.Errorf("not impl: simple")
}
func (games Games) createEvent(ctx context.Context, id string, v any) error { func (games Games) createEvent(ctx context.Context, id string, v any) error {
payload, err := json.Marshal(v) payload, err := json.Marshal(v)
if err != nil { if err != nil {