190 lines
4.1 KiB
Go
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
|
|
}
|