提问者:小点点

我该如何为“手指大战”写一些人工智能呢?


如果这个帖子不适合你,请原谅。 也许我不该问这种问题。

我不经常发帖,但是我和我儿子一起写了一些代码。 我们编了一个简单的“手指大战”游戏。 我对此并不熟悉,但我很快就理解了基本算法。 我知道我们的代码有点冗长,但是当你学习基本代码时,它更容易阅读和理解。

通常你在操场上面对另一个玩家玩这个游戏。 两个球员都用他们的手分别露出一个手指。 玩家1可以将一个(或一些)手指传递给他的另一只手,也可以触摸他对手的手,从而在那里增加相同数量的手指。 如果一只手的手指超过五根,你就从五根开始,然后继续玩下去。 如果一只手降至0,你仍然可以添加手指。 然而,当对手的手都降到0时,剩下手指的人就赢了。

你可以通过运行我的代码来尝试这个游戏:Player1的手是一个&; B Player2手牌为C和; D.Player1开始。

我的问题是:“我该如何编写‘与电脑对战’?” 我不知道从哪里开始。 我班上有一个“def ai(self):pass”。 我可以放什么进去?

向所有接受挑战并教给我们东西的人干杯,亲切的问候,昆金克

这里是到目前为止的代码。

class FingerWars:
    
    hands = {'A': 1, 'B': 1, 'C': 1, 'D': 1}
    players = {'player1': 'Player1', 'player2': 'Player2'}
    player = 'player2'
    loop = True

    source_hands_str = {'player1': 'A or B', 'player2': 'C or D'}
    target_hands_str = {'A': 'B, C or D', 'B': 'A, C or D', 'C': 'A, B or D', 'D': 'A, B or C'}

    def __init__(self, player1='Player1', player2='Player2'):
        """
        Set player names or leave default
        :param player1: 
        :param player2: 
        """
        self.players['player1'] = player1
        self.players['player2'] = player2

    def game(self):
        """
        Main game loop.
        Toggle player turns.
        :return: void
        """
        while self.loop:
            if self.player == 'player1':
                self.player = 'player2'
            else:
                self.player = 'player1'
            self.fingers()
            if self.players[self.player] == 'computer':
                self.ai()
            else:
                self.turn()
            self.evaluate()
    
    def ai(self):
        """
        AI is called when one of the players is called 'computer'.
        How on earth might this work?
            LEVEL ONE: challenge
            LEVEL TWO: unbeatable
        :return: void
        """
        pass

    def turn(self):
        """
        Game turn.
        Can player only play from one hand?
        User specified target.
        Auto or user specified number of fingers.
        Do the math.
        :return: void
        """
        # AUTO CHOOSE IF ONE HAND = 0
        if self.player == 'player1':
            if self.hands['A'] == 0:
                source_hand = 'B'
                print(self.players[self.player] + 'source hand is : ' + source_hand)
            elif self.hands['B'] == 0:
                source_hand = 'A'
                print(self.players[self.player] + 'source hand is : ' + source_hand)
            else:
                source_hand = input(
                    self.players[self.player] + " choose a source hand (" + self.source_hands_str[self.player] + ")? ").upper()
        else:
            if self.hands['C'] == 0:
                source_hand = 'D'
                print(self.players[self.player] + 'source hand is : ' + source_hand)
            elif self.hands['D'] == 0:
                source_hand = 'C'
                print(self.players[self.player] + 'source hand is : ' + source_hand)
            else:
                source_hand = input(
                    self.players[self.player] + " choose a source hand (" + self.source_hands_str[self.player] + ")? ").upper()

        # SPECIFY TARGET HAND
        target_hand = input(
            self.players[self.player] + " choose a target hand (" + self.target_hands_str[source_hand] + ")? ").upper()
        fingers = self.hands[source_hand]

        # SPECIFY NB OF FINGERS IN INTERNAL FINGER SWAP
        if fingers > 1:
            if (source_hand in ('A', 'B') and target_hand in ('A', 'B'))\
                    or (source_hand in ('C', 'D') and target_hand in ('C', 'D')):
                fingers = int(input(self.players[self.player] + " how many fingers? "))

        print(self.players[self.player] + " : " + source_hand + "  (" + str(self.hands[source_hand]) + ") -> " + target_hand)

        # DO THE TURN PLAY MATH
        if source_hand == 'A' or source_hand == 'B':
            if target_hand == 'A' or target_hand == 'B':
                self.hands[source_hand] = self.hands[source_hand] - fingers
                self.hands[target_hand] = self.hands[target_hand] + fingers
            else:
                self.hands[target_hand] = self.hands[target_hand] + fingers

        if source_hand == 'C' or source_hand == 'D':
            if target_hand == 'C' or target_hand == 'D':
                self.hands[source_hand] = self.hands[source_hand] - fingers
                self.hands[target_hand] = self.hands[target_hand] + fingers
            else:
                self.hands[target_hand] = self.hands[target_hand] + fingers

    def evaluate(self):
        """
        evaluates fingers in hand. Evaluates win.
        :return: void
        """
        # EVALUATE FINGERS IN HAND
        for key, value in self.hands.items():
            if value > 4:
                self.hands[key] = self.hands[key]-5
                
        # EVALUATE WINNER
        if self.hands['A'] == 0 and self.hands['B'] == 0:
            print('Player : ' + self.players[self.player] + ' wins the finger war!')
            self.fingers()
            self.loop = False
        if self.hands['C'] == 0 and self.hands['D'] == 0:
            print('Player : ' + self.players[self.player] + ' wins the finger war!')
            self.fingers()
            self.loop = False

    def fingers(self):
        """
        prints user feedback. This is called after each turn
        :return: void
        """
        feedback = "A:" + str(self.hands['A']) + " B:" + str(self.hands['B'])\
            + " vs C:" + str(self.hands['C']) + " D:" + str(self.hands['D'])
        print(feedback)


def main():
    # game = FingerWars()
    game = FingerWars('Player1', 'Player2')
    game.game()


if __name__ == "__main__":
    main()

共1个答案

匿名用户

要做到这一点,您需要建立一个状态空间的模型,AI可以使用该模型进行搜索。 这样做的一个好方法是使用:

  • 封装游戏当前状态的数据结构,
  • 用于获取当前状态下的操作的函数,
  • 用于应用和撤消操作的函数。

给定这些函数,您可以应用极大极小算法来向前模拟游戏。 但是,有几个复杂的问题:

  • 您可能无法搜索到游戏结束,因此您可以在某个深度停止搜索。
  • 然后,您需要一个评估函数来表示游戏的状态有多好。
  • 您可能希望实现alpha-beta剪枝以减小树的大小。
  • 您还可以使用迭代深化动态计算搜索深度。
  • 由于存在重复状态,您可能需要一个换位表来减少搜索树中重复分支的数量。

另一种方法是仅仅枚举游戏的所有可能状态(相对来说没有那么多),并从已证明的状态向后工作,直到到达开始状态。 然后,你就会有一个玩游戏的最佳策略。

这应该会让你开始--这里有很多关于minimax,alpha-beta剪枝和类似的问题,当你准备好的时候,这些问题可以帮助你深入研究。