Example #1
0
    def chooseMove(self, board, prevMove): #REMEMBER TO CHECK IF FINDVALIDMOVES HAS BEEN CALLED BEFORE GETTING
        '''
        board is a two-dimensional list representing the current board configuration.
        board is a copy of the original game board, so you can do to it as you wish.
        board[i][j] is 'W', 'B', 'G' when row i and column j contains a
        white piece, black piece, or no piece respectively.
        As usual i, j starts from 0, and board[0][0] is the top-left corner.
        prevMove gives the i, j coordinates of the last move made by your opponent.
        prevMove[0] and prevMove[1] are the i and j-coordinates respectively.
        prevMove may be None if your opponent has no move to make during his last turn.
        '''       
        memUsedMB = memory.getMemoryUsedMB()
        if memUsedMB > constants.MEMORY_LIMIT_MB - 100: #If I am close to memory limit
            #don't allocate memory, limit search depth, etc.
            #RandomPlayer uses very memory so it does nothing
            pass

        dirs = ((-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1))
        color = self.color
       
        if   color == 'W': oppColor = 'B'
        elif color == 'B': oppColor = 'W'
        else: assert False, 'ERROR: Current player is not W or B!'

        self.numberOfPly +=1
        colorValue = 1 if color == 'W' else -1
        bitBoards = bu.convertToBitBoards(board)
        x=self.negamax(bitBoards,DEPTH,colorValue, -99999, 99999, None)[1]
        coordinates=None
        if x!=None:
            coordinates = divmod(x, constants.BRD_SIZE)
        print "Move: ", coordinates

        return coordinates
Example #2
0
    def run(self):
        data = self.player.getColor()
        assert data == 'W' or data == 'B', "ERROR: expecting color to be 'W' or 'B'"
        self.soc.send(data)

        while True:
            data = self.soc.recv(constants.BUF_SIZE)
            choice = int(data[0])
            data = data[1:]
            outData = None
            if choice == 1: #chooseMove
                board = self.unpackBoard(data)
                a = constants.BRD_SIZE*constants.BRD_SIZE                
                data = data[a:]
                cols = data.strip().split()
                prevMove = int(cols[0]),  int(cols[1])
                
                if prevMove[0] >= constants.BRD_SIZE or prevMove[1] >=constants.BRD_SIZE : prevMove = None
                move = self.player.chooseMove(board, prevMove)
                memMB = memory.getMemoryUsedMB()
                if move:  outData = '%d %d %f' % (move[0], move[1], memMB)
                else:     outData = '%d %d %f' % (constants.BRD_SIZE+1, constants.BRD_SIZE+1, memMB) #no move                
                self.soc.send(outData)

            elif choice == 2: #gameEnd
                board = self.unpackBoard(data)
                self.player.gameEnd(board)
                outData = '0' #noop
                self.soc.send(outData)
                break
            else:
                assert False, 'ERROR: expect data[0] to be 0 or 1'

        self.soc.close()
