绘制窗口内游戏页面
绘制井字格
创建井字棋游戏界面创建一个画布并设置其大小和背景颜色
canvas = tk.Canvas(window, bg='white', height=450, width=470)
canvas.pack()
定义函数init()for循环设置井字格线条
def init():
for i in range(1, 3):
canvas.create_line(i * 150 + 10, 20, i * 150 + 10, 460)
canvas.create_line(10, i * 150 + 10, 460, i * 150 + 10)
再在init()函数中为井字棋盘每格设置对应数字
# 设置数字
lb1 = tk.Label(win, text="1")
lb1.place(x=135, y=80)
lb2 = tk.Label(win, text="2")
lb2.place(x=295, y=80)
lb3 = tk.Label(win, text="3")
lb3.place(x=445, y=80)
lb4 = tk.Label(win, text="4")
lb4.place(x=135, y=230)
lb5 = tk.Label(win, text="5")
lb5.place(x=295, y=235)
lb6 = tk.Label(win, text="6")
lb6.place(x=445, y=235)
lb7 = tk.Label(win, text="7")
lb7.place(x=135, y=365)
lb8 = tk.Label(win, text="8")
lb8.place(x=295, y=365)
lb9 = tk.Label(win, text="9")
lb9.place(x=445, y=365)
创造输入框和标签以及按钮
label创建定义标签,以及Entry创建输入框
lb = tk.Label(win,text="请输入要落子的数字位置(1-9):",width=30)
lb.pack()
entry = tk.Entry(win,width=30)
entry.pack()
定义两个按钮,分别为‘按下落子’和‘重新开始’,要记得最后command引用游戏创建的函数
b1 = tk.Button(window, text='按下落子', width=10, height=2, command=click)
b1.pack()
b2 = tk.Button(window, text='重新开始', width=10, height=2, command=restart)
b2.pack()
定义函数def click(),设置输入框输入错误提示
def click():
游戏结束则失灵
if gameover:
return
int获取数字,if循环展示错误提示框
num = int(e.get())
if (num not in range(1, 10)):
tk.messagebox.showwarning(title='警告', message='输入必须在(1-9)范围内!')
return
index = num - 1
if (board[index] != ''):
tk.messagebox.showwarning(title='警告', message='此处不为空,不能落子!') # 警告弹窗
return
player_move落子
player_move(index)
利用函数创建棋盘数据
定义游戏进度,创建我方点击按钮时,实现对应数字呈现井字棋落子,对落子设置颜色样式
#定义游戏进度
global gameover
gameover = False
global step
step = 0
设置定义我方落子函数def player_move(index):
# 我方落子
def player_move(index):
global step
r = 20 # 正方形半径
# 绘制颜色样式
canvas.create_rectangle(points[index][0] - r, points[index][1] - r, points[index][0] + r, points[index][1] + r,
fill='purple')
# 修改棋盘数据
board[index] = '玩家'
# 步数+1
step += 1
# 判断胜负
isWin()
if gameover:
return
再新创建一个py文件命名TicTacToeAI.py进行编写定义对手AI,首先定义ai类,创建ai决策,返回最佳决策落子,还要进行局面评估遍历所有赢法,从而进行对局下棋。
class AI:
# 颜色
color = ''
enemycolor = ''
定义evaluate函数,创建决策返回最佳决策落子,decs获取当前局面的所有决策,for循环遍历所以决策,用new_board[dec]假设落子,value进行局面评估价值
def decide(self, color, enemycolor, board):
self.color = color
self.enemycolor = enemycolor
maxValue = -90000
pos = 0
decs = self.get_Decisions(board) # 获取当前局面的所有决策
for dec in decs: # 遍历所有决策
new_board = board.copy()
new_board[dec] = color # 假设落子
value = self.evaluate(new_board) # 评估子局面价值
if value > maxValue:
maxValue = value
pos = dec
返回最大价值决策
return pos
定义get_Decisions函数返回当前局面的所有决策,再用if…else对其进行编译
def get_Decisions(self, board):
decs = []
# 先手
if board[4] == '':
decs.append(4)
# 后手
else:
for i in range(9):
# 找到一个空位,当做一种决策
if board[i] == '':
decs.append(i)
return decs
定义函数evaluate进行局面评估
def evaluate(self, board):
value = 0
wins = [[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循环遍历所有赢法
# 遍历所有赢法
for win in wins:
b = board[win[0]], board[win[1]], board[win[2]]
if b == (self.color, self.color, self.color):
value += 10000
elif b == ('', self.color, self.color) or b == (self.color, '', self.color) or b == (
self.color, self.color, ''):
value += 500
elif b == (self.color, '', '') or b == ('', '', self.color) or b == ('', self.color, ''):
value += 10
elif b == ('', self.enemycolor, self.enemycolor) or b == (self.enemycolor, '', self.enemycolor) or b == (
self.enemycolor, self.enemycolor, ''):
value -= 5000
elif b == ('', '', self.enemycolor) or b == ('', self.enemycolor, '') or b == (self.enemycolor, '', ''):
value -= 50
return value
回到之前的游戏设置py文件中,在上面导包区加上import TicTacToeAI as ai,再进行AI落子的编写定义函数ai_move()设置下棋,绘制样式颜色
def ai_move():
index=ai.AI().decide('AI','玩家',board)
r=20#圆的半径
#绘制
canvas.create_oval(points[index][0]-r,points[index][1]-r,points[index][0]+r,points[index][1]+r,fill='yellow')
board[index]='AI'
isWin()
判断游戏胜利
利用def isWin():函数判断游戏是否结束胜利,global gameover为其定义如何胜利列表,结束后输出赢家是谁
def isWin():
global gameover
# 所有可能获胜的组合
win = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [0, 4, 8], [1, 4, 7], [2, 5, 8], [2, 4, 6]]
for i in win:
if board[i[0]] == board[i[1]] == board[i[2]] and board[i[0]] != '':
gameover = True
tk.messagebox.showinfo(title="输入错误", message='赢家是' + board[i[0]])
return
定义重新开始
定义def restart()函数重置游戏,清空画布上所有东西,调用上面init()以便于点击按钮游戏重新开始
# 判断游戏是否结束
def isWin():
global gameover
# 所有可能获胜的组合
win = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [0, 4, 8], [1, 4, 7], [2, 5, 8], [2, 4, 6]]
for i in win:
if board[i[0]] == board[i[1]] == board[i[2]] and board[i[0]] != '':
gameover = True
tk.messagebox.showinfo(title="输入错误", message='赢家是' + board[i[0]])
return
实现登录页面与游戏的连接
在注册登录页面代码中导入import subprocess再使用subprocess.Popen使游戏登录界面与井字棋游戏界面实现点击连接
subprocess.Popen(['python', 'D:/python/pythonProject1/输入进入/3.py'])
添加位置(登录注册页面代码)
if usr_name in usrs_info:
print('3')
if usr_pwd == usrs_info[usr_name]:
tk.messagebox.showinfo(title='Welcome', message='How are your?' + usr_name)
subprocess.Popen(['python', 'D:/python/pythonProject1/输入进入/3.py'])
else:
tk.messagebox.showerror(message='您的密码出错了!!请重新输入')