コード例 #1
0
ファイル: aifunctions.py プロジェクト: Kluchy/ConnectFour
def blockTrap(originalBoard, myMove, opponentMove, futureBoard, playerTurn):
    numrows, numcolumns= py.shape(originalBoard)
    opponentTurn= getOpponent( playerTurn )
    interBoard= py.copy( originalBoard )
    interBoard[myMove]= playerTurn
    winningChains= glf.getSequentialCellsPlus( interBoard, 4 )
    #print "winning Chains: " ,winningChains
    opWins= winningChains[opponentTurn]
    numOpWins= len( opWins )
    
    fwinningChains= glf.getSequentialCellsPlus( futureBoard, 4 )
    fopWins= fwinningChains[opponentTurn]
    #print "fopWins: ", fopWins
    fnumOpWins= len( fopWins )
    
    if fnumOpWins >= numOpWins + 2:
        #then there was a trap.
        
        #get entries in fwinningChains that are new (i.e not in winningChains)
        newOpPossibleWins= []
        for pair in fopWins:
            #print "pair is: ", pair
            posOfPair, directOfPair= pair
            absent= True
            for pos,direct in opWins:
                if directOfPair == direct and posOfPair.tolist() == pos.tolist():
                    absent= False
            if absent:
                newOpPossibleWins.append(pair)
        #check that there are only 2 new possibilities
        #assert len(newOpPossibleWins) == 2
        
        #go through the first 4
        for posWin in newOpPossibleWins:
            pos,direct= posWin
            rowdirect,columndirect= direct
            for row in pos:
                x,y= row[0], row[1]
                adjRow= x+rowdirect
                adjCol= y+columndirect
                if  adjRow < 6 and adjRow > 0 and adjCol < 7 and adjCol > 0 and isPlayable( (x,y), originalBoard ) and originalBoard[adjRow,adjCol] == opponentTurn:
                    return 1, (x,y)
        return -1, myMove
            
        '''#check if opponentMove is playable from originalBoard
        if isPlayable( opponentMove, originalBoard ):
            return 1, opponentMove
        else:
            #must have been made playable by myMove
            return -1, myMove'''
    else:
        #appears to be no trap
        return 0, myMove
コード例 #2
0
ファイル: aiplayer.py プロジェクト: Kluchy/ConnectFour
def randomMovePlusPlus(gameBoard, playerTurn):
    move= None
    sequentialCells= glf.getSequentialCellsPlus(gameBoard,4)

    if playerTurn == 1:
        possibleWins= sequentialCells[1]
        possibleLosses= sequentialCells[2]
    elif playerTurn == 2:
        possibleWins= sequentialCells[2]
        possibleLosses= sequentialCells[1]
        
    #print "TRY TO WIN"
    for pos, direction in possibleWins:
        move= aif.blockOrWin(gameBoard, pos)
        if move:
            #print "WOOOOOOOONNN, playing: ", move
            break
            
    if not move:
        #print "TRY TO BLOCK OPPONENT"
        for pos, direction in possibleLosses:
            move= aif.blockOrWin(gameBoard, pos)
            if move:
                #print "BLOCKING OPPONENT, playing: " , move
                break

    if not move:
        #print "COULD NOT BLOCK OR WIN, playing random"
        return randomMove(gameBoard),1
    else:
        return move,0
コード例 #3
0
ファイル: aiplayer.py プロジェクト: Kluchy/ConnectFour
def lookAheadOnePlus(gameBoard, playerTurn):
    #get all possible moves on gameBoard
    possibleMoves= aif.getValidMoves(gameBoard)
    #get best move based on state of resulting boards
    bestMove, isBlockOrWin= bestLocalMovePlus(gameBoard, playerTurn)
    x,y= bestMove
    #score board for this player and opponent
    myOrScores, yourOrScores, orCandidateSlots= aif.scoreBoard(gameBoard, playerTurn)
    if not aif.isSafeToPlay((x,y), yourOrScores, gameBoard):
        #CAN USE THIS TO PREVENT CONNECT FOUR TRAPS
        #print "BEST MOVE IS A LOSS?!?!?!"
        pass
    if isBlockOrWin:
        #there cannot be a better play than a block or a win
        #print "FOUND IS BLOCK OR WIN FROM BESTLOCALMOVEPLUS"
        return bestMove, isBlockOrWin
    #find the best play that is neither a block or a win
    bestBoard= py.copy(gameBoard)
    bestBoard[bestMove]= playerTurn #py.zeros(py.shape(gameBoard))
    
    opponentTurn= aif.getOpponent(playerTurn)
    for x,y in possibleMoves:
        #play move
        newBoard= py.copy(gameBoard)
        newBoard[x,y]= playerTurn
        oldSequentialCells= glf.getSequentialCellsPlus( bestBoard, 3 )
        oldWinOpportunities= oldSequentialCells[playerTurn]
        oldLoseOpportunities= oldSequentialCells[opponentTurn]
        newSequentialCells= glf.getSequentialCellsPlus( newBoard, 3 )
        newWinOpportunities= newSequentialCells[playerTurn]
        newLoseOpportunities= newSequentialCells[opponentTurn]
        
        myScores, yourScores, candidateSlots= aif.scoreBoard(newBoard, playerTurn)
        if aif.isSafeToPlay((x,y), yourOrScores, gameBoard) and len(newLoseOpportunities) < len(oldLoseOpportunities):
            #print "FOUND SOMETHING BETTER THAN BESTLOCALMOVEPLUS: ", x,y
            bestMove= (x,y)
            bestBoard= newBoard
    #return move leading to that state
    return bestMove, isBlockOrWin
コード例 #4
0
ファイル: aifunctions.py プロジェクト: Kluchy/ConnectFour
def blockTrapFirst(originalBoard, myMove, opponentMove, futureBoard, playerTurn):
    opponentTurn= getOpponent( playerTurn )
    interBoard= py.copy( originalBoard )
    interBoard[myMove]= playerTurn
    winningChains= glf.getSequentialCellsPlus( interBoard, 4 )
    opWins= winningChains[opponentTurn]
    numOpWins= len( opWins )
    
    fwinningChains= glf.getSequentialCellsPlus( futureBoard, 4 )
    fopWins= fwinningChains[opponentTurn]
    fnumOpWins= len( fopWins )
    
    if fnumOpWins >= numOpWins + 2:
        #then there was a trap.
        #check if opponentMove is playable from originalBoard
        if isPlayable( opponentMove, originalBoard ):
            return 1, opponentMove
        else:
            #must have been made playable by myMove
            return -1, myMove
    else:
        #appears to be no trap
        return 0, myMove
コード例 #5
0
ファイル: aifunctions.py プロジェクト: Kluchy/ConnectFour
def evalB( gameBoard, playerTurn ):
    opponentTurn= getOpponent( playerTurn )
    
    #get whether board contains win or loss (or both)
    allWins= glf.getSequentialCellsNoV( gameBoard, 4 )
    wins= len( allWins[playerTurn] )
    losses= len( allWins[opponentTurn] )
    
    #get results of scoreBoard
    myScores, yourScores, candidateSlots= scoreBoard( gameBoard, playerTurn )
    times= 2
    tempPt= 0.0
    tempOt= 0.0
    for score in sorted(candidateSlots.keys(), reverse=True):
        if times == 0:
            break
        nextBests= candidateSlots[score]
        for x,y,player in nextBests:
            if player == playerTurn:
                #update partial score
                tempPt+= score
            else:
                tempOt+= score
        times-=1
    
    #get the number of offensive plays
    offPlays= 0.0
    validMoves= getValidMoves( gameBoard )
    filterWorked, validMoves= uselessSlotFilter( gameBoard, validMoves, playerTurn )
    if filterWorked:
        offPlays= len(validMoves)
        
    #get the number of win/lose opportunities
    sequentialCells= glf.getSequentialCellsPlus( gameBoard, 4 )
    winOpportunities= sequentialCells[playerTurn]
    loseOpportunities= sequentialCells[opponentTurn]
    numWins= len(winOpportunities)
    numLosses= len(loseOpportunities)

    #calculate linear combination
    #value= wins * 10000 + losses * (-10000) + tempPt * 0.3 + tempOt * (-0.1) + offPlays * 0.4 + numWins * 0.3 +  numLosses * (-0.3)
    #value= wins * 10000 + losses * (-10000)  + offPlays * 0.4 + numWins * 0.6 + tempPt * 0.1 + numLosses * (-0.1) +  + tempOt * (-0.1)
    value= wins * 10000 + losses * (-10000)  + offPlays * 0.4 + tempPt * 0.1 + numWins * 0.1 + numLosses * (-0.05) + tempOt * (-0.05)
    #print "value is ", value
    return value
コード例 #6
0
ファイル: aifunctions.py プロジェクト: Kluchy/ConnectFour
 def scoreTreeWithSeqCellsPlus( self, playerTurn ):
     #print "start scoring tree" 
     opponent= getOpponent( playerTurn )
     for boardNode in self.leafNodes:
         #print "start sequentialCellsPlus"
         sequentialCells= glf.getSequentialCellsPlus( boardNode.board, 4 )
         #print "end sequentialCellsPlus"
         myCells= sequentialCells[playerTurn]
         oppCells= sequentialCells[ opponent ]
         #print "start boardContainswinner"
         winnerFound, winnerPlayerID, _, _=  glf.boardContainsWinner( boardNode.board, 4 )
         #print "end boardContainsWinner"
         if winnerFound and winnerPlayerID == opponent:
             score= len(myCells) - len(oppCells) - 1000.0
         elif winnerFound and winnerPlayerID == playerTurn:
             score= len(myCells) - len(oppCells) + 100.0
         else:
             score= len(myCells) - len(oppCells)           
         boardNode.value= score
     #print "done scoring leaves"
     #recurse up the tree
     children= self.leafNodes
     parents= self.getPriorGen( children )
     while parents != [None]:
         for parentNode in parents:
             childrenOfParent= self.structure[parentNode]
             player= childrenOfParent[0].playerTurn
             childrenValues= []
             for child in childrenOfParent:
                 childrenValues.append( child.value )
             if player == playerTurn:
                 #get maximum
                 parentNode.value= max( childrenValues )
             else:
                 #get minimum
                 parentNode.value= min( childrenValues )
         children= parents
         parents= self.getPriorGen( children ) 
コード例 #7
0
ファイル: aifunctions.py プロジェクト: Kluchy/ConnectFour
def scoreBoard(gameBoard, playerTurn):
    #2 black copies of board
    myScores= (gameBoard != 0) * (-1)
    #myCandidateSlots= dict()
    yourScores= (gameBoard != 0) * (-1)
    #yourCandidateSlots= dict()
    candidateSlots= dict()
    #for seq=2:4
    sequentialPositions= 2
    limit= 5
    for sequentialPos in range(sequentialPositions,limit):
        sequentialCells= glf.getSequentialCellsPlus(gameBoard, sequentialPos)
        #print "CELLS ARE: ", sequentialCells
        myCells= sequentialCells[playerTurn]
        #print "MY CELLS ARE: ", myCells
        yourCells= sequentialCells[1] if playerTurn == 2 else sequentialCells[2]
        for sequence in  myCells:
            #add sequentialPos to slot == 0
            #print "sequence is : ", sequence
            pos,direction= sequence
            #print "pos is: ", pos
            for row in pos:
                #print "row is: ", row
                r,c= row[0], row[1]
                #print "r,c are: ", r, c
                if gameBoard[r,c] == 0:
                    oldscore= myScores[r,c]
                    myScores[r,c]+= sequentialPos
                    #print "Adding ", r,c ,"to index ", myScores[r,c]
                    #print "Removeing ", r,c , "from index ", oldscore
                    try:
                        candidateSlots[myScores[r,c]]+= [(r,c,playerTurn)]
                    except KeyError:
                        candidateSlots[myScores[r,c]]= [(r,c,playerTurn)]
                        
                    if oldscore != 0:
                        try:
                            candidateSlots[oldscore].remove((r,c,playerTurn))
                        except KeyError:
                            candidateSlots[oldscore]=[]
                        
                    '''try:
                        myCandidateSlots[(r,c)]+= sequentialPos
                    except KeyError:
                        myCandidateSlots[(r,c)]= sequentialPos'''
        for sequence in yourCells:
            pos,direction= sequence
            for row in pos:
                r,c= row[0], row[1]
                if gameBoard[r,c] == 0:
                    oldscore= yourScores[r,c]
                    yourScores[r,c]+= sequentialPos
                    opponentTurn= 1 if playerTurn == 2 else 2
                    try:
                        candidateSlots[yourScores[r,c]]+= [(r,c,opponentTurn)]
                    except KeyError:
                        candidateSlots[yourScores[r,c]]= [(r,c,opponentTurn)]
                        
                    if oldscore != 0:
                        try:
                            candidateSlots[oldscore].remove((r,c,opponentTurn))
                        except KeyError:
                            candidateSlots[oldscore]=[]
                    
                    '''try:
                        yourCandidateSlots[(r,c)]+= sequentialPos
                    except KeyError:
                        yourCandidateSlots[(r,c)]= sequentialPos'''
                    
    return myScores, yourScores, candidateSlots 
コード例 #8
0
ファイル: aiplayer.py プロジェクト: Kluchy/ConnectFour
def lookAheadThricePlus(gameBoard, playerTurn):
    #get all possible moves on gameBoard
    possibleMoves= aif.getValidMoves(gameBoard)
    #get best move based on state of resulting boards
    bestMove, isBlockOrWin= lookAheadTwicePlus(gameBoard, playerTurn)
    x,y= bestMove
    #score board for this player and opponent
    myOrScores, yourOrScores, orCandidateSlots= aif.scoreBoard(gameBoard, playerTurn)
    if not aif.isSafeToPlay((x,y), yourOrScores, gameBoard):
        #print "lookAheadThricePlus: -- BEST MOVE IS A LOSS?!?!?!"
        pass
    if isBlockOrWin:
        #there cannot be a better play than a block or a win
        #print "lookAheadThricePlus: --- FOUND IS BLOCK OR WIN FROM BESTLOCALMOVEPLUS"
        return bestMove, isBlockOrWin
    elif isBlockOrWin == 2:
        return bestMove, 2

    bestBoard= py.copy(gameBoard)
    bestBoard[bestMove]= playerTurn #py.zeros(py.shape(gameBoard))
    trapFlag= 0
    slot= (-1,-1)
    opponentTurn= aif.getOpponent(playerTurn)
    opponentPossibleMoves= aif.getValidMoves(bestBoard)
    for x,y in opponentPossibleMoves:
        temp= py.copy(bestBoard)
        temp[x,y]= opponentTurn
        t, s= aif.preventTrapPlus(gameBoard,bestMove, (x,y), temp, playerTurn)
        if t == 1:
            #print " PREVENTING TRAAAAAAAAAP IN DEFAULT LOOKAHEADTHRICEPLUS ----------------------------"
            return s, 2
        elif t == -1:
            trapFlag= t
            slot= s
            break
        elif t == 0:
            pass
    #get best move for opponent
    yourBestMove, _= lookAheadTwicePlus(bestBoard, opponentTurn)
    bestBoard[yourBestMove]= opponentTurn
    
    myOtherBestMove, _= lookAheadTwicePlus(bestBoard, playerTurn)
    bestBoard[myOtherBestMove]= playerTurn
    
    #find the best play that is neither a block or a win
    for x,y in possibleMoves:
        if (x,y) == slot:
            #print "AVOIDING AVOINDING AVOIDING AVOIDING AVOIDING"
            pass
        else:
            #play move
            newBoard= py.copy(gameBoard)
            newBoard[x,y]= playerTurn
            newBoardAfterMyFirstTurn= py.copy(newBoard)
            #get opponent move
            opponentMove, _= lookAheadTwicePlus(gameBoard, opponentTurn)
            newBoard[opponentMove]= opponentTurn
            flag2,slot2= aif.preventTrapPlus(gameBoard, (x,y), opponentMove, newBoard, playerTurn)
            if trapFlag == -1 and flag2 != -1 and aif.isSafeToPlayPlus( (x,y), playerTurn, gameBoard ):
                #print "ThricePlus: REPLACING BAD BEST MOVE ", bestMove, " LEADING TO TRAP WITH ", x,y
                bestMove= (x,y)
                bestBoard= newBoard
                trapFlag= 0
            #get my next best move based on this new state
            #TODO if final state has trap or is loss, discard this original move completely. If not, move on to compare this state to the best state seen.
            #TODO check if no traps for opponent but trap for self, then play there
            myMove, _= lookAheadTwicePlus(newBoard, playerTurn)
            newBoard[myMove]= playerTurn
            flag3,slot3= aif.preventTrapPlus(newBoardAfterMyFirstTurn, opponentMove, myMove, newBoard, opponentTurn)
            if flag3 == 1 and aif.isSafeToPlayPlus( slot3, playerTurn, gameBoard ):
                #Trap already active in our favor, use it!
                return slot3, 1
            if flag3 == -1 and aif.isSafeToPlayPlus( slot3, playerTurn, gameBoard ):
                #opponent made a move that activated the trap: consider our move that led to it as a valid place to play
                pass
            if flag2== -1:
                pass
            else:
                oldSequentialCells= glf.getSequentialCellsPlus( bestBoard, 4 )
                oldWinOpportunities= oldSequentialCells[playerTurn]
                oldLoseOpportunities= oldSequentialCells[opponentTurn]
                newSequentialCells= glf.getSequentialCellsPlus( newBoard, 4 )
                newWinOpportunities= newSequentialCells[playerTurn]
                newLoseOpportunities= newSequentialCells[opponentTurn]

                myScores, yourScores, candidateSlots= aif.scoreBoard(newBoard, playerTurn)
                if aif.isSafeToPlay((x,y), yourOrScores, gameBoard) and len(newLoseOpportunities) < len(oldLoseOpportunities):
                    bestMove= (x,y)
                    bestBoard= newBoard

    #return move leading to that state
    if trapFlag == -1 and bestMove == slot:
        #print "OOOOOOOOOOOOH NOOOOooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo DON'T PLAY THERE"
        pass
    return bestMove, isBlockOrWin
