import pygame,sys,time
from pygame.locals import *
global boardsize,boardtopleft,boardrightbottom
global gsize  #棋盘格子的尺寸
global buttontop,buttonbottom
global buttonleft,buttonright
global bsize     #按钮尺寸
boardsize=550
boardtopleft=22
boardrightbottom=572
gsize=68.75  #棋盘格子的尺寸
buttontop=180
buttonbottom=204
buttonleft=628
buttonright=876
bsize=62     #按钮尺寸

def getScore(board):
    #返回黑棋和白棋各自的数量
    bscore=0
    wscore=0
    for r in range(8):
        for c in range(8):
            if board[r][c]==-1:
                bscore+=1
            elif board[r][c]==1:
                wscore+=1
    return bscore,wscore

def drawscreen(win,board,surflist,bpos,piece):
    # 绘制棋盘,win为棋盘所在窗口，bpos为button的坐标[row,col]
    # surflist为背景图黑棋行，背景图白棋行，黑棋，白棋和提示棋的Surface组成的列表
    #piece表示当前棋子的颜色，用于控制显示落子
    if piece==-1:
        win.blit(surflist[0], [0, 0])
    else:
        win.blit(surflist[1], [0, 0])
    font1 = pygame.font.Font(None, 32)
    bnum,wnum=getScore(board)
    str1 = str(bpos[0]) + " , " + str(bpos[1])
    scorestr = str(bnum) + " : " + str(wnum)
    txt1_surf = font1.render(str1, 1, (0, 0, 0))
    score_surf = font1.render(scorestr, 1, (94,39,7))
    #txt3_surf = font1.render(str3, 1, (0, 0, 255))
    win.blit(txt1_surf, [640, 250])
    win.blit(score_surf, [730,36])
    #win.blit(txt3_surf, [605, 450])

    #开始显示棋子
    for r in range(8):
        for c in range(8):
            if board[r][c] == -1:
                #黑棋
                win.blit(surflist[2], [c * gsize  + boardtopleft, r * gsize + boardtopleft])
            elif board[r][c] == 1:
                #白棋
                win.blit(surflist[3], [c * gsize  + boardtopleft, r * gsize + boardtopleft])
            elif board[r][c] >= 100:
                #提示棋
                win.blit(surflist[4], [c * gsize  + boardtopleft, r * gsize + boardtopleft])
                str2=str(board[r][c]-100)
                txt2_surf = font1.render(str2, 1, (0, 0, 0))
                win.blit(txt2_surf, [c * gsize + boardtopleft+25, r * gsize + boardtopleft+25])


    pygame.display.flip()



def cursor2button(x,y):
    #屏幕光标位置转换为按钮
    #[0,0]~[7,7]为棋盘相应格子
    #[10,0]~[10,3]为四个控制按钮
    #[-1,-1]为不合法的点击
    row=-1
    col=-1
    if x>=boardtopleft and x<=boardrightbottom and y>=boardtopleft and y<=boardrightbottom:
        row = int((y - boardtopleft) / gsize)
        col = int((x - boardtopleft) / gsize)
    elif x>=buttonleft and x<=buttonright and y>=buttontop and y<=buttonbottom:
        row=10
        col=int((x-buttonleft)/bsize)
    return row,col

def resetBoard(board):
    #游戏数据清零,每个玩家有两个棋子在棋盘的中央
    #用于开始新游戏
    for r in range(8):
        for c in range(8):
            board[r][c]=0
    board[3][3]=-1
    board[3][4]=1
    board[4][3]=1
    board[4][4]=-1

def isOnBoard(x,y):
    if x >= 0 and x <= 7 and y >= 0 and y <= 7:
        return True
    else:
        return False

def getNewBoard():
    #创建新的数据表，用于程序初始化
    board=[]
    for i in range(8):
        board.append([0]*8)
    return board

def get_input(window):
    pass

def judge(board,piece,pos):
    #在棋盘上根据在行列pos[row,col]上的落子piece，进行计算
    dir=[ [1,0],[1,-1],[0,-1],[-1,-1],[-1,0],[-1,1],[0,1],[1,1] ]

    reverlist = []          #八个方向的总列表
    #八个方向遍历
    for i in range(8):
        revli=[]            #一个方向的小列表
        r,c=pos
        while True:
            r+=dir[i][1]
            c+=dir[i][0]
            if isOnBoard(r,c):
                if board[r][c]== -piece:
                    #只有遇到对方棋子，就在小列表中记录其坐标
                    revli.append([r,c])
                elif board[r][c]==piece:
                    #遇到同色棋子，把小列表并入大列表，
                    # 退出while循环,进入下一个方向的判断
                    for rr,cc in revli:
                        reverlist.append([rr,cc])
                    break
                elif board[r][c]==0 or board[r][c]>=100:
                    #遇到空白则退出whie循环，进入下一个方向的判断
                    break
            else:
                #超出棋盘的范围
                break
    if len(reverlist)==0:
        return False
    return reverlist

