# -*- coding: utf-8 -*- # @Time : 2020/12/20 13:37 # @Author : Zhenghui Lyu # @File : main.py # @Software: PyCharm from tkinter import * from tkinter.messagebox import * X = 'X' O = 'O' EMPTY = ' ' computer = X human = O def ask_yes_no(question): """询问玩家是否先走棋子""" response = None while response not in ('y', 'n'): # 如果输入不是y或n则再次输入 response = input(question).lower() return response # 返回y或n def pieces(): """根据先走顺序返回电脑和人所用棋子""" global computer, human go_first = ask_yes_no('玩家是否先走?(y/n)') if go_first == 'y': print('玩家先走') human = X # 先走用X computer = O else: print('电脑先走') computer = X human = O return computer, human # def new_board(): """保存走棋信息列表""" board = [] for square in range(9): board.append(EMPTY) return board def legal_moves(board): """得到可以下棋位置的序列""" moves = [] for square in range(9): if board[square] == EMPTY: moves.append(square) return moves def winner(board): WAYS_TO_WIN = ((1, 2, 3), (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 False # 默认非赢 def computer_move(board, computer, human): board = board[:] # 创建副本,不影响原board BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7) # 最佳下棋位置 for move in legal_moves(board): board[move] = computer if winner(board) == computer: print('电脑下棋的位置...', move) return move board[move] = EMPTY for move in legal_moves(board): board[move] = human if winner(board) == human: print('电脑下棋的位置是...', move) return move board[move] = EMPTY for move in BEST_MOVES: if move in legal_moves(board): print('电脑机器人下棋的位置是', move) return move def DrawQipan(): cv.create_line(0, 40, 120, 40) cv.create_line(0, 80, 120, 80) cv.create_line(0, 120, 120, 120) cv.create_line(40, 0, 40, 120) cv.create_line(80, 0, 80, 120) cv.create_line(120, 0, 120, 120) cv.pack() def drawGameImage(board): for square in range(9): if board[square] == X: img1 = imgs[0] i = square % 3 j = square // 3 cv.create_image((i * 40 + 20, j * 40 + 20), image=img1) cv.pack() elif board[square] == O: img1 = imgs[1] i = square % 3 j = square // 3 cv.create_image((i * 40 + 20, j * 40 + 20), image=img1) cv.pack() def callback(event): global computer, human, board print('点击在', event.x, event.y) x = (event.x) // 40 y = (event.y) // 40 print('点击在', x, y) legal = legal_moves(board) move = y * 3 + x if move not in legal: print('已经落子') return board[move] = human if human == O: img = imgs[1] else: img = imgs[0] cv.create_image((x * 40 + 20, y * 40 + 20), image=img) cv.pack() if not winner(board): move = computer_move(board, computer, human) board[move] = computer drawGameImage(board) the_winner = winner(board) if the_winner == computer: print('电脑机器人赢!\n') showinfo(title='提示', message='电脑机器人赢了') elif the_winner == human: print('玩家赢\n') showinfo(title='提示', message='玩家赢了') elif the_winner == 'TIE': print('平局和棋,游戏结束\n') showinfo(title='提示', message='平局和棋') if __name__ == '__main__': root = Tk() root.title('井字棋') imgs = [PhotoImage(file='X.GIF'), PhotoImage(file='O.GIF')] cv = Canvas(root, bg='green', width=226, height=226) cv.pack() cv.focus_set() computer, human = pieces() turn = X DrawQipan() board = new_board() if turn == human: pass else: move = computer_move(board, computer, human) board[move] = computer drawGameImage(board) cv.bind('<Button-1>', callback) root.mainloop()