예제 #1
0
 def __init__(self, initialgamestate, aistonetype, plydepth,
              tilesearchrange, analyzerparameter):
     BaseAI.__init__(self, initialgamestate, aistonetype)
     self.EnemyStoneType = "black" if self.AIStoneType == "white" else "white"
     self.PlyDepth = plydepth
     self.OpenSearchRange = tilesearchrange
     self.analyzerparameter = analyzerparameter
예제 #2
0
    def checkforwork(self):
        while True:
            data = self.InputQueue.get()
            if data[0] == "START":
                board = data[1]

                self.aiutils = BaseAI(board, self.AIStoneType)
                hashtable_size = []
                #print("*" * 10)
                self.Zobrist_Hash_Table = []
                for depth in range(1, self.PlyDepth + 1):
                    self.TerminalNodes = 0
                    startnode = Node(None, None, None, -10000000, 10000000)
                    self.alphabeta(self.aiutils.duplicateboard(board),
                                   startnode, depth, True,
                                   self.OpenSearchRange, self.CurrentDepth)
                    self.CurrentDepth += 1
                    #print("DEPTH", depth, "HASH SIZE:", len(self.Zobrist_Hash_Table))
                    hashtable_size.append(len(self.Zobrist_Hash_Table))

                best = max(startnode.children, key=lambda x: x.value)
                #print("RESULT:", best.position, best.value, "ITERATIONS:", self.Iterations, "TERMINAL_NODES:", self.TerminalNodes)
                self.OutputQueue.put(
                    ((best.value, best.position), hashtable_size))
            elif data == "EXIT":
                break
예제 #3
0
    def __init__(self, initialgamestate, aistonetype, timelimit, remote=True):
        BaseAI.__init__(self, initialgamestate, aistonetype)
        self.EnemyStoneType = "black" if self.AIStoneType == "white" else "white"
        self.This2ActuatorQ = multiprocessing.Queue()
        self.Actuator2ThisQ = multiprocessing.Queue()
        self.TimeLimit = timelimit
        self.ReportHook = lambda x: None
        self.Process = None
        self.datalist = []
        self.PID = None

        self.Remote = remote
예제 #4
0
 def CheckForWork(self, board):
     self.aiutils = BaseAI(board, self.AIStoneType)
     startnode = Node(None, None, None)
     self.AlphaBeta(self.aiutils.duplicateboard(board), startnode,
                    self.PlyDepth, True, -10000000, 10000000,
                    self.OpenSearchRange)
     result = []
     for items in startnode.children:
         result.append((items.value, items.position))
     result = sorted(result, key=lambda x: x[0], reverse=True)
     try:
         return result[0]
     except:
         print("Damn an error has occured")
         print("result:", result)
         print("startnode.children:", startnode.children)
         print("getopenmoves of default board:",
               self.aiutils.getopenmoves())
예제 #5
0
    def __init__(self,
                 initialgamestate,
                 aistonetype,
                 plydepth,
                 tilesearchrange,
                 use_xta,
                 xta_coefficient,
                 remote=True):
        BaseAI.__init__(self, initialgamestate, aistonetype)
        self.EnemyStoneType = "black" if self.AIStoneType == "white" else "white"
        self.PlyDepth = plydepth
        self.This2ActuatorQ = multiprocessing.Queue()
        self.Actuator2ThisQ = multiprocessing.Queue()
        self.OpenSearchRange = tilesearchrange

        self.ReportHook = lambda x: None
        self.Process = None
        self.datalist = []
        self.PID = None
        self.Use_XTA = True if use_xta else False
        self.XTA_Coefficient = xta_coefficient

        self.Remote = remote
예제 #6
0
    def runmcts(self, startnode):
        starttime = time.time()
        node = startnode
        iters = 0

        while True:
            if time.time() - starttime > self.TimeLimit:
                break
            else:
                boardg = BaseAI(node.GameState, self.AIStoneType)
                newb = boardg.duplicateboard(node.GameState)
                while True:
                    if node.Children:
                        node = node.getbestchild()
                    else:
                        break
                if boardg.getlimitedopenmoves(node.GameState):
                    m = random.choice(
                        boardg.getlimitedopenmoves(node.GameState))
                    newb.addstone(m, newb.Turn)
                    g = Node(m, newb, parent=node)
                    newb = boardg.duplicateboard(newb)
                    node = g
                    result = 0
                    while True:
                        if boardg.getlimitedopenmoves(newb):
                            newb.addstone(
                                random.choice(
                                    boardg.getlimitedopenmoves(newb)),
                                newb.Turn)
                            check = WinChecker(newb)
                            if check.check(self.AIStoneType):
                                result = 1
                                break
                            elif check.check(self.EnemyStoneType):
                                result = -1
                                break
                            else:
                                break

                        else:
                            break
                    node.update(result)
            iters += 1
        print("iters", iters)
        return 0