def computerMove(board,piece):
    #电脑走棋程序,返回最优值走法的坐标
    #可以扩展一下，直接返回坐标已经可翻转棋的列表

    #清理辅助棋子数据
    for r in range(8):
        for c in range(8):
            if board[r][c] >= 100:
                board[r][c] = 0
    #开始遍历所有空白棋格
    for r in range(8):
        for c in range(8):
            if board[r][c]==0:
                revlst=judge(board,piece,[r,c])
                if revlst==False:
                    #该位置不能落子，开始下一个for循环
                    continue
                else:
                    #在复制的数据里记录位置数据
                    board[r][c]=100+len(revlst)

    maxrow=-1
    maxcol=-1
    maxpiece=101                        #最小值为101-100
    for r in range(8):
        for c in range(8):
            if board[r][c]>=maxpiece:   #必须是>=
                maxrow=r
                maxcol=c
                maxpiece = board[r][c]

    return maxrow,maxcol

def cleartishi(board):
    for r in range(8):
        for c in range(8):
            if board[r][c]>=100:
                board[r][c]=0


#main
pygame.init()
screen=pygame.display.set_mode([900,600])
surflist=[]
surflist.append(pygame.image.load("qipan9x6_b.png"))
surflist.append(pygame.image.load("qipan9x6_w.png"))
surflist.append(pygame.image.load("qizi_black.png"))
surflist.append(pygame.image.load("qizi_white.png"))
surflist.append(pygame.image.load("qizi_tishi.png"))

#初始化为人人对战
player2="computer"

#-1为黑棋，1为白棋，0无子，
# 大于100，说明该处落子合法，其值减去100就为该处落子后，可以翻转的对方棋子的数量
#piece为当前棋子的颜色
piece=-1
ppiece=-1
#生成棋盘数据
myboard=getNewBoard()
resetBoard(myboard)
drawscreen(screen,myboard,surflist,[-1,-1],piece)
#历史记录
boardhistory=[]
boardhistory.append([piece,myboard])

while True:
    for event in pygame.event.get():
        #开始等待玩家落子或选择按钮
        if event.type == pygame.QUIT:
            pygame.display.quit()
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            cursor_x=event.pos[0]                 #取得x坐标
            cursor_y=event.pos[1]
            row,col=cursor2button(cursor_x,cursor_y)
            #刷新屏幕
            drawscreen(screen,myboard,surflist,[row,col],piece)
            if row==-1 and col ==-1:
                #非法点击，提示音，进入下一次for循环
                continue
            if row==10 and col==0:
                #离开
                pygame.display.quit()
                print("Player select quit game")
                sys.exit()
            elif row==10 and col==1:
                # 悔棋
                if len(boardhistory)<=1:
                    continue
                boardhistory.pop()      #删除最后一个元素
                piece,tmplist=boardhistory.pop()
                myboard=tmplist[:]
                drawscreen(screen, myboard, surflist, [row, col], piece)

            elif row==10 and col==2:
                # 认输
                pass
            elif row==10 and col==3:
                # 重玩
                resetBoard(myboard)
                piece=-1
                drawscreen(screen, myboard, surflist, [-1, -1], piece)
                continue
            else:
                #棋盘上的点击
                reverlist=judge(myboard,piece,[row,col])
                if reverlist==False:
                    #不是合理位置，提示音，不对棋盘进行修改，直接进入下一次for循环
                    continue
                else:
                    #输入有效，执行修改棋盘的指令
                    myboard[row][col] = piece           #
                    for r, c in reverlist:
                        myboard[r][c] = piece
                    piece = -piece
                    drawscreen(screen, myboard, surflist, [row, col],piece)
                    #当前棋盘加入历史记录，只记录玩家步骤
                    boardhistory.append([piece, myboard])

                    if player2 == "computer":
                        # 电脑计算获得最佳落子位置
                        row, col = computerMove(myboard, piece)
                        drawscreen(screen, myboard, surflist, [row, col], piece)
                        time.sleep(2)
                        cleartishi(myboard)
                        drawscreen(screen, myboard, surflist, [row, col], piece)
                        if row == -1:
                            # 找不到可走的位置
                            #直接根据成绩判断输赢
                            pass
                        else:
                            #此时的位置一定能是合理位置，judge函数一定不会返回False
                            reverlist = judge(myboard, piece, [row, col])

                            myboard[row][col] = piece
                            for r, c in reverlist:
                                myboard[r][c] = piece
                            piece = -piece
                            drawscreen(screen, myboard, surflist, [row, col], piece)
