def bestLocalMove(gameBoard, playerTurn): #score board for this player and opponent myScores, yourScores, candidateSlots= aif.scoreBoard(gameBoard, playerTurn) #get positions for score in sorted(candidateSlots.keys(), reverse=True): nextBests= candidateSlots[score] for x,y,player in nextBests: if aif.isSafeToPlay((x,y), yourScores, gameBoard): return x,y else: #print "CANNOT PLAY AT ", x, y,"-----------------------------------" pass
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 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