Skip to main content
 首页 » 编程设计

python之如何使用数组值列表检查数组

2025年05月04日50jiqing9006

我正在尝试解决基于剪刀石头布的编程挑战。我的目标是给出游戏 Action 列表,确定游戏获胜的 Action 。我的问题是检查比赛是否获胜。我有一个获胜组合列表,例如游戏网格是:

1, 2, 3, 
4, 5, 6, 
6, 7, 8, 

例如,获胜组合为:4, 5, 6 因为它是连续 3 个。

我的问题是我不知道如何有效地检查所有这些获胜组合。我试图列出获胜组合,然后通过它运行游戏板以检查获胜者,这太棒了,只是它不起作用而且我不知道如何合理地接近它。

这是我的代码:

def is_winner(grid): 
    player1_wins = ['X','X','X'] 
    player2_wins = ['O','O','O'] 
    player_win = [player1_wins, player2_wins] 
 
    win1 = [0,3,6] #[1,4,7] 
    win2 = [1,4,7] #[2,5,8] 
    win3 = [2,5,8] #[3,6,9] 
    win4 = [0,4,8] #[1,5,9] 
    win5 = [6,7,8] #[7,8,9] 
    win6 = [3,4,5] #[4,5,6] 
    win7 = [0,1,2] #[1,2,3] 
    win8 = [6,7,8] #[7,8,9] 
    winning_grids = [win1, win2, win3, win4, win5, win6, win7, win8] 
 
    if any(grid[winning_grids]) == any(player_win): # !!!! Broken code here !!!! 
        return True # Game won 
    else: 
        return False 
 
def tic_tac_toe(games): 
    for game in range(games): 
        grid = ['1','2','3', 
                '4','5','6', 
                '7','8','9'] 
        moves = [int(x) for x in raw_input().split()] 
 
        turn = 1 
        for move in moves: 
            if turn % 2 != 0: 
                grid[move-1] = 'X' 
            elif turn % 2 == 0: 
                grid[move-1] = 'O' 
            if is_winner(grid): 
                print("Game over on turn %d" % turn) 
 
        print(grid) 
tic_tac_toe(input()) 

示例输入如下所示:

3 
7 5 4 1 9 2 8 3 6 
5 1 3 7 6 4 2 9 8 
5 1 2 8 6 4 7 3 9 

如果是 3 场比赛,玩家 1 先开始,玩家 2 是每个字符串中的下一个数字。

答案是:第 1 局 - 第 7 步。第 2 局 - 第 6 步,第 3 局 - 和局。 (尚未实现)

我该怎么做才能检查获胜着法/有人对如何修复我的代码有任何建议吗?

请您参考如下方法:

我认为你需要的是使用一个类。我本可以尝试修复您的代码,但我认为您需要彻底重新考虑一下。

从逻辑上讲,您可以将其分解为一个游戏对象,该对象跟踪单个游戏的移动。您可以简单地走一步,然后在每一步之后检查是否赢得了比赛。

我不确定您是否熟悉类,但我认为将井字游戏作为对象来实现会更好。您还可以在许多其他场景中重复使用游戏类。不仅仅是为了确定每场比赛的胜利。在一个复杂的程序中,您甚至可以将游戏对象传递给其他对象,以便它们可以以自己的方式与之交互。这超出了本答案的范围,但希望您明白我的意思。

试试下面的代码,我特意对其进行了大量注释并使其(希望)易于理解。它很长,但它分解了每项任务,因此很容易理解正在发生的事情。 (至少对我来说是)

您可以使用此代码中的概念来修复您的实现。要么使用我的代码片段来修复你的代码,要么根据需要使用我的版本。

通过这段代码,游戏对象可以跟踪轮到谁了、每个玩家的移动、游戏是否获胜、游戏是否结束、获胜玩家是谁以及下棋次数。

此外,我特意编写了代码,使其适用于 Python 2.7 和 3.4。通常,我尝试只为 Python 3x 编写代码,但这是我的偏好。

