Add curses menu and watering feature

pull/1/head
Jake Funke 2017-03-08 08:18:45 +00:00
parent 180a4fe80f
commit ca4f48105b
2 changed files with 61 additions and 23 deletions

View File

@ -1,7 +1,6 @@
from __future__ import division from __future__ import division
import time import time
import pickle import pickle
import curses
import json import json
import math import math
import os.path import os.path
@ -145,7 +144,10 @@ class Plant(object):
self.rarity = self.rarity_check() self.rarity = self.rarity_check()
self.ticks = 0 self.ticks = 0
self.dead = False self.dead = False
self.filename = this_filename self.file_name = this_filename
self.start_time = int(time.time())
self.last_time = int(time.time())
self.watered_date = 0
def rarity_check(self): def rarity_check(self):
# Generate plant rarity # Generate plant rarity
@ -155,7 +157,7 @@ class Plant(object):
uncommon_range = round((2/3)*(CONST_RARITY_MAX-common_range)) uncommon_range = round((2/3)*(CONST_RARITY_MAX-common_range))
rare_range = round((2/3)*(CONST_RARITY_MAX-common_range-uncommon_range)) rare_range = round((2/3)*(CONST_RARITY_MAX-common_range-uncommon_range))
legendary_range = round((2/3)*(CONST_RARITY_MAX-common_range-uncommon_range-rare_range)) legendary_range = round((2/3)*(CONST_RARITY_MAX-common_range-uncommon_range-rare_range))
godly_range = round((2/3)*(CONST_RARITY_MAX-common_range-uncommon_range-rare_range-legendary_range)) # godly_range = round((2/3)*(CONST_RARITY_MAX-common_range-uncommon_range-rare_range-legendary_range))
# print common_range, uncommon_range, rare_range, legendary_range, godly_range # print common_range, uncommon_range, rare_range, legendary_range, godly_range
@ -163,7 +165,7 @@ class Plant(object):
uncommon_max = common_max + uncommon_range uncommon_max = common_max + uncommon_range
rare_max = uncommon_max + rare_range rare_max = uncommon_max + rare_range
legendary_max = rare_max + legendary_range legendary_max = rare_max + legendary_range
godly_max = legendary_max + godly_range godly_max = CONST_RARITY_MAX
# print common_max, uncommon_max, rare_max, legendary_max, godly_max # print common_max, uncommon_max, rare_max, legendary_max, godly_max
if 0 <= rare_seed <= common_max: if 0 <= rare_seed <= common_max:
@ -174,7 +176,7 @@ class Plant(object):
rarity = 2 rarity = 2
elif rare_max < rare_seed <= legendary_max: elif rare_max < rare_seed <= legendary_max:
rarity = 3 rarity = 3
elif legendary_max < rare_seed <= CONST_RARITY_MAX: elif legendary_max < rare_seed <= godly_max:
rarity = 4 rarity = 4
return rarity return rarity
@ -187,6 +189,10 @@ class Plant(object):
# do stage 5 stuff (after fruiting) # do stage 5 stuff (after fruiting)
1==1 1==1
def water(self):
# Increase plant growth stage
self.watered_date = datetime.datetime.now().date()
def mutate_check(self): def mutate_check(self):
# Create plant mutation # Create plant mutation
# TODO: when out of debug this needs to be set to high number (1000 # TODO: when out of debug this needs to be set to high number (1000
@ -198,7 +204,7 @@ class Plant(object):
mutation = random.randint(0,len(self.mutation_dict)-1) mutation = random.randint(0,len(self.mutation_dict)-1)
if self.mutation == 0: if self.mutation == 0:
self.mutation = mutation self.mutation = mutation
print "mutation!" #print "mutation!"
return True return True
else: else:
return False return False
@ -237,9 +243,10 @@ class Plant(object):
if self.stage < len(self.stage_dict)-1: if self.stage < len(self.stage_dict)-1:
if self.ticks == life_stages[self.stage]: if self.ticks == life_stages[self.stage]:
self.growth() self.growth()
print self.parse_plant() #print self.parse_plant()
if self.mutate_check(): if self.mutate_check():
print self.parse_plant() 1==1
#print self.parse_plant()
# what kills the plant? # what kills the plant?
@ -278,6 +285,7 @@ class DataManager(object):
def save_plant(self, this_plant): def save_plant(self, this_plant):
# create savefile # create savefile
this_plant.last_time = int(time.time())
with open(self.savefile_path, 'wb') as f: with open(self.savefile_path, 'wb') as f:
pickle.dump(this_plant, f, protocol=2) pickle.dump(this_plant, f, protocol=2)
@ -289,28 +297,42 @@ class DataManager(object):
def data_write_json(self, this_plant): def data_write_json(self, this_plant):
# create json file for user to use outside of the game (website?) # create json file for user to use outside of the game (website?)
this_plant.watered_date = this_plant.watered_date.strftime("%Y-%m-%d")
json_file = os.path.join(self.botany_dir,self.this_user + '_plant_data.json') json_file = os.path.join(self.botany_dir,self.this_user + '_plant_data.json')
with open(json_file, 'w') as outfile: with open(json_file, 'w') as outfile:
json.dump(this_plant.__dict__, outfile) json.dump(this_plant.__dict__, outfile)
def whats_happened(self,this_plant):
# need to calculate lifetime ticks to determine stage of life
# need to calculate if it's been too long since it's watered
current_timestamp = int(time.time())
current_date = datetime.datetime.now().date()
time_delta_overall = current_timestamp - this_plant.start_time
time_delta_last = current_timestamp - this_plant.last_time
time_delta_watered = (current_date - this_plant.watered_date).days
# compare timestamp of signout to timestamp now
# need to create timestamps to begin with..
# create plant birthday = unix datetime
if __name__ == '__main__': if __name__ == '__main__':
my_data = DataManager() my_data = DataManager()
# if plant save file exists # if plant save file exists
if my_data.check_plant(): if my_data.check_plant():
print "Welcome back, " + getpass.getuser() #print "Welcome back, " + getpass.getuser()
my_plant = my_data.load_plant() my_plant = my_data.load_plant()
print my_plant.parse_plant() #print my_plant.parse_plant()
# otherwise create new plant # otherwise create new plant
else: else:
print "Welcome, " + getpass.getuser() #print "Welcome, " + getpass.getuser()
#TODO: onboarding, select seed, select whatever else #TODO: onboarding, select seed, select whatever else
my_plant = Plant(my_data.savefile_path) my_plant = Plant(my_data.savefile_path)
my_plant.start_life() my_plant.start_life()
print "Your plant is living :)" #print "Your plant is living :)"
botany_menu = CursedMenu(my_plant) botany_menu = CursedMenu(my_plant)
botany_menu.show([1,2,3], title=' botany ', subtitle='Options') botany_menu.show([1,"water",3], title=' botany ', subtitle='Options')
#raw_input('Press return to save and exit...\n') #raw_input('Press return to save and exit...\n')
my_data.save_plant(my_plant) my_data.save_plant(my_plant)
my_data.data_write_json(my_plant) my_data.data_write_json(my_plant)
print "end" #print "end"

View File

@ -1,6 +1,7 @@
import curses, os, traceback, threading, time import curses, os, traceback, threading, time, datetime
class CursedMenu(object): class CursedMenu(object):
#TODO: create a side panel with log of events..?
'''A class which abstracts the horrors of building a curses-based menu system''' '''A class which abstracts the horrors of building a curses-based menu system'''
def __init__(self, this_plant): def __init__(self, this_plant):
'''Initialization''' '''Initialization'''
@ -17,10 +18,11 @@ class CursedMenu(object):
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE) curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
self.highlighted = curses.color_pair(1) self.highlighted = curses.color_pair(1)
self.normal = curses.A_NORMAL self.normal = curses.A_NORMAL
thread = threading.Thread(target=self.update_plant_live, args=()) screen_thread = threading.Thread(target=self.update_plant_live, args=())
thread.daemon = True screen_thread.daemon = True
thread.start() screen_thread.start()
# TODO: tweaking this to try to get rid of garble bug
self.screen.clear()
def show(self, options, title="Title", subtitle="Subtitle"): def show(self, options, title="Title", subtitle="Subtitle"):
'''Draws a menu with the given parameters''' '''Draws a menu with the given parameters'''
@ -56,6 +58,7 @@ class CursedMenu(object):
def draw(self): def draw(self):
'''Draw the menu and lines''' '''Draw the menu and lines'''
self.screen.refresh()
self.screen.border(0) self.screen.border(0)
self.screen.addstr(2,2, self.title, curses.A_STANDOUT) # Title for this menu self.screen.addstr(2,2, self.title, curses.A_STANDOUT) # Title for this menu
self.screen.addstr(4,2, self.subtitle, curses.A_BOLD) #Subtitle for this menu self.screen.addstr(4,2, self.subtitle, curses.A_BOLD) #Subtitle for this menu
@ -66,18 +69,27 @@ class CursedMenu(object):
textstyle = self.highlighted textstyle = self.highlighted
self.screen.addstr(5+index,4, "%d - %s" % (index+1, self.options[index]), textstyle) self.screen.addstr(5+index,4, "%d - %s" % (index+1, self.options[index]), textstyle)
self.screen.refresh() try:
self.screen.refresh()
except Exception as exception:
# Makes sure data is saved in event of a crash due to window resizing
self.__exit__()
traceback.print_exc()
def update_plant_live(self): def update_plant_live(self):
# TODO: fix thread synchronization issue.. text garbling
# Updates plant data on menu screen, live!
# Will eventually use this to display ascii art...
while self.exit is not True: while self.exit is not True:
plant_string = self.plant.parse_plant() plant_string = self.plant.parse_plant()
plant_ticks = str(self.plant.ticks) plant_ticks = str(self.plant.ticks)
self.screen.addstr(10,2, plant_string, curses.A_NORMAL) self.screen.addstr(10,2, plant_string, curses.A_NORMAL)
self.screen.addstr(11,2, plant_ticks, curses.A_NORMAL) self.screen.addstr(11,2, plant_ticks, curses.A_NORMAL)
if self.plant.watered_date == datetime.datetime.now().date():
self.screen.addstr(6,13, " - plant watered already!", curses.A_NORMAL)
self.screen.refresh() self.screen.refresh()
time.sleep(1) time.sleep(1)
#curses.endwin()
#os.system('clear')
def get_user_input(self): def get_user_input(self):
'''Gets the user's input and acts appropriately''' '''Gets the user's input and acts appropriately'''
@ -109,6 +121,9 @@ class CursedMenu(object):
if request == 1: if request == 1:
self.screen.addstr(8,15,str(self.plant.ticks), curses.A_STANDOUT) # Title for this menu self.screen.addstr(8,15,str(self.plant.ticks), curses.A_STANDOUT) # Title for this menu
self.screen.refresh() self.screen.refresh()
if request == "water":
self.plant.water()
def __exit__(self): def __exit__(self):
self.exit = True self.exit = True
@ -119,4 +134,5 @@ class CursedMenu(object):
'''demo''' '''demo'''
# cm = CursedMenu() # cm = CursedMenu()
# cm.show([1,2,3], title=' botany ', subtitle='Options') # cm.show([1,"water",3], title=' botany ', subtitle='Options')