Example #3
0
    def chooseMove(self, board, prevMove):
        '''
        board is a two-dimensional list representing the current board configuration.
        board is a copy of the original game board, so you can do to it as you wish.
        board[i][j] is 'W', 'B', 'G' when row i and column j contains a
        white piece, black piece, or no piece respectively.
        As usual i, j starts from 0, and board[0][0] is the top-left corner.
        prevMove gives the i, j coordinates of the last move made by your opponent.
        prevMove[0] and prevMove[1] are the i and j-coordinates respectively.
        prevMove may be None if your opponent has no move to make during his last turn.
        '''       
        memUsedMB = memory.getMemoryUsedMB()
        if memUsedMB > constants.MEMORY_LIMIT_MB - 100: #If I am close to memory limit
            #don't allocate memory, limit search depth, etc.
            #RandomPlayer uses very memory so it does nothing
            pass
               
        dirs = ((-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1))
        color = self.color
        if   color == 'W': oppColor = 'B'
        elif color == 'B': oppColor = 'W'
        else: assert False, 'ERROR: Current player is not W or B!'

        moves = []
        for i in xrange(len(board)):
            for j in xrange(len(board[i])):
                if board[i][j] != 'G': continue #background is green, i.e., empty square
                for ddir in dirs:
                    if self.validMove(board, (i,j), ddir, color, oppColor):
                        moves.append((i,j))
                        break
        if len(moves) == 0: return None #no valid moves
        i = random.randint(0,len(moves)-1) #randomly pick a valid move
        return moves[i]
 def chooseMove(self, board, prevMove):
     '''
     board is a two-dimensional list representing the current board configuration.
     board is a copy of the original game board, so you can do to it as you wish.
     board[i][j] is 'W', 'B', 'G' when row i and column j contains a
     white piece, black piece, or no piece respectively.
     As usual i, j starts from 0, and board[0][0] is the top-left corner.
     prevMove gives the i, j coordinates of the last move made by your opponent.
     prevMove[0] and prevMove[1] are the i and j-coordinates respectively.
     prevMove may be None if your opponent has no move to make during his last turn.
     '''       
     memUsedMB = memory.getMemoryUsedMB()
     if memUsedMB > constants.MEMORY_LIMIT_MB - 100: #If I am close to memory limit
         #don't allocate memory, limit search depth, etc.
         #RandomPlayer uses very memory so it does nothing
         pass
     return self.pickBestMove(board)
Example #5
0
    def run(self):
        data = self.player.getColor()
        assert data == 'W' or data == 'B', "ERROR: expecting color to be 'W' or 'B'"
        self.soc.send(data)

        while True:
            data = self.soc.recv(constants.BUF_SIZE)
            choice = int(data[0])
            data = data[1:]
            outData = None
            if choice == 1:  #chooseMove
                board = self.unpackBoard(data)
                a = constants.BRD_SIZE * constants.BRD_SIZE
                data = data[a:]
                cols = data.strip().split()
                prevMove = int(cols[0]), int(cols[1])

                if prevMove[0] >= constants.BRD_SIZE or prevMove[
                        1] >= constants.BRD_SIZE:
                    prevMove = None
                move = self.player.chooseMove(board, prevMove)
                memMB = memory.getMemoryUsedMB()
                if move: outData = '%d %d %f' % (move[0], move[1], memMB)
                else:
                    outData = '%d %d %f' % (
                        constants.BRD_SIZE + 1, constants.BRD_SIZE + 1, memMB
                    )  #no move
                self.soc.send(outData)

            elif choice == 2:  #gameEnd
                board = self.unpackBoard(data)
                self.player.gameEnd(board)
                outData = '0'  #noop
                self.soc.send(outData)
                break
            else:
                assert False, 'ERROR: expect data[0] to be 0 or 1'

        self.soc.close()
Example #6
0
    def chooseMove(self, board, prevMove):
        '''
        board is a two-dimensional list representing the current board configuration.
        board is a copy of the original game board, so you can do to it as you wish.
        board[i][j] is 'W', 'B', 'G' when row i and column j contains a
        white piece, black piece, or no piece respectively.
        As usual i, j starts from 0, and board[0][0] is the top-left corner.
        prevMove gives the i, j coordinates of the last move made by your opponent.
        prevMove[0] and prevMove[1] are the i and j-coordinates respectively.
        prevMove may be None if your opponent has no move to make during his last turn.
        '''
        memUsedMB = memory.getMemoryUsedMB()
        if memUsedMB > constants.MEMORY_LIMIT_MB - 100:  #If I am close to memory limit
            #don't allocate memory, limit search depth, etc.
            #RandomPlayer uses very memory so it does nothing
            pass

        dirs = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0),
                (1, 1))
        color = self.color
        if color == 'W': oppColor = 'B'
        elif color == 'B': oppColor = 'W'
        else: assert False, 'ERROR: Current player is not W or B!'

        moves = []
        for i in xrange(len(board)):
            for j in xrange(len(board[i])):
                if board[i][j] != 'G':
                    continue  #background is green, i.e., empty square
                for ddir in dirs:
                    if self.validMove(board, (i, j), ddir, color, oppColor):
                        moves.append((i, j))
                        break
        if len(moves) == 0: return None  #no valid moves
        i = random.randint(0, len(moves) - 1)  #randomly pick a valid move
        return moves[i]
