package game type victoryCheck struct { ID string Nickname string CardType string CardName string Priority int Met bool } func (e *Engine) RunSettlement() map[string]interface{} { harmony := e.settleHarmony() challenge := e.settleChallenge() harmonyOK := harmony["success"].(bool) imprisoned := challenge["imprisoned"].([]string) victory := e.settleVictory(harmonyOK, imprisoned) return map[string]interface{}{ "harmony": harmony, "challenge": challenge, "victory": victory, } } func (e *Engine) settleHarmony() map[string]interface{} { var cards []map[string]interface{} total := 0 for _, c := range e.HarmonyZone { cards = append(cards, map[string]interface{}{ "uid": c.UID, "type_id": c.TypeID, "name": c.Name, "mp": c.MP, }) total += c.MP } return map[string]interface{}{ "cards": cards, "total_mp": total, "target": e.HarmonyTarget, "success": total >= e.HarmonyTarget, } } func (e *Engine) settleChallenge() map[string]interface{} { var perPlayer []map[string]interface{} maxMP := 0 for _, p := range e.Players { var cards []map[string]interface{} total := 0 for _, c := range p.ChallengeZone { eff := c.MP if eff < 0 { eff = 0 } total += eff cards = append(cards, map[string]interface{}{ "uid": c.UID, "type_id": c.TypeID, "name": c.Name, "mp": c.MP, "effective_mp": eff, }) } perPlayer = append(perPlayer, map[string]interface{}{ "player_id": p.ID, "nickname": p.Nickname, "cards": cards, "total_mp": total, }) if total > maxMP { maxMP = total } } allSame := true for _, pp := range perPlayer { if pp["total_mp"].(int) != perPlayer[0]["total_mp"].(int) { allSame = false break } } var imprisoned []string if !allSame && maxMP > 0 { for _, pp := range perPlayer { if pp["total_mp"].(int) == maxMP { imprisoned = append(imprisoned, pp["player_id"].(string)) } } } return map[string]interface{}{ "per_player": perPlayer, "max_mp": maxMP, "imprisoned": imprisoned, } } func (e *Engine) settleVictory(harmonyOK bool, imprisoned []string) map[string]interface{} { isJailed := func(pid string) bool { for _, id := range imprisoned { if id == pid { return true } } return false } var all []victoryCheck for _, p := range e.Players { if len(p.Hand) == 0 { continue } last := p.Hand[0] def := GetCardDef(last.TypeID) if def == nil { continue } all = append(all, victoryCheck{ ID: p.ID, Nickname: p.Nickname, CardType: last.TypeID, CardName: last.Name, Priority: def.Priority, }) } culpritWins := false for pri := 1; pri <= 5; pri++ { var group []int for i, vc := range all { if vc.Priority == pri { group = append(group, i) } } if len(group) == 0 { continue } for _, i := range group { switch all[i].CardType { case "culprit": all[i].Met = !isJailed(all[i].ID) if all[i].Met { culpritWins = true } } } for _, i := range group { switch all[i].CardType { case "alien": all[i].Met = isJailed(all[i].ID) case "infected_person": all[i].Met = !harmonyOK case "accomplice": all[i].Met = culpritWins case "go_home_club": all[i].Met = true case "culprit": // already set above default: all[i].Met = harmonyOK } } anyWin := false for _, i := range group { if all[i].Met { anyWin = true break } } if !anyWin { continue } var winners []map[string]interface{} for _, i := range group { if all[i].Met { winners = append(winners, vcToMap(all[i])) } } return map[string]interface{}{ "checks": allToMaps(all), "winners": winners, "winning_priority": pri, "end_type": "normal", } } return map[string]interface{}{ "checks": allToMaps(all), "winners": []map[string]interface{}{}, "end_type": "all_dead", } } func vcToMap(vc victoryCheck) map[string]interface{} { return map[string]interface{}{ "player_id": vc.ID, "nickname": vc.Nickname, "card_type": vc.CardType, "card_name": vc.CardName, "priority": vc.Priority, "met": vc.Met, } } func allToMaps(all []victoryCheck) []map[string]interface{} { var r []map[string]interface{} for _, vc := range all { r = append(r, vcToMap(vc)) } return r }