Python 如何使用数组值列表检查数组?
我正在尝试解决一个基于石头剪刀的编程挑战。我的目标是给出一个游戏动作的列表,确定游戏在哪一步获胜。我的问题是检查比赛是否获胜。我有一个获胜组合列表,例如游戏网格:Python 如何使用数组值列表检查数组?,python,arrays,python-2.7,tic-tac-toe,Python,Arrays,Python 2.7,Tic Tac Toe,我正在尝试解决一个基于石头剪刀的编程挑战。我的目标是给出一个游戏动作的列表,确定游戏在哪一步获胜。我的问题是检查比赛是否获胜。我有一个获胜组合列表,例如游戏网格: 1, 2, 3, 4, 5, 6, 6, 7, 8, 然后一个获胜的组合将是例如:4、5、6,因为它是一行中的3 我的问题是我不知道如何有效地检查所有这些获胜的组合。我试着列出一个获胜组合的列表,然后运行游戏板来检查赢家,这将是非常棒的,只是它不起作用,我不知道如何合理地接近它 这是我的密码: def is_winner(grid)
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步。第二场-第六步,第三场-平局。(尚未实施)
我能做些什么来检查获胜的举动/有人对如何修复我的代码有什么建议吗?我想你需要的是使用一个类。我本可以尝试修复你的代码,但我认为你需要彻底重新思考 从逻辑上讲,您可以将其分解为一个游戏对象,用于跟踪单个游戏的移动。你可以简单地移动一步,然后在每次移动后检查,看看游戏是否赢了 我不确定您是否熟悉类,但我认为tic-tac-toe游戏最好作为对象实现。您还可以在许多其他场景中重用game类。不仅仅是为了决定每场比赛的胜负。在一个复杂的程序中,您甚至可以将游戏对象传递给其他对象,以便它们能够以自己的方式与之交互。这超出了这个答案的范围,但希望你明白我的意思 尝试下面的代码,我特意对其进行了大量的注释,使其(希望)易于理解。它很长,但它会分解每个任务,以便很容易了解正在发生的事情。(至少对我来说是这样) 您可以使用此代码中的概念来修复您的实现。要么使用我的代码片段来修复你的代码,要么只要使用我的版本就行了 使用此代码,游戏对象将跟踪轮到谁、每个玩家所做的移动、游戏是否获胜、游戏是否结束、获胜玩家是谁以及所玩的移动次数 另外,我特意编写了代码,以便它可以在Python2.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')
我想你需要的是使用一个类。我本可以尝试修复你的代码,但我认为你需要彻底重新思考 从逻辑上讲,您可以将其分解为一个游戏对象,用于跟踪单个游戏的移动。你可以简单地移动一步,然后在每次移动后检查,看看游戏是否赢了 我不确定您是否熟悉类,但我认为tic-tac-toe游戏最好作为对象实现。您还可以在许多其他场景中重用game类。不仅仅是为了决定每场比赛的胜负。在一个复杂的程序中,您甚至可以将游戏对象传递给其他对象,以便它们能够以自己的方式与之交互。这超出了这个答案的范围,但希望你明白我的意思 尝试下面的代码,我特意对其进行了大量的注释,使其(希望)易于理解。它很长,但它会分解每个任务,以便很容易了解正在发生的事情。(至少对我来说是这样) 您可以使用此代码中的概念来修复您的实现。要么使用我的代码片段来修复你的代码,要么只要使用我的版本就行了 使用此代码,游戏对象将跟踪轮到谁、每个玩家所做的移动、游戏是否获胜、游戏是否结束、获胜玩家是谁以及所玩的移动次数 另外,我特意编写了代码,以便它可以在Python2.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')
@雷佩雷亚回答得很好。但如果您不能根据自己的需求使用类,或者只是不想使用,我将采用不同的方法 这篇文章背后的想法是展示python的功能方面。“函数式”编程的主要概念之一是,您无法访问函数的外部范围。我在全局名称空间中添加了
player\u one
和player\u two
来作弊。但它很容易转换成100%的函数代码。这是一个例子
这段代码可以在python2和python3上运行
唯一要做的就是将保存的输入更改为实际输入
player_one = 'X'
player_two = 'O'
# You can add "HAZ THE MOVEZ" joke here:
def has_the_moves(player, moves):
if len(moves) <= 2:
return None
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]
# We will return a player name (not bool) if he is a winner.
# This name will be used later.
tried = [set(posibility) <= set(moves) for posibility in winning_grids]
return player if any(tried) else None
def is_winner(grid):
player_one_moves = [i for i, x in enumerate(grid) if x == player_one]
player_two_moves = [i for i, x in enumerate(grid) if x == player_two]
player_one_won = has_the_moves(player_one, player_one_moves)
player_two_won = has_the_moves(player_two, player_two_moves)
# If we a have a winner:
if player_one_won or player_two_won:
return player_one_won if player_one_won else player_two_won
return None
def end_game(winner=None, last_turn=False):
""" This function can be used when you find a winner,
or when the end of the game is reached.
"""
if last_turn:
print('Game ended in a draw.')
if winner:
print('Player {} won.'.format(winner))
def tic_tac_toe(games):
# For testing purposes let's save user's input:
saved_moves = ['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']
for game in range(games):
grid = [str(x) for x in range(1, 10)] # one-liner
moves = [int(x) for x in saved_moves[game].split()] # TODO: make sure to change saved_moves[game]
for turn, move in enumerate(moves):
grid[move - 1] = player_one if turn % 2 == 0 else player_two
# Stop the game?
winner = is_winner(grid)
if winner:
print('Game over on turn {}.'.format(turn + 1))
end_game(winner=winner)
break; # no more iterations required.
if turn == len(moves) - 1:
end_game(last_turn=True)
if __name__ == '__main__':
# We running 3 games:
saved_games_number = 3
tic_tac_toe(saved_games_number)
@雷佩雷亚回答得很好。但如果您不能根据自己的需求使用类,或者只是不想使用,我将采用不同的方法 这篇文章背后的想法是展示python的功能方面。“函数式”编程的主要概念之一是,您无法访问函数的外部范围。我在全局名称空间中添加了
player\u one
和player\u two
来作弊。但它很容易转换成100%的函数代码。这是一个例子
这段代码可以在python2和python3上运行
唯一要做的就是将保存的输入更改为实际输入
player_one = 'X'
player_two = 'O'
# You can add "HAZ THE MOVEZ" joke here:
def has_the_moves(player, moves):
if len(moves) <= 2:
return None
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]
# We will return a player name (not bool) if he is a winner.
# This name will be used later.
tried = [set(posibility) <= set(moves) for posibility in winning_grids]
return player if any(tried) else None
def is_winner(grid):
player_one_moves = [i for i, x in enumerate(grid) if x == player_one]
player_two_moves = [i for i, x in enumerate(grid) if x == player_two]
player_one_won = has_the_moves(player_one, player_one_moves)
player_two_won = has_the_moves(player_two, player_two_moves)
# If we a have a winner:
if player_one_won or player_two_won:
return player_one_won if player_one_won else player_two_won
return None
def end_game(winner=None, last_turn=False):
""" This function can be used when you find a winner,
or when the end of the game is reached.
"""
if last_turn:
print('Game ended in a draw.')
if winner:
print('Player {} won.'.format(winner))
def tic_tac_toe(games):
# For testing purposes let's save user's input:
saved_moves = ['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']
for game in range(games):
grid = [str(x) for x in range(1, 10)] # one-liner
moves = [int(x) for x in saved_moves[game].split()] # TODO: make sure to change saved_moves[game]
for turn, move in enumerate(moves):
grid[move - 1] = player_one if turn % 2 == 0 else player_two
# Stop the game?
winner = is_winner(grid)
if winner:
print('Game over on turn {}.'.format(turn + 1))
end_game(winner=winner)
break; # no more iterations required.
if turn == len(moves) - 1:
end_game(last_turn=True)
if __name__ == '__main__':
# We running 3 games:
saved_games_number = 3
tic_tac_toe(saved_games_number)