Skip to content

AI有时候会自杀 #372

@CuteReimu

Description

@CuteReimu

可以参考这段代码:

var v1 = calculateMessageCardValue(whoseTurn, inFrontOfWhom, colors, checkThreeSame)
if (sender != null) {
// TODO 临时这样写,后续应该改成调用Player.countMessageCard来计数
class TmpCard(colors: List<color>) : Card(999, colors, Up, false) {
override val type: card_type = card_type.UNRECOGNIZED
override fun canUse(g: Game, r: Player, vararg args: Any) = false
override fun execute(g: Game, r: Player, vararg args: Any) = Unit
}
fun merge(a: Int, b: Int): Int = if (a == 600 || b == 600) 600 // 其中一个已经赢了,就是赢了,以防共赢的情况下还非要出牌拦敌方
else a + b
if (colors.size == 2 && inFrontOfWhom.skills.any { it is JinShen }) { // 金生火
var valueInFrontOfWhom = 0
for (c in inFrontOfWhom.cards.toList()) {
val v = inFrontOfWhom.calculateMessageCardValue(whoseTurn, inFrontOfWhom, c.colors, checkThreeSame)
if (v > valueInFrontOfWhom) {
valueInFrontOfWhom = v
v1 = calculateMessageCardValue(whoseTurn, inFrontOfWhom, c.colors, checkThreeSame)
}
}
}
if (sender.skills.any { it is MianLiCangZhen }) { // 邵秀
inFrontOfWhom.messageCards.add(TmpCard(colors))
var valueSender = -1
var valueMe = 0
for (c in sender.cards.filter(Card::isBlack)) {
val v = sender.calculateMessageCardValue(whoseTurn, inFrontOfWhom, c.colors, checkThreeSame)
if (v > valueSender) {
valueSender = v
valueMe = calculateMessageCardValue(whoseTurn, inFrontOfWhom, c.colors, checkThreeSame)
}
}
logger.debug("这是[邵秀]传出的情报,计算[绵里藏针]额外分数为$valueMe")
v1 = merge(v1, valueMe)
inFrontOfWhom.messageCards.removeLast()
}
if (Black in colors && inFrontOfWhom.skills.any { it is YiYaHuanYa }) { // 王魁
inFrontOfWhom.messageCards.add(TmpCard(colors))
var valueInFrontOfWhom = -1
var valueMe = 0
for (c in inFrontOfWhom.cards.filter(Card::isBlack)) {
for (p in listOf(sender, sender.getNextLeftAlivePlayer(), sender.getNextRightAlivePlayer())) {
val v = inFrontOfWhom.calculateMessageCardValue(whoseTurn, p, c.colors, checkThreeSame)
if (v > valueInFrontOfWhom) {
valueInFrontOfWhom = v
valueMe = calculateMessageCardValue(whoseTurn, p, c.colors, checkThreeSame)
}
}
}
v1 = merge(v1, valueMe)
logger.debug("这是[王魁]接收的情报,计算[以牙还牙]额外分数为$valueMe")
inFrontOfWhom.messageCards.removeLast()
}
if (Black !in colors && sender.skills.any { it is ChiZiZhiXin } && sender !== inFrontOfWhom) { // 青年小九
inFrontOfWhom.messageCards.add(TmpCard(colors))
var valueSender = 30
var valueMe = 0
for (c in sender.cards.filter { it.colors.any { c -> c in colors } }) {
val v = sender.calculateMessageCardValue(whoseTurn, sender, c.colors, checkThreeSame)
if (v > valueSender) {
valueSender = v
valueMe = calculateMessageCardValue(whoseTurn, sender, c.colors, checkThreeSame)
}
}
logger.debug("这是[SP小九]传出的情报,计算[赤子之心]额外分数为$valueMe")
v1 = merge(v1, when {
valueSender > 30 -> valueMe
isPartnerOrSelf(sender) -> 20
else -> -20
})
inFrontOfWhom.messageCards.removeLast()
}
// TODO CP韩梅还要判断一下拿牌,这里就暂时先不写了
if (Blue in colors && sender.skills.any { it is AnCangShaJi }) { // SP韩梅
inFrontOfWhom.messageCards.add(TmpCard(colors))
if (sender.cards.any { it.isPureBlack() }) {
val v = sender.calculateMessageCardValue(whoseTurn, inFrontOfWhom, listOf(Black))
var valueMe = 0
if (v > 0) valueMe = calculateMessageCardValue(whoseTurn, inFrontOfWhom, listOf(Black))
logger.debug("这是[CP韩梅]传出的情报,计算[暗藏杀机]额外分数为$valueMe")
v1 = merge(v1, valueMe)
}
inFrontOfWhom.messageCards.removeLast()
}
fun addScore(p: Player, score: Int) {
if (p.identity != Black) { // 军潜:己方加分,敌方减分,神秘人不管
if (identity == p.identity) v1 = merge(v1, score)
if (identity != p.identity && identity != Black) v1 = merge(v1, -score)
} else if (p === this) { // 神秘人:自己加分,其他人不管
v1 = merge(v1, score)
}
}
if (Black in colors && inFrontOfWhom.skills.any { it is ShiSi }) { // 老汉【视死】
addScore(inFrontOfWhom, 20)
}
if (inFrontOfWhom.skills.any { it is ZhiYin }) { // 程小蝶【知音】【惊梦】
if (Black in colors) { // 惊梦
addScore(inFrontOfWhom, 10)
}
if (colors.any { it != Black }) { // 知音
addScore(inFrontOfWhom, 10)
addScore(sender, 10)
}
}
if (sender.skills.any { it is MingEr }) { // 老鳖【明饵】
if (colors.any { it != Black }) {
addScore(sender, 10)
addScore(inFrontOfWhom, 10)
}
}
if (sender !== inFrontOfWhom && sender.roleFaceUp && sender.skills.any { it is ZhenLi }) {
// 李书云【真理】
if (colors.any { it != Black }) {
addScore(sender, 20)
}
}
if (sender !== inFrontOfWhom && sender.skills.any { it is HanHouLaoShi }) {
// 哑炮【憨厚老实】
if (sender.cards.isNotEmpty()) {
addScore(sender, -10)
addScore(inFrontOfWhom, 10)
}
}
if (colors.any { it != Black } && inFrontOfWhom.skills.any { it is WorkersAreKnowledgable }) {
// 王响【咱们工人有知识】
addScore(inFrontOfWhom, 9)
}
if (Black !in colors && inFrontOfWhom.skills.any { it is ZhuanJiao || it is JiSong }) {
// 白小年【转交】、鬼脚【急送】
addScore(inFrontOfWhom, 11)
}
if (sender.skills.any { it is CangShenJiaoTang }) {
// 玛利亚【藏身教堂】
if (sender.isPartnerOrSelf(inFrontOfWhom) && !inFrontOfWhom.isPublicRole && inFrontOfWhom.roleFaceUp) {
addScore(inFrontOfWhom, 80)
}
// 防御玛利亚【藏身教堂】:公开角色的黑色情报可能被偷走
if (inFrontOfWhom.isPublicRole && (inFrontOfWhom.messageCards.count(Black) > 0 || Black in colors)) {
inFrontOfWhom.messageCards.add(TmpCard(colors))
var maLiYaMaxValue = 0
var myMaxValue = 0
var asMessage = false
for (messageCard in inFrontOfWhom.messageCards.filter { it.isBlack() }) {
val removeValue = sender.calculateRemoveCardValue(whoseTurn, inFrontOfWhom, messageCard)
if (removeValue + 10 >= maLiYaMaxValue) {
maLiYaMaxValue = removeValue + 10
asMessage = false
myMaxValue = calculateRemoveCardValue(whoseTurn, inFrontOfWhom, messageCard)
}
if (sender !== inFrontOfWhom) {
val senderGainValue = sender.calculateMessageCardValue(whoseTurn, sender, messageCard)
val totalLoss = removeValue + senderGainValue
if (totalLoss > maLiYaMaxValue) {
maLiYaMaxValue = totalLoss
asMessage = true
myMaxValue = calculateRemoveCardValue(whoseTurn, inFrontOfWhom, messageCard) +
calculateMessageCardValue(whoseTurn, sender, messageCard)
}
}
}
v1 = merge(v1, myMaxValue)
if (!asMessage) {
addScore(sender, 10)
}
inFrontOfWhom.messageCards.removeLast()
}
}
if (!inFrontOfWhom.roleFaceUp && (inFrontOfWhom.hasEverFaceUp || inFrontOfWhom === this) &&
inFrontOfWhom !== sender && inFrontOfWhom.skills.any { it is LianXin }) {
// 成年小九、成年韩梅【暗度陈仓】
addScore(inFrontOfWhom, if (sender.isPartner(inFrontOfWhom)) 20 else 10)
}
if (Black in colors && inFrontOfWhom.roleFaceUp &&
inFrontOfWhom.skills.any { it is YiXin } && inFrontOfWhom.messageCards.count(Black) == 2) {
// 李宁玉【遗信】
var liNingYuValue = -1
var myValue = 0
for (handCard in inFrontOfWhom.cards) {
for (p in game!!.players) {
if (!p!!.alive || p === inFrontOfWhom) continue
val v = inFrontOfWhom.calculateMessageCardValue(whoseTurn, p, handCard)
if (v > liNingYuValue) {
liNingYuValue = v
myValue = calculateMessageCardValue(whoseTurn, p, handCard)
}
}
}
v1 = merge(v1, myValue)
}
// 防御王富贵【江湖令】:从王富贵的角度判断是否想要弃掉牌
if (sender.skills.any { it is JiangHuLing } && sender.skills.any { it is OneTurnSkill } && sender !== inFrontOfWhom) {
// 王富贵已经发动了江湖令,模拟他的决策过程
inFrontOfWhom.messageCards.add(TmpCard(colors))
var wangFuGuiMaxValue = 0
var myMaxValue = 0
var isBlack = false
for (messageCard in inFrontOfWhom.messageCards) {
// 从王富贵的角度计算移除这张牌的价值
var wangFuGuiValue = sender.calculateRemoveCardValue(whoseTurn, inFrontOfWhom, messageCard)
if (messageCard.isBlack()) {
wangFuGuiValue += 10
}
if (wangFuGuiValue > wangFuGuiMaxValue) {
wangFuGuiMaxValue = wangFuGuiValue
myMaxValue = calculateRemoveCardValue(whoseTurn, inFrontOfWhom, messageCard)
isBlack = messageCard.isBlack()
}
}
v1 = merge(v1, myMaxValue)
if (isBlack) addScore(sender, 10)
inFrontOfWhom.messageCards.removeLast()
}
if (Black in colors && inFrontOfWhom.skills.any { it is RuGui } && inFrontOfWhom.messageCards.count(Black) == 2) {
// 老汉【如归】
if (whoseTurn !== inFrontOfWhom && whoseTurn.alive) {
var laoHanValue = -1
var myValue = 0
for (mCard in inFrontOfWhom.messageCards + TmpCard(colors)) {
val v = inFrontOfWhom.calculateMessageCardValue(whoseTurn, whoseTurn, mCard)
if (v > laoHanValue) {
laoHanValue = v
myValue = calculateMessageCardValue(whoseTurn, whoseTurn, mCard)
}
}
v1 = merge(v1, myValue)
}
}
}
if (v1 > 460) v1 = 600
else if (v1 < -460) v1 = -600
v1 = (v1 * coefficientA + coefficientB).roundToInt()
if (v1 > 460) v1 = 600
else if (v1 < -460) v1 = -600
return v1

比如,蓝方老汉(LaoHan)0黑,红方现在2黑1红,待收情报(FightPhase.messageCard)是红黑双色,因为老汉接黑是20分,红方2黑1红接红黑是100-112=-12分,只差8分,再按照性格波动一下(Player.coefficientAPlayer.coefficientB),浪费一张手牌(-10分)去截获就是划算的了,因此老汉。

这种情况下,可能有另一个队友,波动并没有这么大,或者往相反的方向波动Player.coefficientAPlayer.coefficientB),就会和老汉抢情报。

有什么好的办法调整一下呢?

Metadata

Metadata

Assignees

Labels

AIAI相关need help难搞,需要帮助

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions