Exemple #1
0
def getAllPossibleGrid(grid: Grid, dir) -> List[Grid]:
    '''
    :param grid: A grid
    :param dir: A move
    :return: a list of all possible result of move
    '''
    if grid.isTerminal():
        # return the original grid if the game is terminal
        return [grid.clone()]
    ret = grid.clone()
    ret.move(dir)
    if not grid.canMove([dir]):
        raise ValueError('Invalid Move')
    cells = ret.getAvailableCells()
    grids = []
    for cell in cells:
        ret2 = ret.clone()
        ret2.setCellValue(cell, 2)
        grids.append(ret2)
    return grids
Exemple #2
0
class GameManager:
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.computerAI = None
        self.playerAI = None
        self.displayer = None
        self.over = False

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        for i in range(self.initTiles):
            self.insertRandonTile()

        self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                print("Player's Turn:")
                move = self.playerAI.getMove(gridCopy)
                print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - 1")
                    self.over = True
            else:
                print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            if not self.over:
                self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.clock())

            turn = 1 - turn
        print(maxTile)

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0, 99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1]

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)
Exemple #3
0
class GameManager:
    def __init__(self,
                 size=4,
                 intelligentAgent=None,
                 computerAI=None,
                 displayer=None):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.over = False

        # Initialize the AI players
        self.computerAI = computerAI or ComputerAI()
        self.intelligentAgent = intelligentAgent or IntelligentAgent()
        self.displayer = displayer or Displayer()

    def updateAlarm(self) -> None:
        """ Checks if move exceeded the time limit and updates the alarm """
        if time.process_time() - self.prevTime > maxTime:
            raise Exception(
                f'Too much time of {time.process_time() - self.prevTime}')
            self.over = True

        self.prevTime = time.process_time()

    def getNewTileValue(self) -> int:
        """ Returns 2 with probability 0.95 and 4 with 0.05 """
        return self.possibleNewTiles[random.random() > self.probability]

    def insertRandomTiles(self, numTiles: int):
        """ Insert numTiles number of random tiles. For initialization """
        for i in range(numTiles):
            tileValue = self.getNewTileValue()
            cells = self.grid.getAvailableCells()
            cell = random.choice(cells) if cells else None
            self.grid.setCellValue(cell, tileValue)

    def start(self) -> int:
        """ Main method that handles running the game of 2048 """

        # Initialize the game
        self.insertRandomTiles(self.initTiles)
        self.displayer.display(self.grid)
        turn = PLAYER_TURN  # Player AI Goes First
        self.prevTime = time.process_time()

        while self.grid.canMove() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                print("Player's Turn: ", end="")
                move = self.intelligentAgent.getMove(gridCopy)
                print("Trying to do player turn")
                print(actionDic[move])

                # If move is valid, attempt to move the grid
                if move != None and 0 <= move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                    else:
                        print("Invalid intelligentAgent Move - Cannot move")
                        self.over = True
                else:
                    print("Invalid intelligentAgent Move - Invalid input")
                    self.over = True
            else:
                print("Computer's turn: ")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                print("Trying to do computer")
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            # Comment out during heuristing optimizations to increase runtimes.
            # Printing slows down computation time.
            self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm()
            turn = 1 - turn
        print(f'This means it can move {self.over}')
        return self.grid.getMaxTile()