Example #7
0
  def chooseMove(self,board,prevMove):
      memUsedMB = memory.getMemoryUsedMB()
      if memUsedMB > constants.MEMORY_LIMIT_MB - 100: #If I am close to memory limit
          #don't allocate memory, limit search depth, etc.
          #RandomPlayer uses very memory so it does nothing
          pass
             
      dirs = ((-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1))
      color = self.color
      if   color == 'W': oppColor = 'B'
      elif color == 'B': oppColor = 'W'
      else: assert False, 'ERROR: Current player is not W or B!'

      moves = []
      for i in xrange(len(board)):
          for j in xrange(len(board[i])):
              if board[i][j] != 'G': continue #background is green, i.e., empty square
              for ddir in dirs:
                  if self.validMove(board, (i,j), ddir, color, oppColor):
                      moves.append((i,j))
                      break
      if len(moves) == 0: return None #no valid moves
      i = random.randint(0,len(moves)-1) #randomly pick a valid move
      return moves[i]
Example #8
0
  def chooseMove(self, board, prevMove):
    '''
    board is a two-dimensional list representing the current board configuration.
    board is a copy of the original game board, so you can do to it as you wish.
    board[i][j] is 'W', 'B', 'G' when row i and column j contains a
    white piece, black piece, or no piece respectively.
    As usual i, j starts from 0, and board[0][0] is the top-left corner.
    prevMove gives the i, j coordinates of the last move made by your opponent.
    prevMove[0] and prevMove[1] are the i and j-coordinates respectively.
    prevMove may be None if your opponent has no move to make during his last turn.
    '''

    # Check for the memory

    memUsedMB = memory.getMemoryUsedMB()
    if memUsedMB > constants.MEMORY_LIMIT_MB - 100:
      #If I am close to memory limit
      #don't allocate memory, limit search depth, etc.
      #RandomPlayer uses very memory so it does nothing
      print "Over memory limit, please alter!"


    # dirs = ((-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)) # same as the dirs in constants.py
    # color = self.myColor
    # if   color == 'W': oppColor = 'B'
    # elif color == 'B': oppColor = 'W'
    # else: assert False, 'ERROR: Current player is not W or B!'

    # This is from random player
    # find all valid moves

    # to have a random element in our movement making
    randomSwitch = random.randint(0,1)

    # opening move database
    # parallel, diagonal and perpendicular openings
    # if white, parallel is the best. If black, avoid parallel

    boardParallel = [['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'B', 'W', 'G', 'G',
 'G'], ['G', 'G', 'G', 'B', 'W', 'G', 'G', 'G'], ['G', 'G', 'G', 'B', 'W', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G'
, 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G']]

    boardDiagonal1 = [['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'W', 'G', 'G',
 'G'], ['G', 'G', 'G', 'W', 'W', 'G', 'G', 'G'], ['G', 'G', 'G', 'B', 'W', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G'
, 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G']]

    boardDiagonal2 = [['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G',
 'G'], ['G', 'G', 'G', 'W', 'W', 'W', 'G', 'G'], ['G', 'G', 'G', 'B', 'W', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G'
, 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G']]

    boardDiagonal3 = [['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G',
 'G'], ['G', 'G', 'G', 'W', 'B', 'G', 'G', 'G'], ['G', 'G', 'G', 'W', 'W', 'G', 'G', 'G'], ['G', 'G', 'G', 'W', 'G', 'G'
, 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G']]

    boardDiagonal4 = [['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G',
 'G'], ['G', 'G', 'G', 'W', 'B', 'G', 'G', 'G'], ['G', 'G', 'W', 'W', 'W', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G'
, 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G'], ['G', 'G', 'G', 'G', 'G', 'G', 'G', 'G']]


    if self.moveCount == 0 and self.myColor == "W":
      self.moveCount += 1
      return (2,4)

    if board == boardParallel and self.myColor == "W":
      return (3,2)

    if board == boardDiagonal1 and self.myColor == "B":
      return (2,5)

    if board == boardDiagonal2 and self.myColor == "B":
      return (2,5)

    if board == boardDiagonal3 and self.myColor == "B":
      return (5,2)

    if board == boardDiagonal4 and self.myColor == "B":
      return (5,2)

    # selection of moves
    moves = []
    for i in xrange(len(board)):
      for j in xrange(len(board[i])):
        if board[i][j] != 'G': continue #background is green, i.e., empty square
        for ddir in constants.DIRECTIONS:
          if self.validMove(board, (i,j), ddir, self.myColor, self.oppoColor):
            moves.append((i,j))
            break
    if len(moves) == 0: return None #no valid moves

    # Use minimax to get best move
    bestMove = moves[0]
    bestValue = self.bestValue

    # reverse the moves for a random ordering of the variables.
    if randomSwitch == 1:
      moves = moves[::-1]
    #  print "reversed!"

    emptySpaces = self.count_empty(board)
    if emptySpaces < 12:
      print "Changing depth of search"
      self.depth = 11

    for move in moves:
      # you are a max player
      value = self.max_value(board, move, self.depth, self.alpha, self.beta)
      print "  M, V:", move, value
      if value > bestValue:
        bestValue = value
        bestMove = move

      print bestMove
      self.moveCount += 1
      return bestMove
Example #9
0
  def chooseMove(self, board, prevMove):
    '''
    board is a two-dimensional list representing the current board configuration.
    board is a copy of the original game board, so you can do to it as you wish.
    board[i][j] is 'W', 'B', 'G' when row i and column j contains a
    white piece, black piece, or no piece respectively.
    As usual i, j starts from 0, and board[0][0] is the top-left corner.
    prevMove gives the i, j coordinates of the last move made by your opponent.
    prevMove[0] and prevMove[1] are the i and j-coordinates respectively.
    prevMove may be None if your opponent has no move to make during his last turn.
    '''

    # Check for the memory

    memUsedMB = memory.getMemoryUsedMB()
    if memUsedMB > constants.MEMORY_LIMIT_MB - 100:
      #If I am close to memory limit
      #don't allocate memory, limit search depth, etc.
      #RandomPlayer uses very memory so it does nothing
      print "Over memory limit, please alter!"

    # Get the current state of the board
    count_empty = self.count_empty(board)

    # dirs = ((-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)) # same as the dirs in constants.py
    # color = self.myColor
    # if   color == 'W': oppColor = 'B'
    # elif color == 'B': oppColor = 'W'
    # else: assert False, 'ERROR: Current player is not W or B!'

    # This is from random player
    # find all valid moves

    state = 0 #state 0 = opening, state 1 = after opening,

    #parallel, diagonal and perpendicular openings
    # if white, parallel is the best. If black, avoid parallel

    opening_moves = {}


    moves = []
    for i in xrange(len(board)):
      for j in xrange(len(board[i])):
        if board[i][j] != 'G': continue #background is green, i.e., empty square
        for ddir in constants.DIRECTIONS:
          if self.validMove(board, (i,j), ddir, self.myColor, self.oppoColor):
            moves.append((i,j))
            break
    if len(moves) == 0: return None #no valid moves

    # Use minimax to get best move
    bestMove = moves[0]
    bestValue = self.bestValue


    for move in moves:
      # you are a max player

      # additional part for late game.
      if count_empty <= 12:
        value = self.max_value(board, move, 12, self.alpha, self.beta)
      else:
        value = self.max_value(board, move, self.depth, self.alpha, self.beta)

      print "  M, V:", move, value
      if value > bestValue:
        bestValue = value
        bestMove = move

      print bestMove
      moveCount += 1
      return bestMove
Example #10
0
    def chooseMove(self, board, prevMove):
        functionStartTime = time.time()
        '''
        board is a two-dimensional list representing the current board configuration.
        board is a copy of the original game board, so you can do to it as you wish.
        board[i][j] is 'W', 'B', 'G' when row i and column j contains a
        white piece, black piece, or no piece respectively.
        As usual i, j starts from 0, and board[0][0] is the top-left corner.
        prevMove gives the i, j coordinates of the last move made by your opponent.
        prevMove[0] and prevMove[1] are the i and j-coordinates respectively.
        prevMove may be None if your opponent has no move to make during his last turn.
        '''
        player, opponent = makeBitBoard(board, self.color)
        numEmptiesLeft = getNumEmptiesLeft(player, opponent)

        # Check if the engine unconventionally asks white to play first.
        # If yes, we flip horizontally for the game.
        if self.whiteStartFirst == -1:
            if numEmptiesLeft == 60:
                self.whiteStartFirst = self.color == 'W'
            elif numEmptiesLeft == 59:
                self.whiteStartFirst = self.color == 'B'
            if self.whiteStartFirst:
                print "White Starts First!"
            else:
                print "Black Starts First!"

        if self.whiteStartFirst:
            player = horizontalMirrorDiscsSingle(player)
            opponent = horizontalMirrorDiscsSingle(opponent)

        moveMade = False
        useOpeningBook = True
        validMoves = getMoves(player, opponent)
        score = "N.A."

        if validMoves:

            if useOpeningBook:  # If opening book is to be used
                combined = (player << 128) | opponent
                unique, symmetryIndex = getUniqueBoard(
                    combined)  # Not rly a perf issue... only ~ 30x per game
                if unique in openingBook:
                    move = getSymmetricMoveSingleInverse(
                        random.choice(openingBook[unique]), symmetryIndex)
                    moveMade = True
                    print "Opening book used!"

            if not moveMade:
                searchDepth = getSuggestedDepthForCompetition(
                    self.schedule["midGameTimeLeft"],
                    self.schedule["gameTimeLeft"],
                    self.schedule["endGameNumEmpties"],
                    self.schedule["minSearchDepth"], player, opponent,
                    self.schedule["previousDepthCounters"],
                    self.schedule["previousSearchTime"])
                isEndGame = searchDepth > 60
                if isEndGame:
                    print "Endgame Search, # Empties:", numEmptiesLeft
                else:
                    print "Search Depth:", searchDepth
                # init schedule analysis stuff
                depthCounters = None if isEndGame else getNewDepthCounters(
                    searchDepth)
                searchTimeStart = time.time()
                # do search
                searchResults = reversiABNegaScout(player, opponent,
                                                   searchDepth, depthCounters)
                # record schedule analysis stuff
                searchTime = time.time() - searchTimeStart
                self.schedule["previousDepthCounters"] = depthCounters
                self.schedule["previousSearchTime"] = searchTime
                # assign search results
                move, score = searchResults
                moveMade = True
        else:
            return None  # No valid move, better return None

        if self.printBoard:
            try:
                rev = [m[1] for m in validMoves if m[0] == move][0]
                printPlayer, printOpponent = getPut(player, opponent, move,
                                                    rev)
                if self.whiteStartFirst:
                    printPlayer = horizontalMirrorDiscsSingle(printPlayer)
                    printOpponent = horizontalMirrorDiscsSingle(printOpponent)
                printBitBoard(printPlayer, printOpponent, self.color)
            except:
                pass

        # Print stats...
        ramUsage = ""
        try:
            ramUsage = " RAM: %2.1fMB" % memory.getMemoryUsedMB()
        except:
            pass
        printLines = ("Move: " + bitToLetterCoors[move] + " Score: " +
                      str(score), "Time Left: %ds" %
                      (self.schedule["gameTimeLeft"] -
                       (time.time() - functionStartTime)) + ramUsage)
        print "\n".join(printLines)
        print "=" * max(len(l) for l in printLines) + "\n"

        # Flip back move if needed...
        if self.whiteStartFirst:
            move = bitToIndex2D[horizontalMirrorDiscsSingle(move)]
        else:
            move = bitToIndex2D[move]

        functionTime = time.time() - functionStartTime
        self.schedule["midGameTimeLeft"] -= functionTime
        self.schedule["gameTimeLeft"] -= functionTime

        return move