예제 #7
0
    def AlphaBeta(self, board, node, depth, isMaximizingPlayer, alpha, beta,
                  tilesearchrange):
        #print("CURRENT POSITION",move,isMaximizingPlayer)
        if WinChecker(board).checkboth() or depth == 0 or BaseAI(
                board, self.AIStoneType).getopenmoves() == 0:
            ganalyst = Analyzer(board, self.analyzer[0], self.analyzer[1],
                                self.analyzer[2], self.analyzer[3])
            return ganalyst.grader(self.AIStoneType) - ganalyst.grader(
                self.EnemyStoneType)

        if isMaximizingPlayer:
            v = -10000000
            for moves in self.aiutils.getlimitedopenmoves(
                    board, self.OpenSearchRange):
                g = Node(moves, None, node)
                dupedboard = self.aiutils.duplicateboard(board)
                dupedboard.addstone(moves, self.AIStoneType)
                v = max(
                    v,
                    self.AlphaBeta(dupedboard, g, depth - 1, False, alpha,
                                   beta, tilesearchrange))
                g.value = v
                alpha = max(alpha, v)
                if beta <= alpha:
                    #print("BETA CUTOFF")
                    break
            return v
        else:
            v = 10000000
            for moves in self.aiutils.getlimitedopenmoves(
                    board, self.OpenSearchRange):
                g = Node(moves, None, node)
                dupedboard = self.aiutils.duplicateboard(board)
                dupedboard.addstone(moves, self.AIStoneType)
                v = min(
                    v,
                    self.AlphaBeta(dupedboard, g, depth - 1, True, alpha, beta,
                                   tilesearchrange))
                g.value = v
                beta = min(beta, v)
                if beta <= alpha:
                    #print("ALPHA CUTOFF")
                    break
            return v
예제 #8
0
class AlphaBetaActuator():
    def __init__(self, aistonetype, depth, tilesearchrange, analyzerparameter):
        self.AIStoneType = aistonetype
        self.EnemyStoneType = "black" if self.AIStoneType == "white" else "white"
        self.PlyDepth = depth
        self.OpenSearchRange = tilesearchrange
        self.analyzer = analyzerparameter

    def CheckForWork(self, board):
        self.aiutils = BaseAI(board, self.AIStoneType)
        startnode = Node(None, None, None)
        self.AlphaBeta(self.aiutils.duplicateboard(board), startnode,
                       self.PlyDepth, True, -10000000, 10000000,
                       self.OpenSearchRange)
        result = []
        for items in startnode.children:
            result.append((items.value, items.position))
        result = sorted(result, key=lambda x: x[0], reverse=True)
        try:
            return result[0]
        except:
            print("Damn an error has occured")
            print("result:", result)
            print("startnode.children:", startnode.children)
            print("getopenmoves of default board:",
                  self.aiutils.getopenmoves())

    def AlphaBeta(self, board, node, depth, isMaximizingPlayer, alpha, beta,
                  tilesearchrange):
        #print("CURRENT POSITION",move,isMaximizingPlayer)
        if WinChecker(board).checkboth() or depth == 0 or BaseAI(
                board, self.AIStoneType).getopenmoves() == 0:
            ganalyst = Analyzer(board, self.analyzer[0], self.analyzer[1],
                                self.analyzer[2], self.analyzer[3])
            return ganalyst.grader(self.AIStoneType) - ganalyst.grader(
                self.EnemyStoneType)

        if isMaximizingPlayer:
            v = -10000000
            for moves in self.aiutils.getlimitedopenmoves(
                    board, self.OpenSearchRange):
                g = Node(moves, None, node)
                dupedboard = self.aiutils.duplicateboard(board)
                dupedboard.addstone(moves, self.AIStoneType)
                v = max(
                    v,
                    self.AlphaBeta(dupedboard, g, depth - 1, False, alpha,
                                   beta, tilesearchrange))
                g.value = v
                alpha = max(alpha, v)
                if beta <= alpha:
                    #print("BETA CUTOFF")
                    break
            return v
        else:
            v = 10000000
            for moves in self.aiutils.getlimitedopenmoves(
                    board, self.OpenSearchRange):
                g = Node(moves, None, node)
                dupedboard = self.aiutils.duplicateboard(board)
                dupedboard.addstone(moves, self.AIStoneType)
                v = min(
                    v,
                    self.AlphaBeta(dupedboard, g, depth - 1, True, alpha, beta,
                                   tilesearchrange))
                g.value = v
                beta = min(beta, v)
                if beta <= alpha:
                    #print("ALPHA CUTOFF")
                    break
            return v
