You are on page 1of 5

"""

Cookie Clicker Simulator


"""

import simpleplot
import math
import random

# Used to increase the timeout, if necessary


import codeskulptor
codeskulptor.set_timeout(20)

import poc_clicker_provided as provided

# Constants
SIM_TIME = 10000000000.0

class ClickerState:
"""
Simple class to keep track of the game state.
"""

def __init__(self):
self._total_cookies = 0.0
self._cookies = 0.0
self._time = 0.0
self._cps = 1.0
self._histories = [(0.0, None, 0.0, 0.0)]

def __str__(self):
"""
Return human readable state
"""

return "total cookies: " + str(self._total_cookies) + "\n" + \


"cookies: " + str(self._cookies) + "\n" + \
"time: " + str(self._time) + "\n" + "cps: " + str(self._cps) + \
"history: " +str(self._histories)

def get_cookies(self):
"""
Return current number of cookies
(not total number of cookies)

Should return a float


"""
return self._cookies

def get_cps(self):
"""
Get current CPS

Should return a float


"""
return self._cps

def get_time(self):
"""
Get current time
Should return a float
"""
return self._time

def get_history(self):
"""
Return history list

History list should be a list of tuples of the form:


(time, item, cost of item, total cookies)

For example: [(0.0, None, 0.0, 0.0)]

Should return a copy of any internal data structures,


so that they will not be modified outside of the class.
"""
return list(self._histories)

def time_until(self, cookies):


"""
Return time until you have the given number of cookies
(could be 0.0 if you already have enough cookies)

Should return a float with no fractional part


"""
diff_cookies = cookies - self._cookies
if diff_cookies <= 0:
return 0.0
else:
return math.ceil(diff_cookies/self._cps)*1.0

def wait(self, time):


"""
Wait for given amount of time and update state

Should do nothing if time <= 0.0


"""
if time > 0:
self._total_cookies += time*self._cps
self._cookies += time*self._cps
self._time += time

def buy_item(self, item_name, cost, additional_cps):


"""
Buy an item and update state

Should do nothing if you cannot afford the item


"""
if self._cookies >= cost:
self._cookies -= cost
self._cps += additional_cps
self._histories.append((self._time, item_name, cost,
self._total_cookies))

def simulate_clicker(build_info, duration, strategy):


"""
Function to run a Cookie Clicker game for the given
duration with the given strategy. Returns a ClickerState
object corresponding to the final state of the game.
"""
clicker_state = ClickerState()
clone_build_info = build_info.clone()
while(clicker_state.get_time() <= duration):
if(clicker_state.get_time() > duration):
break
purchase_item = strategy(clicker_state.get_cookies(),
clicker_state.get_cps(),
clicker_state.get_history(), duration -
clicker_state.get_time(),
clone_build_info)
if purchase_item==None:
break
time_until =
clicker_state.time_until(clone_build_info.get_cost(purchase_item))
if time_until + clicker_state.get_time() > duration:
break
clicker_state.wait(time_until)
clicker_state.buy_item(purchase_item,
clone_build_info.get_cost(purchase_item), clone_build_info.get_cps(purchase_item))
clone_build_info.update_item(purchase_item)

if clicker_state.get_time() < duration:


clicker_state.wait(duration - clicker_state.get_time())

return clicker_state

def strategy_cursor_broken(cookies, cps, history, time_left, build_info):


"""
Always pick Cursor!

Note that this simplistic (and broken) strategy does not properly
check whether it can actually buy a Cursor in the time left. Your
simulate_clicker function must be able to deal with such broken
strategies. Further, your strategy functions must correctly check
if you can buy the item in the time left and return None if you
can't.
"""
return "Cursor"

def strategy_none(cookies, cps, history, time_left, build_info):


"""
Always return None

This is a pointless strategy that will never buy anything, but


that you can use to help debug your simulate_clicker function.
"""
return None

def strategy_cheap(cookies, cps, history, time_left, build_info):


"""
Always buy the cheapest item you can afford in the time left.
"""
min_cost = -1
cheapest = None
list_item = build_info.build_items()
for item in list_item:
cost = build_info.get_cost(item)
if cps*time_left + cookies >= cost and (min_cost == -1 or min_cost > cost):
cheapest = item
min_cost = cost
return cheapest

def strategy_expensive(cookies, cps, history, time_left, build_info):


"""
Always buy the most expensive item you can afford in the time left.
"""
min_cost = -1
expensive = None
list_item = build_info.build_items()
for item in list_item:
cost = build_info.get_cost(item)
if cps*time_left + cookies >= cost and (min_cost == -1 or min_cost < cost):
expensive = item
min_cost = cost
return expensive

def strategy_best1(cookies, cps, history, time_left, build_info):


"""
The best strategy that you are able to implement.
"""
max_total_cookies = -1
best = None
list_item = build_info.build_items()
for item in list_item:
cost = build_info.get_cost(item)
if cps*time_left + cookies > cost:
time_need = math.ceil((cost-cookies)/cps)
additional_cps = cps + build_info.get_cps(item)
total_cookies = time_need*cps + (time_left - time_need)*additional_cps
if max_total_cookies == -1 or max_total_cookies < total_cookies:
max_total_cookies = total_cookies
best = item
return best

def strategy_best2(cookies, cps, history, time_left, build_info):


"""
The best strategy that you are able to implement.
"""
max_total_cookies = -1
best = None
list_item = build_info.build_items()
list_pur_item = []
for item in list_item:
cost = build_info.get_cost(item)
if cps*time_left + cookies > cost:
list_pur_item.append(item)
if len(list_pur_item) > 0:
return random.choice(list_pur_item)
else:
return None

def run_strategy(strategy_name, time, strategy):


"""
Run a simulation for the given time with one strategy.
"""
state = simulate_clicker(provided.BuildInfo(), time, strategy)
print strategy_name, ":", state

# Plot total cookies over time

# Uncomment out the lines below to see a plot of total cookies vs. time
# Be sure to allow popups, if you do want to see it

# history = state.get_history()
# history = [(item[0], item[3]) for item in history]
# simpleplot.plot_lines(strategy_name, 1000, 400, 'Time', 'Total Cookies',
[history], True)

def run():
"""
Run the simulator.
"""
#run_strategy("Cursor", SIM_TIME, strategy_cursor_broken)

# Add calls to run_strategy to run additional strategies


run_strategy("Cheap", SIM_TIME, strategy_cheap)
run_strategy("Expensive", SIM_TIME, strategy_expensive)
run_strategy("Best", SIM_TIME, strategy_best1)
run_strategy("Best", SIM_TIME, strategy_best2)

run()

You might also like