Exemple #4
0
class GameManager:
	def __init__(self, size = 4):
		# init some variables
		self.grid = Grid(size)
		self.possibleNewTileValue = [2, 4]
		self.possibility = defaultPossibility
		self.initTiles = defaultInitialTiles
		self.computerAI = None
		self.playerAI = None
		self.displayer = None
		self.over = False

	def setComputerAI(self, compAI):
		self.computerAI = compAI

	def setPlayerAI(self, playerAI):
		self.playerAI = playerAI

	def setDisplayer(self, displayer):
		self.displayer = displayer

	def updateAlarm(self, curTime):
		# 0.1 sec for the running time outside the AI module
		if curTime - self.lastTime > timeLimit + 0.1:
			self.over = True
		else:
			self.lastTime = curTime

	def start(self):
		#insert 2 random tiles
		for i in xrange(self.initTiles):
			self.insertRandonTile()

		# show the initial grid state
		self.displayer.display(self.grid)

		#player plays first
		turn = PLAYER_TURN
		maxTile = 0

		# set init alarm
		self.lastTime = time.clock()#time.time()

		# check game over conditions
		while not self.isGameOver() and not self.over:
			# make a copy make sure AI cannot change the real grid and cheat
			gridCopy = self.grid.clone()
			move = None

			if turn == PLAYER_TURN:
				print "Player's Turn"
				move = self.playerAI.getMove(gridCopy)
				print actionDic[move]

				#validate move
				if move != None and move >= 0 and move < 4:
					if self.grid.canMove([move]):
						self.grid.move(move)
						#update maxTile
						maxTile = self.grid.getMaxTile()
					else:
						print "Invalid PlayerAI Move"
						self.over = True
				else:
					print "Invalid PlayerAI Move - 1"
					self.over = True
			else:  # computer turn
				print "Computer's turn"
				move = self.computerAI.getMove(gridCopy)  # move should be (x, y) format
				#validate move
				if self.grid.canInsert(move):
					self.grid.setCellValue(move, self.getNewTileValue())
				else:
					print "Invalid Computer AI Move"
					self.over = True

			if not self.over:
				self.displayer.display(self.grid)

			# once you exceeds the time limit, previous action will be your last action
			self.updateAlarm(time.clock()) #time.time()
			turn = 1 - turn
		print maxTile


	def isGameOver(self):
		return not self.grid.canMove()

	def getNewTileValue(self):
		if randint(0,99) < 100 * self.possibility: 
			return self.possibleNewTileValue[0] 
		else: 
			return self.possibleNewTileValue[1]

	def insertRandonTile(self):
		tileValue = self.getNewTileValue()
		cells = self.grid.getAvailableCells()
		cell = cells[randint(0, len(cells) - 1)]
		self.grid.setCellValue(cell, tileValue)
Exemple #5
0
class GameManager:
    def __init__(self, size = 4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles  = defaultInitialTiles
        self.computerAI = None
        self.playerAI   = None
        self.displayer  = None
        self.over       = False

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
#        print "time elapsed = ", currTime - self.prevTime
#        st = raw_input()
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        for i in xrange(self.initTiles):
            self.insertRandonTile()

        #self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                print "Player's Turn:",
                move = self.playerAI.getMove(gridCopy)
                print actionDic[move]

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        print "Invalid PlayerAI Move"
                        self.over = True
                else:
                    print "Invalid PlayerAI Move - 1"
                    self.over = True
            else:
                print "Computer's turn:"
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print "Invalid Computer AI Move"
                    self.over = True

            if not self.over:
                self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.clock())

            turn = 1 - turn
        print maxTile

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0,99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1];

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)
Exemple #6
0
class GameManager:
    def __init__(self, size = 4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles  = defaultInitialTiles
        self.computerAI = None
        self.playerAI   = None
        self.displayer  = None
        self.over       = False

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
            print ("time over")
            pass
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        for i in xrange(self.initTiles):
            self.insertRandonTile()

        self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                # print "Player's Turn:",
                move = self.playerAI.getMove(gridCopy)
                print actionDic[move]

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                        print ("max: %d, free: %d, " %(maxTile,len(self.grid.getAvailableCells())))
                    else:
                        print "Invalid PlayerAI Move"
                        self.over = True
                else:
                    print "Invalid PlayerAI Move - 1"
                    self.over = True
                self.displayer.display(self.grid)
                # s = Node(self.grid)
                # print(" eval: " + str(s.eval(True))+"\n")
                # v = raw_input()

                print("stopped @ depth %d" %self.playerAI.IDSDepth)
                s = 0
                for count in self.playerAI.exploredNodes:
                    l = len(self.playerAI.exploredNodes[count])
                    print("%d: %d" %(count,l))
                    s += l
                print("total :%s" %s)
            else:
                # print "Computer's turn:"
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print "Invalid Computer AI Move"
                    self.over = True
                # s = Node(self.grid)
                # print(" eval: " + str(s.eval(True))+"\n")
            if not self.over:
                # self.displayer.display(self.grid)
                pass
                
            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.clock())

            turn = 1 - turn
        print maxTile

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        if randint(0,99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1];

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)
Exemple #7
0
class MyGame:
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = 0.9
        self.initTiles = 2
        self.displayer = Displayer()
        self.timer = 0
        self.turns = 2

    def get_move(self, gridCopy):
        # all the rest code is demo. here is the important code:
        my_tree = BuildTree(gridCopy)
        my_tree.build_it(0)
        return my_tree.get_best_move()

        # print('AvailableCells:')
        # print(self.grid.getAvailableCells()) # [(0, 1), (0, 2), (0, 3), (1, 0) ...]
        # print('AvailableMoves:')
        # print(self.grid.getAvailableMoves()) # [1, 2, 3] or [0, 1, 2, 3] ...

        # if self.grid.canMove([move]):
        # self.grid.move(move)
        # self.grid.getAvailableCells()
        # self.grid.getAvailableMoves()
        # self.grid.insertTile(pos, value) -> maybe redundant and 'move' is enough
        # self.grid.clone()
        # maxTile = self.grid.getMaxTile()
        # ACTIONS = {
        #     0: "UP",
        #     1: "DOWN",
        #     2: "LEFT",
        #     3: "RIGHT"
        # }

        # return randint(0, 3)

    def getNewTileValue(self):
        if randint(0, 99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1]

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)

    def start(self):
        for i in range(self.initTiles):
            self.insertRandonTile()
        self.displayer.display(self.grid)
        maxTile = 0
        while self.timer < self.turns:
            gridCopy = self.grid.clone()
            move = self.get_move(gridCopy)
            print('move: ', str(move))
            if self.grid.canMove([move]):
                self.grid.move(move)
                maxTile = self.grid.getMaxTile()
                self.timer += 1
            else:
                print("Invalid Move")
            self.displayer.display(self.grid)
        print('max tile:', str(maxTile))
Exemple #8
0
class GameManager:
	def __init__(self, size = 4):
		#self.grid = Grid(size)
		self.possibleNewTiles = [2, 4]
		self.probability = defaultProbability
		self.initTiles  = defaultInitialTiles
		self.computerAI = None
		self.playerAI   = None
		self.over   = False
		self.grid = Grid(size)

	def setComputerAI(self, computerAI):
		self.computerAI = computerAI

	def setPlayerAI(self, playerAI):
		self.playerAI = playerAI

	def updateAlarm(self, currTime):
		if currTime - self.prevTime > timeLimit + allowance:
			print 'Out of time'
			self.over = True
		else:
			while time.clock() - self.prevTime < timeLimit + allowance:
				pass

		self.prevTime = time.clock()

	def start(self):
		#for i in xrange(self.initTiles):
		#	self.insertRandonTile()

		sel_board = randint(0, 4)

		if sel_board == 0:
			self.board1(self.grid)
		elif sel_board == 1:
			self.board2(self.grid)
		elif sel_board == 2:
			self.board3(self.grid)
		elif sel_board == 3:
			self.board4(self.grid)
		else:
			self.board5(self.grid)

		# Player AI Goes First
		turn = PLAYER_TURN
		maxTile = 0

		self.prevTime = time.clock()

		while not self.isGameOver() and not self.over:
			# Copy to Ensure AI Cannot Change the Real Grid to Cheat
			gridCopy = self.grid.clone()

			move = None

			if turn == PLAYER_TURN:
				#print "Player's Turn:",
				move = self.playerAI.getMove(gridCopy)
				#print actionDic[move]

				# Validate Move
				if move != None and move >= 0 and move < 4:
					if self.grid.canMove([move]):
						self.grid.move(move)
						#self.playerAI.utility(self.grid, True)

						# Update maxTile
						maxTile = self.grid.getMaxTile()
					else:
						#print "Invalid PlayerAI Move"
						self.over = True
				else:
					#print "Invalid PlayerAI Move - 1"
					self.over = True
			else:
				#print "Computer's turn:"
				move = self.computerAI.getMove(gridCopy)

				# Validate Move
				if move and self.grid.canInsert(move):
					self.grid.setCellValue(move, self.getNewTileValue())
				else:
					print "Invalid Computer AI Move"
					self.over = True

			# Exceeding the Time Allotted for Any Turn Terminates the Game
			self.updateAlarm(time.clock())

			turn = 1 - turn

	def isGameOver(self):
		return not self.grid.canMove()

	def getNewTileValue(self):
		if randint(0,99) < 100 * self.probability:
			return self.possibleNewTiles[0]
		else:
			return self.possibleNewTiles[1];

	def insertRandonTile(self):
		tileValue = self.getNewTileValue()
		cells = self.grid.getAvailableCells()
		cell = cells[randint(0, len(cells) - 1)]
		self.grid.setCellValue(cell, tileValue)

	# Have predefined board conditions to explore games from an advanced state.
	def board1(self, grid):
		grid.map = [[2, 0, 2, 0], [4, 32, 16, 4], [2, 4, 128, 16], [128, 1024, 4, 2]]

	def board2(self, grid):
		grid.map = [[8, 8, 4, 2], [1024, 16, 64, 4], [4, 128, 16, 2], [256, 4, 0, 0]]

	def board3(self, grid):
		grid.map = [[0, 0, 4, 32], [0, 0, 0, 512], [2, 4, 8, 64], [0, 8, 32, 16]]

	def board4(self, grid):
		grid.map = [[2, 2, 4, 0], [1024, 32, 16, 0], [64, 512, 8, 8], [8, 2, 4, 2]]

	def board5(self, grid):
		grid.map = [[32, 16, 8, 0], [1024, 8, 16, 0], [8, 0, 0, 0], [4, 2, 2, 0]]
Exemple #9
0
class GameManager:
	def __init__(self, size = 4):
		# init some variables
		self.grid = Grid(size)
		self.possibleNewTileValue = [2, 4]
		self.possibility = defaultPossibility
		self.initTiles = defaultInitialTiles
		self.computerAI = None
		self.playerAI = None
		self.displayer = None
		self.over = False

	def setComputerAI(self, compAI):
		self.computerAI = compAI

	def setPlayerAI(self, playerAI):
		self.playerAI = playerAI

	def setDisplayer(self, displayer):
		self.displayer = displayer

	def updateAlarm(self, curTime):
		# 0.1 sec for the running time outside the AI module
		if curTime - self.lastTime > timeLimit + 0.1:
			self.over = True
		else:
			self.lastTime = curTime

	def start(self):
        #insert 2 random tiles
		for i in xrange(self.initTiles):
			self.insertRandonTile()

		# show the initial grid state
		self.displayer.display(self.grid)

		#player plays first
		turn = PLAYER_TURN
		maxTile = 0

		# set init alarm
		self.lastTime = time.clock()

		# check game over conditions
		while not self.isGameOver() and not self.over:
            # make a copy make sure AI cannot change the real grid and cheat
			gridCopy = self.grid.clone()
			move = None

			if turn == PLAYER_TURN:
				print "Player's Turn"
				move = self.playerAI.getMove(gridCopy)
				print actionDic[move]

				#validate move
				if move != None and move >= 0 and move < 4:
					if self.grid.canMove([move]):
						self.grid.move(move)
						#update maxTile
						maxTile = self.grid.getMaxTile()
					else:
						print "Invalid PlayerAI Move"
						self.over = True
				else:
					print "Invalid PlayerAI Move - 1"
					self.over = True
			else:
				print "Computer's turn"
				move = self.computerAI.getMove(gridCopy)
				#validate move
				if move and self.grid.canInsert(move):
					self.grid.setCellValue(move, self.getNewTileValue())
				else:
					print "Invalid Computer AI Move"
					self.over = True

			if not self.over:
				self.displayer.display(self.grid)

			# once you exceeds the time limit, previous action will be your last action
			self.updateAlarm(time.clock())
			turn = 1 - turn
		print maxTile


	def isGameOver(self):
		return not self.grid.canMove()

	def getNewTileValue(self):
		if randint(0,99) < 100 * self.possibility: 
			return self.possibleNewTileValue[0] 
		else: 
			return self.possibleNewTileValue[1];

	def insertRandonTile(self):
		tileValue = self.getNewTileValue()
		cells = self.grid.getAvailableCells()
		cell = cells[randint(0, len(cells) - 1)]
		self.grid.setCellValue(cell, tileValue)
class GameManager:
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.computerAI = None
        self.playerAI = None
        self.displayer = None
        self.over = False

    def setComputerAI(self, computerAI):
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        self.displayer = displayer

    def updateAlarm(self, currTime):
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
        else:
            while time.perf_counter() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.perf_counter()

    def start(self):
        for i in range(self.initTiles):
            self.insertRandomTile()

        self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.perf_counter()

        timecount = 0

        while not self.isGameOver() and not self.over:
            timecount += 1
            print(timecount, "th TURN:")
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()
            move = None
            if turn == PLAYER_TURN:
                print("Player's Turn:", end="")
                move = self.playerAI.getMove(gridCopy)
                print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - 1")
                    self.over = True

                print(self.evaluator(self.top5()))
            else:
                print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            if not self.over:
                self.displayer.display(self.grid)

            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.perf_counter())

            turn = 1 - turn
        print(maxTile)

    def isGameOver(self):
        return not self.grid.canMove()

    def getNewTileValue(self):
        random.seed(218)
        if random.randint(0, 99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1]

    def insertRandomTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        random.seed(218)
        cell = cells[random.randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)

    def sumOfScore(self):
        sum = 0
        for i in range(4):
            for j in range(4):
                sum += self.grid.map[i][j]
        return sum

    #Modified part for evaluation:
    def top5(self):
        flatten_list = list(chain.from_iterable(self.grid.map))
        flatten_list.sort(reverse=True)
        return flatten_list[0:5]

    def evaluator(self, res):
        score = 10
        std = [2048, 2048, 1024, 1024, 1024]
        for i in range(5):
            if res[i] == 0:
                score -= 10
            elif res[i] > std[i]:
                score += 2 * math.log2(std[i] / res[i])
            else:
                score -= 0.5 * math.log2(std[i] / res[i])
        return score
Exemple #11
0
class Game:
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.agent = GreedyAgent()
        self.displayer = BeatifulDisplay()
        self.displayStep = defaultDisplayStep
        self._debugFlag = False
        self._failMess = None

    def setAgent(self, agent: Agent):
        self.agent = agent

    def setDisplay(self, displayer: Display, displayStep: int):
        self.displayer = displayer
        self.displayStep = displayStep

    def isLose(self):
        return not self.grid.canMove()

    def isWin(self):
        return self.grid.getMaxTile() == 2048

    def getNewTileValue(self):
        return self.possibleNewTiles[randint(0,
                                             len(self.possibleNewTiles) - 1)]

    def insertRandonTile(self):
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        if not cell:
            self._debugFlag = True
            self._failMess = "No available empty cell"
            raise ValueError(self._failMess)
        self.grid.setCellValue(cell, tileValue)

    def display(self):
        self.displayer.display(self.grid)

    def getScore(self):
        return self.grid.getMaxTile()

    def main(self):
        for i in range(self.initTiles):
            self.insertRandonTile()
        if self.displayStep > 0:
            self.display()

        step = 1

        while not self.isWin() and not self.isLose() and not self._debugFlag:
            gridCopy = self.grid.clone()
            move = self.agent.getMove(gridCopy)
            #print(actionDic[move])
            if move is not None and 0 <= move < 4:
                if self.grid.canMove([move]):
                    self.grid.move(move)
                else:
                    self._debugFlag = True
                    self._failMess = "Invalid Agent Move: the grid would not change"
                    break
            else:
                self._debugFlag = True
                self._failMess = "Invalid Agent Move: Value Error: " + str(
                    move)
                break

            self.insertRandonTile()
            if self.displayStep > 0 and step % self.displayStep == 0:
                #sleep(0.1)
                print('step: ', step)
                self.display()
            #print(self.getScore())
            step += 1

        if self._debugFlag:
            raise ValueError(self._failMess)

        if self.displayStep > 0:
            self.display()
            print('Ends in step', step)
            if self.isWin():
                print("Agent wins!!")
            if self.isLose():
                print("Agent Loses!!")

        return self.isWin(), self.getScore()
