def randomOffenseOneWithTwicePlus( gameBoard, playerTurn ): move,isBlockOrWin= randomOffenseWithTwicePlus(gameBoard,playerTurn) if isBlockOrWin == 2 or isBlockOrWin: return move, isBlockOrWin #consider all my possible moves validMoves= aif.getValidMoves( gameBoard ) bestMove= move bestNumPlayerIDs= -1 for (x,y) in validMoves: #simulate this move, and assume opponent plays 'best' possible move. #the best move from me is the one leaving the state with a higher #sequence of my playerID as a valid win AFTER opponent's 'best' move tempBoard= py.copy(gameBoard) tempBoard[x,y]= playerTurn opponentTurn= aif.getOpponent(playerTurn) oppMove, _= randomOffenseWithTwicePlus(tempBoard, opponentTurn) tempBoard[oppMove]= opponentTurn #get new valid moves and new uselessSlotFilter values. Compare with #best seen thus far newValidMoves= aif.getValidMoves( tempBoard ) filterWorked, newValidMoves= aif.uselessSlotFilter( tempBoard, newValidMoves, playerTurn ) if filterWorked: for (_,_,value) in newValidMoves: if value > 1 and value > bestNumPlayerIDs and aif.isSafeToPlayPlus( (x,y), playerTurn, gameBoard ): bestMove= (x,y) bestNumPlayerIDs= value return bestMove, 0
def lookAheadTwice(gameBoard, playerTurn): #get all possible moves on gameBoard possibleMoves= aif.getValidMoves(gameBoard) #get best move based on state of resulting boards myBestMove, isBlockOrWin= lookAheadOne(gameBoard, playerTurn) if isBlockOrWin: #print "FOUND IS BLOCK OR WIN FROM LOOKAHEADONE" return myBestMove, isBlockOrWin bestBoard= py.copy(gameBoard) #board state after opponent makes a move #play my best move based on local state bestBoard[myBestMove]= playerTurn opponentTurn= aif.getOpponent(playerTurn) yourBestMove, _= lookAheadOne(bestBoard, opponentTurn) #play opponent's best move based on local state bestBoard[yourBestMove]= opponentTurn for x,y in possibleMoves: #play move newBoard= py.copy(gameBoard) newBoard[x,y]= playerTurn #get opponent's best move based on this new state opponentMove, _= lookAheadOne(newBoard, opponentTurn) opponentBoard= py.copy(newBoard) opponentBoard[opponentMove]= opponentTurn #score state opponent led to isNewBetter, myScore, yourScore= aif.isBetterState(opponentBoard, bestBoard, opponentTurn) if isNewBetter == 1: #print "FOUND SOMETHING BETTER THAN lookAheadOne: ", x,y myBestMove= (x,y) bestBoard= opponentBoard yourBestMove= opponentMove return myBestMove, isBlockOrWin
def randomOffense(gameBoard, playerTurn): move,isRandom= randomMovePlusPlus( gameBoard, playerTurn ) if not isRandom: #print "RandomOffense --- blocking" return move, not isRandom validMoves= aif.getValidMoves( gameBoard ) filterWorked, validMoves= aif.uselessSlotFilter( gameBoard, validMoves, playerTurn ) if filterWorked: #choose move with higher number move= (-1,-1) bestVal= -1 for (x,y,value) in validMoves: if value > bestVal: move= (x,y) bestVal= value return move, not isRandom return move, not isRandom
def knnPlayer( trainPlies, gameBoard, playerTurn ): bestMove= (None,None) bestAcc= -float("inf") #consider your next step validMoves= aif.getValidMoves( gameBoard ) for (x, y) in validMoves: gameBoard[x,y]= playerTurn plie= [] numrows, numColumns= py.shape(gameBoard) for i in range(0,numColumns): plie+= reversed( gameBoard[0:numrows,i] ) acc= aif.knn( 150, trainPlies, plie, playerTurn ) if acc > bestAcc: #probably win for us bestMove= (x,y) bestAcc= acc gameBoard[x,y]= 0 return bestMove,0
def randomOffenseWithTwicePlus(gameBoard, playerTurn): move,isBlockOrWin= lookAheadTwicePlus(gameBoard,playerTurn) if isBlockOrWin == 2 or isBlockOrWin: return move, isBlockOrWin '''isSingleLineTrap, blockingMove= aif.blockSingleLineTrap(gameBoard, playerTurn) if isSingleLineTrap: return blockingMove, isSingleLineTrap''' validMoves= aif.getValidMoves( gameBoard ) filterWorked, validMoves= aif.uselessSlotFilter( gameBoard, validMoves, playerTurn ) if filterWorked: #choose move with higher number bestVal= -1 for (x,y,value) in validMoves: if value > 1 and value > bestVal and aif.isSafeToPlayPlus( (x,y), playerTurn, gameBoard ): move= (x,y) bestVal= value return move, 0 return move, 0
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
def lookAheadThrice(gameBoard, playerTurn): #get all possible moves on gameBoard possibleMoves= aif.getValidMoves(gameBoard) #get best move based on state of resulting boards myBestMove, isBlockOrWin= lookAheadTwice(gameBoard, playerTurn) if isBlockOrWin: #print "NOT GONNA BOTHER, FOUND BLOCK OR WIN" return myBestMove, isBlockOrWin bestBoard= py.copy(gameBoard) #play my best move based on local state bestBoard[myBestMove]= playerTurn opponentTurn= aif.getOpponent(playerTurn) yourBestMove, _= lookAheadTwice(bestBoard, opponentTurn) #print "lookAheadThrice -- yourBestMove ", yourBestMove #play opponent's best move based on local state bestBoard[yourBestMove]= opponentTurn myOtherBestMove, _= lookAheadTwice(bestBoard, playerTurn) bestBoard[myOtherBestMove]= playerTurn for x,y in possibleMoves: #play move newBoard= py.copy(gameBoard) newBoard[x,y]= playerTurn #get opponent's best move based on this new state opponentMove, _= lookAheadTwice(newBoard, opponentTurn) newBoard[opponentMove]= opponentTurn #get my next best move based on this new state myMove, _= lookAheadOne(newBoard, playerTurn) newBoard[myMove]= playerTurn #score this 'final' state isNewBetter, myScore, yourScore= aif.isBetterState(newBoard, bestBoard, playerTurn) #print isNewBetter, myScore, yourScore if isNewBetter == 1: #print "FOUND SOMETHING BETTER THAN lookAheadTwice: ", x,y bestBoard= newBoard myBestMove= (x,y) return myBestMove, not isBlockOrWin
def lookAheadOne(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) 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)) for x,y in possibleMoves: #play move newBoard= py.copy(gameBoard) newBoard[x,y]= playerTurn isNewBetter, myScore, yourScore= aif.isBetterState(newBoard, bestBoard, playerTurn) if isNewBetter == 1: #print "FOUND SOMETHING BETTER THAN BESTLOCALMOVEPLUS: ", x,y bestMove= (x,y) bestBoard= newBoard #return move leading to that state return bestMove, isBlockOrWin
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
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