def __init__(self, value,occupied_positions, player, oplayer, cutoffdepth):
		
		self.value=value
                self.occupied_positions=occupied_positions
		self.player = player
		self.oplayer = oplayer
		self.cutOffDepth = cutoffdepth
                self.zzz=evaluation(self.value,self.occupied_positions,self.player,self.oplayer)
		self.rootEvalFunction = self.zzz.eval()
                #print self.rootEvalFunction
		self.negativeInfiniti = -100000
		self.positiveInfiniti = 100000
		self.bestRootNode = None
                
		self.rootNode = alphabeta_decision(None, value,occupied_positions, player, oplayer, self.negativeInfiniti, 0, False, [], self.negativeInfiniti, None, cutoffdepth, self.negativeInfiniti, self.positiveInfiniti)
                self.rootNode.travFile()
	def __init__(self, value,occupied_positions, playerValue, opponentPlayerValue, cutOffDepthValue):
		self.gridBoxCell = []
		self.value=value
                self.occupied_positions=occupied_positions
		self.player = playerValue
		self.opponentPlayer = opponentPlayerValue
		self.cutOffDepth = cutOffDepthValue
		
                aaa=evaluation(self.value,self.occupied_positions,self.player,self.opponentPlayer)
                self.rootEvalFunction=aaa.eval()
                  
		
		self.negative = -100000
		self.positive = 100000
		self.bestRootNode = None
		print "Node,Depth,Value"
		self.rootNode = nextmin(None,value,occupied_positions, playerValue, opponentPlayerValue, self.negative, 0, False, [], self.negative, None, cutOffDepthValue)
	def recursiveAlphaBeta(self, rootNodeObject):
                originalNode = deepcopy(rootNodeObject)
		if rootNodeObject.currentDepthOfNode < self.cutOffDepth:
			childNode = None
			prune = False
			flag1=False
			for i in range(0, 5):
				for j in range(0, 5):
					rootNodeObject.travFile()
					if rootNodeObject.occupied_positions[i][j] == "*" and prune == False:
						flag1=True
						if rootNodeObject.playMax == True:
							if rootNodeObject.parentNode != None:
								
								if rootNodeObject.eval_value <= rootNodeObject.parentNode.alpha:
									
									prune = True
								else:
								
									prune = False
						else:
							if rootNodeObject.parentNode != None:
								
								if rootNodeObject.eval_value >= rootNodeObject.parentNode.beta:
									
									prune = True
								else:
								
									prune = False

						if prune == True:
							
							break					
						else:
							
							pos = Position(i, j)
                                                          
							if rootNodeObject.playMax == True:
                                                                rootNodeObject.occupied_positions = deepcopy(originalNode.occupied_positions)
								childNode = alphabeta_decision(rootNodeObject, rootNodeObject.value,rootNodeObject.occupied_positions, rootNodeObject.player, rootNodeObject.oplayer, self.negativeInfiniti, rootNodeObject.currentDepthOfNode+1, False, [], rootNodeObject.value[i][j], pos, self.cutOffDepth, rootNodeObject.alpha, rootNodeObject.beta)
							else:
                                                                rootNodeObject.occupied_positions = deepcopy(originalNode.occupied_positions)
								childNode = alphabeta_decision(rootNodeObject, rootNodeObject.value,rootNodeObject.occupied_positions, rootNodeObject.player, rootNodeObject.oplayer, self.positiveInfiniti, rootNodeObject.currentDepthOfNode+1, True, [], rootNodeObject.value[i][j], pos, self.cutOffDepth, rootNodeObject.alpha, rootNodeObject.beta)
							
                                                        
                                                        childNode.travFile()
							if childNode.currentDepthOfNode == rootNodeObject.cutOffDepth:
								print rootNodeObject
								rootNodeObject.travFile()
                                                        
							rootNodeObject.childNodes.append(childNode)
							self.recursiveAlphaBeta(childNode)
			if flag1==False:
                            self.xyz=evaluation(self.value,self.occupied_positions,rootNodeObject.player,rootNodeObject.oplayer)
                            rootNodeObject.eval_value = self.xyz.eval()
			if rootNodeObject.playMax == True:
				if rootNodeObject.parentNode != None:
					if rootNodeObject.parentNode.alpha < rootNodeObject.eval_value:
                                            if rootNodeObject.parentNode.eval_value < rootNodeObject.eval_value:
						rootNodeObject.parentNode.eval_value = rootNodeObject.eval_value
                                            rootNodeObject.parentNode.eval_value = rootNodeObject.eval_value
                                            if rootNodeObject.eval_value < rootNodeObject.parentNode.beta:
						rootNodeObject.parentNode.alpha = max(rootNodeObject.eval_value, rootNodeObject.alpha)
						rootNodeObject.parentNode.bestChild = rootNodeObject.currentPosition
						#print rootNodeObject.parentNode
						

			else:
				
				if rootNodeObject.parentNode != None:
                                    if rootNodeObject.parentNode.beta >= rootNodeObject.eval_value:
					rootNodeObject.parentNode.eval_value = rootNodeObject.eval_value
                                        if rootNodeObject.parentNode.eval_value < rootNodeObject.eval_value:
                                            rootNodeObject.parentNode.eval_value = rootNodeObject.eval_value
					if rootNodeObject.eval_value > rootNodeObject.parentNode.alpha:
                                            rootNodeObject.parentNode.beta = min(rootNodeObject.eval_value, rootNodeObject.beta)
                                            rootNodeObject.parentNode.bestChild = rootNodeObject.currentPosition
		if rootNodeObject.parentNode != None:
                    rootNodeObject.parentNode.travFile()			
						
		return rootNodeObject
