Skip to content

Commit

Permalink
商玉、SP连鸢AI
Browse files Browse the repository at this point in the history
  • Loading branch information
CuteReimu committed Dec 11, 2024
1 parent c3276bd commit f3bc141
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 40 deletions.
2 changes: 2 additions & 0 deletions src/main/kotlin/phase/WaitForSelectRole.kt
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ data class WaitForSelectRole(val game: Game, val options: List<MutableList<RoleS
han_mei,
lian_yuan,
a_fu_luo_la,
sp_lian_yuan,
shang_yu,
)
}
}
33 changes: 15 additions & 18 deletions src/main/kotlin/skill/JieDaoShaRen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package com.fengsheng.skill

import com.fengsheng.*
import com.fengsheng.card.Card
import com.fengsheng.card.count
import com.fengsheng.phase.FightPhaseIdle
import com.fengsheng.protos.Common.color.Black
import com.fengsheng.protos.Role.skill_jie_dao_sha_ren_a_tos
import com.fengsheng.protos.Role.skill_jie_dao_sha_ren_b_tos
import com.fengsheng.protos.skillJieDaoShaRenAToc
Expand All @@ -14,7 +12,6 @@ import com.fengsheng.protos.skillJieDaoShaRenBTos
import com.google.protobuf.GeneratedMessage
import org.apache.logging.log4j.kotlin.logger
import java.util.concurrent.TimeUnit
import kotlin.random.Random