コード例 #9
0
ファイル: aiplayer.py プロジェクト: Kluchy/ConnectFour
def lookAheadTwicePlus(gameBoard, playerTurn):
    #get all possible moves on gameBoard
    possibleMoves= aif.getValidMoves(gameBoard)
    #get best move based on state of resulting boards
    bestMove, isBlockOrWin= lookAheadOnePlus(gameBoard, playerTurn)
    x,y= bestMove
    #score board for this player and opponent
    myOrScores, yourOrScores, orCandidateSlots= aif.scoreBoard(gameBoard, playerTurn)
    if not aif.isSafeToPlay((x,y), yourOrScores, gameBoard):
        #print "lookAheadTwicePlus: -- BEST MOVE IS A LOSS?!?!?!"
        pass
    if isBlockOrWin:
        #there cannot be a better play than a block or a win
        return bestMove, isBlockOrWin

    bestBoard= py.copy(gameBoard)
    bestBoard[bestMove]= playerTurn
    trapFlag= 0
    slot= (-1,-1)
    opponentTurn= aif.getOpponent(playerTurn)
    opponentPossibleMoves= aif.getValidMoves(bestBoard)
    for x,y in opponentPossibleMoves:
        temp= py.copy(bestBoard)
        temp[x,y]= opponentTurn
        t, s= aif.blockTrap(gameBoard,bestMove, (x,y), temp, playerTurn)
        if t == 1 and aif.isSafeToPlayPlus( s, playerTurn, gameBoard ):
            #print " PREVENTING TRAAAAAAAAAP IN DEFAULT LOOKAHEADTWICEPLUS ----------------------------"
            return s, 2
        elif t == -1:
            trapFlag= t
            slot= s
            break
        elif t == 0:
            pass
    #get best move for opponent
    yourBestMove, _= lookAheadOnePlus(bestBoard, opponentTurn)
    bestBoard[yourBestMove]= opponentTurn
    
    #find the best play that is neither a block or a win
    for x,y in possibleMoves:
        if trapFlag == -1 and (x,y) == slot:
            #print "AVOIDING AVOINDING AVOIDING AVOIDING AVOIDING"
            pass
        else:
            #play move
            newBoard= py.copy(gameBoard)
            newBoard[x,y]= playerTurn
            #get opponent move
            opponentMove, _= lookAheadOnePlus(gameBoard, opponentTurn)
            newBoard[opponentMove]= opponentTurn
            if trapFlag == -1 and bestMove == slot and (x,y) != slot and aif.isSafeToPlayPlus( (x,y), playerTurn, gameBoard ):
                #print "REPLACING BAD BEST MOVE ", bestMove, " LEADING TO TRAP WITH ", x,y
                bestMove= (x,y)
                bestBoard= newBoard
                trapFlag= 0
            oldSequentialCells= glf.getSequentialCellsPlus( bestBoard, 3 )
            oldWinOpportunities= oldSequentialCells[playerTurn]
            oldLoseOpportunities= oldSequentialCells[opponentTurn]
            newSequentialCells= glf.getSequentialCellsPlus( newBoard, 3 )
            newWinOpportunities= newSequentialCells[playerTurn]
            newLoseOpportunities= newSequentialCells[opponentTurn]

            myScores, yourScores, candidateSlots= aif.scoreBoard(newBoard, playerTurn)
            if aif.isSafeToPlay((x,y), yourOrScores, gameBoard) and len(newLoseOpportunities) < len(oldLoseOpportunities):
                #print "FOUND SOMETHING BETTER THAN LOOKAHEADONE: ", x,y
                bestMove= (x,y)
                bestBoard= newBoard
    #return move leading to that state
    if trapFlag == -1 and bestMove == slot:
        #print "OOOOOOOOOOOOH NOOOOooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo DON'T PLAY THERE"
        pass
    return bestMove, isBlockOrWin