def preventTrapPlus(originalBoard, myMove, opponentMove, futureBoard, playerTurn): #if futureoard has a trap, find missing slot that will lead to trap and play there. #return flag and that position if it exists and it's possible to play there now. #print "IN" #if exists but not of them are playable yet, return flag and (-1,-1) opponentTurn= getOpponent(playerTurn) possibleLosses= [] traps= [] trapFound= False possibleBadMoves= py.zeros((0,0)) yourOrScores, myOrScores, orCandidateSlots= scoreBoard(originalBoard, opponentTurn) yourFScores, myFScores, futureCandidateSlots= scoreBoard(futureBoard, opponentTurn) for score in futureCandidateSlots.keys(): #if trapFound: # break if score >= 7: #get slots loseSlots= futureCandidateSlots[score] for slot in loseSlots: slotX,slotY,player= slot if player != opponentTurn: #print" ok" pass else: #print"this is for opponent" temp= py.copy(futureBoard) temp[slotX,slotY]= opponentTurn isLoss2, winner2, pos2= glf.moveYieldsWin(temp, 4, (slotX,slotY), 'r') #print isLoss2 if isLoss2: #check if any pair seen thus far are actually part of a trap for ((x,y),pos) in possibleLosses: #print "loop" #print "comparing ", pos , " with ", pos2 if isTrap(pos, pos2, originalBoard): traps.append( [ ( (x,y),pos ),( (slotX,slotY),pos2 ) ] ) trapFound= True possibleBadMoves= py.append( possibleBadMoves, pos ) possibleBadMoves= py.append( possibleBadMoves, pos2 ) #break possibleLosses.append( ((slotX,slotY), pos2) ) #if slot not in possibleLosses: # possibleLosses.append(slot) if trapFound: myX,myY= myMove yourX,yourY= opponentMove for pair in traps: for ((x,y), pos) in pair: for row in pos: #print "checking for prevention block: ", row[0], row[1] if isSafeToPlayPlus( (row[0],row[1]), playerTurn, originalBoard): return 1, (row[0],row[1]) #before returning, check if myMove is involved in any traps #how to check if move involved in trap? #1----if removing it from futureBoard does not change numTraps found possibleBadMoves= py.reshape(possibleBadMoves, (len(possibleBadMoves)/2,2)) for row in possibleBadMoves: if (myX-1, myY) == (row[0], row[1]): return -1, myMove return 0, myMove '''if isPlayable(opponentMove, originalBoard): #then can bprevent trap by playing where opponent would have played return 1, opponentMove elif myY == yourY and myX == yourX+1: #then my move opened up the possibility of a trap: do not play at my move return -1, myMove else: print "preventing trap failed because current moves did not lead to it! What happened..........." return -2, myMove ''' else: return 0, myMove
''' def isSafeToPlay((x,y), opponentScores, gameBoard): return opponentScores[x-1,y] < 7 and isPlayable( (x,y), gameBoard ) ''' '@param (x,y) - coordinates of target slot '@param playerTurn - player about to make a move '@gameBoard - board state under consideration '@calling getOpponent '@caller functions in ai ''' def isSafeToPlayPlus( (x,y), playerTurn, gameBoard): temp=py.copy(gameBoard) opponentTurn= getOpponent(playerTurn) temp[x-1,y]= opponentTurn isLoss, _, _= glf.moveYieldsWin(temp, 4, (x-1,y), 'r') return not isLoss and isPlayable( (x,y), gameBoard ) ''' '@param x,y - target move '@param TODO TODO TODO TODO TODO refine '@spec return true if x,y allows opponent to win or if future board already has a win for opponent ''' def leadsToLoss((x,y)): return ''' '@param originalBoard - initial state of board before applying myMove and opponentMove '@param myMove - move I want to make '@param opponentMove - move I Think opponent will make '@param futureBoard - new sate of board after applying myMove and opponentMove
def preventTrap(originalBoard, myMove, opponentMove, futureBoard, playerTurn): #if futureoard has a trap, find missing slot that will lead to trap and play there. #return flag and that position if it exists and it's possible to play there now. #if exists but not of them are playable yet, return flag and (-1,-1) opponentTurn= getOpponent(playerTurn) possibleLosses= [] trapFound= False yourOrScores, myOrScores, orCandidateSlots= scoreBoard(originalBoard, opponentTurn) yourFScores, myFScores, futureCandidateSlots= scoreBoard(futureBoard, opponentTurn) for score in futureCandidateSlots.keys(): if trapFound: break if score >= 7: #get slots loseSlots= futureCandidateSlots[score] for slot in loseSlots: slotX,slotY,player= slot if player != opponentTurn: pass elif yourFScores[slotX-1,slotY] >= 7: #this slot and the one above it form a trap temp= py.copy(futureBoard) temp[slotX-1,slotY]= opponentTurn isLoss1, winner1, pos1= glf.moveYieldsWin(temp, 4, (slotX-1,slotY), 'r') temp[slotX-1,slotY]= 0 temp[slotX,slotY]= opponentTurn isLoss2, winner2, pos2= glf.moveYieldsWin(temp, 4, (slotX,slotY), 'r') if isLoss1 and isLoss2: trapFound= True #print slotX, slotY, " and ", slotX-1,slotY break #find sequentialPositions leading to a win with this slot #get playable moves on current board #play at a slot that is in intersection of sequentialPositions and playable moves elif yourFScores[slotX+1,slotY] >= 7: #this slot and the one below it form a trap temp= py.copy(futureBoard) temp[slotX+1,slotY]= opponentTurn isLoss1, winner1, pos1= glf.moveYieldsWin(temp, 4, (slotX+1,slotY), 'r') temp[slotX+1,slotY]= 0 temp[slotX,slotY]= opponentTurn isLoss2, winner2, pos2= glf.moveYieldsWin(temp, 4, (slotX,slotY), 'r') if isLoss1 and isLoss2: trapFound= True #print slotX, slotY, " and ", slotX+1,slotY break if slot not in possibleLosses: possibleLosses.append(slot) if trapFound: myX,myY= myMove yourX,yourY= opponentMove if isPlayable(opponentMove, originalBoard): #then can bprevent trap by playing where opponent would have played return 1, opponentMove elif myY == yourY and myX == yourX+1: #then my move opened up the possibility of a trap: do not play at my move return -1, myMove else: #print "preventing trap failed because current moves did not lead to it! What happened..........." return -2, myMove else: return 0, myMove
def gamePlay(player1Mode, player2Mode,trainPlies=None, useGui=1): sequentialPositionsNeeded= 4 playerModes= {1:player1Mode, 2:player2Mode} if useGui: plt.ion() boardHandler= gui.createBoard() else: boardHandler= None shape= (gui.NUM_ROWS, gui.NUM_COLUMNS) gameBoard= py.zeros(shape) winner= -1 playerTurn= 1 playerColor= gui.PLAYER1_COLOR cumulatedTime= 0.0 numMoves= 0 while winner == -1: moveValid= True #print "-------------------------------------------------Start Turn---------------------------------------------" #print playerTurn if playerModes[playerTurn] == "Human": res= boardHandler.ginput(n=1, timeout=9999999) x,y= res[0] x,y= math.floor(x),math.floor(y) #update gameBoard if move valid if glf.isMoveValid( x, gameBoard ): matrixX,matrixY= glf.playMove( (x,y), gameBoard, boardHandler, playerColor, playerTurn, useGui ) else: #request click from same player moveValid= False print "move not valid. please click in a cell" elif playerModes[playerTurn] == "Random": startTime= time.time() matrixX,matrixY= ai.randomMove(gameBoard) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "RandomPlus": startTime= time.time() matrixX,matrixY= ai.randomMovePlus(gameBoard) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "RandomPlus2": startTime= time.time() matrixX,matrixY= ai.randomMovePlus2(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "RandomPlusPlus": startTime= time.time() (matrixX,matrixY),isRandom= ai.randomMovePlusPlus(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "BestLocal": startTime= time.time() matrixX,matrixY= ai.bestLocalMove(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "BestLocalPlus": startTime= time.time() (matrixX,matrixY),isBlockOrWin= ai.bestLocalMovePlus(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "lookAheadOne": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.lookAheadOne(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "lookAheadTwice": startTime= time.time() (matrixX,matrixY),isBlockOrWin= ai.lookAheadTwice(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "lookAheadThrice": startTime= time.time() (matrixX,matrixY),isBlockOrWin= ai.lookAheadThrice(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "lookAheadOnePlus": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.lookAheadOnePlus(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "lookAheadTwicePlus": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.lookAheadTwicePlus(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "lookAheadThricePlus": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.lookAheadThricePlus(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "randomOffense": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.randomOffense(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "randomOffenseWithTwicePlus": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.randomOffenseWithTwicePlus(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "randomOffenseOneWithTwicePlus": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.randomOffenseOneWithTwicePlus(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "forwardEval": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.forwardEval(gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "knnPlayer": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.knnPlayer( trainPlies[playerTurn], gameBoard, playerTurn ) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "minimaxKnn": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.minimaxKnn( trainPlies[playerTurn], gameBoard, playerTurn) endTime= time.time() matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) elif playerModes[playerTurn] == "minimaxSeqCellsPlus": startTime= time.time() (matrixX,matrixY),isBlockOrwin= ai.minimaxSeqCellsPlus( None, gameBoard, playerTurn) endTime= time.time() #if not glf.isMoveValid( matrixX, gameBoard ): # print "minimaxSeqCellsPlus returns invalid move: ", matrixX, matrixY matrixX,matrixY= glf.playMove( (matrixY,matrixX), gameBoard, boardHandler, playerColor, playerTurn, useGui ) #print "-------------------------------------------------End Turn---------------------------------------------" if moveValid: if playerTurn == 2: cumulatedTime+= endTime-startTime numMoves+=1 res,winner,pos= glf.moveYieldsWin( gameBoard, sequentialPositionsNeeded, (matrixX,matrixY), playerColor ) if res: print "WE HAVE A WINNER!!" print winner print "positons are: " print pos fileText= "average time for " + str(playerModes[2]) + " = " + str( cumulatedTime / numMoves ) with open( 'times', 'a' ) as f: f.write( fileText + "\n" ) return winner elif glf.gameContainsTie(gameBoard): print "Game is Tied!! GG" fileText= "average time for " + str(playerModes[2]) + " = " + str( cumulatedTime / numMoves ) with open( 'times', 'a' ) as f: f.write( fileText + "\n" ) return 0 #next player's turn if playerTurn == 1: playerTurn= 2 playerColor= gui.PLAYER2_COLOR else: playerTurn= 1 playerColor= gui.PLAYER1_COLOR