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