用Python写AI机器人来玩僵尸骰子

用Python写AI机器人来玩僵尸骰子

首页休闲益智滚动机器人更新时间:2024-05-09
编程游戏是一种游戏类型,玩家不是直接玩游戏,而是编写机器人程序来自主玩游戏。我已经创建了一个Zombie Dice模拟器,允许程序员练习他们的技能,同时玩得开心玩游戏AI。Zombie Dice机器人可以简单或非常复杂,非常适合课堂练习或个人编程挑战。

如何玩僵尸骰子

Zombie Dice是有趣的骰子游戏。玩家是僵尸,试图吃尽可能多的人类大脑,而不是“枪击”。他们的脸上有一杯13个骰子,上面有大脑,脚步声和霰弹枪的图标。骰子是绿色(大脑更有可能),红色(霰弹枪更可能)和黄色(在大脑和霰弹枪之间均匀分开)。

轮到他们了:

  1. 玩家随机从杯子中掏出骰子,直到他们手中有三个骰子并滚动它们。玩家总是掷三个骰子。
  2. 他们抛开任何大脑(人类大脑被吃掉)和霰弹枪(反击的人)。
  3. 如果玩家在本回合中留出了三支霰弹枪,他们的回合以零点结束。
  4. 如果他们决定再次掷骰子,那么玩家会手上拿着任何骰子。
  5. 否则,玩家可以选择结束他们的回合,他们将在每个大脑中收集一个点并将所有骰子返回到下一个玩家的杯子。
  6. 或者玩家可以选择继续转弯并再次滚动。回到第1步,注意到任何已经出现的骰子都会被重复使用。

僵尸骰子有一个“推动你的运气”游戏机制:你重新掷骰子越多,你可以获得的大脑越多,但你最有可能累积三支霰弹枪而失去一切。一旦玩家达到13分,其余玩家再转一圈(可能会赶上)并且游戏结束。得分最高的玩家获胜。

Bot编程挑战

要使用pip安装模拟器,请运行pip install zombiedice(在Windows上)或pip3 install zombiedice(在macOS和Linux上)。要运行带有一些预制机器人的演示,运行python -m zombiedice(在Windows上)或python3 -m zombiedice(在macOS和Linux上)以查看模拟器的web gui示例:

模拟器可以快速运行数百个游戏,注意每个机器人获得了多少胜利和关系。

你将通过编写一个带有turn()方法的类来创建机器人,当你的机器人轮到它时,模拟器就会调用它。在这个turn()方法中,你可以zombiedice.roll()像你想要掷骰子一样经常调用这个函数(当然,你应该在轮到你时至少调用它一次)。类超出了本文的范围,但您只需更改myzombie.py中的turn()代码即可

import zombiedice class MyZombie: def __init__(self, name): self.name = name def turn(self, gameState): # gameState is a dict with info about the current state of the game. # You can choose to ignore it in your code. diceRollResults = zombiedice.roll() # first roll # roll() returns a dictionary with keys 'brains', 'shotgun', and # 'footsteps' with how many rolls of each type there were. # The 'rolls' key is a list of (color, icon) tuples with the # exact roll result information. # Example of a roll() return value: # {'brains': 1, 'footsteps': 1, 'shotgun': 1, # 'rolls': [('yellow', 'brains'), ('red', 'footsteps'), # ('green', 'shotgun')]} # The code logic for your zombie goes here: brains = 0 while diceRollResults is not None: brains = diceRollResults['brains'] if brains < 2: diceRollResults = zombiedice.roll() # roll again else: break class AlwaysRollsTwicePerTurn: def __init__(self, name): self.name = name def turn(self, gameState): zombiedice.roll() zombiedice.roll() zombies = ( zombiedice.examples.RandomCoinFlipZombie(name='Random'), zombiedice.examples.RollsUntilInTheLeadZombie(name='Until Leading'), zombiedice.examples.MinNumShotgunsThenStopsZombie(name='Stop at 2 Shotguns', minShotguns=2), zombiedice.examples.MinNumShotgunsThenStopsZombie(name='Stop at 1 Shotgun', minShotguns=1), MyZombie(name='My Zombie Bot'), AlwaysRollsTwicePerTurn(name='Rolls Twice'), # Add any other zombie players here. ) # Uncomment one of the following lines to run in CLI or Web GUI mode: #zombiedice.runTournament(zombies=zombies, numGames=1000) zombiedice.runWebGui(zombies=zombies, numGames=1000)

