Пример #1
0
    def nxtABMv(self, nodeName, currentState, nodeType, current_depth, valid_pits_list, play_turn, alpha, beta):
        returnValList = []
        returnStateList = []
        currentState.depth = current_depth
        global_ret_state = currentState
        eval_val = self.evaluate(self.playTurn, currentState)
        game_end = False
        if not valid_pits_list:
            game_end = True
            #self.tlfobj.write('endgame\n')
        '''
        if current_depth ==self.maxDepth and currentState.freeTurn:
            self.tlfobj.write('last depth and freeturn\n')
        elif current_depth==self.maxDepth and not currentState.freeTurn:
            self.tlfobj.write('last depth and not freeturn\n')
        elif current_depth<self.maxDepth and currentState.freeTurn:
            self.tlfobj.write('intr depth and freeturn\n')
        elif current_depth<self.maxDepth and not currentState.freeTurn:
            self.tlfobj.write('intr depth and not freeturn\n')'''
        

        method.write_entry_log(self.tlfobj, param.TASK_OPTION['ALPHABETA'], nodeName, nodeType, self.maxDepth, current_depth, currentState.freeTurn, eval_val, alpha, beta, game_end)
        if not valid_pits_list:
            #self.tlfobj.write('gameend\n')
            return eval_val, currentState, param.NOT_PRUNED
        if current_depth == self.maxDepth:
            # as lst depth evaluate and print
            if not currentState.freeTurn:
                return eval_val, currentState, param.NOT_PRUNED
            else:
                if nodeType == param.MAX_NODE:
                    v = param.PLUS_INFINITY
                else:
                    v = param.MINUS_INFINITY

                for pit_id in valid_pits_list:
                    alpha_update_pending = False
                    beta_update_pending = False
                    child_state = self.nextState(currentState, play_turn, pit_id)
                    child_valid_pits_list = []
                    next_depth = current_depth
                    #if child_state.freeTurn:
                        #calculate the valid_pits_list for the child
                    child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                            
                    val, ret_child_state, is_pruned = self.nxtABMv(method.get_node_name(play_turn, pit_id), child_state, nodeType, \
                                                        next_depth, child_valid_pits_list, play_turn, alpha, beta)
                    
                    if nodeType == param.MAX_NODE:
                        #v = min(v, val)  #as freeturn doing opposite
                        if val < v:
                            v = val
                            ret_state = ret_child_state
                    else:
                        #v = max(v, val)
                        if val > v:
                            v = val
                            ret_state = ret_child_state

                    if not child_valid_pits_list:
                        val = self.evaluate(self.playTurn, child_state)
                        ret_state = child_state
                        #print the state
                        #check for alpha beta values
                        str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + ','+ str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                        #self.tlfobj.write('freeturn\n')
                        #method.write_entry_log(self.tlfobj, param.TASK_OPTION['MINIMAX'], nodeName, nodeType, self.maxDepth, current_depth, currentState.freeTurn, eval_val, alpha=None, beta=None)
                        self.tlfobj.write(str_arr)

                    #check for pruning!!
                    if nodeType == param.MAX_NODE:
                            #as it is free turn we will update its beta value
                        prune_needed = method.should_prune(alpha, v)
                        beta_update_pending = True
                    else:
                        prune_needed = method.should_prune(v, beta)
                        alpha_update_pending = True
                    
                    if prune_needed:
                        str_arr = str(nodeName) + ',' + str(current_depth) + ',' + str(v) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                        self.tlfobj.write(str_arr)
                        if alpha_update_pending:
                            alpha = v
                        else:
                            beta = v
                        return method.get_eval(nodeType, alpha, beta, currentState.freeTurn), None, param.PRUNED
                    else:                                                                          
                        if nodeType == param.MAX_NODE:
                            # buts its a freeturn so update beta
                            if beta > v:
                                beta = v
                                global_ret_state = ret_state
                        else:
                            if alpha < v:
                                alpha = v
                                global_ret_state = ret_state   

                    str_arr = str(nodeName) + ',' + str(current_depth) + ',' + str(v) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                    self.tlfobj.write(str_arr)
                #If code reaches here then we will return the correct value
                ret_state = global_ret_state
                if (global_ret_state.depth > currentState.depth) and currentState.depth!=0:
                    ret_state = currentState
                elif (global_ret_state == currentState) and currentState.depth!=0:
                    ret_state = currentState
                return v, ret_state, param.NOT_PRUNED
                     
        #if it is a intermediatory node
        else:
            
            if currentState.freeTurn:
                #print 'inter free turn'
                if nodeType == param.MAX_NODE:
                    v = param.PLUS_INFINITY
                else:
                    v = param.MINUS_INFINITY
                
                for pit_id in valid_pits_list:
                    alpha_update_pending = False
                    beta_update_pending = False
                    opponent_turn = method.get_opponent_id(play_turn)
                    child_state = self.nextState(currentState, play_turn, pit_id)
                    #child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                    next_depth = current_depth
                    next_node_type = nodeType
                    if child_state.freeTurn:
                        child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                        next_play_turn = play_turn
  
                    else:
                        child_valid_pits_list = child_state.players[opponent_turn].get_valid_list()
                        next_play_turn = opponent_turn

                    val, ret_child_state, is_pruned = self.nxtABMv(method.get_node_name(play_turn, pit_id), child_state, next_node_type,\
                                next_depth, child_valid_pits_list, next_play_turn, alpha, beta)
                    
                    #self.tlfobj.write('value got '+str(val)+'\n')
                    if nodeType == param.MAX_NODE:
                        #v = min(v, val)  #as freeturn doing opposite
                        if val < v:
                            v = val
                            ret_state = ret_child_state
                    else:
                        #v = max(v, val)
                        if val > v:
                            v = val
                            ret_state = ret_child_state

                    #self.tlfobj.write('value chosen '+str(v)+'\n')
                    if not child_valid_pits_list:
                        val = self.evaluate(self.playTurn, child_state)
                        ret_state = child_state
                        is_pruned = False
                        #print the state
                        #str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + '\n'
                        str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                        self.tlfobj.write(str_arr)
                    
                    #check for pruning!!
                    if nodeType == param.MAX_NODE:
                            #as it is free turn we will update its beta value
                        prune_needed = method.should_prune(alpha, v)
                        beta_update_pending = True
                    else:
                        prune_needed = method.should_prune(v, beta)
                        alpha_update_pending = True
                    
                    if prune_needed:
                        #print nodeName, ',', current_depth, ',', val, ',',method.print_alphabeta(alpha),',', method.print_alphabeta(beta)
                        str_arr = str(nodeName) + ',' + str(current_depth) + ',' + str(v) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                        self.tlfobj.write(str_arr)
                        if alpha_update_pending:
                            alpha = v
                        else:
                            beta = v
                        return method.get_eval(nodeType, alpha, beta, currentState.freeTurn), None, param.PRUNED
                    
                    else:                                                                          
                        if nodeType == param.MAX_NODE:
                            # buts its a freeturn so update beta
                            if beta > v:
                                beta = v
                                global_ret_state = ret_state
                        else:
                            if alpha < v:
                                alpha = v
                                global_ret_state = ret_state                       
                    #print nodeName, ',', current_depth, ',', method.print_alphabeta(method.get_eval(nodeType, alpha, beta, currentState.freeTurn)), ',',method.print_alphabeta(alpha),',', method.print_alphabeta(beta)
                    str_arr = str(nodeName) + ',' + str(current_depth) + ',' + str(v) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                    self.tlfobj.write(str_arr)
                    
                ret_state = global_ret_state
                if (global_ret_state.depth > currentState.depth) and currentState.depth!=0:
                    ret_state = currentState
                elif (global_ret_state == currentState) and currentState.depth!=0:
                    ret_state = currentState
                return v, ret_state, param.NOT_PRUNED    
                    
            
            else:
                if nodeType == param.MAX_NODE:
                    v = param.MINUS_INFINITY
                else:
                    v = param.PLUS_INFINITY

                for pit_id in valid_pits_list:
                    alpha_update_pending = False
                    beta_update_pending = False
                    opponent_turn = method.get_opponent_id(play_turn)
                    child_state = self.nextState(currentState, play_turn, pit_id)
                    #print 'child_state\n',child_state.print_info()
                    if child_state.freeTurn:
                        child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                        next_play_turn = play_turn
                        next_depth = current_depth+1
                    else:
                        child_valid_pits_list = child_state.players[opponent_turn].get_valid_list()
                        next_play_turn = opponent_turn
                        next_depth = current_depth+1


                    val, ret_child_state, is_pruned = self.nxtABMv(method.get_node_name(play_turn, pit_id), child_state, method.alternate_type(nodeType),\
                                next_depth, child_valid_pits_list, next_play_turn, alpha, beta)
                    
                    if nodeType == param.MAX_NODE:
                        #v = max(v, val)
                        if val> v:
                            v = val
                            ret_state = ret_child_state
                    else:
                        #v = min(v, val)
                        if val<v:
                            v = val
                            ret_state = ret_child_state 

                    if not child_valid_pits_list:
                        val = self.evaluate(self.playTurn, child_state)
                        ret_state = child_state
                        is_pruned = False
                        #print the state
                        #str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + '\n'
                        str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                        self.tlfobj.write(str_arr)

                    
                    if nodeType == param.MAX_NODE:
                            #as it is not free turn we will update its alpha value
                        prune_needed = method.should_prune(v, beta)
                        alpha_update_pending = True
                    else:
                        prune_needed = method.should_prune(alpha, v)
                        beta_update_pending = True
                    
                    if prune_needed:
                        #print nodeName, ',', current_depth, ',', val, ',',method.print_alphabeta(alpha),',', method.print_alphabeta(beta)
                        str_arr = str(nodeName) + ',' + str(current_depth) + ',' + str(v) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                        self.tlfobj.write(str_arr)
                        if alpha_update_pending:
                            alpha = v
                        else:
                            beta = v
                        return method.get_eval(nodeType, alpha, beta, currentState.freeTurn), None, param.PRUNED
                    else:                                                                          
                        if nodeType == param.MAX_NODE:
                            # buts it is not a freeturn so update beta
                            #self.tlfobj.write(str(val) + 'updating alpha\n')
                            if alpha < v:
                                #self.tlfobj.write('updated')
                                alpha = v
                                global_ret_state = ret_state
                        else:
                            #self.tlfobj.write(str(val) + 'updating beta\n')
                            if beta > v:
                            #    self.tlfobj.write('updated')
                                beta = v                     
                                global_ret_state = ret_state
                    #print nodeName, ',', current_depth, ',', method.print_alphabeta(method.get_eval(nodeType, alpha, beta, currentState.freeTurn)), ',',method.print_alphabeta(alpha),',', method.print_alphabeta(beta)
                    str_arr = str(nodeName) + ',' + str(current_depth) + ',' + str(v) + ',' + str(method.print_alphabeta(alpha)) + ',' + str(method.print_alphabeta(beta)) + '\n'
                    self.tlfobj.write(str_arr)

                # after visiting all child and no pruning done
                ret_state = global_ret_state
                if (global_ret_state.depth > currentState.depth) and currentState.depth!=0:
                    ret_state = currentState
                elif (global_ret_state == currentState) and currentState.depth!=0:
                    ret_state = currentState
                #return method.get_eval(nodeType, alpha, beta, currentState.freeTurn), ret_state, param.NOT_PRUNED
                return v, ret_state, param.NOT_PRUNED
