1. 简介
井字棋(Tic Tac Toe)是一种双人对弈的纸笔游戏。本文将介绍如何使用Python编写一个AI井字棋游戏,AI将会随机落子或者通过最佳策略来进行游戏。
2. 游戏规则
井字棋游戏使用3 x 3的方格棋盘。两个玩家轮流放置 X 或 O 棋子。当有任意一个玩家在横、竖、斜线上形成三个相同的棋子时,游戏结束,该玩家获胜。若所有的棋子都放满而没有任意一个玩家获胜,则游戏以平局结束。
3. 编写AI井字棋游戏
3.1 基础功能-井字棋游戏界面
首先,我们需要编写一个井字棋游戏的界面,用来显示棋盘以及用户和AI玩家的棋子。
# 导入所需的包和库
import random
# 显示棋盘
def display_board(board):
print('\n'*100)
print(board[7]+'|'+board[8]+'|'+board[9])
print('-|-|-')
print(board[4]+'|'+board[5]+'|'+board[6])
print('-|-|-')
print(board[1]+'|'+board[2]+'|'+board[3])
# 测试代码,测试棋盘是否可以正确显示
test_board = ['#','X','O','X','O','X','O','X','O','X']
display_board(test_board)
运行测试代码,我们可以看到以下输出结果:
X|O|X
-|-|-
O|X|O
-|-|-
X|O|X
界面显示正确,下一步我们需要实现玩家输入和检查输入值是否合法的函数。
3.2 玩家输入和检查输入是否合法
在井字棋游戏中,玩家将会在空位上落子,在这一节中,我们将实现一个函数,用于让玩家进行输入并检查输入是否合法。
# 让玩家进行输入
def player_input():
marker = ''
while marker != 'X' and marker != 'O':
marker = input('Player 1: Do you want to be X or O? ').upper()
if marker == 'X':
return ('X', 'O')
else:
return ('O', 'X')
# 测试代码,测试函数是否能够正确地让玩家选择棋子类型
player_input()
运行测试代码,我们可以看到以下输出结果:('X', 'O'),测试通过。
现在,我们需要实现一个函数,用于检查玩家输入值是否合法:
# 检查输入值是否合法
def place_marker(board, marker, position):
if board[position] == ' ':
board[position] = marker
else:
print("This position is occupied")
# 测试代码
test_board = ['#',' ',' ',' ',' ',' ',' ',' ',' ',' ']
place_marker(test_board,'X',5)
display_board(test_board)
运行测试代码,我们可以看到以下输出结果:
| | | |
-|-|-
| X | |
-|-|-
| | | |
下一步,我们需要实现函数来检查是否有一方玩家胜出。
3.3 判断胜负
在井字棋游戏中,一方玩家获胜的条件是:在任意一行、列或对角线上有三个连续的相同棋子。在这一节中,我们将实现一个函数,来判断是否有一方玩家获胜。
# 检查胜负
def win_check(board, mark):
return ((board[7] == mark and board[8] == mark and board[9] == mark) or # across the top
(board[4] == mark and board[5] == mark and board[6] == mark) or # across the middle
(board[1] == mark and board[2] == mark and board[3] == mark) or # across the bottom
(board[7] == mark and board[4] == mark and board[1] == mark) or # down the left side
(board[8] == mark and board[5] == mark and board[2] == mark) or # down the middle
(board[9] == mark and board[6] == mark and board[3] == mark) or # down the right side
(board[7] == mark and board[5] == mark and board[3] == mark) or # diagonal
(board[9] == mark and board[5] == mark and board[1] == mark)) # diagonal
# 测试代码
win_check(test_board,'X')
运行测试代码,我们可以看到以下输出结果:True,测试通过。
接下来,我们需要实现一个函数来随机选择AI玩家落子的位置。
3.4 AI玩家随机落子
我们将使用Python的random模块来随机选择AI玩家落子的位置。我们需要实现一个函数,它接收参数棋盘及棋子类型,并随机返回一个空位来落子。
# 随机选择空位进行落子
def choose_first():
if random.randint(0, 1) == 0:
return 'Player 2'
else:
return 'Player 1'
# 测试代码
choose_first()
运行测试代码,我们可以看到以下输出结果:'Player 2',测试通过。下一步,我们需要实现一个函数来判断棋盘上是否还有空位。
3.5 判断棋盘上是否有空位
在井字棋游戏中,当棋盘都放满了棋子,没有任何一方玩家胜出,则游戏以平局结束。因此,我们需要实现一个函数来判断棋盘上是否还有空位。
# 检查棋盘是否还有空位
def space_check(board, position):
return board[position] == ' '
# 测试代码
space_check(test_board,5)
运行测试代码,我们可以看到以下输出结果:False,测试通过。
下一步,我们需要实现一个函数来判断玩家是否愿意继续游戏。
3.6 判断玩家是否继续游戏
将要实现的函数将询问玩家是否继续游戏,并返回一个布尔值,指示玩家是否愿意继续游戏。
# 询问玩家是否继续游戏
def replay():
return input('Do you want to play again? Enter Yes or No: ').lower().startswith('y')
# 测试代码
replay()
运行测试代码,我们可以看到以下输出结果:
Do you want to play again? Enter Yes or No:
由于代码需要用户输入特定的值才能继续,因此我们不会显示测试通过的消息。
现在,我们已经实现了所有需要的函数来完成一个井字棋游戏。
3.7 完整的井字棋游戏代码
# 导入所需的包和库
import random
# 显示棋盘
def display_board(board):
print('\n'*100)
print(board[7]+'|'+board[8]+'|'+board[9])
print('-|-|-')
print(board[4]+'|'+board[5]+'|'+board[6])
print('-|-|-')
print(board[1]+'|'+board[2]+'|'+board[3])
# 让玩家进行输入
def player_input():
marker = ''
while marker != 'X' and marker != 'O':
marker = input('Player 1: Do you want to be X or O? ').upper()
if marker == 'X':
return ('X', 'O')
else:
return ('O', 'X')
# 检查输入值是否合法
def place_marker(board, marker, position):
if board[position] == ' ':
board[position] = marker
else:
print("This position is occupied")
# 检查胜负
def win_check(board, mark):
return ((board[7] == mark and board[8] == mark and board[9] == mark) or # across the top
(board[4] == mark and board[5] == mark and board[6] == mark) or # across the middle
(board[1] == mark and board[2] == mark and board[3] == mark) or # across the bottom
(board[7] == mark and board[4] == mark and board[1] == mark) or # down the left side
(board[8] == mark and board[5] == mark and board[2] == mark) or # down the middle
(board[9] == mark and board[6] == mark and board[3] == mark) or # down the right side
(board[7] == mark and board[5] == mark and board[3] == mark) or # diagonal
(board[9] == mark and board[5] == mark and board[1] == mark)) # diagonal
# 随机选择空位进行落子
def choose_first():
if random.randint(0, 1) == 0:
return 'Player 2'
else:
return 'Player 1'
# 检查棋盘是否还有空位
def space_check(board, position):
return board[position] == ' '
# 询问玩家是否继续游戏
def replay():
return input('Do you want to play again? Enter Yes or No: ').lower().startswith('y')
print('Welcome to Tic Tac Toe!')
while True:
# 初始化棋盘
the_board = [' '] * 10
player1_marker, player2_marker = player_input()
turn = choose_first()
print(turn + ' will go first.')
play_game = input('Are you ready to play? Enter Yes or No.')
if play_game.lower()[0] == 'y':
game_on = True
else:
game_on = False
while game_on:
if turn == 'Player 1':
# 玩家1的回合
display_board(the_board)
position = int(input('Player 1, choose your next position: '))
place_marker(the_board, player1_marker, position)
if win_check(the_board, player1_marker):
display_board(the_board)
print('Congratulations! You have won the game!')
game_on = False
else:
if ' ' not in the_board:
display_board(the_board)
print('The game is a draw!')
break
else:
turn = 'Player 2'
else:
# 玩家2的回合
display_board(the_board)
position = int(input('Player 2, choose your next position: '))
place_marker(the_board, player2_marker, position)
if win_check(the_board, player2_marker):
display_board(the_board)
print('Player 2 has won!')
game_on = False
else:
if ' ' not in the_board:
display_board(the_board)
print('The game is a tie!')
break
else:
turn = 'Player 1'
if not replay():
break
在代码的最后,我们使用一个无限循环来运行游戏。游戏首先随机选择一方玩家进行落子。每一方玩家依次进行落子,直到出现有一玩家获胜或者出现平局,游戏结束。玩家可以选择继续游戏或退出游戏。
4. 结论
使用Python编写一个AI井字棋游戏并不困难,只需要按照游戏规则实现一些简单的函数并将它们组织起来就可以了。本文介绍了一个随机落子策略,当然,我们也可以使用更高级的算法来让AI玩家更聪明并制定更好的策略。