这个我很久以前还真写过一个小程序来验证过。结果和
@管清文不太一样,结果是30个杀,15个闪,12个回合左右就可以分出胜负。
------
更新,我们的结论是相似的,只是计算回合的方法不一样。
代码分为两个文件,libsoldier.py 如下:
import random class CardDeck: def __init__(self): self.cards = ["D"] * 15 + ['K'] * 30 self.used_cards = [] def shuffle(self): self.used_cards.extend(self.cards) random.shuffle(self.used_cards) self.cards = self.used_cards self.used_cards = [] def issue_cards(self, number): if len(self.cards) < number: self.shuffle() issued_cards = self.cards[:number] self.cards = self.cards[number:] return issued_cards def to_used(self, card): self.used_cards.append(card) class Soldier: def __init__(self, name, card_deck): self.hand_cards = [] self.name = name self.deck = card_deck self.blood = 5 self.attack_flag = 0 self.defend_flag = 0 self.death_flag = 0 def draw(self, cards): self.hand_cards.extend(cards) def attack(self): # 攻击,有杀出杀! self.attack_flag = 0 if 'K' in self.hand_cards: self.play('K') self.attack_flag = 1 # print(self.name + " kill") return self.attack_flag def defend(self): #防御,有闪出闪! self.defend_flag = 0 if 'D' in self.hand_cards: self.play('D') self.defend_flag = 1 # print(self.name + " dash") return self.defend_flag def discard(self): #弃牌 if len(self.hand_cards) <= self.blood: pass else: while len(self.hand_cards) > self.blood: if 'K' in self.hand_cards: #先丢杀 self.play('K') # print(self.name + " discard K") continue elif 'D' in self.hand_cards: #再丢闪 self.play('D') # print(self.name + " discard D") continue def action(self): # 回合 self.draw(self.deck.issue_cards(2)) # print(self.name + " hand cards are " + str(self.hand_cards)) self.attack() self.discard() # print(self.name + "huihe ends") return self.attack_flag def take_initial_cards(self): self.draw(self.deck.issue_cards(4)) def play(self, card): #出牌 self.hand_cards.remove(card) self.deck.to_used(card) def check_health(self): # 扣血 if self.defend_flag == 0: self.blood -= 1 else: pass def death_check(self): # 检查是否死亡 self.death_flag = 0 if self.blood == 0: self.death_flag = 1 return self.death_flag
然后是游戏环节, play.py
from libsoldier import CardDeck from libsoldier import Soldier def game(): winner = '' huihe_number = 0 new_deck = CardDeck() new_deck.shuffle() simayi = Soldier("simayi", new_deck) zhugeliang = Soldier("zhugeliang", new_deck) simayi.take_initial_cards() zhugeliang.take_initial_cards() while True: if zhugeliang.action(): simayi.defend() simayi.check_health() huihe_number += 1 if simayi.death_check(): winner = "zhugeliang" break if simayi.action(): zhugeliang.defend() zhugeliang.check_health() huihe_number += 1 if zhugeliang.death_check(): winner = "simayi" break return winner, huihe_number / 2 sum = 0 win_rate = 0 for _ in range(1000): winner, number = game() sum += number if winner == "zhugeliang": win_rate += 1 print(sum/1000.0, win_rate/1000.0)
最后的结果是12.1305. 基本上是
@管清文答案的一半左右,是不是我们对回合的定义不一样?我是按照题主说的,两个人都动一次,算一个回合。
先手优势挺大,基本上是6:4开。
我当时测试的比楼主的还要复杂一些,因为我还测试了英姿 vs 闭月 vs 制衡 等等。总之其实只要没有锦囊,出杀出闪都挺机械的,不太需要涉及到AI。
话说如果持续不断的回答三国杀问题,会不会成为“三国杀话题的优秀回答者” ?^_^