2016-07-13 2 views
0

저는 tic tac 발가락과 같은 작은 게임을 프로그래밍하여 파이썬에 대한 이해를 높이려고 노력해 왔습니다. 나는 처음부터 게임의 복사본을 만들었지 만 게임을위한 합리적인 인공 지능을 만드는 방법을 찾기 위해갔습니다. 미니 맥을 사용하여이 목표를 달성하기로 결정했습니다. 나는 알고리즘에 대한 튜토리얼을 발견하고 게임을 위해 그것을 주조하려고 시도했다.python - tic tac 발가락에 대한 minimax 알고리즘 모든 빈 공간에 동일한 기호를 채워서 보드 업데이트

그러나 코드가 실행되면 인공 지능의 첫 번째 회전이 시작됩니다. 보드에 남아있는 모든 빈 공간은 동일한 기호로 채워져 승리를 강요하여 게임을 실행 불가능하게 만듭니다.

익숙하지 않았고 알고리즘에 익숙하지 않았기 때문에 저는 YouTube 튜토리얼에서 코드를 가져 와서 게임용으로 사용할 수 있도록 편집했습니다. 여기

이 위의 코드

[1, 0, 0, 0, 0, 0, 0, 0, 0] 
[1, -1, 0, 0, 0, 0, 0, 0, 0] 
[1, -1, 1, 0, 0, 0, 0, 0, 0] 
[1, -1, 1, -1, 0, 0, 0, 0, 0] 
[1, -1, 1, -1, 1, 0, 0, 0, 0] 
[1, -1, 1, -1, 1, -1, 0, 0, 0] 
[1, -1, 1, -1, 1, -1, 1, 0, 0] 
[1, -1, 1, -1, 1, -1, 1, -1, 0] 
[1, -1, 1, -1, 1, -1, 1, -1, 1] 
[1, -1, 1, -1, 1, -1, 1, -1, -1] 
[1, -1, 1, -1, 1, -1, 1, 1, -1] 
[1, -1, 1, -1, 1, -1, 1, 1, 1] 
[1, -1, 1, -1, 1, -1, -1, 1, 1] 
[1, -1, 1, -1, 1, -1, -1, -1, 1] 
[1, -1, 1, -1, 1, -1, -1, -1, -1 
[1, -1, 1, -1, 1, 1, -1, -1, -1] 
[1, -1, 1, -1, 1, 1, 1, -1, -1] 
[1, -1, 1, -1, 1, 1, 1, 1, -1] 
[1, -1, 1, -1, 1, 1, 1, 1, 1] 
[1, -1, 1, -1, -1, 1, 1, 1, 1] 
[1, -1, 1, -1, -1, -1, 1, 1, 1] 
[1, -1, 1, -1, -1, -1, -1, 1, 1] 
[1, -1, 1, -1, -1, -1, -1, -1, 1 
[1, -1, 1, -1, -1, -1, -1, -1, - 
[1, -1, 1, 1, -1, -1, -1, -1, -1 
[1, -1, 1, 1, 1, -1, -1, -1, -1] 
[1, -1, 1, 1, 1, 1, -1, -1, -1] 
[1, -1, 1, 1, 1, 1, 1, -1, -1] 
[1, -1, 1, 1, 1, 1, 1, 1, -1] 
[1, -1, 1, 1, 1, 1, 1, 1, 1] 
[1, -1, -1, 1, 1, 1, 1, 1, 1] 
[1, -1, -1, -1, 1, 1, 1, 1, 1] 
[1, -1, -1, -1, -1, 1, 1, 1, 1] 
[1, -1, -1, -1, -1, -1, 1, 1, 1] 
[1, -1, -1, -1, -1, -1, -1, 1, 1 
[1, -1, -1, -1, -1, -1, -1, -1, 
[1, -1, -1, -1, -1, -1, -1, -1, 
[1, 1, -1, -1, -1, -1, -1, -1, - 
[1, 1, 1, -1, -1, -1, -1, -1, -1 
[1, 1, 1, 1, -1, -1, -1, -1, -1] 
[1, 1, 1, 1, 1, -1, -1, -1, -1] 
[1, 1, 1, 1, 1, 1, -1, -1, -1] 
[1, 1, 1, 1, 1, 1, 1, -1, -1] 
[1, 1, 1, 1, 1, 1, 1, 1, -1] 
[1, 1, 1, 1, 1, 1, 1, 1, 1] 
8 
[1, 1, 1, 1, 1, 1, 1, 1, 1] 
[1, 1, 1, 1, 1, 1, 1, 1, 1] 
The computer has won this game. 

어떤 제안에서 출력되는 코드

import random 
import time 
import sys 
from sys import maxsize 




#converts numbers from the board to X O and "" for printing out the board 
def numToSymbol(board): 
    visual = board 
    for i in range(0, 9): 
     if visual[i] == -1: 
      visual[i]= "X" 
     elif visual[i] == 1: 
      visual[i] = "O" 
     elif visual[i] == 0: 
      visual[i] = " " 
    return visual 


def symbolToNum(visual): 
    board = visual 
    for i in range(0, 9): 
     if board[i] == "X": 
      board[i] = -1 
     elif board[i] == "O": 
      board[i] = 1 
     elif board[i] == " ": 
      board[i] = 0 
    return board 


# prints the board, first coverting numbers throught numtoSymbol 
def drawBoard(): 
    visual = numToSymbol(board) 
    print(
     "|"+ str(visual[0]) + "|" + str(visual[1]) + "|" + str(visual[2]) + "| \n" 
     "-------\n" 
     "|"+ str(visual[3]) + "|" + str(visual[4]) + "|" + str(visual[5]) + "| \n" 
     "-------\n" 
     "|"+ str(visual[6]) + "|" + str(visual[7]) + "|" + str(visual[8]) + "| \n" 
     "-------") 
    symbolToNum(visual) 


# checks the possible options for 3 in a row and if any are all held by one side returns true 
def checkWin(board, winConditions, ai): 
    if ai == True: 
     win = 3 
    if ai == False: 
     win = -3 
    for row in winConditions: 
     checkA = board[row[0]] 
     checkB = board[row[1]] 
     checkC = board[row[2]] 
     if checkA + checkB + checkC == int(win): 
      return True 

    return False 

def checkDraw(board): 
    emptyTile = 9 
    for tile in board: 
     if tile != 0: 
      emptyTile -= 1 
    if emptyTile == 0: 
     completion(2) 

def availableMoves(board, bonus): 
    availableSlots = [] 
    for position in range(0,9): 
     if board[position] == 0: 
      availableSlots.append(position + bonus) 
    return availableSlots 



def playerTurn(board, remainingTurns): 
    board = board 
    checkDraw(board) 
    visual =drawBoard() 
    print("pick one of the available slots \n") 
    availableSlots = availableMoves(board, 1) 
    print(availableSlots) 
    choice = int(input('Select a tile from those shown above:\n')) -1 
    while True:  
     if 0 <= choice <= 8: 
      if board[choice] == 0: 
       board[choice] = -1 
       break 
      else: 
       choice = int(input('Select a tile from those shown above which has not already been selected:\n')) -1 
     else: 
      choice = int(input('Select a tile from those shown above:\n')) -1 
    visual = drawBoard() 
    if checkWin(board, winConditions, False) == True: 
     completion(0) 
    else: 
     aiTurn(board, remainingTurns - 1) 


class Node(object): 

    def __init__(self, remainingTurns, playerNum, board, value = 0): 
     self.depth = remainingTurns 
     self.playerNum = playerNum 
     self.board = board 
     self.value = value 
     self.moves = availableMoves(self.board, 0) 
     self.children = [] 
     self.createChildren() 

    def availableMoves(self, board): 
     self.availableSlots = [] 
     for position in range(0,9): 
      if board[position] == 0: 
       availableSlots.append(position) 
     return self.availableSlots 

    def winCheck(self, state, playerNum): 
     self.winConditions = [[0, 1, 2],[3, 4, 5],[6, 7, 8],[0, 3, 6],[1, 4, 7],[2, 5, 8],[0, 4, 8],[2, 4, 6]] 
     self.win = 3 
     for row in self.winConditions: 
      self.checkA = self.state[row[0]] 
      self.checkB = self.state[row[1]] 
      self.checkC = self.state[row[2]] 
      if self.checkA + self.checkB + self.checkC == int(self.win * self.playerNum): 
       return True 
     return False 

    def createChildren(self): 
     if self.depth > 0: 
      for i in self.moves: 
       self.state = self.board 
       self.state[i] = self.playerNum 
       print(board) 
       self.children.append(Node(self.depth - 1, self.playerNum * -1, self.state, self.realVal(self.state, self.playerNum))) 


    def realVal(self, value, playerNum): 
     value = self.winCheck(self.state, self.playerNum) 
     if value == True: 
      return maxsize * self.playerNum 
     else: 
      return 0 




def minimax(node, depth, playerNum): 
    if depth == 0 or abs(node.value) == maxsize: 
     return node.value 

    bestValue = maxsize * -playerNum 

    for i in range(len(node.children)): 
     child = node.children[i] 
     val = minimax(child, depth - 1, -playerNum) 
     if (abs(maxsize * playerNum - val) < abs(maxsize * playerNum - bestValue)): 
      bestValue = val 
    return bestValue 


def aiTurn(board, remainingTurns): 
    checkDraw(board) 
    print('Waiting for ai') 
    time.sleep(2) 
    board = board 
    state = board 
    currentPlayer = 1 
    tree = Node(remainingTurns, currentPlayer, state) 
    bestChoice = -100 
    bestValue = maxsize * -1 
    for i in range(len(tree.children)): 
     n_child = tree.children[i] 
     i_val = minimax(n_child, remainingTurns, -currentPlayer,) 
     if (abs(currentPlayer * maxsize - i_val) <= abs(currentPlayer * maxsize - bestValue)): 
      bestValue = i_val 
      bestChoice = i 
    print(bestChoice) 
    print(board) 
    #choice = minimax(tree, remainingTurns, 1) 
    board[bestChoice] = 1 
    print(board) 
    if checkWin(board, winConditions, True) == True: 
     completion(1) 
    else: 
     playerTurn(board, remainingTurns - 1) 



def completion(state): 
    if state == 1: 
     print('The computer has won this game.') 
     choice = str(input('press y if you would like to play another game; Press n if you would not \n')) 
     if choice == 'y' or choice == 'Y': 
      playGame() 
     else: 
      sys.exit() 
    if state == 0: 
     print('you win!') 
     choice = str(input('press y if you would like to play another game; Press n if you would not \n')) 
     if choice == 'y' or choice == 'Y': 
      playGame() 
     else: 
      sys.exit() 
    if state == 2: 
     print('you drew') 
     choice = str(input('press y if you would like to play another game; Press n if you would not \n')) 
     if choice == 'y' or choice == 'Y': 
      playGame() 
     else: 
      sys.exit()   




def playGame(): 
    global board 
    board = [0,0,0,0,0,0,0,0,0] 

    global winConditions 
    winConditions = [ 
       [0, 1, 2], 
       [3, 4, 5], 
       [6, 7, 8], 
       [0, 3, 6], 
       [1, 4, 7], 
       [2, 5, 8], 
       [0, 4, 8], 
       [2, 4, 6] 
       ] 


    global remainingTurns 
    remainingTurns = 9 
    playerFirst = random.choice([True, False]) 

    if playerFirst == True: 
     playerTurn(board, remainingTurns) 
    else: 
     aiTurn(board, remainingTurns) 


if __name__ == '__main__': 
    playGame() 

입니까?

답변

0

문제는 당신이 당신의 노드를 초기화하기 때 그냥 board의 심판 복사있다 :

self.board = board 

당신이 값 그렇지

self.board = board[::] 

모든 노드 객체가 같은 보드에 참조를 복사해야합니다 반면 : 세계적인 것.

관련 문제