Files
2026-06-18 17:31:10 +08:00

190 lines
4.1 KiB
Go

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
}