def main():
    count=0
    playcon=True
    global firstplayer
    global secondplayer
    global firstplayer_algo
    global firstplayer_depth
    global secondplayer_algo
    global secondplayer_depth
    player=""
    oplayer=""
    cutt_off_depth=0
    firstplayer=""
    secondplayer=""
    firstplayer_algo=0
    firstplayer_depth=0
    secondplayer_algo=0
    secondplayer_depth=0
    turn1=1
    zaza=0
    fileName = ""
# Read File Name
    for a in range(len(sys.argv)):
	if sys.argv[a] == "-i":
		fileName = sys.argv[a+1]
		break;
    f = open(fileName,'r')   
    value=[]
    occupied_positions=[]
    with open(fileName, 'r') as f:
        line=f.readline().rstrip()
        if(int(line)<4):
            task=int(line)
            for i in range(1,13):
                line=f.readline().rstrip()
                if(i==1):
                    player=line
                elif(i==2):
                    cutt_off_depth=int(line)
                    if cutt_off_depth==0:
                        print "depth not accepted" 
                        sys.exit()
                elif(i>2 and i<=7):
                    ls=[]
                    ls=map(int,line.split())
                    value.append(ls)
                elif(i>7):
                    occ=[]
                    for c in line:
                        occ.append(c)
                    occupied_positions.append(occ)
        else:
            task=int(line)
            
            # print occupiedList, " before for loop"
            for i in range(1, 17):
                line = f.readline().rstrip()
                # print "Line read is ", line, " i is, ", i
                if i == 1:
                        firstplayer = line
                elif i == 2:
                        firstplayer_algo = int(line)
                elif i == 3:
                        firstplayer_depth = int(line)
                if i == 4:
                        secondplayer = line
                elif i == 5:
                        secondplayer_algo = int(line)
                elif i == 6:
                        secondplayer_depth = int(line)
                elif i <= 11 and i >= 7:
                        ls=[]
                        ls=map(int,line.split())
                        value.append(ls)
                elif i >= 12 and i <= 17:
                        occ=[]
                        for c in line:
                            occ.append(c)
                        occupied_positions.append(occ)
    playerX='X'
    PlayerO='O'
    #print occupied_positions
    
    #print player,oplayer    
    if(task==1):
        if(player==playerX):
            oplayer='O'
        else:
            oplayer='X'
        evaluation_function=0
        maxi=0
        player1=0
        player2=0
        y=evaluation(value,occupied_positions,player,oplayer)
        evaluation_function=y.eval()
    