Exemple #12
0
class GameManager:
    """ Game Manager class
    
    Agrs:
        size: Puzzle grid side size
        ComputerAI: ComputerAI class object running the computer's moves
        PlayerAI: PlayerAI class object running the player's moves optimizing the implemented heuristics
        displayer: Displayer class object allowing the Game Manager to display the current state of the game 
        currTime: time.clock object indicating the current time at each move
    
    Methods:
        setComputerAI(): Set ComputerAI object
        setPlayerAI(): Set PlayerAI object
        setDisplayer(): Set Displayer object
        updateAlarm(): Check time consumed in the decision-making process doesn't exceed time limit
        start(): Start running the game
        isGameOver(): Check if the game is over, not allowing the player to perform any further moves
        getNewTileValue(): Get the value of the computer's new tile to be inserted
        insertRandomTile(): Insert the computer's new tile in a random available cell

    """
    def __init__(self, size=4):
        self.grid = Grid(size)
        self.possibleNewTiles = [2, 4]
        self.probability = defaultProbability
        self.initTiles = defaultInitialTiles
        self.computerAI = None
        self.playerAI = None
        self.displayer = None
        self.over = False

    def setComputerAI(self, computerAI):
        """ Set ComputerAI object """
        self.computerAI = computerAI

    def setPlayerAI(self, playerAI):
        """ Set PlayerAI object """
        self.playerAI = playerAI

    def setDisplayer(self, displayer):
        """ Set Displayer object """
        self.displayer = displayer

    def updateAlarm(self, currTime):
        """ Check time consumed in the decision-making process doesn't exceed time limit 
        
        Args:
            currTime: time.clock object indicating the current time at each move
                
        """
        if currTime - self.prevTime > timeLimit + allowance:
            self.over = True
        else:
            while time.clock() - self.prevTime < timeLimit + allowance:
                pass

            self.prevTime = time.clock()

    def start(self):
        """ Start running the game """
        for i in range(self.initTiles):
            self.insertRandomTile()

        self.displayer.display(self.grid)

        # Player AI Goes First
        turn = PLAYER_TURN
        maxTile = 0

        self.prevTime = time.clock()

        while not self.isGameOver() and not self.over:
            # Copy to Ensure AI Cannot Change the Real Grid to Cheat
            gridCopy = self.grid.clone()

            move = None

            if turn == PLAYER_TURN:
                print("Player's Turn:", end="")
                move = self.playerAI.getMove(gridCopy)
                print(actionDic[move])

                # Validate Move
                if move != None and move >= 0 and move < 4:
                    if self.grid.canMove([move]):
                        self.grid.move(move)

                        # Update maxTile
                        maxTile = self.grid.getMaxTile()
                    else:
                        print("Invalid PlayerAI Move")
                        self.over = True
                else:
                    print("Invalid PlayerAI Move - 1")
                    self.over = True
            else:
                print("Computer's turn:")
                move = self.computerAI.getMove(gridCopy)

                # Validate Move
                if move and self.grid.canInsert(move):
                    self.grid.setCellValue(move, self.getNewTileValue())
                else:
                    print("Invalid Computer AI Move")
                    self.over = True

            if not self.over:
                self.displayer.display(self.grid)

            print(self.over)
            # Exceeding the Time Allotted for Any Turn Terminates the Game
            self.updateAlarm(time.clock())

            turn = 1 - turn
            print(self.over)
        print(maxTile)

    def isGameOver(self):
        """ Check if the game is over, not allowing the player to perform any further moves 
        
        Returns: Boolean whether the game is over or not
            
        """
        return not self.grid.canMove()

    def getNewTileValue(self):
        """ Get the value of the computer's new tile to be inserted 
        
        Returns: Value of the computer's new tile to be inserted 
        
        """
        if randint(0, 99) < 100 * self.probability:
            return self.possibleNewTiles[0]
        else:
            return self.possibleNewTiles[1]

    def insertRandomTile(self):
        """ Insert the computer's new tile in a random available cell """
        tileValue = self.getNewTileValue()
        cells = self.grid.getAvailableCells()
        cell = cells[randint(0, len(cells) - 1)]
        self.grid.setCellValue(cell, tileValue)