虽然循环没有正确断开,但脚本挂起

时间:2016-08-19 00:55:42

标签: python python-2.7

问题在于它没有检测到平局而只是在没有人获胜的情况下挂起。我知道在这里粘贴整个脚本并寻求帮助并不是一个好习惯,但我想出了所有想法。我从github那里得到了这个TicTacToe脚本,并试图在两个AI玩家之间实现随机移动(两者都只进行随机移动)。

    import random
    import time


class Tic(object):
 winning_combos = (
    [0, 1, 2], [3, 4, 5], [6, 7, 8],
    [0, 3, 6], [1, 4, 7], [2, 5, 8],
    [0, 4, 8], [2, 4, 6])

    winners = ('X-win', 'Draw', 'O-win')

    def __init__(self, squares=[]):
        if len(squares) == 0:
            self.squares = [" " for i in range(9)]
        else:
            self.squares = squares

def show(self):
    for element in [self.squares[i:i + 3] for i in range(0, len(self.squares), 3)]:
        print(element)

def available_moves(self):
    """what spots are left empty?"""
    return [k for k, v in enumerate(self.squares) if v is " "]

def available_combos(self, player):
    """what combos are available?"""
    return self.available_moves() + self.get_squares(player)

def complete(self):
    """is the game over?"""
    if " " not in [v for v in self.squares]:
        return True
    if self.winner() != " ":
        return True
    return False

def X_won(self):
    return self.winner() == 'X'

def O_won(self):
    return self.winner() == 'O'

def tied(self):
    return self.complete() is True and self.winner() is " "

def winner(self):
    for player in ('X', 'O'):
        positions = self.get_squares(player)
        for combo in self.winning_combos:
            win = True
            for pos in combo:
                if pos not in positions:
                    win = False
            if win:
                return player

    return " "

def get_squares(self, player):
    """squares that belong to a player"""
    return [k for k, v in enumerate(self.squares) if v == player]

def make_move(self, position, player):
    """place on square on the board"""
    self.squares[position] = player


def determine(board, player):
    a = -2
    choices = []
    if len(board.available_moves()) == 9:
        return 4
    for move in board.available_moves():
        board.make_move(move, player)
        board.make_move(move, " ")
        if val > a:
            a = val
            choices = [move]
        elif val == a:
            choices.append(move)
    return random.choice(choices)


def get_enemy(player):
    if player == 'O':
        return 'X'
    return 'O'


board = Tic()

count = 0
player = 'X'

while not board.complete():
        if board.complete():
            break
        while count == 0:
            player_move = int(random.randint(1, 9))
            if player_move not in board.available_moves():
                continue
            board.make_move(player_move, player)

            player = get_enemy(player)
            count += 1

        while count == 1:
            computer_move = int(random.randint(1, 9))
            if computer_move not in board.available_moves():
                continue
            board.make_move(computer_move, player)

            count -= 1

        if board.complete():
            break


if board.complete():
        print("winner is", board.winner())
        final_win = "winner is " + board.winner()
        log = open("log_for_orig.txt", "a")
        log.write(final_win + "\n" + "\n")

2 个答案:

答案 0 :(得分:1)

这是一种选择可用移动的非常糟糕的方式:

typeof $: function  // As expected.
typeof draggable: undefined  // How can it be undefined and still work?
typeof click: undefined  // ???
typeof button: undefined

当有大量可用动作时,它会正常工作。但是当可用动作很少时,while count == 0: player_move = int(random.randint(1, 9)) if player_move not in board.available_moves(): continue 可能需要很长时间才能选择其中一个,所以你的程序可能会挂起。

random.randint()模块提供了直接从列表中选择元素的功能。

random

请参阅How to randomly select an item from a list?

答案 1 :(得分:0)

玩家块

    while count == 0:
        player_move = int(random.randint(1, 9))
        if player_move not in board.available_moves():
            continue

计算机程序块

    while count == 1:
        computer_move = int(random.randint(1, 9))
        if computer_move not in board.available_moves():
            continue

问题在于上面两段代码。

在第一个区块中,当count为0,并且player_move不在可用的移动中时,则您通过执行继续跳过,因此count仍然为0,这将使其进入相同的第一个区块并继续此模式,直到除非球员改变了他的举动。你基本上应该提示用户改变他的举动而不是继续。

同样适用于第二个代码块。当计算机正在播放时,你应该以更好的方式处理它。