Python 井字游戏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22285833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python tic tac toe game
提问by user3295015
I am unsure if all of the code will be necessary or not so i will post it:
我不确定是否需要所有代码,所以我会发布它:
# Tic-Tac-Toe
# Plays the game of tic-tac-toe against a human opponent
# global constants
X = "X"
O = "O"
EMPTY = " "
TIE = "TIE"
NUM_SQUARES = 9
def display_instruct():
"""Display game instructions."""
print(
"""
Welcome to the greatest intellectual challenge of all time: Tic-Tac-Toe.
This will be a showdown between your human brain and my silicon processor.
You will make your move known by entering a number, 0 - 8. The number
will correspond to the board position as illustrated:
0 | 1 | 2
---------
3 | 4 | 5
---------
6 | 7 | 8
Prepare yourself, human. The ultimate battle is about to begin. \n
"""
)
def ask_yes_no(question):
"""Ask a yes or no question."""
response = None
while response not in ("y", "n"):
response = input(question).lower()
return response
def ask_number(question, low, high):
"""Ask for a number within a range."""
response = None
while response not in range(low, high):
response = int(input(question))
return response
def pieces():
"""Determine if player or computer goes first."""
go_first = ask_yes_no("Do you require the first move? (y/n): ")
if go_first == "y":
print("\nThen take the first move. You will need it.")
human = X
computer = O
else:
print("\nYour bravery will be your undoing... I will go first.")
computer = X
human = O
return computer, human
def new_board():
"""Create new game board."""
board = []
for square in range(NUM_SQUARES):
board.append(EMPTY)
return board
def display_board(board):
"""Display game board on screen."""
print("\n\t", board[0], "|", board[1], "|", board[2])
print("\t","---------")
print("\t",board[3], "|", board[4], "|", board[5])
print("\t","---------")
print("\t",board[6], "|", board[7], "|", board[8])
def legal_moves(board):
"""Create list of legal moves."""
moves = []
for square in range(NUM_SQUARES):
if board[square] == EMPTY:
moves.append(square)
return moves
def winner(board):
"""Determine the game winner."""
WAYS_TO_WIN = ((0, 1, 2),
(3, 4, 5),
(6, 7, 8),
(0, 3, 6),
(1, 4, 7),
(2, 5, 8),
(0, 4, 8),
(2, 4, 6))
for row in WAYS_TO_WIN:
if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:
winner = board[row[0]]
return winner
if EMPTY not in board:
return TIE
return None
def human_move(board, human):
"""Get human move."""
legal = legal_moves(board)
move = None
while move not in legal:
move = ask_number("Where will you move? (0 - 8):", 0, NUM_SQUARES)
if move not in legal:
print("\nThat square is already occupied, foolish human. Choose another.\n")
print("Fine...")
return move
def computer_move(board, computer, human):
"""Make computer move."""
# make a copy to work with since function will be changing list
board = board[:]
# the best positions to have, in order
BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7)
print("I shall take square number,", end="")
# if computer can win, take that move
for move in legal_moves(board):
board[move] = computer
if winner(board) == computer:
print(move)
return move
# done checking this move, undo it
board[move] = EMPTY
# if human can win, block that move
for move in legal_moves(board):
board[move] = human
if winner(board) == human:
print(move)
return move
# done checkin this move, undo it
board[move] = EMPTY
# since no one can win on next move, pick best open square
for move in BEST_MOVES:
if move in legal_moves(board):
print(move)
return move
def next_turn(turn):
"""Switch turns."""
if turn == X:
return O
else:
return X
def congrat_winner(the_winner, computer, human):
"""Congratulate the winner."""
if the_winner != TIE:
print(the_winner, "won!\n")
else:
print("It's a tie!\n")
if the_winner == computer:
print("As I predicted, human, I am triumphant once more. \n" \
"Proof that computers are superior to humans in all regards.")
elif the_winner == human:
print("No, no! It cannot be! Somehow you tricked me, human. \n" \
"But never again! I, the computer, so swear it!")
elif the_winner == TIE:
print("You were most lucky, human, and somehow managed to tie me. \n" \
"Celebrate today... for this is the best you will ever achieve.")
def main():
display_instruct()
computer, human = pieces()
turn = X
board = new_board()
display_board(board)
while not winner(board):
if turn == human:
move = human_move(board, human)
board[move] = human
else:
move = computer_move(board, computer, human)
board[move] = computer
display_board(board)
turn = next_turn(turn)
the_winner = winner(board)
congrat_winner(the_winner, computer, human)
# start the program
main()
input("\n\nPress the enter key to quit.")
This is an example in a book i am reading and i am not fully understanding, i think understand all of it up until:
这是我正在阅读的书中的一个例子,我没有完全理解,我认为理解所有内容,直到:
for row in WAYS_TO_WIN:
if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:
winner = board[row[0]]
return winner
Can somebody please explain what this function does and more specifically what the condition
if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:is testing?
有人可以解释一下这个函数是做什么的,更具体地说,条件
if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:是什么?
回答by mackworth
It's just checking the current board to see if any winning combination of cells (as listed in the row array) have (a) the same value and (b) that value is not EMPTY.
它只是检查当前棋盘以查看是否有任何获胜的单元格组合(如行数组中所列)具有 (a) 相同的值和 (b) 该值不是 EMPTY。
Note: in Python, if a == b == c != d, checks that a ==b AND b == c AND c != d
注意:在 Python 中,如果 a == b == c != d,则检查 a ==b AND b == c AND c != d
So if cells 0, 1, and 2, all have X, then on the first pass through the loop, it will return X from the winner routine.
因此,如果单元格 0、1 和 2 都具有 X,则在第一次通过循环时,它将从获胜例程中返回 X。
回答by Isaac
The best way to see what is going on is to put some printstatements in this code when you run it.
查看正在发生的事情的最佳方法是在print运行此代码时在此代码中放入一些语句。
Judging by the way things are names, you can tell that you're looking to see if someone has won the game. You know from the rules of TicTacToe that if X or O have three in a row, column, or diagonal, that player wins. You see in the board[x] == board[y] == board[z]that we're probably testing for three in a row here. So what is x, y z? Well, look at WAYS_TO_WIN. In that array are rows indicating the indices that are in a row, column, or diagonal. Thus, we're testing to see if a row, column, or diagonal contains the same character, and that character is NOT EMPTY(which is the " "[space] character).
从事物的名称来看,您可以看出您正在寻找是否有人赢得了比赛。您从井字游戏的规则中知道,如果 X 或 O 在一行、一列或对角线上有三个,则该玩家获胜。你看到board[x] == board[y] == board[z]我们可能在这里连续测试三个。那么什么是x, y z?嗯,看看WAYS_TO_WIN。该数组中的行表示行、列或对角线中的索引。因此,我们正在测试行、列或对角线是否包含相同的字符,并且该字符不是EMPTY(即" "[空格] 字符)。
回答by Scormer
I am new to Python. The script below for tic tac toe game is from one of my exercises. It uses a different approach.
我是 Python 的新手。下面的井字游戏脚本来自我的一个练习。它使用不同的方法。
For the data structure, I used integer value 0 for blank cells, +1 for computer placed cells and -1 for user placed cells.
对于数据结构,我使用整数值 0 表示空白单元格,+1 表示计算机放置的单元格,-1 表示用户放置的单元格。
The main benefit is I can use the lineValue, i.e., the sum of all three cells' values in a line, to track the status of each line. All 8 line values are stored in the list lineValues. This can make the decision much easier. For example, When it's my (computer's) turn, if there is a line with lineValue==2, I know I am going to win. Otherwise, if there are line(s) with lineValue ==-2, I have to block the intersection (if any) of these lines.
主要的好处是我可以使用lineValue,即一行中所有三个单元格值的总和,来跟踪每行的状态。所有 8 个行值都存储在列表lineValues 中。这可以使决策更加容易。例如,当轮到我(计算机)时,如果有一行 lineValue==2,我就知道我会赢。否则,如果有 lineValue ==-2 的线,我必须阻止这些线的交叉点(如果有)。
The key for making decision is the function findMostValuableCell. What it does is to find out which cell is most valuable for the next move (i.e., which cell appears in most number of lines for a specific lineValue). There is no try-out test (what-if test) in this script. It uses quite a few list comprehensions.
决策的关键是函数findMostValuableCell。它所做的是找出哪个单元格对于下一步移动最有价值(即,对于特定的 lineValue,哪个单元格出现在最多的行中)。此脚本中没有试用测试(假设测试)。它使用了相当多的列表推导式。
Hope it can help.
希望它能有所帮助。
ttt = [0 for i in range(9)]
lines = [[0, 1, 2],[3, 4, 5],[6, 7, 8],[0, 3, 6],[1, 4, 7],[2, 5, 8],[0, 4, 8],[2, 4, 6]]
lineValues = [0 for i in range(8)]
userChar = {1: "O", -1: "X", 0: "_"}
turn = -1 # defalut to user move first
#*****************************************************
def main():
global userChar, turn
if input("Do you want me to start first? (Y/N)").lower()=="y":
userChar = {1:"X",-1:"O",0:"_"}
turn = 1
display()
while not hasWinner():
if 0 in ttt:
nextMove(turn)
turn *= -1
display()
else:
print("It's a tie!")
break
#*****************************************************
def hasWinner():
if max(lineValues) == 3:
print("******** I win!! ********")
return True
elif min(lineValues) == -3:
print("******** You win ********")
return True
#*****************************************************
def nextMove(turn):
if turn== -1: #User's turn
print("It's your turn now (" + userChar[-1]+"):")
while not isUserMoveSuccessful(input("Please choose your cell number:")):
print("Your choice is not valid!")
else: #Computer's turn
print("It's my turn now...")
for lineValue in [2,-2,-1,1,0]:
cell = findMostValuableCell(lineValue)
if cell>=0: #found a cell for placement
markCell(cell, turn)
print ("I chose cell", str(cell),"." )
return
#*****************************************************
def isUserMoveSuccessful(userInput):
s = list(userInput)[0]
if '012345678'.find(s)>=0 and ttt[int(s)]==0:
markCell(int(s), turn)
return True
#*****************************************************
def findMostValuableCell(lineValue):
if set(ttt)=={0}:
return 1
allLines = [i for i in range(8) if lineValues[i]==lineValue]
allCells =[j for line in allLines for j in lines[line] if ttt[j]==0]
cellFrequency = dict((c, allCells.count(c)) for c in set(allCells))
if len(cellFrequency)>0: # get the cell with highest frequency.
return max(cellFrequency, key=cellFrequency.get)
else:
return -1
#*****************************************************
def markCell(cell, trun):
global lineValues, ttt
ttt[cell]=turn
lineValues = [sum(cellValue) for line in lines for cellValue in [[ttt[j] for j in line]]]
#*****************************************************
def display():
print(' _ _ _\n'+''.join('|'+userChar[ttt[i]]+('|\n' if i%3==2 else '') for i in range(9)))
#*****************************************************
main()
回答by Ashwani Jha
I would put it simply. Row is a variable that is assigned to each tuple in the tuple WAYS_TO_WIN. In the first iteration, row = (0,1,2) it checks if value at 0==1==2.
我会简单地说。Row 是一个变量,分配给元组 WAYS_TO_WIN 中的每个元组。在第一次迭代中,row = (0,1,2) 检查值是否为 0==1==2。
In the second iteration, row = (3,4,5) it checks if value at 3==4==5.
在第二次迭代中,row = (3,4,5) 检查值是否为 3==4==5。
Row goes to each inner tuple of the outer tuple ways_to_win till row = (2,4,6) is reached. That's what the program is doing.
Row 转到外部元组 way_to_win 的每个内部元组,直到达到 row = (2,4,6)。这就是程序正在做的事情。
回答by vamshi mannem
List item
def tic_tac_toe(): board = [1, 2, 3, 4, 5, 6, 7, 8, 9] end = False win_commbinations = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6))
def draw(): print(board[0], board[1], board[2]) print(board[3], board[4], board[5]) print(board[6], board[7], board[8]) print()
def p1(): n = choose_number() if board[n] == "X" or board[n] == "O": print("\nYou can't go there. Try again") p1() else: board[n] = "X"
def p2(): n = choose_number() if board[n] == "X" or board[n] == "O": print("\nYou can't go there. Try again") p2() else: board[n] = "O"
def choose_number(): while True: while True: a = input() try: a = int(a) a -= 1 if a in range(0, 9): return a else: print("\nThat's not on the board. Try again") continue except ValueError: print("\nThat's not a number. Try again") continue
def check_board(): count = 0 for a in win_commbinations: if board[a[0]] == board[a[1]] == board[a[2]] == "X": print("Player 1 Wins!\n") print("Congratulations!\n") return True
if board[a[0]] == board[a[1]] == board[a[2]] == "O": print("Player 2 Wins!\n") print("Congratulations!\n") return True for a in range(9): if board[a] == "X" or board[a] == "O": count += 1 if count == 9: print("The game ends in a Tie\n") return Truewhile not end: draw() end = check_board() if end == True: break print("Player 1 choose where to place a cross") p1() print() draw() end = check_board() if end == True: break print("Player 2 choose where to place a nought") p2() print()
if input("Play again (y/n)\n") == "y": print() tic_tac_toe()
项目清单
def tic_tac_toe(): board = [1, 2, 3, 4, 5, 6, 7, 8, 9] end = False win_combinations = ((0, 1, 2), (3, 4, 5), (6 , 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6))
def draw(): 打印(板[0], 板[1], 板[2]) 打印(板[3], 板[4], 板[5]) 打印(板[6], 板[7] , 板[8]) 打印()
def p1(): n = choose_number() if board[n] == "X" or board[n] == "O": print("\n你不能去那里。再试一次") p1() else :板[n] =“X”
def p2(): n = choose_number() if board[n] == "X" or board[n] == "O": print("\n你不能去那里。再试一次") p2() else :板[n] =“O”
def choose_number(): while True: while True: a = input() try: a = int(a) a -= 1 if a in range(0, 9): return a else: print("\nThat's not on the board. Try again") 继续,除了 ValueError: print("\nThat's not a number. Try again") continue
def check_board(): count = 0 for a in win_combinations: if board[a[0]] == board[a[1]] == board[a[2]] == "X": print("Player 1赢了!\n") print("Congratulations!\n") 返回 True
if board[a[0]] == board[a[1]] == board[a[2]] == "O": print("Player 2 Wins!\n") print("Congratulations!\n") return True for a in range(9): if board[a] == "X" or board[a] == "O": count += 1 if count == 9: print("The game ends in a Tie\n") return Truewhile not end: draw() end = check_board() if end == True: break print("玩家 1 选择放置十字的位置") p1() print() draw() end = check_board() if end ==正确:break print("玩家 2 选择放置零的位置") p2() print()
if input("Play again (y/n)\n") == "y": print() tic_tac_toe()

