def playerMovePre(self):
        global nowply, isGameing, playerCanMove, disboard
        if len(othello.canMove(disboard, 1)) == 0 and len(othello.canMove(disboard, -1)) == 0:
            blacknum = 0
            whitlenum = 0
            for i in range(8):
                for j in range(8):
                    if disboard[i][j] == 1:
                        blacknum += 1
                    elif disboard[i][j] == -1:
                        whitlenum += 1
            self.nowTurn.setText(" 경기 완료")
            if ply == 1:
                if blacknum > whitlenum:
                    self.winner.setText(" 흑, 플레이어가 이겼습니다.")
                elif blacknum < whitlenum:
                    self.winner.setText(" 백, AI가 이겼습니다.")
                else:
                    self.winner.setText(" 무승부 입니다.")
            elif ply == -1:
                if blacknum > whitlenum:
                    self.winner.setText(" 흑, AI가 이겼습니다.")
                elif blacknum < whitlenum:
                    self.winner.setText(" 백, 플레이어가 이겼습니다.")
                else:
                    self.winner.setText(" 무승부 입니다.")
            isGameing = False
        else:
            if len(othello.canMove(disboard, ply)) == 0:
                self.showMessageBox()
                nowply = -1 * nowply

                self.aiMove()
            else:
                playerCanMove = True
    def playerMove(self, plc):
        global cnt, nowply
        can = False
        for i in othello.canMove(disboard, ply):
            if plc == i:
                can = True
                break
        if can:
            othello.move(plc, disboard, ply)
            cnt += 1
            nowply = -1 * nowply
            self.nowTurn.setText(" 인공지능 턴, 생각중...")
            self.resetBoard(disboard, nowply, plc)

            self.aiMove()
