参考学习:Python实现井字棋游戏
井字棋(Tic-Tac-Toe),初高中进行打发时间的一种画x画o的游戏,3*3的格子组成,一方把行列斜行连成相同的就算获胜。
那么怎么利用进行人机对弈这种简单的小游戏那。我们先不急于写代码,先进行思考,程序的实现是进行方便人们的,我们设计井字棋,肯定想让程序智能化,能够最大程度的模拟人,所以我们设计一个无敌的“人”,最后的结果只能是玩家输或者平局,机器必不可能输。
顺着这个思想想,怎么让机器无敌,这个时候就要考虑这个游戏本身了,因为游戏简单,我们很轻松就可以推到想赢所对应的步骤,把这种思想步骤灌输给计算机,让他学习到,想输都难,大概这就是人工智能(AI)吧,不过我们的这个游戏简单,简易的不能准确的称为标准的人工智能,做不到AlphaGo那样可以对战世界冠军,但是总体AlphaGo也是通过不断学习不断增强的。
言归正传,说我们的井字棋。井字棋我们分为0-8,横着排就是这样。
想要获胜就要:
(第一个下角,后面的下中)(第一个下中,后面的下角)(不然的必定有一个死棋)
棋盘采用包含9个元素的列表来实现
棋盘为board
board[0]到board[8]存储代表棋子的字符串
字符串0到8代表未落子
字符串X
、O
表示两种棋子,也就是玩家和机器进行下的棋子
1.先有一个棋盘
棋盘的设计不唯一,可以设计多种样式的棋盘,有兴趣的话可以进行自行探索。
board = list("012345678")
def dis_board(board):
#显示出棋盘
print("\t{0} | {1} | {2}".format(board[0], board[1], board[2]))
print("\t_ | _ | _")
print("\t{0} | {1} | {2}".format(board[3], board[4], board[5]))
print("\t_ | _ | _")
print("\t{0} | {1} | {2}".format(board[6], board[7], board[8]))
2.进行询问:是x先走还是o先走
3.人机进行交互落子
首要目的是要确保AI的每一步都不能出错,一出错可能就满盘皆输
这样就可以让AI立于不败之地了。
AI先找到可以落子的位置
def _moves(board):
#寻求可落子的位置
moves = []
for i in range(9):
if board[i] in list("012345678"): #遍历了棋盘的位置如果位置为0-8那么这个位置可以落子
moves.append(i)
return moves
询问玩家落子位置,无效落子重复询问
def playermove(board):
#询问并确定玩家的选择落子位置,无效落子重复询问
move = 9
while move not in _moves(board):
move = int(input("请选择落子位置(0-8):"))
return move
参数:棋盘,AI棋子,玩家棋子
并且运用winner函数,赢就返回True
def computermove(board,computerletter,playerletter):
#核心算法:计算AI的落子位置
boardcopy = board.copy()
#规则一:判断如果某位置落子可以获胜,则选择这个位置
for move in _moves(boardcopy):
boardcopy[move] = computerletter
if winner(boardcopy):
return move
boardcopy[move] = str(move)
#规则二:某个位置玩家下一步落子就可以获胜,则选择该位置
for move in _moves(boardcopy):
boardcopy[move] = playerletter
if winner(boardcopy):
return move
boardcopy[move] = str(move)
#规则三:按照中心、角、边的选择空的位置
for move in(4,0,2,6,8,1,3,5,7):
if move in _moves(board):
return move
winner函数:判断怎样是获胜
分为八种情况,三种横线,三种竖线,两种对角线
def winner(board):
#判断所给棋子是否获胜
_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 r in _to_win:
if board[r[0]] == board[r[1]] == board[r[2]]:
return True
return False
Tie函数:还有判定平局的情况
def Tie(board):
#判断是否平局
for i in list("012345678"):
if i in board:
return False
return True
# python菜鸟
# 2022.01.10
def dis_board(board):
#显示出棋盘
print("\t{0} | {1} | {2}".format(board[0], board[1], board[2]))
print("\t_ | _ | _")
print("\t{0} | {1} | {2}".format(board[3], board[4], board[5]))
print("\t_ | _ | _")
print("\t{0} | {1} | {2}".format(board[6], board[7], board[8]))
def _moves(board):
#寻求可落子的位置
moves = []
for i in range(9):
if board[i] in list("012345678"): #遍历了棋盘的位置如果位置为0-8那么这个位置可以落子
moves.append(i)
return moves
def playermove(board):
#询问并确定玩家的选择落子位置,无效落子重复询问
move = 9
while move not in _moves(board):
move = int(input("请选择落子位置(0-8):"))
return move
def computermove(board,computerletter,playerletter):
#核心算法:计算AI的落子位置
boardcopy = board.copy()
#规则一:判断如果某位置落子可以获胜,则选择这个位置
for move in _moves(boardcopy):
boardcopy[move] = computerletter
if winner(boardcopy):
return move
boardcopy[move] = str(move)
#规则二:某个位置玩家下一步落子就可以获胜,则选择该位置
for move in _moves(boardcopy):
boardcopy[move] = playerletter
if winner(boardcopy):
return move
boardcopy[move] = str(move)
#规则三:按照中心、角、边的选择空的位置
for move in(4,0,2,6,8,1,3,5,7):
if move in _moves(board):
return move
def winner(board):
#判断所给棋子是否获胜
_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 r in _to_win:
if board[r[0]] == board[r[1]] == board[r[2]]:
return True
return False
def Tie(board):
#判断是否平局
for i in list("012345678"):
if i in board:
return False
return True
def tic_tac_toe():
#井字棋
board = list("012345678")
playerletter = input("请选择棋子x(玩家)或者o(AI)——(x先走,o后走):")
if playerletter in("X","x"):
turn = "player"
playerletter = "x"
computerletter = "o"
else:
turn = "AI"
computerletter = "x"
playerletter = "o"
print("{}先走!".format(turn))
while True:
dis_board(board)
if turn == 'player':
move = playermove(board)
board[move] = playerletter
if winner(board):
dis_board(board)
print("恭喜玩家获胜!")
break
else:
turn = "AI"
else:
move = computermove(board, computerletter, playerletter)
print("人工智能AI落子位置:",move)
board[move] = computerletter
if winner(board):
dis_board(board)
print("人工智能AI获胜!")
break
else:
turn = "player"
if Tie(board):
dis_board(board)
print('平局!')
break
if __name__=='__main__':
tic_tac_toe()
请选择棋子x(玩家)或者o(AI)——(x先走,o后走):x
player先走!
0 | 1 | 2
_ | _ | _
3 | 4 | 5
_ | _ | _
6 | 7 | 8
请选择落子位置(0-8):8
0 | 1 | 2
_ | _ | _
3 | 4 | 5
_ | _ | _
6 | 7 | x
人工智能AI落子位置: 4
0 | 1 | 2
_ | _ | _
3 | o | 5
_ | _ | _
6 | 7 | x
请选择落子位置(0-8):2
0 | 1 | x
_ | _ | _
3 | o | 5
_ | _ | _
6 | 7 | x
人工智能AI落子位置: 5
0 | 1 | x
_ | _ | _
3 | o | o
_ | _ | _
6 | 7 | x
请选择落子位置(0-8):3
0 | 1 | x
_ | _ | _
x | o | o
_ | _ | _
6 | 7 | x
人工智能AI落子位置: 0
o | 1 | x
_ | _ | _
x | o | o
_ | _ | _
6 | 7 | x
请选择落子位置(0-8):7
o | 1 | x
_ | _ | _
x | o | o
_ | _ | _
6 | x | x
人工智能AI落子位置: 6
o | 1 | x
_ | _ | _
x | o | o
_ | _ | _
o | x | x
请选择落子位置(0-8):1
o | x | x
_ | _ | _
x | o | o
_ | _ | _
o | x | x
平局!
进程已结束,退出代码0
遇到的一些问题