/**
* 商玉技能【借刀杀人】:争夺阶段,你可以翻开此角色牌,然后抽取另一名角色的一张手牌并展示之。若展示的牌是:**黑色**,则你可以将其置入一名角色的情报区,并将你的角色牌翻至面朝下。**非黑色**,则你摸一张牌。
Expand Down Expand Up @@ -198,21 +195,21 @@ class JieDaoShaRen : ActiveSkill {
val availableTargets = player.game!!.players.filter {
it!!.alive && it.isEnemy(player) && it.cards.isNotEmpty()
}.ifEmpty { return false }
val weights = availableTargets.map { it!! to it.cards.count(Black).toDouble() / it.cards.size }
val totalWeight = weights.sumOf { it.second }
var target = availableTargets.first()!!
if (totalWeight > 0.0) { // 按权重随机
var weight = Random.nextDouble(totalWeight)
for ((p, w) in weights) {
if (weight < w) {
target = p
break
}
weight -= w
}
} else {
target = availableTargets.random()!!
}
// val weights = availableTargets.map { it!! to it.cards.count(Black).toDouble() / it.cards.size }
// val totalWeight = weights.sumOf { it.second }
// var target = availableTargets.first()!!
// if (totalWeight > 0.0) { // 按权重随机
// var weight = Random.nextDouble(totalWeight)
// for ((p, w) in weights) {
// if (weight < w) {
// target = p
// break
// }
// weight -= w
// }
// } else {
val target = availableTargets.random()!!
// }
GameExecutor.post(player.game!!, {
skill.executeProtocol(player.game!!, player, skillJieDaoShaRenATos {
targetPlayerId = player.getAlternativeLocation(target.location)
Expand Down
70 changes: 48 additions & 22 deletions src/main/kotlin/skill/TanQiuZhenLi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,12 @@ package com.fengsheng.skill
import com.fengsheng.*
import com.fengsheng.RobotPlayer.Companion.sortCards
import com.fengsheng.card.Card
import com.fengsheng.card.count
import com.fengsheng.card.PlayerAndCard
import com.fengsheng.phase.MainPhaseIdle
import com.fengsheng.protos.Common.color
import com.fengsheng.protos.Common.color.Blue
import com.fengsheng.protos.Common.color.Red
import com.fengsheng.protos.*
import com.fengsheng.protos.Common.color.*
import com.fengsheng.protos.Role.skill_tan_qiu_zhen_li_a_tos
import com.fengsheng.protos.Role.skill_tan_qiu_zhen_li_b_tos
import com.fengsheng.protos.skillTanQiuZhenLiAToc
import com.fengsheng.protos.skillTanQiuZhenLiATos
import com.fengsheng.protos.skillTanQiuZhenLiBToc
import com.fengsheng.protos.skillTanQiuZhenLiBTos
import com.google.protobuf.GeneratedMessage
import org.apache.logging.log4j.kotlin.logger
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -205,22 +200,53 @@ class TanQiuZhenLi : MainPhaseSkill() {

companion object {
fun ai(e: MainPhaseIdle, skill: ActiveSkill): Boolean {
if (e.whoseTurn.getSkillUseCount(SkillId.TAN_QIU_ZHEN_LI) > 0) return false
val availableColor = ArrayList<color>()
if (e.whoseTurn.messageCards.count(Red) < 2) availableColor.add(Red)
if (e.whoseTurn.messageCards.count(Blue) < 2) availableColor.add(Blue)
val color = availableColor.randomOrNull() ?: return false

fun isPureColor(c: Card) = c.colors.size == 1 && c.colors.first() == color

val target = e.whoseTurn.game!!.players.filter {
it!!.isEnemy(e.whoseTurn) && it.alive && it.messageCards.any(::isPureColor)
}.randomOrNull() ?: return false
val card = target.messageCards.filter(::isPureColor).randomOrNull() ?: return false
val cardId = card.id
e.whoseTurn.getSkillUseCount(SkillId.TAN_QIU_ZHEN_LI) == 0 || return false
val player = e.whoseTurn
var target: PlayerAndCard? = null
var value = 0
for (p in e.whoseTurn.game!!.players.shuffled()) {
p!!.alive && p !== player || continue
for (c in p.messageCards.toList()) {
!player.checkThreeSameMessageCard(c) || continue
val v1 = player.calculateRemoveCardValue(player, p, c)
val v2 = player.calculateMessageCardValue(player, player, c)
player.messageCards.add(c)
val blackHandCard = p.cards.sortCards(p.identity, true).find { it.isPureBlack() }
var vOther3 = 0
if (blackHandCard != null)
vOther3 = -10 + p.calculateMessageCardValue(player, player, blackHandCard)
val blackMessageCard = p.messageCards.find { it.isPureBlack() }
var vOther4 = 0
if (blackMessageCard != null)
vOther4 = p.calculateRemoveCardValue(player, p, blackMessageCard) +
p.calculateMessageCardValue(player, player, blackMessageCard)
if (vOther3 > 0 || vOther4 > 0) {
if (vOther3 > vOther4) { // 从对方角度看,从手牌放分高
var v3 = player.calculateMessageCardValue(player, player, blackHandCard!!)
if (p.identity != Black && player.identity != Black) {
if (player.identity == p.identity) v3 -= 10
else v3 += 10
}
if (v1 + v2 + v3 > value) {
value = v1 + v2 + v3
target = PlayerAndCard(p, c)
}
} else { // 从对方角度看,从情报区放分高
val v4 = player.calculateRemoveCardValue(player, p, blackMessageCard!!) +
player.calculateMessageCardValue(player, player, blackMessageCard)
if (v1 + v2 + v4 > value) {
value = v1 + v2 + v4
target = PlayerAndCard(p, c)
}
}
}
player.messageCards.removeLast()
}
}
if (target == null) return false
GameExecutor.post(e.whoseTurn.game!!, {
skill.executeProtocol(e.whoseTurn.game!!, e.whoseTurn, skillTanQiuZhenLiATos {
targetPlayerId = e.whoseTurn.getAlternativeLocation(target.location)
targetPlayerId = e.whoseTurn.getAlternativeLocation(target.player.location)
this.cardId = cardId
})
}, 3, TimeUnit.SECONDS)
Expand Down

0 comments on commit f3bc141

Please sign in to comment.