MyZombie类的turn()方法中的代码一直在调用,zombiedice.roll()直到它至少滚动了两个大脑。第二个机器人在AlwaysRollsTwicePerTurn类中实现,它有一个turn()方法,每次转动只需掷骰子两次。运行此程序会调用runWebGui()并打开Web浏览器,如图6-1所示,准备运行模拟。您可以检查zombiedice包的examples.py文件中的源代码,以了解其他bot如何工作。

尝试编写一些自己的机器人来玩Zombie Dice,看看他们如何与其他机器人进行比较。如果你发现自己在现实世界中玩这个游戏,你将获得成千上万的模拟游戏的好处,告诉你最好的策略之一就是在你掷出两支霰弹枪后停下来。但你总是可以试试你的运气......

一步一步构建MyZombie

我将MyZombie在上一节中描述创建类的过程。从这个导入zombiedice模块的基本模板开始,使用turn()调用方法创建一个类zombiedice.roll(),然后运行锦标赛:

import zombiedice class MyZombie: def __init__(self, name): self.name = name def turn(self, gameState): zombiedice.roll() zombies = ( zombiedice.examples.RandomCoinFlipZombie(name='Random'), MyZombie(name='My Zombie Bot'), ) # Uncomment one of the following lines to run in CLI or Web GUI mode: zombiedice.runWebGui(zombies=zombies, numGames=1000)

在MyZombie至今只滚动骰子一个,这是一个非常保守的策略,是不可能得到很多分。为了确定它是否应该再次滚动,我们需要检查返回值zombiedice.roll(),这是一个显示三个骰子滚动结果的字典。它看起来像这样:

{'brains': 1, 'footsteps': 1, 'shotgun': 1, 'rolls': [('yellow', 'brains'), ('red', 'footsteps'), ('green', 'shotgun')]}

这个字典有一个'brains',, 'footsteps'和'shotgun'键,其值是那种滚动的数量。确切的卷在'rolls'键的值中:元组列表。每个元组代表一个骰子,由一个颜色和出现的图标组成。

假设我们想要制定战略,我们的僵尸将继续滚动,直到至少有两个大脑滚动。我们需要跟踪到目前为止在本回合中已经滚动了多少脑(在一个brains变量中),从那开始0。如果将来的召唤zombiedice.roll()回归None,那么我们知道我们在本回合中已经达到或超过了三支霰弹枪并且将获得零分。更新turn(),使其看起来像这样:

def turn(self,gameState): diceRollResults = zombiedice.roll() 大脑= 0 而diceRollResults不是None: diceRollResults = zombiedice.roll()

现在代码将继续滚动骰子直到它返回None。但就在那时,我们已经达到了三支霰弹枪而失去了转弯。我们需要添加逻辑,以便在某些时候方法在zombiedice.roll()开始返回之前返回None。让我们diceRollResults来看看有多少脑子被卷起来:

def turn(self, gameState): diceRollResults = zombiedice.roll() brains = 0 while diceRollResults is not None: diceRollResults = zombiedice.roll()

那更好,现在zombiedice.roll()只要我们在轮到我们还没有达到两个大脑滚动时就被调用。但是,这种方法没有变化的条件。它只是永远循环!让我们添加更多代码:

def turn(self, gameState): diceRollResults = zombiedice.roll() brains = 0 while diceRollResults is not None: brains = diceRollResults['brains'] if brains < 2: diceRollResults = zombiedice.roll()

这个新代码说如果我们至少推出了两个大脑,那么继续前进并突破循环并最终从方法返回,这告诉模拟器机器人完成了它。

为gameState参数传递的值是具有以下键的字典:

机器人的想法

你可以在Zombie Dice中尝试很多策略。尝试编写执行以下操作的机器人:

请务必查看模块中的examples.py文件,以获取已经创建的一些机器人的代码。然后将它们加载到模拟器中,看看它们的表现如何!

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved