예제 #1
0
    def getMove(self, board):
        output.log("Selecting move...", module = "Player")
        tree = self.getGameTree(board, 1)
        energy = len(tree.children)

        moves = [x.board.move for x in tree.children]

        if len(moves) == 0:
            return None

        if energy < self.energythreshold:
            output.log("Energy %s is lower than %s, so I'll play near the bottom" %  (energy, self.energythreshold), module = "Player")
            move1 = min(moves, key = lambda x : x[0][0]) #choose nearest to the top
            move2 = min(moves, key = lambda x : x[1][0])
            move = min(move1, move2)
        else:
            output.log("Energy %s is higher or equal to %s, so I'll play near the top" %  (energy, self.energythreshold), module = "Player")
            move1 = max(moves, key = lambda x : x[0][0]) #choose nearest to the top
            move2 = max(moves, key = lambda x : x[1][0])
            move = max(move1, move2)

        output.log(move, module = "Player")

        output.log("Move is ", move, module = "Player")
        return move
예제 #2
0
    def getMove(self, board):
        output.log("Selecting move...", module = "Player")

        moveInput = self.inputStream.readline().strip()

        try:
            matches = re.findall(r'^(\d+) (\d+) (\d+) (\d+)$', moveInput)[0]
            matches = [int(match) for match in matches]
            move = ((matches[0], matches[1]), (matches[2], matches[3]))
        except IndexError:
            output.log("Error parsing input!", module = "Error")
            move = None


        return move
예제 #3
0
    def sanitize(self, verbose=True):
        if verbose:
            output.log("Sanitizing board...", module = 'Board')

        def testrefillBoard(refill):
            for i in range(0, self.columns):
                for j in range(0, self.rows):
                    if (refill[0].getItem(i, j) > 0):
                        return False
            return True

        #WARNING: the snippet below does not correctly simmulate the game's logic
        donesanitizing = False
        while not donesanitizing:
            donegravity = False
            while not donegravity:
                self.explodePatterns()
                donegravity = self.simulateGravity()

            donesanitizing = testrefillBoard(self.refillBoard())

        if verbose:
            output.log("Done sanitizing.", module = 'Board')
예제 #4
0
 def getMove(self, board):
     output.log("Calculating tree up to %s levels..." % self.depth, module = "Player")
     tree = self.getGameTree(board, self.depth)
     output.log("Calculating path...", module = "Player")
     (score, path) = self.getPath(tree)
     output.log("Path is %s (Score: %s). Will take first step and recalculate." % (path, score), module = "Player")
     if len(path) > 0:
         return path[0]
     else:
         return None
예제 #5
0
    def __init__(self, *args, **kwargs):

        def getPlayer(name):

            playeroptions = {

             'Human':
                player.Human(self.moves, self.name, self.inputStream),

             'BestScore':
                player.BestScore(self.moves, self.depth),

             'BestEnergy':
                player.BestEnergy(self.moves, self.depth),

             'BestScoreBetterEnergy':
                player.BestScoreBetterEnergy(self.moves, self.depth, self.minenergy),

             'EnergyVSEntropy':
                player.EnergyVSEntropy(self.moves, self.depth, self.energythreshold),

             'EnergyVSEntropyReversed':
                player.EnergyVSEntropyReversed(self.moves, self.depth, self.energythreshold),

             'GreedyEnergyVSEntropy':
                player.GreedyEnergyVSEntropy(self.moves, self.energythreshold)

            }

            return playeroptions[name]

        def getListOfPossibleMoves(rows, columns):

            moves = []

            #horizontals
            for i_a in range(0, rows):
                for j_a in range(0, columns-1):
                    moves.append(((i_a, j_a), (i_a, j_a+1)))

            #verticals
            for i_a in range(0, rows-1):
                for j_a in range(0, columns):
                    moves.append(((i_a, j_a), (i_a+1, j_a)))

            #output.log("For this %sx%s board, there are a total of %s possible moves " % (rows, columns, len(moves)), module = 'Logic')
            return moves

        self.pauses = kwargs.get('pause', False)
        self.shorten = kwargs.get('shorten', False)
        self.limit = kwargs.get('limit')
        self.depth = kwargs.get('depth')
        self.minenergy = kwargs.get('minenergy', 2)
        self.energythreshold = kwargs.get('energythreshold')

        self.boardfile = kwargs.get('boardfile', None)
        self.refillfile = kwargs.get('refillfile', None)

        # Human Player
        self.name = None
        self.inputStream = sys.stdin

        # Main loop terminates when this is set True
        self.forceEnd = False

        # generate a new game
        if self.boardfile is None:
            columns = kwargs.get('columns')
            rows = kwargs.get('rows')
            colours = kwargs.get('colours')
            self.moves = getListOfPossibleMoves(columns, rows)
            self.board = board.Board(columns, rows, colours)
            self.board.sanitize()

        # load a saved board
        else:
            try:
                self.board = board.Board.LoadBoard(self.boardfile)
                self.board.refillboard = board.Board.LoadRefill(self.refillfile)
            except Exception as e:
                output.log("Error: ", e, module = 'Logic')
                sys.exit(0)

            self.moves = getListOfPossibleMoves(self.board.rows, self.board.columns)

        self.player  = getPlayer(kwargs.get('player'))
예제 #6
0
    def playGame(self):

        STATE_BEGIN, STATE_MOVE, STATE_EXPLODE, STATE_GRAVITY, STATE_REFILL, STATE_TERMINATE = range(6)

        def stateBegin():

            output.event('logic_stateBegin', {
              'iteration' : self.iteration,
              'board_state' : self.board.state
            })

            return STATE_MOVE

        def stateMove():
            move = self.player.getMove(self.board)

            if (move == None):
                return True
            else:

                result = self.board.makeMove(move)

                output.event('logic_stateMove', {
                  'move' : str(move),
                  'marked_board' : self.board.state.reprConsoleMarkMoves(list(move)),
                  'move_result' : result
                })
                return False

        def stateExplode():

            (patterns, exploded) = self.board.explodePatterns()

            output.event('logic_stateExplode', {
              'patterns' : patterns,
              'exploded' : exploded,
              'board_state' : self.board.state,
              'shorten' : self.shorten
            })

            return exploded

        def stateGravity():

            fallCount = 0
            while not self.board.simulateGravity():
                fallCount += 1

            output.event('logic_stateGravity', {
              'board_state' : self.board.state,
              'fall_count' : fallCount,
              'shorten' : self.shorten
            })

        def stateRefill():
            (refill,_) = self.board.refillBoard()

            output.event('logic_stateRefill', {
              'board_state' : self.board.state,
              'refill' : refill,
              'shorten' : self.shorten
            })

        count = 0
        chain = 0
        totalcount = 0
        totalchain = 0
        score = 0

        self.iteration = 1
        while not self.forceEnd and (self.iteration <= self.limit or self.limit == 0):

            self.state = stateBegin()

            while self.state != STATE_BEGIN:
                if (self.state == STATE_MOVE):

                    #chain starts at -1 because the first time pieces explode, points should be multiplied by 2^0.
                    chain = -1
                    score = 0
                    jewels = []

                    result = stateMove()
                    if result:
                        output.log("Terminal state achieved in iteration %s. Score: %s." % (self.iteration, self.player.score), module = 'Logic')
                        output.log(self.board.state, module = 'Logic', printModule = False)
                        self.state = STATE_TERMINATE
                        break

                    self.state = STATE_EXPLODE

                elif (self.state == STATE_EXPLODE):
                    exploded = stateExplode()
                    count += exploded
                    jewels.append(exploded)
                    totalcount += exploded
                    chain += 1
                    totalchain += chain
                    self.lastscore = self.player.updateScore(exploded, chain)
                    score += self.lastscore
                    self.state = STATE_GRAVITY

                elif (self.state == STATE_GRAVITY):
                    stateGravity()
                    patterns = self.board.getPatterns()
                    if self.board.hasOnes(patterns):
                        self.state = STATE_EXPLODE
                    else:
                        self.state = STATE_REFILL

                elif (self.state == STATE_REFILL):
                    stateRefill()
                    patterns = self.board.getPatterns()
                    if self.board.hasOnes(patterns):
                        self.state = STATE_EXPLODE
                    else:
                        output.log("Local Chain: %s\tJewels: %s: %s\tScore: %s" % (chain, jewels, sum(jewels), score), module = 'Logic')
                        output.log("Total Chain: %s\tJewels: %s\tScore: %s" % (totalchain, totalcount, self.player.score), module = 'Logic')
                        self.state = STATE_BEGIN

            if (self.state == STATE_TERMINATE):
                break

            self.iteration += 1

            if (self.pauses):
                raw_input("Press enter to continue.")

        return {
          'iterations' : self.iteration - 1,
          'totalChains' : totalchain,
          'totalJewels' : totalcount,
          'score' : self.player.score
        }
예제 #7
0
    def getMove(self, board):
        output.log("Calculating tree up to %s levels..." % self.depth, module = "Player")
        tree = self.getGameTree(board, self.depth)
        output.log("Calculating best path...", module = "Player")
        (totalenergy, path) = self.getPath(tree)

        energyperdepthlevel =  (totalenergy / self.depth)

        if len(path) > 0:
            if energyperdepthlevel < self.energythreshold:
                output.log("Energy per depth level is %s, below the threshold of %s" % (energyperdepthlevel, self.energythreshold), module = "Player")
                output.log("Will attempt to get lucky and play near the bottom", module = "Player")

                moves = [x.board.move for x in tree.children]

                move1 = min(moves, key = lambda x : x[0][0]) #choose nearest to the bottom
                move2 = min(moves, key = lambda x : x[1][0])
                move = min(move1, move2)
                return move

            else:
                output.log("Energy per depth level is %s, above the threshold of %s" % (energyperdepthlevel, self.energythreshold), module = "Player")
                output.log("Path is %s (Energy: %s). Will take first step and recalculate." % (path, totalenergy), module = "Player")
                move = path[0]

                return move
        else:
            return None
예제 #8
0
                depth = b_depth,
            minenergy = b_minenergy,
                pause = b_pause,
      energythreshold = b_energythreshold,
              shorten = b_shorten
    )


# handle ^C
def handle_SIGINT(signal, frame):
    print('You pressed Ctrl+C!')
    game.endGame()

signal.signal(signal.SIGINT, handle_SIGINT)

output.log("**************************************", module = 'Main')
output.log("* Welcome to AI Bejeweled", module = 'Main')
output.log("* Rules:", module = 'Logic')
if game.boardfile is not None:
    output.log("*  Using board from %s and refill from %s " % (game.boardfile, game.refillfile), module = 'Main')
output.log("*  %sx%sx%s (%s possible moves)" % (game.board.columns, game.board.rows, game.board.colors, len(game.moves)), module = 'Main')
output.log("*  Using IA Agent %s " % game.player, module = 'Main')
if game.limit > 0:
    output.log("*  Will terminate after %s moves" % (game.limit), module = 'Main')
output.log("**************************************", module = 'Main')

results = game.playGame()

output.log("****************************************************************", module = 'Main')
output.log("* Simulation terminated after %s moves" % results['iterations'], module = 'Main')
output.log("****************************************************************", module = 'Main')