# -*- 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()