def run(self):
     '''
     Runs the set and stores the results in Set.scoreBoard
     
     @note: Unlike in the game runner, run() in Set does NOT reset scoring values,
     so calling run() twice would mean that the results of two sets will be represented within
     Set.scoreBoard. This is potentially useful in the case that running a single set is inconclusive.
     '''
     
     # ====================
     # INITIALIZE VARIABLES
     # ====================
     
     numGames = 0
     setOver = False
     
     # =======
     # RUN SET
     # =======
     
     while not setOver:
         
         # ===========================
         # TEST FOR END SET CONDITIONS
         # ===========================
         
         if self.maximumGames > 0 and numGames >= self.maximumGames:
             setOver = True
             logging.info('Game Limit Set Termination')
             continue
         elif numGames >= self.minimumGames and not utility.decay(self.decay):
             setOver = True
             logging.info('Set Decay Termination')
             continue
         
         logging.info('\nGAME #{}'.format(numGames))
         
         # ========
         # RUN GAME
         # ========
         
         # run game and get results
         results = self.gameRunner.run()
         
         logging.debug(results)
         
         # update score board with results
         for script_name in results:
             logging.debug('{} survived game #{}'.format(script_name, numGames))
             self.scoreBoard[script_name] += 1
             
         numGames += 1
     
     logging.info(self.scoreBoard)
         
     
     
     
    def run(self):
        '''
        Runs the game simulation and returns the winner.
        
        @return: A list containing the names of all the robots that survived the round.
        '''
        
        # reset important variables
        self.numRounds = 0
        self.gameOver = False
        self.board = Board(self.scripts)
        
        # ==============
        # START GRAPHICS
        # ==============
        
        # if graphics not None, start graphics runner
        if not (self.graphics is None):
            
            # give graphics object initial board state
            self.graphics.update(copy.deepcopy(self.board))
            
            # start graphics thread
            self.graphics.start()
            
        # ========
        # RUN GAME
        # ========
        
        # This loop runs the logic for each round,
        # rounds continue until one of the end game conditions are met.
        while not self.gameOver:
            
#             logging.debug('\nGAME ROUND #{}'.format(self.numRounds))
            
            # ============================
            # TEST FOR END GAME CONDITIONS
            # ============================
            
            if self.maximumRounds > 0 and self.numRounds >= self.maximumRounds:             # round limit reached
                self.gameOver = True
#                 logging.debug('Round Limit Reached')
            elif self.numRounds >= self.minimumRounds and not utility.decay(self.decay):    # decay termination
                self.gameOver = True
#                 logging.debug('Decay Limit Reached')
            elif len(self.board.getRobots()) <= 1:                                          # one or fewer robots left
                self.gameOver = True
                logging.debug('{} robot(s) left'.format(len(self.board.getRobots())))
            elif self.graphics is not None and self.graphics.exitFlag:                      # graphics window closed
                self.gameOver = True
#                 logging.debug('Graphics Window Closed')
                
            # ===============
            # PERFORM UPDATES
            # ===============
            
            # update board    
            self.board.update()
            
            # update graphics and delay if necessary
            if self.graphics is not None:
                self.graphics.update(copy.deepcopy(self.board))
                
                if self.synchronizeGraphics:
                    time.sleep(self.graphics.delay / 1000)  # Graphics.delay is in miliseconds, time.sleep() takes seconds
                
            # increment number of rounds
            self.numRounds += 1
        
        # =================
        # END OF GAME LOGIC
        # =================
        
        # if 1 or 0 robots left, end game
        if len(self.board.getRobots()) == 1:
            
            # Only one robot left, that robot is the winner
            # print out winner and exit

            # print winner
            logging.info("A winner is " + list(self.board.getRobots().keys())[0])
        elif len(self.board.getRobots()) < 1:
            
            # no robots left,
            # declare game a tie
            
            # print tie
            logging.info("The game is a tie, everyone is dead.")
        elif len(self.board.getRobots()) > 1:
            
            # multiple robots left, declare a tie
            logging.info("multiple robots left: {}".format(list(self.board.getRobots().keys())))
        
        # kill graphics
#         self.graphics.exit()
            
        # return result
        return self.board.getRobots()