Пример #2
0
    def nxtMnmxMv(self, nodeName, currentState, nodeType, current_depth, valid_pits_list, play_turn):
        #print nodeName, currentState.print_info()
        returnValList = []
        returnStateList = []
        currentState.depth = current_depth
        eval_val = self.evaluate(self.playTurn, currentState)
        ret_val = eval_val
        ret_state = currentState
        game_end = False
        if not valid_pits_list:
            game_end = True
            #self.tlfobj.write('endgame\n')
        '''        
        if current_depth ==self.maxDepth and currentState.freeTurn:
            self.tlfobj.write('last depth and freeturn\n')
        elif current_depth==self.maxDepth and not currentState.freeTurn:
            self.tlfobj.write('last depth and not freeturn\n')
        elif current_depth<self.maxDepth and currentState.freeTurn:
            self.tlfobj.write('intr depth and freeturn\n')
        elif current_depth<self.maxDepth and not currentState.freeTurn:
            self.tlfobj.write('intr depth and not freeturn\n')
        '''        
        method.write_entry_log(self.tlfobj, param.TASK_OPTION['MINIMAX'], nodeName, nodeType, self.maxDepth, current_depth, currentState.freeTurn, eval_val, alpha=None, beta=None, game_end = game_end)
        if not valid_pits_list:
            #self.tlfobj.write('gameend\n')
            return eval_val, currentState
        if current_depth == self.maxDepth:
            if not currentState.freeTurn:
                return eval_val, currentState
            else:
                for pit_id in valid_pits_list:
                    child_state = self.nextState(currentState, play_turn, pit_id)
                    child_valid_pits_list = []
                    next_depth = current_depth
                    #if child_state.freeTurn:
                        #calculate the valid_pits_list for the child
                    child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                    val, ret_state = self.nxtMnmxMv(method.get_node_name(play_turn, pit_id), \
                        child_state, nodeType, next_depth, child_valid_pits_list, play_turn)

                    if not child_valid_pits_list:
                        val = self.evaluate(self.playTurn, child_state)
                        ret_state = child_state
                        #print the state
                        str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + '\n'
                        #self.tlfobj.write('freeturn\n')
                        #method.write_entry_log(self.tlfobj, param.TASK_OPTION['MINIMAX'], nodeName, nodeType, self.maxDepth, current_depth, currentState.freeTurn, eval_val, alpha=None, beta=None)
                        self.tlfobj.write(str_arr)

                    returnValList.append(val)
                    returnStateList.append(ret_state)
                    #print nodeName, ',',current_depth, ',', method.return_opposite_type(nodeType, returnValList)
                    #printing opposite because its freeturn
                    str_arr = str(nodeName) + ',' + str(current_depth) +','+ str(method.return_opposite_type(nodeType, returnValList)) + '\n'
                    #print str_arr
                    self.tlfobj.write(str_arr)

                #if not returnValList:
                #    returnValList.append(ret_val)
                #    returnStateList.append(currentState)
                ret_val = method.return_opposite_type(nodeType, returnValList)
                idx = returnValList.index(ret_val) 
                if (returnStateList[idx].depth > currentState.depth) and currentState.depth!=0:
                    ret_state = currentState
                else:
                    ret_state = returnStateList[idx]
                return ret_val,ret_state
        
        else:
        
            if currentState.freeTurn:
                #it will pass same nodetype, depth to child
                #valid pit list should from the same play_turn as it will now be extended
                for pit_id in valid_pits_list:
                    opponent_turn = method.get_opponent_id(play_turn)
                    child_state = self.nextState(currentState, play_turn, pit_id)
                    #child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                    next_depth = current_depth
                    next_node_type = nodeType
                    if child_state.freeTurn:
                        child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                        next_play_turn = play_turn
  
                    else:
                        child_valid_pits_list = child_state.players[opponent_turn].get_valid_list()
                        next_play_turn = opponent_turn

                    val, ret_state = self.nxtMnmxMv(method.get_node_name(play_turn, pit_id), child_state, next_node_type,\
                                next_depth, child_valid_pits_list, next_play_turn)

                    if not child_valid_pits_list:
                        val = self.evaluate(self.playTurn, child_state)
                        ret_state = child_state
                        #print the state
                        str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + '\n'
                        #self.tlfobj.write('freeturn\n')
                        #method.write_entry_log(self.tlfobj, param.TASK_OPTION['MINIMAX'], nodeName, nodeType, self.maxDepth, current_depth, currentState.freeTurn, eval_val, alpha=None, beta=None)
                        self.tlfobj.write(str_arr)
                    #else:    
                        # val, ret_state = self.nxtMnmxMv(method.get_node_name(play_turn, pit_id), child_state, next_node_type,\
                        #         next_depth, child_valid_pits_list, next_play_turn)
                    returnValList.append(val)
                    returnStateList.append(ret_state)
                    str_arr = str(nodeName) + ',' + str(current_depth) +','+ str(method.return_opposite_type(nodeType, returnValList)) + '\n'
                    #print str_arr
                    self.tlfobj.write(str_arr)

                ret_val = method.return_opposite_type(nodeType, returnValList)
                idx = returnValList.index(ret_val)
                if (returnStateList[idx].depth > currentState.depth) and currentState.depth!=0:
                    ret_state = currentState
                else:
                    ret_state = returnStateList[idx]
                return ret_val,ret_state
                
            else:
                #valid_pits_list should be the opponents valid pit list
                for pit_id in valid_pits_list:
                    opponent_turn = method.get_opponent_id(play_turn)
                    child_state = self.nextState(currentState, play_turn, pit_id)
                    #print 'child_state\n',child_state.print_info()
                    if child_state.freeTurn:
                        child_valid_pits_list = child_state.players[play_turn].get_valid_list()
                        next_play_turn = play_turn
                        next_depth = current_depth+1
                    else:
                        child_valid_pits_list = child_state.players[opponent_turn].get_valid_list()
                        next_play_turn = opponent_turn
                        next_depth = current_depth+1

                    val, ret_state = self.nxtMnmxMv(method.get_node_name(play_turn, pit_id), child_state, method.alternate_type(nodeType),\
                                 next_depth, child_valid_pits_list, next_play_turn)
                    if not child_valid_pits_list:

                        val = self.evaluate(self.playTurn, child_state)
                        ret_state = child_state
                        #method.write_entry_log(self.tlfobj, param.TASK_OPTION['MINIMAX'], nodeName, nodeType, self.maxDepth, next_depth, child_state.freeTurn, eval_val, alpha=None, beta=None, game_end = True)
                        #print the state
                        #print 'check'
                        #self.tlfobj.write('game-end\n')
                        str_arr = str(method.get_node_name(play_turn, pit_id)) + ',' + str(next_depth) + ',' + str(val) + '\n'
                        self.tlfobj.write(str_arr)
                    #else:
                        
                    returnValList.append(val)
                    returnStateList.append(ret_state)
                    str_arr = str(nodeName) + ',' + str(current_depth) +','+ str(method.return_same_type(nodeType, returnValList)) + '\n'
                    #print str_arr
                    self.tlfobj.write(str_arr)

                ret_val = method.return_same_type(nodeType, returnValList)
                idx = returnValList.index(ret_val)
                if (returnStateList[idx].depth > currentState.depth) and currentState.depth!=0:
                    ret_state = currentState
                else:
                    ret_state = returnStateList[idx]
                return ret_val,ret_state