예제 #9
0
class AlphaBetaActuator:
    def __init__(self, inputqueue, outputqueue, aistonetype, depth,
                 tilesearchrange, use_xta, xta_coefficient):
        self.AIStoneType = aistonetype
        self.EnemyStoneType = "black" if self.AIStoneType == "white" else "white"
        self.InputQueue = inputqueue
        self.OutputQueue = outputqueue
        self.PlyDepth = depth
        self.OpenSearchRange = tilesearchrange
        self.aiutils = None
        self.Matrix = generate_random_matrix(
            25
        )  # Select default Zobrist matrix size as 25, change if necessary
        self.Zobrist_Hash_Table = [
        ]  # Moved the below 2 lines of code up to __init__ to avoid PEP warnings
        self.CurrentDepth = 1
        self.Iterations = 0
        self.TerminalNodes = 0
        self.Use_XTA = True if use_xta else False
        self.XTA_Coefficient = xta_coefficient
        self.checkforwork()

    def checkforwork(self):
        while True:
            data = self.InputQueue.get()
            if data[0] == "START":
                board = data[1]

                self.aiutils = BaseAI(board, self.AIStoneType)
                hashtable_size = []
                #print("*" * 10)
                self.Zobrist_Hash_Table = []
                for depth in range(1, self.PlyDepth + 1):
                    self.TerminalNodes = 0
                    startnode = Node(None, None, None, -10000000, 10000000)
                    self.alphabeta(self.aiutils.duplicateboard(board),
                                   startnode, depth, True,
                                   self.OpenSearchRange, self.CurrentDepth)
                    self.CurrentDepth += 1
                    #print("DEPTH", depth, "HASH SIZE:", len(self.Zobrist_Hash_Table))
                    hashtable_size.append(len(self.Zobrist_Hash_Table))

                best = max(startnode.children, key=lambda x: x.value)
                #print("RESULT:", best.position, best.value, "ITERATIONS:", self.Iterations, "TERMINAL_NODES:", self.TerminalNodes)
                self.OutputQueue.put(
                    ((best.value, best.position), hashtable_size))
            elif data == "EXIT":
                break

    def alphabeta(self, board, node, depth, ismaximizingplayer,
                  tilesearchrange, originaldepth):
        self.Iterations += 1
        # Hash table is disabled for now until I'm sure it helps with performance
        """hashval = board.generatehash(self.Matrix)
        for hash in self.Zobrist_Hash_Table:
            if hash[0] == hashval:
                if hash[2] < originaldepth - 1:
                    self.Zobrist_Hash_Table.remove(hash)
                else:
                    return hash[1]"""
        # print("CURRENT POSITION",move,isMaximizingPlayer)
        if WinChecker(board).checkboth() or depth == 0:
            """hashval = board.generatehash(self.Matrix)
            for hash in self.Zobrist_Hash_Table:
                if hash[0] == hashval:
                    if hash[2] < originaldepth-1:
                        self.Zobrist_Hash_Table.remove(hash)
                    else:
                        return hash[1]"""
            ganalyst = Analyzer(board)
            aiscore = ganalyst.grader(self.AIStoneType)
            enemyscore = ganalyst.grader(self.EnemyStoneType)
            if self.Use_XTA:
                coefficient = ExtensiveAnalysis(board).grader(self.AIStoneType)
                # Hash table is disabled for now until I'm sure it helps with performance
                # self.Zobrist_Hash_Table.append((hashval, aiscore - enemyscore - (self.XTA_Coefficient*coefficient), originaldepth))
                return aiscore - enemyscore - (self.XTA_Coefficient *
                                               coefficient)

            else:
                # Hash table is disabled for now until I'm sure it helps with performance
                #self.Zobrist_Hash_Table.append((hashval, aiscore - enemyscore, originaldepth))
                return aiscore - enemyscore
        if ismaximizingplayer:
            v = -10000000
            for move in self.aiutils.getlimitedopenmoves(
                    board, self.OpenSearchRange):
                g = Node(move, None, node, node.alpha, node.beta)
                if depth == 1: self.TerminalNodes += 1
                dupedboard = self.aiutils.duplicateboard(board)
                dupedboard.addstone(move, self.AIStoneType)
                v = max(
                    v,
                    self.alphabeta(dupedboard, g, depth - 1, False,
                                   tilesearchrange, originaldepth))
                g.value = v
                node.alpha = max(node.alpha, v)
                if node.beta <= node.alpha:
                    break
            return v
        else:
            v = 10000000
            for move in self.aiutils.getlimitedopenmoves(
                    board, self.OpenSearchRange):
                g = Node(move, None, node, node.alpha, node.beta)
                if depth == 1: self.TerminalNodes += 1
                dupedboard = self.aiutils.duplicateboard(board)
                dupedboard.addstone(move, self.EnemyStoneType)
                v = min(
                    v,
                    self.alphabeta(dupedboard, g, depth - 1, True,
                                   tilesearchrange, originaldepth))
                g.value = v
                node.beta = min(node.beta, v)
                if node.beta <= node.alpha:
                    break
            return v