#        print evaluation_function
    
        z=next_state(value,occupied_positions,player,oplayer,evaluation_function)
        occupied_positions=z.state()
        y=evaluation(value,occupied_positions,player,oplayer)
        evaluation_function=y.eval()
        
#        print occupied_positions
#        print evaluation_function
#    
    #print content
    elif(task==2):
        if(player==playerX):
            oplayer='O'
        else:
            oplayer='X'
        nx=minimax_algos(value,occupied_positions,player,oplayer,cutt_off_depth)
        nx.NodeForMiniMax()    
                    
            
        
        
        
        
    elif(task==3):
        if(player==playerX):
            oplayer='O'
        else:
            oplayer='X'
        nxx=AlphaBeta(value,occupied_positions,player,oplayer,cutt_off_depth)
        nxx.getBestRootNodeForAlphaBeta()
#        print "alphabeta"
    elif(task==4):
        i=0
        for i in range(5):
            for j in range(5):
                if occupied_positions[i][j]=='*':
                    count+=1
        while(i<=count):
            i+=1
            if turn1 == 1:
                if firstplayer_algo == 1:
                    y1=evaluation(value,occupied_positions,firstplayer,secondplayer)
                    evaluation_function=y1.eval()
                    z1=next_state(value,occupied_positions,firstplayer,secondplayer,evaluation_function)
                    occupied_positions=z1.state()
                    y2=evaluation(value,occupied_positions,firstplayer,secondplayer)
                    evaluation_function=y2.eval()
                    rz = open('trace_state.txt','a+')
                    for i in range(5):
                        for j in range(5):
                            rz.write(occupied_positions[i][j])
                       
                        rz.write("\n")
                       
                    
                elif firstplayer_algo == 2:
                    nx=minimax_algos(value,occupied_positions,firstplayer,secondplayer,firstplayer_depth)
                    nx.NodeForMiniMax()
                    rz = open('trace_state.txt','a+')
                    for i in range(5):
                        for j in range(5):
                            rz.write(occupied_positions[i][j])
                       
                        rz.write("\n")
                       
                elif firstplayer_algo == 3:
                    nxx=AlphaBeta(value,occupied_positions,firstplayer,secondplayer,firstplayer_depth)
                    nxx.getBestRootNodeForAlphaBeta()
                    rz = open('trace_state.txt','a+')
                    for i in range(5):
                        for j in range(5):
                            rz.write(occupied_positions[i][j])
                            
                        rz.write("\n")
                       
                turn1=2
            elif turn1==2:
                if secondplayer_algo == 1:
                    y3=evaluation(value,occupied_positions,secondplayer,firstplayer)
                    evaluation_function=y4.eval()
                    z3=next_state(value,occupied_positions,secondplayer,firstplayer,evaluation_function)
                    occupied_positions=z3.state()
                    y4=evaluation(value,occupied_positions,secondplayer,firstplayer)
                    evaluation_function=y4.eval()
                    for i in range(5):
                        for j in range(5):
                            rz.write(occupied_positions[i][j])
                        rz.write("\n")

                elif secondplayer_algo == 2:
                    nx=minimax_algos(value,occupied_positions,secondplayer,firstplayer,secondplayer_depth)
                    nx.NodeForMiniMax()
                    rz = open('trace_state.txt','a+')
                    for i in range(5):
                        for j in range(5):
                            rz.write(occupied_positions[i][j])
                        rz.write("\n")
                        
                    
                elif secondplayer_algo == 3:
                    nxx=AlphaBeta(value,occupied_positions,secondplayer,firstplayer,secondplayer_depth)
                    nxx.getBestRootNodeForAlphaBeta()
                    rz = open('trace_state.txt','a+')
                    for i in range(5):
                        for j in range(5):
                            rz.write(occupied_positions[i][j])
                        rz.write("\n")
                        
                turn1=1
            
            
            
                             
                
                    
    
    r1 = open('next_state.txt','w+')
    for i in range(5):
        for j in range(5):
            r1.write(occupied_positions[i][j])
        r1.write("\n")    
    r1.close()
    rz.close()
    f.close()
	def __init__(self, parentNodeObject, value,occupied_positions, playerValue, opponentPlayerValue, currentEvalFunctionValue, currentDepthOfNodeValue, playMaxValue, childNodesValues, currentValueValue, currentPositionValue, cutOffDepthValue):
            self.value=value
            self.occupied_positions=occupied_positions
            self.parentNode = None
            self.gridBoxCell = []
            self.player = ""
            self.opponentPlayer = ""
            self.currentEvalFunction = 0
            self.currentDepthOfNode = 0
            self.playMax = True
            self.childNodes = []
            self.currentValue = 0
            self.currentPosition = None
            self.bestChild = None
            self.bestGridBox = []
            self.cutOffDepth = cutOffDepthValue
            #print self.cutOffDepth,"AAAAAAAAAAAAA"
            if(parentNodeObject != None):
                self.parentNode = parentNodeObject
                    
                print parentNodeObject.currentEvalFunction
                    
            self.gridBoxCell = []

            self.player = playerValue
            self.opponentPlayer = opponentPlayerValue
            self.currentEvalFunction = currentEvalFunctionValue
            self.currentDepthOfNode = currentDepthOfNodeValue
            self.playMax = playMaxValue
            for i in range(0, len(childNodesValues)):
                childNodes.append(childNodesValues[i])

            self.currentValue = currentValueValue
            if currentPositionValue != None:
                    
                self.currentPosition = currentPositionValue
                
                self.currentValue = self.value[self.currentPosition[0]][self.currentPosition[1]]
                
                if self.playMax == True and self.parentNode != None:
                
                    i=currentPositionValue[0]
                    j=currentPositionValue[1]
                    self.occupied_positions[i][j] = self.player
                    for k in range(5):
                        for l in range(5):
                            print occupied_positions[k][l],
                        print    
                    if((i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                        self.occupied_positions[i-1][j]=self.player
                    #print occupied_positions[i-1][j]
                    if((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer) and ((i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                        self.occupied_positions[i+1][j]=self.player
                    #print occupied_positions[i+1][j]
                    if((j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player) or (i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) )):
                        self.occupied_positions[i][j+1]=self.player
                    #print occupied_positions[i][j-1]
                    if((j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player)or (i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                        self.occupied_positions[i][j-1]=self.player
                    
                    q=evaluation(self.value,self.occupied_positions,self.player,self.opponentPlayer)
                    self.currentEvalFunction=q.eval()
                    
                    '''
                    enemyPositions = self.getEnemyBoxPositionsAdjacentToTheBox(self.value,self.occupied_positions, currentPositionValue.rowIndex, currentPositionValue.columnIndex, self.player, self.opponentPlayer)
                    for eachEnemyPosition in enemyPositions:
                        self.occupied_positions[eachEnemyPosition.rowIndex][eachEnemyPosition.columnIndex] = self.player
                    
                    playerValue = 0
                    opponentValue = 0
                    for i in range(5):
                        for j in range(5):
                            # print box
                            if self.occupied_positions[i][j] == self.player:
                                playerValue+=self.value[i][j]
                            elif self.occupied_positions[i][j] == self.opponentPlayer:
                                opponentValue+=self.value[i][j]
                    self.currentEvalFunction = playerValue - opponentValue		
                    '''
                    
                    if self.parentNode.currentEvalFunction < self.currentEvalFunction and  self.currentDepthOfNode == self.cutOffDepth:
                            # print "maximizing parent %s " %(self.parentNode.currentPosition)
                        self.parentNode.currentEvalFunction = self.currentEvalFunction
                        self.parentNode.bestChild = currentPositionValue
                        self.parentNode.bestGridBox = deepcopy(self.occupied_positions)
                        nextmin.bestGridBoxOutput = deepcopy(self.occupied_positions)

                            # GameNode.bestGridBoxOutput = []
                            # for i in range(0, len(self.gridBoxCell)):
                            # 	GameNode.bestGridBoxOutput.append([])
                            # 	for j in range(0, len(self.gridBoxCell)):
                            # 		GameNode.bestGridBoxOutput[i].append(self.gridBoxCell[i][j])
                            # self.parentNode.bestChild = deepcopy(self)

                elif self.playMax == False and self.parentNode != None:
                        # print "For %s, current Value %d subtracted from %d " %(opponentPlayerValue, self.currentValue, self.currentEvalFunction) 				
                        # self.currentEvalFunction = parentsOriginalEvalFunction - self.currentValue
                    '''
                    self.occupied_positions[currentPositionValue.rowIndex][currentPositionValue.columnIndex] = self.opponentPlayer
                    enemyPositions = self.getEnemyBoxPositionsAdjacentToTheBox(self.value,self.occupied_positions, currentPositionValue.rowIndex, currentPositionValue.columnIndex, self.opponentPlayer, self.player)
                    for eachEnemyPosition in enemyPositions:
                        self.gridBoxCell[eachEnemyPosition.rowIndex][eachEnemyPosition.columnIndex].occupiedBy = self.opponentPlayer
                            # self.currentEvalFunction += (2 * self.gridBoxCell[eachEnemyPosition.rowIndex][eachEnemyPosition.columnIndex].value)
                    '''
                    i=currentPositionValue[0]
                    j=currentPositionValue[1]
                    self.occupied_positions[i][j] = self.opponentPlayer
                    if((i!=0 and self.occupied_positions[i-1][j]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer) or (j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) or (j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer))):
                        self.occupied_positions[i-1][j]=self.opponentPlayer
                    #print occupied_positions[i-1][j]
                    if((i!=4 and self.occupied_positions[i+1][j]==self.player) and ((i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) or (j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) or (j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer))):
                        self.occupied_positions[i+1][j]=self.opponentPlayer
                    #print occupied_positions[i+1][j]
                    if((j!=4 and self.occupied_positions[i][j+1]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer) or (i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) or (j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) )):
                        self.occupied_positions[i][j+1]=self.opponentPlayer
                    #print occupied_positions[i][j-1]
                    if((j!=0 and self.occupied_positions[i][j-1]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer)or (i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) or (j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer))):
                        self.occupied_positions[i][j-1]=self.opponentPlayer
                    qq=evaluation(self.value,self.occupied_positions,self.player,self.opponentPlayer)
                    self.currentEvalFunction=qq.eval()
                    
                    '''
                    playerValue = 0
                    opponentValue = 0
                    for i in range(5):
                        for j in range(5):
                            if (self.occupied_positions[i][j] == self.player):
                                playerValue+=self.value[i][j]
                            elif (self.occupied_positions[i][j] == self.opponentPlayer):
                                opponentValue+=self.value[i][j]
                    self.currentEvalFunction = playerValue - opponentValue
                    '''
                    if self.parentNode.currentEvalFunction >= self.currentEvalFunction and self.currentDepthOfNode == self.cutOffDepth:
                            # print "minimizing parent %s " %(self.parentNode.currentPosition)
                        self.parentNode.currentEvalFunction = self.currentEvalFunction
                        self.parentNode.bestChild = currentPositionValue
                        self.parentNode.bestGridBox = deepcopy(self.occupied_positions)
                        nextmin.bestGridBoxOutput = deepcopy(self.occupied_positions)
                    
            #if(self.parentNode == None):
                print self
def main():
    
    fileName = ""
# Read File Name
    for a in range(len(sys.argv)):
	if sys.argv[a] == "-i":
		fileName = sys.argv[a+1]
		break;
    #f = open('testcase1.txt','r')   
    value=[]
    occupied_positions=[]
    with open(fileName, 'r') as f:
        for i in range(0,13):
            line=f.readline().rstrip()
            if(i==0):
                task=int(line)
                #print task
            elif(i==1):
                player=line
            elif(i==2):
                cutt_off_depth=int(line)
                if cutt_off_depth==0:
                    print "depth not accepted" 
                    sys.exit()
            elif(i>2 and i<=7):
                ls=[]
                ls=map(int,line.split())
                value.append(ls)
            elif(i>7):
                occ=[]
                for c in line:
                    occ.append(c)
                occupied_positions.append(occ)
    
    playerX='X'
    PlayerO='O'
    #print occupied_positions
    if(player==playerX):
        oplayer='O'
    else:
        oplayer='X'
    #print player,oplayer    
    if(task==1):
        evaluation_function=0
        maxi=0
        player1=0
        player2=0
        y=evaluation(value,occupied_positions,player,oplayer)
        evaluation_function=y.eval()
    
#        print evaluation_function
    
        z=next_state(value,occupied_positions,player,oplayer,evaluation_function)
        occupied_positions=z.state()
        y=evaluation(value,occupied_positions,player,oplayer)
        evaluation_function=y.eval()
        
#        print occupied_positions
#        print evaluation_function
#    
    #print content
    elif(task==2):

        nx=minimax_algos(value,occupied_positions,player,oplayer,cutt_off_depth)
        nx.NodeForMiniMax()    
                    
            
        
        
        
        
    elif(task==3):
        nxx=AlphaBeta(value,occupied_positions,player,oplayer,cutt_off_depth)
        nxx.getBestRootNodeForAlphaBeta()
#        print "alphabeta"

    r1 = open('next_state.txt','w+')
    for i in range(5):
        for j in range(5):
            r1.write(occupied_positions[i][j])
        r1.write("\n")    
    r1.close()
    
    f.close()
	def __init__(self, parentNodeObject, value,occupied_positions, player, oplayer, currentEvalFunctionValue, currentDepthOfNodeValue, playMaxValue, childNodesValues, currentValueValue, currentPositionValue, cutoffdepth, alphaValue, betaValue):
		
                if alphabeta_decision.head == False:
                
                    r5 = open('traverse_log.txt','w')
                    r5.seek(0)
                    r5.truncate()
                    r5.write("Node,Depth,Value,Alpha,Beta\n")
                    r5.close()
                    alphabeta_decision.head=True
                self.value=value
                self.occupied_positions=occupied_positions
		self.alpha = alphaValue
		self.beta = betaValue
		self.parentNode = None
		
		
		self.playMax = True
		self.childNodes = []
		
		self.currentPosition = None
		self.bestChild = None
		self.bestGridBox = []
		self.cutOffDepth = cutoffdepth
		self.pm = False
		
		if(parentNodeObject != None):
			self.parentNode = parentNodeObject
		
		
		self.player = player
		self.oplayer = oplayer
		self.eval_value = currentEvalFunctionValue
                # self.eval_value,"RV RV RV" 
		self.currentDepthOfNode = currentDepthOfNodeValue
		self.playMax = playMaxValue
		for i in range(0, len(childNodesValues)):
			childNodes.append(childNodesValues[i])

		self.currentValue = currentValueValue

		
		if currentPositionValue != None:
			self.currentPosition = currentPositionValue
                        #print self.currentPosition
			self.currentValue = self.value[self.currentPosition.rowIndex][self.currentPosition.columnIndex]
			parentModified = False
			if self.playMax == True and self.parentNode != None:
				
                                i=currentPositionValue.rowIndex
                                j=currentPositionValue.columnIndex
                                self.occupied_positions[i][j]=self.player
                
                                if((i!=0 and self.occupied_positions[i-1][j]==self.oplayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                                    self.occupied_positions[i-1][j]=self.player
                    #print occupied_positions[i-1][j]
                                if((i!=4 and self.occupied_positions[i+1][j]==self.oplayer) and ((i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                                    self.occupied_positions[i+1][j]=self.player
                    #print occupied_positions[i+1][j]
                                if((j!=4 and self.occupied_positions[i][j+1]==self.oplayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player) or (i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) )):
                                    self.occupied_positions[i][j+1]=self.player
                    #print occupied_positions[i][j-1]
                                if((j!=0 and self.occupied_positions[i][j-1]==self.oplayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player)or (i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                                    self.occupied_positions[i][j-1]=self.player
		
				if self.currentDepthOfNode == self.cutOffDepth :
					
                                        zaaa=evaluation(self.value,self.occupied_positions,self.player,self.oplayer)
                                        self.eval_value=zaaa.eval()
                                        
					self.parentNode.eval_value = max(self.eval_value, self.parentNode.eval_value)

					if self.parentNode.alpha < self.eval_value :
						
						self.parentNode.bestChild = currentPositionValue
						self.parentNode.bestGridBox = deepcopy(self.occupied_positions)
						alphabeta_decision.bestGridBoxOutput = deepcopy(self.occupied_positions)
						parentModified = True
						self.pm = True
						if self.eval_value < self.parentNode.beta:
							self.parentNode.alpha = self.eval_value
						
                                else:
                                    parentModified = False
                                    self.pm = False		
 			elif self.playMax == False and self.parentNode != None:
				i=currentPositionValue.rowIndex
                                j=currentPositionValue.columnIndex
                                self.occupied_positions[i][j]=self.oplayer
                
                                if((i!=0 and self.occupied_positions[i-1][j]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.oplayer) or (j!=0 and self.occupied_positions[i][j-1]==self.oplayer) or (j!=4 and self.occupied_positions[i][j+1]==self.oplayer))):
                                    self.occupied_positions[i-1][j]=self.oplayer
                    #print occupied_positions[i-1][j]
                                if((i!=4 and self.occupied_positions[i+1][j]==self.player) and ((i!=0 and self.occupied_positions[i-1][j]==self.oplayer) or (j!=0 and self.occupied_positions[i][j-1]==self.oplayer) or (j!=4 and self.occupied_positions[i][j+1]==self.oplayer))):
                                    self.occupied_positions[i+1][j]=self.oplayer
                    #print occupied_positions[i+1][j]
                                if((j!=4 and self.occupied_positions[i][j+1]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.oplayer) or (i!=0 and self.occupied_positions[i-1][j]==self.oplayer) or (j!=0 and self.occupied_positions[i][j-1]==self.oplayer) )):
                                    self.occupied_positions[i][j+1]=self.oplayer
                    #print occupied_positions[i][j-1]
                                if((j!=0 and self.occupied_positions[i][j-1]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.oplayer)or (i!=0 and self.occupied_positions[i-1][j]==self.oplayer) or (j!=4 and self.occupied_positions[i][j+1]==self.oplayer))):
                                    self.occupied_positions[i][j-1]=self.oplayer
				# For leaf nodes calculate the E(S) and propogate to parent as necessary
				
                                if self.currentDepthOfNode == self.cutOffDepth:
                                        #print occupied_positions
					zzaaa=evaluation(self.value,self.occupied_positions,self.player,self.oplayer)
                                        self.eval_value=zzaaa.eval()
                                        #print self.eval_value
                                        self.parentNode.eval_value = min(self.eval_value, self.parentNode.eval_value)
					if self.parentNode.beta >= self.eval_value:
						
						self.parentNode.bestChild = currentPositionValue
						self.parentNode.bestGridBox = deepcopy(self.occupied_positions)
						alphabeta_decision.bestGridBoxOutput = deepcopy(self.occupied_positions)
						parentModified = True
						self.pm = True
						if self.eval_value > self.parentNode.alpha:
							self.parentNode.beta = self.eval_value
						
				else:
					parentModified = False
					self.pm = False
	def __init__(self, parentNodeObject, value,occupied_positions, playerValue, opponentPlayerValue, currentEvalFunctionValue, currentDepthOfNodeValue, playMaxValue, childNodesValues, currentValueValue, currentPositionValue, cutOffDepthValue):
		
                if nextmin.head == False:
                        
			rr = open('traverse_log.txt','w')
                        rr.seek(0)
                        rr.truncate()
			rr.write("Node,Depth,Value\n")
			rr.close()
			nextmin.head = True
		self.parentNode = None
                self.occupied_positions=occupied_positions
                self.value=value
		
		self.player = ""
		self.opponentPlayer = ""
		self.currentEvalFunction = 0
		self.currentDepthOfNode = 0
		self.playMax = True
		self.childNodes = []
		self.currentValue = 0
		self.currentPosition = None
		self.bestChild = None
		self.bestGridBox = []
		self.cutOffDepth = cutOffDepthValue
		
		if(parentNodeObject != None):
			self.parentNode = parentNodeObject
		
		self.player = playerValue
		self.opponentPlayer = opponentPlayerValue
		self.currentEvalFunction = currentEvalFunctionValue
		self.currentDepthOfNode = currentDepthOfNodeValue
		self.playMax = playMaxValue
		for i in range(0, len(childNodesValues)):
			childNodes.append(childNodesValues[i])

		self.currentValue = currentValueValue
		if currentPositionValue != None:
			
			self.currentPosition = currentPositionValue
			
			self.currentValue = self.value[self.currentPosition.rowIndex][self.currentPosition.columnIndex]
			
			if self.playMax == True and self.parentNode != None:
				
				#self.occupied_positions[currentPositionValue.rowIndex][currentPositionValue.columnIndex] = self.player
				
                                i=currentPositionValue.rowIndex
                                j=currentPositionValue.columnIndex
                                self.occupied_positions[i][j]=self.player
                
                                if((i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                                    self.occupied_positions[i-1][j]=self.player
                    #print occupied_positions[i-1][j]
                                if((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer) and ((i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                                    self.occupied_positions[i+1][j]=self.player
                    #print occupied_positions[i+1][j]
                                if((j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player) or (i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=0 and self.occupied_positions[i][j-1]==self.player) )):
                                    self.occupied_positions[i][j+1]=self.player
                    #print occupied_positions[i][j-1]
                                if((j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) and ((i!=4 and self.occupied_positions[i+1][j]==self.player)or (i!=0 and self.occupied_positions[i-1][j]==self.player) or (j!=4 and self.occupied_positions[i][j+1]==self.player))):
                                    self.occupied_positions[i][j-1]=self.player
                                
                                
                                zaa=evaluation(self.value,self.occupied_positions,self.player,self.opponentPlayer)
                                self.currentEvalFunction=zaa.eval()
				if self.parentNode.currentEvalFunction < self.currentEvalFunction and self.parentNode != None and self.currentDepthOfNode == self.cutOffDepth:
					# print "maximizing parent %s " %(self.parentNode.currentPosition)
					self.parentNode.currentEvalFunction = self.currentEvalFunction
					self.parentNode.bestChild = currentPositionValue
					self.parentNode.bestGridBox = deepcopy(self.occupied_positions)
					nextmin.bestGridBoxOutput = deepcopy(self.occupied_positions)
					
					

 			elif self.playMax == False and self.parentNode != None:
 				
                                
                                i=currentPositionValue.rowIndex
                                j=currentPositionValue.columnIndex
                                self.occupied_positions[i][j]=self.opponentPlayer
                
                                if((i!=0 and self.occupied_positions[i-1][j]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer) or (j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) or (j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer))):
                                    self.occupied_positions[i-1][j]=self.opponentPlayer
                    #print occupied_positions[i-1][j]
                                if((i!=4 and self.occupied_positions[i+1][j]==self.player) and ((i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) or (j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) or (j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer))):
                                    self.occupied_positions[i+1][j]=self.opponentPlayer
                    #print occupied_positions[i+1][j]
                                if((j!=4 and self.occupied_positions[i][j+1]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer) or (i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) or (j!=0 and self.occupied_positions[i][j-1]==self.opponentPlayer) )):
                                    self.occupied_positions[i][j+1]=self.opponentPlayer
                    #print occupied_positions[i][j-1]
                                if((j!=0 and self.occupied_positions[i][j-1]==self.player) and ((i!=4 and self.occupied_positions[i+1][j]==self.opponentPlayer)or (i!=0 and self.occupied_positions[i-1][j]==self.opponentPlayer) or (j!=4 and self.occupied_positions[i][j+1]==self.opponentPlayer))):
                                    self.occupied_positions[i][j-1]=self.opponentPlayer
                                
                                
                                zaa=evaluation(self.value,self.occupied_positions,self.player,self.opponentPlayer)
                                self.currentEvalFunction=zaa.eval()
				if self.parentNode.currentEvalFunction >= self.currentEvalFunction and self.parentNode != None and self.currentDepthOfNode == self.cutOffDepth:
					# print "minimizing parent %s " %(self.parentNode.currentPosition)
					self.parentNode.currentEvalFunction = self.currentEvalFunction
					self.parentNode.bestChild = currentPositionValue
					self.parentNode.bestGridBox = deepcopy(self.occupied_positions)
					nextmin.bestGridBoxOutput = deepcopy(self.occupied_positions)
					
		print self