我正在撰寫我的第一個代碼(井字游戲),但我無法弄清楚為什么會出現名稱錯誤。
首先,我有一個串列(板)。
然后我有一個我定義的函式 (possible_victory_for() )。它應該是帶有串列(temp_board)的東西,稍后將在下一個函式中定義。
下一個函式 (computer_move()) 說 temp_board = board 然后呼叫 possible_victory_for()。
在我的理解中,看到“板”似乎作業正常,temp_board = board 應該足以定義 temp_board。但 Python 不同意。
我嘗試在一個簡單的示例中重新創建錯誤,如下所示:
board = [1, 2, 3]
temp_board = board
if temp_board[0] == 1:
print("it works")
但這作業正常并且不會產生錯誤。所以也許這與函式之間的通信有關(或者只是某個地方的錯字)?
由于我未能縮短代碼并得到相同的錯誤,所以我現在附上我所做的一切。對不起,很長的帖子。
(如果您決定運行代碼,請選擇中等難度,這就是錯誤發生的地方)。
# I need these functions to make everything work
# clear_output was imported by Google Colab, not sure if it's standard
# all mentions of clear_output can be deleted if needed, the code will work
# but it will show every turn made by computer/human, not just the current board
from IPython.core.display import clear_output
from random import randrange
# Sets the board at the beginning
board = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Just displays the current board
def display_board():
print(
"\n ------- ------- ------- ",
"\n| | | |",
"\n| ",board[0]," | ",board[1]," | ",board[2]," |",
"\n| | | |",
"\n ------- ------- ------- ",
"\n| | | |",
"\n| ",board[3]," | ",board[4]," | ",board[5]," |",
"\n| | | |",
"\n ------- ------- ------- ",
"\n| | | |",
"\n| ",board[6]," | ",board[7]," | ",board[8]," |",
"\n| | | |",
"\n ------- ------- ------- "
)
# Asks player to define who plays first (human or computer). Impacts the order of turns.
def who_plays_first():
global first_player
while True:
first_player = int(input("Choose who plays first: 1 for human, 2 for computer"))
if first_player == 1 or first_player == 2:
break
print("invalid input, read the instruction")
if first_player == 1:
first_player = "human"
else:
first_player = "computer"
return(first_player)
# Asks player to set difficulty. Impacts how computer decides on its move.
def choose_difficulty():
global difficulty
while True:
difficulty = int(input("Choose difficulty: 1 = easy, 2 = medium, 3 = hard"))
if difficulty == 1 or difficulty == 2 or difficulty == 3:
break
print("invalid input, read the instruction")
if difficulty == 1:
difficulty = "easy"
elif difficulty == 2:
difficulty = "medium"
else:
difficulty = "hard"
return(difficulty)
# Makes a list of free fields. Used in other functions.
def make_list_of_free_fields():
list_of_free_fields = []
for field in range(1,10):
if field in board:
list_of_free_fields.append(field)
return(list_of_free_fields)
# Checks whether the player (defined by the sign) won.
def victory_for(sign):
if (board[0] == sign and board[1] == sign and board[2] == sign or
board[3] == sign and board[4] == sign and board[5] == sign or
board[6] == sign and board[7] == sign and board[8] == sign or
board[0] == sign and board[3] == sign and board[6] == sign or
board[1] == sign and board[4] == sign and board[7] == sign or
board[2] == sign and board[5] == sign and board[8] == sign or
board[0] == sign and board[4] == sign and board[8] == sign or
board[2] == sign and board[4] == sign and board[6] == sign):
return True
else:
return False
# Same as victory_for, but only used to help computer make its move on medium/hard.
def possible_victory_for(sign):
if (temp_board[0] == sign and temp_board[1] == sign and temp_board[2] == sign or
temp_board[3] == sign and temp_board[4] == sign and temp_board[5] == sign or
temp_board[6] == sign and temp_board[7] == sign and temp_board[8] == sign or
temp_board[0] == sign and temp_board[3] == sign and temp_board[6] == sign or
temp_board[1] == sign and temp_board[4] == sign and temp_board[7] == sign or
temp_board[2] == sign and temp_board[5] == sign and temp_board[8] == sign or
temp_board[0] == sign and temp_board[4] == sign and temp_board[8] == sign or
temp_board[2] == sign and temp_board[4] == sign and temp_board[6] == sign):
return True
else:
return False
# Asks the human player to make their move.
def human_move():
while True:
human_input = int(input("Choose a field"))
if human_input in make_list_of_free_fields():
break
print("You must choose one of the free fields on the board by typing 1-9")
board[human_input-1] = "O"
# This is how the computer makes its move.
# Depends on the difficulty.
# Easy is completely random.
# Medium checks whether:
# a) there's a (list of) move(s) that could guarantee computer's victory
# b) there's a (list of) move(s) that could guarantee human's victory
# - then play a random move out of that list (computer victory has priority)
# Hard is yet to be defined.
def computer_move():
if difficulty == "easy":
while True:
computer_input = randrange(10)
if computer_input in make_list_of_free_fields():
break
board[computer_input-1] = "X"
# elif difficulty == "medium":
else:
brings_computer_victory = []
brings_human_victory = []
for field in make_list_of_free_fields():
temp_board = board
temp_move = field
temp_board[temp_move-1] = "X"
if possible_victory_for("X") == True:
brings_computer_victory.append(temp_move)
if brings_computer_victory != []:
computer_input = randrange(1, len(brings_computer_victory) 1)
board[computer_input-1] = "X"
for field in make_list_of_free_fields():
temp_board = board
temp_move = field
temp_board[temp_move-1] = "O"
if possible_victory_for("O") == True:
brings_human_victory.append(temp_move)
if brings_human_victory != []:
computer_input = randrange(1, len(brings_human_victory) 1)
board[computer_input-1] = "X"
# This is the final piece of code that connects all the functions.
who_plays_first()
choose_difficulty()
clear_output()
if first_player == "human":
display_board()
while True:
human_move()
clear_output()
display_board()
if victory_for("O") == True:
print("You won!")
break
if len(make_list_of_free_fields()) == 0:
print("it's a tie")
break
computer_move()
clear_output()
display_board()
if victory_for("X") == True:
print("You lost!")
break
else:
while True:
computer_move()
clear_output()
display_board()
if victory_for("X") == True:
print("You lost!")
break
if len(make_list_of_free_fields()) == 0:
print("it's a tie")
break
human_move()
clear_output()
display_board()
if victory_for("O") == True:
print("You won!")
break
這是錯誤回溯:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-11-322daee905b6> in <module>
28
29 while True:
---> 30 computer_move()
31 clear_output()
32 display_board()
1 frames
<ipython-input-10-6530342ed281> in computer_move()
24 temp_move = field
25 temp_board[temp_move-1] = "X"
---> 26 if possible_victory_for("X") == True:
27 brings_computer_victory.append(temp_move)
28 if brings_computer_victory != []:
<ipython-input-8-bd71fed33fb4> in possible_victory_for(sign)
1 # Same as victory_for, but only used to help computer make its move on medium/hard.
2 def possible_victory_for(sign):
----> 3 if (temp_board[0] == sign and temp_board[1] == sign and temp_board[2] == sign or
4 temp_board[3] == sign and temp_board[4] == sign and temp_board[5] == sign or
5 temp_board[6] == sign and temp_board[7] == sign and temp_board[8] == sign or
NameError: name 'temp_board' is not defined
uj5u.com熱心網友回復:
temp_board是本地的computer_move,但您將其視為全域。您應該將其作為引數possible_victory_for:
def possible_victory_for(sign, temp_board):
# if (temp_board[0] ...
然后將其computer_move作為引數傳遞:
if possible_victory_for("X", temp_board) == True:
一般來說,我建議將變數作為引數傳遞給你的函式,而不是依賴于從外部范圍內隱式提取它們;它使代碼不同部分之間的依賴關系更加明顯(在這種情況下possible_victory_for,不僅取決于的當前值,還取決于sign的當前值temp_board),從而更容易更改和擴展。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/532027.html
