first
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user