예제 #3
0
    def resetBoard(self, board, now, last=None):
        if now == ply:
            self.nowTurn.setText(" 녹색칸중 하나를 고르세요.")
        else:
            self.nowTurn.setText(" 인공지능 생각중...")
        board = c.deepcopy(board)
        can = othello.canMove(board, now)
        for i in can:
            board[i[1]][i[0]] = 3

        blacknum = 0
        whitlenum = 0
        for i in range(8):
            for j in range(8):
                if board[i][j] == 1:
                    pixmap = QPixmap('./images/black.png')
                    self.buttonGroup[j][i].setPixmap(
                        pixmap.scaled(PieceWidth, PieceWidth,
                                      Qt.KeepAspectRatio))
                    blacknum += 1
                elif board[i][j] == -1:
                    pixmap = QPixmap('./images/white.png')
                    pixmap.scaled(PieceWidth, PieceWidth)
                    self.buttonGroup[j][i].setPixmap(
                        pixmap.scaled(PieceWidth, PieceWidth,
                                      Qt.KeepAspectRatio))
                    whitlenum += 1
                else:
                    pixmap = QPixmap('./images/white.png')
                    pixmap.scaled(PieceWidth, PieceWidth)
                    self.buttonGroup[j][i].setPixmap(
                        pixmap.scaled(0, 0, Qt.KeepAspectRatio))

                if board[i][j] == 3:
                    self.buttonGroup[j][i].setStyleSheet(
                        "background:rgb(125,250,76)")
                else:
                    self.buttonGroup[j][i].setStyleSheet(
                        "background:rgb(92,200,113)")
                if last != None and j == last[0] and i == last[1]:
                    self.buttonGroup[j][i].setStyleSheet(
                        "background:rgb(247,205,118)")
        if ply == 1:
            self.nowGame1.setText(" 흑, 내 점수:\n " + str(blacknum))
            self.nowGame2.setText(" 백, AI 점수:\n " + str(whitlenum))
        elif ply == -1:
            self.nowGame1.setText(" 흑, AI 점수:\n " + str(blacknum))
            self.nowGame2.setText(" 백, 내 점수:\n " + str(whitlenum))
    def aiMove(self):
        global cnt, disboard, nowply, ply, isGameing
        if len(othello.canMove(disboard, 1)) == 0 and len(othello.canMove(disboard, -1)) == 0:
            blacknum = 0
            whitlenum = 0
            for i in range(8):
                for j in range(8):
                    if disboard[i][j] == 1:
                        blacknum += 1
                    elif disboard[i][j] == -1:
                        whitlenum += 1
            self.nowTurn.setText(" 경기 완료")
            if ply == 1:
                if blacknum > whitlenum:
                    self.winner.setText(" 흑, 플레이어가 이겼습니다.")
                elif blacknum < whitlenum:
                    self.winner.setText(" 백, AI가 이겼습니다.")
                else:
                    self.winner.setText(" 무승부 입니다.")
            elif ply == -1:
                if blacknum > whitlenum:
                    self.winner.setText(" 흑, AI가 이겼습니다.")
                elif blacknum < whitlenum:
                    self.winner.setText(" 백, 플레이어가 이겼습니다.")
                else:
                    self.winner.setText(" 무승부 입니다.")

            isGameing = False
        else:
            if cnt == 0:
                cnt += 1

                othello.move([5, 4], disboard, nowply)
                nowply = -1 * nowply
                self.resetBoard(disboard, nowply, [5, 4])

                self.playerMovePre()
            # elif cnt == 1:
            #     cnt += 1
            #
            #     if disboard[4][5] == -1 * nowply or disboard[5][4] == -1 * nowply:
            #         othello.move([5, 5], disboard, nowply)
            #         nowply = -1 * nowply
            #         self.resetBoard(disboard, nowply, [5, 5])
            #     elif disboard[2][3] == -1 * nowply or disboard[3][2] == -1 * nowply:
            #         othello.move([2, 2], disboard, nowply)
            #         nowply = -1 * nowply
            #         self.resetBoard(disboard, nowply, [2, 2])
            #
            #     self.playerMovePre()
            else:
                if len(othello.canMove(disboard, nowply)) == 0:
                    self.showMessageBox()
                    nowply = -1 * nowply
                    self.resetBoard(disboard, nowply)

                    self.playerMovePre()

                else:

                    disboardTmp = c.deepcopy(disboard)

                    if nowply == -1:
                        for a in range(8):
                            for b in range(8):
                                disboardTmp[a][b] = -1 * disboardTmp[a][b]
                    mcts, canMov = self.searchValueDown(disboardTmp, 1, 1, cnt, searchDeep)
                    rsWR = mcts[0][0] / mcts[0][1]
                    for i in range(1, len(canMov)):
                        if rsWR < mcts[i][0] / mcts[i][1]:
                            rsWR = mcts[i][0] / mcts[i][1]
                    sameM = list()
                    sameNum = list()
                    for i in range(len(canMov)):
                        if rsWR == mcts[i][0] / mcts[i][1]:
                            sameM.append(mcts[i])
                            sameNum.append(i)
                    sameRandom = random.randrange(0, len(sameM))

                    self.aiWinRate.setText(
                        " 인공지능 예상 승률: " + str("{0:.2f}".format(mcts[sameNum[sameRandom]][0] / mcts[sameNum[sameRandom]][1] * 100)) + "%")
                    cnt += 1

                    othello.move(canMov[sameNum[sameRandom]], disboard, nowply)
                    nowply = -1 * nowply
                    self.resetBoard(disboard, nowply, canMov[sameNum[sameRandom]])

                    self.playerMovePre()
    def searchValueDown(self, nowBoard, color, mycolor, cnt, repeat):
        # 승률 반환 시킬 배열
        tmp = list()
        # 정책망에 넣기 위해 변환한 데이터 저장
        tmp1 = list()
        # 정책망용 데이터 빈곳 생성
        for i in range(2):
            tmp1.append([
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0], ])
        # 정책망용 데이터 대입
        for i in range(8):
            for j in range(8):
                if nowBoard[i][j] == 1:
                    tmp1[0][i][j] = 1
                elif nowBoard[i][j] == -1:
                    tmp1[1][i][j] = 1
        # 정책망 대입으로 값 도출
        aiResult = model.predict(np.array([tmp1]))
        # 움직일 수 있는 곳 저장
        canMove = othello.canMove(nowBoard, color)

        # 움직일 수 있는 곳이 없다, 상대편으로 넘긴다.
        if len(canMove) == 0:

            Wi = 0
            Ni = 0
            downBoard = c.deepcopy(nowBoard)
            downWN, _ = self.searchValueDown(downBoard, -1 * color, mycolor, cnt + 1, repeat)
            for j in downWN:
                Wi += j[0]
                Ni += j[1]
            tmp.append([Wi, Ni])
            return tmp, []
        # 움직일 수 있는 곳이 한곳보다 많다
        else:
            # 움직일 수 있는 곳들에 두었던 확률을 저장할 변수
            canMovA = list()

            # 움직일 수 있는 곳들에 두었던 확률 저장
            for a in canMove:
                canMovA.append(aiResult[0][a[0] + a[1] * 8])

            # 선별한 움직임을 저장할 변수
            canMovF = list()

            # 범위 안의 것을 저장
            for i in range(len(canMovA)):
                if SearchRange \
                        > abs(1 - canMovA[i]):
                    canMovF.append(canMove[i])

            # 만약 최소 갯수 이하라면 최소 갯수는 채우게 만듬
            if len(canMovF) == 0:
                canMovF = list()
                if len(canMovF) == 0:
                    if semimode:
                        rsD = 3
                        for i in range(len(canMovA)):
                            if rsD > abs(1 - canMovA[i]):
                                rsD = abs(1 - canMovA[i])
                        for i in range(len(canMovA)):
                            if rsD + SemiRange >= abs(1 - canMovA[i]):
                                canMovF.append(canMove[i])
                    else:
                        for z in range(len(canMovA)):
                            canMovF.append(canMove[z])

            # 둘려는 수가 한개인데 원턴킬당하면 빡치니까 전체 다 조사함
            if len(canMovF) == 1:
                downBoard = c.deepcopy(nowBoard)
                othello.move(canMovF[0], downBoard, color)

                # 원턴킬이 나면 무조건 0,1 반환시키게 검사
                onekill = False
                nextCanMove = othello.canMove(downBoard, -1 * color)
                for y in nextCanMove:
                    dnextBoard = c.deepcopy(downBoard)
                    othello.move(y, dnextBoard, -1 * color)
                    if len(othello.canMove(dnextBoard, -1 * color)) == 0 and len(
                            othello.canMove(dnextBoard, color)) == 0:
                        my = 0
                        en = 0
                        for j in downBoard:
                            for k in j:
                                if k == mycolor:
                                    my += 1
                                elif k == -1 * mycolor:
                                    en += 1
                        if my == 0:
                            onekill = True
                        break

                # 원턴킬 이면 이렇게 함
                if onekill:
                    canMovF = list()
                    for z in range(len(canMovA)):
                        canMovF.append(canMove[z])

            # 선별한 수들을 둠
            for i in canMovF:
                # 둔 다음을 저장할 변수
                downBoard = c.deepcopy(nowBoard)
                # 말을 움직임
                othello.move(i, downBoard, color)

                if repeat == 1:
                    aiInput = c.deepcopy(tmp1)
                    aitmp = [
                        [0, 0, 0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0, 0, 0], ]
                    aitmp[i[1]][i[0]] = 1
                    aiInput.append(aitmp)
                    aiResultValue = modelValue.predict(np.array([aiInput]))
                    tmp.append([aiResultValue[0][0], 1])
                elif len(othello.canMove(downBoard, -1 * color)) == 0 and len(othello.canMove(downBoard, color)) == 0:
                    my = 0
                    en = 0
                    for j in downBoard:
                        for k in j:
                            if k == mycolor:
                                my += 1
                            elif k == -1 * mycolor:
                                en += 1
                    if my > en:
                        tmp.append([1, 1])
                    elif my < en:
                        tmp.append([0, 1])
                    else:
                        tmp.append([0.5, 1])
                else:
                    # 원턴킬이 나면 무조건 0,1 반환시키게 검사
                    onekill = False
                    nextCanMove = othello.canMove(downBoard, -1 * color)
                    for y in nextCanMove:
                        dnextBoard = c.deepcopy(downBoard)
                        othello.move(y, dnextBoard, -1 * color)
                        if len(othello.canMove(dnextBoard, -1 * color)) == 0 and len(
                                othello.canMove(dnextBoard, color)) == 0:
                            my = 0
                            en = 0
                            for j in downBoard:
                                for k in j:
                                    if k == mycolor:
                                        my += 1
                                    elif k == -1 * mycolor:
                                        en += 1
                            if my == 0:
                                onekill = True
                            break


                    # 원턴킬 이면 이렇게 함
                    if onekill:
                        tmp.append([0, 1])
                    else:
                        Wi = 0
                        Ni = 0
                        downWN, _ = self.searchValueDown(downBoard, -1 * color, mycolor, cnt + 1, repeat - 1)
                        for j in downWN:
                            Wi += j[0]
                            Ni += j[1]
                        tmp.append([Wi, Ni])
            return tmp, canMovF