class TicTacToeGame: 
    """ 
    A class that implements a tic tac toe game 
    """ 
 
    # This is a class variable that contains 
    # a list of all the winning combos 
    winningCombos = [ 
        [1, 2, 3], 
        [4, 5, 6], 
        [7, 8, 9], 
        [1, 4, 7], 
        [2, 5, 8], 
        [3, 6, 9], 
        [1, 5, 9], 
        [3, 5, 7] 
    ] 
 
    def __init__(self): 
        """ 
        Init method. This gets called when you create a new game object 
        We simply use this method to initialize all our instance variables 
        """ 
 
        # The current player. Either X or O 
        self.currentPlayer = 'X' 
 
        # List of player x moves 
        self.playerXMoves = [] 
 
        # List of player o moves 
        self.playerOMoves = [] 
 
        # Whether or not the game has been won 
        self.isWon = False 
 
        # Whether or not the game is over 
        self.isOver = False 
 
        # The winning player 
        self.winningPlayer = None 
 
        # The number of moves played 
        self.numberOfMovesPlayed = 0 
 
    def doMakeAMoveAtPos(self, pos): 
        """ 
        Makes a move in the game at the specified position 
        1 is the first position, 5 is the center position, etc 
 
        @param pos: The position (1 through 9) 
        @type pos: int 
        @rtype: None 
        """ 
 
        # If the game has already been won 
        if self.isWon: 
            raise ValueError('The game has been won') 
 
        # If the game is over, nobody won 
        if self.isOver: 
            raise ValueError('The game is a tie') 
 
        # Make sure that the position is within range 
        if pos < 1 or pos > 9: 
            raise ValueError('Invalid position. Should be between 1 and 9') 
 
        # Make sure the position isn't already taken 
        if pos in self.playerXMoves or pos in self.playerOMoves: 
            raise ValueError('The position: ' + str(pos) + ' is already taken') 
 
        # Get the current player 
        currentPlayer = self.currentPlayer 
 
        # If the current player is X 
        if currentPlayer == 'X': 
 
            # Add the move and switch to player O 
            currentPlayerMoves = self.playerXMoves 
            currentPlayerMoves.append(pos) 
            self.currentPlayer = 'O' 
 
        # Otherwise, the current player is O 
        else: 
 
            # Add the move and switch to player X 
            currentPlayerMoves = self.playerOMoves 
            currentPlayerMoves.append(pos) 
            self.currentPlayer = 'X' 
 
        # Increment the number of plays.. You could just check the length of 
        # playerXMoves and playerOMoves to get the total number of moves, but 
        # we are going to keep track to avoid more code later 
        self.numberOfMovesPlayed += 1 
 
        # If the number of plays is 9, the game is over 
        if self.numberOfMovesPlayed == 9: 
            self.isOver = True 
 
        # See if the game has been won 
 
        # If there hasn't been enough moves to win yet, no winner 
        if len(currentPlayerMoves) < 3: 
            return 
 
        # Iterate through each winning combo 
        for winningCombo in self.winningCombos: 
 
            # If each number is in the player's moves, the game has been won 
            if set(winningCombo) <= set(currentPlayerMoves): 
 
                self.isWon = True 
                self.winningPlayer = currentPlayer 
                return 
 
 
 
# OK... Our Class has been defined. 
# Now it's time to play tic tac toe. 
 
# Define an input string. How you get this is up to you 
# Change this to different numbers to see what you get. 
inputString = '3 7 5 4 1 9 2 8 3 6 5 1 3 7 6 4 2 9 8 5 1 2 8 6 4 7 3 9' 
 
# Parse the input string into a list of integers 
moves = [int(move) for move in inputString.split()] 
 
# Create the initial game 
game = TicTacToeGame() 
 
# Set the number of games to 1 (This is the first game after all) 
numberOfGames = 1 
 
# Go through all the moves 1 by 1 
for pos in moves: 
 
    # Try to make a move in the current game 
    try: 
        game.doMakeAMoveAtPos(pos) 
 
    # But, since the input is unpredictable, we need to catch errors 
    # What's to stop the input from being '1 1 1 1 1 1 1 1 1', etc 
    # You can't keep playing position number 1 over and over 
    except ValueError as exc: 
 
        # Do what you want with the exception. 
        # For this example, I'm just gonna print it 
        # and move on the the next move 
        print(exc) 
        continue 
 
    # If the game has been won 
    if game.isWon: 
        print('Game ' + str(numberOfGames) + ' Won On Move: ' + str(game.numberOfMovesPlayed) + ' Winning Player: ' + str(game.winningPlayer)) 
 
        # Since the game was won, create a new game 
        game = TicTacToeGame() 
 
        # And increment the game number 
        numberOfGames += 1 
 
    # If the game is a tie 
    elif game.isOver: 
        print('Game ' + str(numberOfGames) + ' Tie') 
 
        # Since the game was a tie, create a new game 
        game = TicTacToeGame() 
 
        # And increment the game number 
        numberOfGames += 1 
 
# If there is an unfinished game, we can report this as well 
if game.numberOfMovesPlayed > 0: 
    print('Game ' + str(numberOfGames) + ' was not finished') 

还有很多可以改进的地方,但你明白了(我希望)当我运行这段代码时,我得到以下输出:

Game 1 Won On Move: 7 Winning Player: X 
The position: 3 is already taken 
Game 2 Won On Move: 6 Winning Player: O 
The position: 2 is already taken 
The position: 8 is already taken 
The position: 6 is already taken 
The position: 4 is already taken 
Game 3 Won On Move: 9 Winning Player: X 
Game 4 was not finished