abbarnes

Cookie Clicker Simulation [codeskulptor]

Dec 12th, 2017
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.24 KB | None | 0 0
  1. """
  2. Cookie Clicker Simulator
  3. """
  4. #http://www.codeskulptor.org/#user43_ULjUFtSgFkDefdl_12.py
  5.  
  6. import simpleplot
  7. import math
  8. #import user43_G4PJLsAMW3DL8ai_22 as simpletest
  9.  
  10. # Used to increase the timeout, if necessary
  11. import codeskulptor
  12. codeskulptor.set_timeout(20)
  13.  
  14. import poc_clicker_provided as provided
  15.  
  16. # Constants
  17. SIM_TIME = 10000000000.0
  18.  
  19. class ClickerState:
  20.     """
  21.    Simple class to keep track of the game state.
  22.    """
  23.    
  24.     def __init__(self):
  25.         self._cps = 1.0
  26.         self._cookies = 0.0
  27.         self._net_cookies = 0.0
  28.         self._time = 0.0
  29.         self._history = [(0.0, None, 0.0, 0.0)]
  30.        
  31.        
  32.     def __str__(self):
  33.         """
  34.        Return human readable state
  35.        """
  36.         return str(self._cookies) + " cookies out of <" + str(self._net_cookies/(SIM_TIME*100000)) + "> million available at time " + str(self._time)
  37.        
  38.     def get_cookies(self):
  39.         """
  40.        Return current number of cookies
  41.        (not total number of cookies)
  42.        
  43.        Should return a float
  44.        """
  45.         return self._cookies
  46.    
  47.     def get_net_cookies(self):
  48.         """
  49.        Return total number of cookies
  50.        
  51.        Should return a float
  52.        """
  53.         return self._net_cookies    
  54.    
  55.     def get_cps(self):
  56.         """
  57.        Get current CPS
  58.  
  59.        Should return a float
  60.        """
  61.         return self._cps
  62.    
  63.     def get_time(self):
  64.         """
  65.        Get current time
  66.  
  67.        Should return a float
  68.        """
  69.         return self._time
  70.    
  71.     def get_history(self):
  72.         """
  73.        Return history list
  74.  
  75.        History list should be a list of tuples of the form:
  76.        (time, item, cost of item, total cookies)
  77.  
  78.        For example: [(0.0, None, 0.0, 0.0)]
  79.  
  80.        Should return a copy of any internal data structures,
  81.        so that they will not be modified outside of the class.
  82.        """
  83.         return list(self._history)
  84.  
  85.     def time_until(self, cookies):
  86.         """
  87.        Return time until you have the given number of cookies
  88.        (could be 0.0 if you already have enough cookies)
  89.  
  90.        Should return a float with no fractional part
  91.        """
  92.         if self._cookies > cookies:
  93.             return 0.0
  94.         else:
  95.             return math.ceil(float(cookies-self._cookies)/self._cps)
  96.    
  97.     def wait(self, time):
  98.         """
  99.        Wait for given amount of time and update state
  100.  
  101.        Should do nothing if time <= 0.0
  102.        """
  103.         if time <= 0:
  104.             return
  105.         else:
  106.             self._cookies += time*self._cps
  107.             self._net_cookies += time*self._cps
  108.             self._time += time
  109.             return
  110.    
  111.     def buy_item(self, item_name, cost, additional_cps):
  112.         """
  113.        Buy an item and update state
  114.  
  115.        Should do nothing if you cannot afford the item
  116.        """
  117.         if self._cookies < cost:
  118.             return
  119.         else:
  120.             self._cookies -= cost
  121.             self._cps += additional_cps
  122.             self._history.append((self._time, item_name, cost, self._net_cookies))
  123.         return
  124.    
  125.    
  126. def simulate_clicker(build_info, duration, strategy):
  127.     """
  128.    Function to run a Cookie Clicker game for the given
  129.    duration with the given strategy.  Returns a ClickerState
  130.    object corresponding to the final state of the game.
  131.    """
  132.  
  133.     #initialize locals
  134.     local_build_info = build_info.clone()
  135.     clicker = ClickerState()
  136.     debug_log = []
  137.     debug = False
  138.    
  139.     #main logic
  140.     while clicker.get_time() < duration:
  141.         next_purchase = strategy(clicker.get_cookies(), clicker.get_cps(),
  142.                                  clicker.get_history(), duration - clicker.get_time(),
  143.                                  local_build_info)
  144.         #check for break conditions
  145.         #i.e. strategy doesn't return next purchase OR insufficient time/funds
  146.         if not next_purchase:
  147.             debug_log.append("Strategy declined purchasing item")
  148.             break
  149.         time_until_purchase = clicker.time_until(local_build_info.get_cost(next_purchase))
  150.         if time_until_purchase + clicker.get_time() > duration:
  151.             debug_log.append(("Cannot afford another ", next_purchase))
  152.             break
  153.        
  154.         #buy next item
  155.         clicker.wait(time_until_purchase)
  156.         clicker.buy_item(next_purchase, local_build_info.get_cost(next_purchase),
  157.                          local_build_info.get_cps(next_purchase))
  158.         debug_log.append(("Buying ", next_purchase, " under strat ", strategy))
  159.         debug_log.append(clicker.get_history())
  160.         local_build_info.update_item(next_purchase)
  161.    
  162.     #use up remaining time
  163.     time_remainder = duration - clicker.get_time()
  164.     debug_log.append((time_remainder, " time left over"))
  165.     clicker.wait(time_remainder)
  166.    
  167.     #buy items at end-time
  168.     next_purchase = strategy(clicker.get_cookies(), clicker.get_cps(),
  169.                              clicker.get_history(), 0.0, local_build_info)
  170.     debug_log.append(("Next purchase: ", next_purchase))
  171.     while next_purchase:
  172.         if clicker.get_cookies() > local_build_info.get_cost(next_purchase):
  173.             clicker.buy_item(next_purchase, local_build_info.get_cost(next_purchase),
  174.                              local_build_info.get_cps(next_purchase))
  175.             local_build_info.update_item(next_purchase)
  176.             next_purchase = strategy(clicker.get_cookies(), clicker.get_cps(),
  177.                                      clicker.get_history(), 0.0, local_build_info)
  178.         else:
  179.             break
  180.     #debugging
  181.     if debug:
  182.         for statement in debug_log:
  183.             print statement
  184.     #end
  185.     return clicker
  186.  
  187.  
  188. def strategy_cursor_broken(cookies, cps, history, time_left, build_info):
  189.     """
  190.    Always pick Cursor!
  191.  
  192.    Note that this simplistic (and broken) strategy does not properly
  193.    check whether it can actually buy a Cursor in the time left.  Your
  194.    simulate_clicker function must be able to deal with such broken
  195.    strategies.  Further, your strategy functions must correctly check
  196.    if you can buy the item in the time left and return None if you
  197.    can't.
  198.    """
  199.     return "Cursor"
  200.  
  201. def strategy_none(cookies, cps, history, time_left, build_info):
  202.     """
  203.    Always return None
  204.  
  205.    This is a pointless strategy that will never buy anything, but
  206.    that you can use to help debug your simulate_clicker function.
  207.    """
  208.     return None
  209.  
  210. def strategy_cheap(cookies, cps, history, time_left, build_info):
  211.     """
  212.    Always buy the cheapest item you can afford in the time left.
  213.    """
  214.  
  215.     cookies += cps*time_left
  216.     items = build_info.build_items()
  217.     costs_items = []
  218.     for item in items:
  219.         costs_items.append((build_info.get_cost(item), item))
  220.     costs_items.sort()
  221.     for cost_item in costs_items:
  222.         if cookies >= cost_item[0]:
  223.             return cost_item[1]
  224.     return None
  225.  
  226. def strategy_expensive(cookies, cps, history, time_left, build_info):
  227.     """
  228.    Always buy the most expensive item you can afford in the time left.
  229.    """
  230.     cookies += cps*time_left
  231.     items = build_info.build_items()
  232.     costs_items = []
  233.     for item in items:
  234.         costs_items.append((build_info.get_cost(item), item))
  235.     costs_items.sort(reverse=True)
  236.     for cost_item in costs_items:
  237.         if cookies >= cost_item[0]:
  238.             return cost_item[1]
  239.     return None
  240.  
  241. def strategy_best(cookies, cps, history, time_left, build_info):
  242.     """
  243.    The best strategy that you are able to implement.
  244.    Returns object you can afford with highest cps to cost ratio.
  245.    """
  246.     cookies += cps*time_left
  247.     items = build_info.build_items()
  248.     costfactors_items = []
  249.     for item in items:
  250.         costfactors_items.append((build_info.get_cps(item)/build_info.get_cost(item),
  251.                                   item))
  252.     costfactors_items.sort(reverse=True)
  253.     for costfactor_item in costfactors_items:
  254.         if cookies >= build_info.get_cost(costfactor_item[1]):
  255.             return costfactor_item[1]
  256.    
  257.     return None
  258.  
  259. def run_strategy(strategy_name, time, strategy):
  260.     """
  261.    Run a simulation for the given time with one strategy.
  262.    """
  263.     state = simulate_clicker(provided.BuildInfo(), time, strategy)
  264.     print strategy_name, ":", state
  265.  
  266.     # Plot total cookies over time
  267.  
  268.     # Uncomment out the lines below to see a plot of total cookies vs. time
  269.     # Be sure to allow popups, if you do want to see it
  270.  
  271.     history = state.get_history()
  272.     history = [(item[0], item[3]) for item in history]
  273.     simpleplot.plot_lines(strategy_name, 1000, 400, 'Time', 'Total Cookies', [history], True)
  274.  
  275. def run():
  276.     """
  277.    Run the simulator.
  278.    """    
  279.     #Add calls to run_strategy to run additional strategies
  280.     run_strategy("Cheap", SIM_TIME, strategy_cheap)
  281.     run_strategy("Expensive", SIM_TIME, strategy_expensive)
  282.     run_strategy("Best", SIM_TIME, strategy_best)
  283.     #run_strategy("Cursor Broken", SIM_TIME, strategy_cursor_broken)
  284.     return
  285.  
  286. run()
  287.  
  288. ##Simpletest Debugging
  289. #simpletest.run_suite_ClickerState(ClickerState)
  290. #simpletest.run_suite_cheap_simulation(simulate_clicker, strategy_cheap)
  291. #simpletest.run_suite_none_simulation(simulate_clicker, strategy_none)
Advertisement
Add Comment
Please, Sign In to add comment