예제 #6
0
def searchDown(nowBoard, color, mycolor, cnt):
    tmp = list()
    tmp1 = list()
    for i in range(2):
        tmp1.append([
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0], ])

    for i in range(8):
        for j in range(8):
            if nowBoard[i][j] == 1:
                tmp1[0][i][j] = 1
            elif nowBoard[i][j] == -1:
                tmp1[1][i][j] = 1
    aiResult = model.predict(np.array([tmp1]))
    canMove = othello.canMove(nowBoard, color)
    if len(canMove) == 0:
        Wi = 0
        Ni = 0
        downBoard = c.deepcopy(nowBoard)
        downWN, _ = searchDown(downBoard, -1 * color, mycolor, cnt + 1)
        for j in downWN:
            Wi += j[0]
            Ni += j[1]
        tmp.append([Wi, Ni])
        return tmp, []
    else:
        canMovA = list()
        for a in canMove:
            canMovA.append(aiResult[0][a[0] + a[1] * 8])
        canMovF = list()

        for i in range(len(canMovA)):
            if 0.71 > abs(1 - canMovA[i]):
                canMovF.append(canMove[i])

        if len(canMovF) == 0:
            rsD = 3
            for i in range(len(canMovA)):
                if rsD > abs(1 - canMovA[i]):
                    rsD = abs(1 - canMovA[i])
            for i in range(len(canMovA)):
                if rsD + 0.0000000001 > abs(1 - canMovA[i]):
                    canMovF.append(canMove[i])

        for i in canMovF:
            downBoard = c.deepcopy(nowBoard)
            othello.move(i, downBoard, color)
            if len(othello.canMove(downBoard, -1 * color)) == 0 and len(othello.canMove(downBoard, color)) == 0:
                my = 0
                en = 0
                for j in downBoard:
                    for k in j:
                        if k == mycolor:
                            my += 1
                        elif k == -1 * mycolor:
                            en += 1
                if my > en:
                    tmp.append([1, 1])
                elif my < en:
                    tmp.append([0, 1])
                else:
                    tmp.append([0.5, 1])
            else:
                Wi = 0
                Ni = 0
                downWN, _ = searchDown(downBoard, -1 * color, mycolor, cnt + 1)
                for j in downWN:
                    Wi += j[0]
                    Ni += j[1]
                tmp.append([Wi, Ni])
        return tmp, canMovF
예제 #7
0
                tmp.append([Wi, Ni])
        return tmp, canMovF


if __name__ == "__main__":
    # 보드 생성

    disboard, cnt = othello.gameInit()
    nowply = 1

    ply = othello.intScan("플레이 색을 고르세요 흑1 백-1 : ")

    while True:
        if nowply == ply:
            print("==========플레이어 턴==========")
            if len(othello.canMove(disboard, nowply)) == 0:
                print("스킵")
            else:
                othello.printBoard(disboard, othello.canMove(disboard, ply))

                while True:
                    plc = othello.giboParse(input("기보를 입력하세요 ex)a2 : "))
                    can = False
                    for i in othello.canMove(disboard, ply):
                        if plc == i:
                            can = True
                            break
                    if can:
                        othello.move(plc, disboard, ply)
                        cnt += 1
                        break