2017-03-06 22:22:13 +00:00
|
|
|
from __future__ import division
|
2017-03-06 21:38:31 +00:00
|
|
|
import time
|
2017-03-06 22:22:13 +00:00
|
|
|
import pickle
|
2017-03-06 21:38:31 +00:00
|
|
|
import json
|
|
|
|
import math
|
|
|
|
import os.path
|
|
|
|
import random
|
2017-03-07 01:56:11 +00:00
|
|
|
import getpass
|
2017-03-07 18:07:13 +00:00
|
|
|
import threading
|
2017-03-08 02:35:04 +00:00
|
|
|
import errno
|
|
|
|
from menu_screen import *
|
2017-03-06 21:38:31 +00:00
|
|
|
# ideas go here
|
|
|
|
# lifecycle of a plant
|
|
|
|
# seed -> seedling -> sprout -> young plant -> mature plant -> flower ->
|
|
|
|
# pollination -> fruit -> seeds
|
|
|
|
|
|
|
|
# neighboring plants can cross pollinate for different plants
|
|
|
|
# health based on checkups and watering
|
|
|
|
|
|
|
|
# development plan
|
|
|
|
# build plant lifecycle just stepping through
|
2017-03-07 00:57:11 +00:00
|
|
|
# - What else should it do during life? growth alone is not all that
|
2017-03-06 21:38:31 +00:00
|
|
|
# interesting.
|
2017-03-07 00:57:11 +00:00
|
|
|
# - how long should each stage last ? thinking realistic lmao
|
|
|
|
|
|
|
|
# interaction
|
|
|
|
# - watering?
|
2017-03-07 21:04:14 +00:00
|
|
|
# - look at plant, how do you feel? (also gets rid of pests)
|
|
|
|
#
|
|
|
|
# if >5 days with no water, plant dies
|
|
|
|
# events
|
|
|
|
# - heatwave
|
|
|
|
# - rain
|
|
|
|
# - bugs
|
|
|
|
#
|
|
|
|
# neighborhood system
|
|
|
|
# - create plant id (sort of like userid)
|
|
|
|
# - list sorted by plantid that wraps so everybody has 2 neighbors :)
|
|
|
|
# - can water neighbors plant once (have to choose which)
|
|
|
|
# - pollination - seed is combination of your plant and neighbor plant
|
|
|
|
# - create rarer species by diff gens
|
|
|
|
# - if neighbor plant dies, node will be removed from list
|
|
|
|
#
|
|
|
|
# garden system
|
|
|
|
# - can plant your plant in the garden to start a new plant
|
2017-03-06 21:38:31 +00:00
|
|
|
|
|
|
|
# build time system
|
|
|
|
# build persistence across sessions
|
2017-03-07 00:57:11 +00:00
|
|
|
|
2017-03-06 21:38:31 +00:00
|
|
|
# build ascii trees
|
|
|
|
# build gui?
|
|
|
|
|
|
|
|
# build multiplayer
|
|
|
|
|
|
|
|
# def display_update:
|
|
|
|
# myscreen = curses.initscr()
|
|
|
|
#
|
|
|
|
# myscreen.border(0)
|
|
|
|
# myscreen.addstr(1, 2, "you've planted a seed")
|
|
|
|
# myscreen.refresh()
|
|
|
|
#
|
|
|
|
# for i in range(1,20):
|
|
|
|
# myscreen.addstr(i, 2, str(i))
|
|
|
|
# time.sleep(1)
|
|
|
|
# myscreen.refresh()
|
|
|
|
#
|
|
|
|
# myscreen.getch()
|
|
|
|
#
|
|
|
|
# curses.endwin()
|
|
|
|
|
2017-03-08 02:35:04 +00:00
|
|
|
|
2017-03-07 01:56:11 +00:00
|
|
|
class Plant(object):
|
2017-03-07 21:04:14 +00:00
|
|
|
# This is your plant!
|
2017-03-06 23:20:31 +00:00
|
|
|
stage_dict = {
|
|
|
|
0: 'seed',
|
|
|
|
1: 'seedling',
|
|
|
|
2: 'young',
|
2017-03-06 23:29:23 +00:00
|
|
|
3: 'mature',
|
|
|
|
4: 'flowering',
|
|
|
|
5: 'fruiting',
|
2017-03-06 23:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
color_dict = {
|
|
|
|
0: 'red',
|
|
|
|
1: 'orange',
|
|
|
|
2: 'yellow',
|
|
|
|
3: 'green',
|
|
|
|
4: 'blue',
|
|
|
|
5: 'indigo',
|
|
|
|
6: 'violet',
|
|
|
|
7: 'white',
|
|
|
|
8: 'black',
|
|
|
|
9: 'gold',
|
|
|
|
10: 'rainbow',
|
|
|
|
}
|
|
|
|
|
|
|
|
rarity_dict = {
|
|
|
|
0: 'common',
|
|
|
|
1: 'uncommon',
|
|
|
|
2: 'rare',
|
|
|
|
3: 'legendary',
|
|
|
|
4: 'godly',
|
|
|
|
}
|
|
|
|
|
|
|
|
species_dict = {
|
|
|
|
0: 'poppy',
|
|
|
|
1: 'cactus',
|
|
|
|
2: 'aloe',
|
|
|
|
3: 'venus flytrap',
|
2017-03-07 00:57:11 +00:00
|
|
|
4: 'jade plant',
|
2017-03-06 23:20:31 +00:00
|
|
|
5: 'fern',
|
2017-03-06 23:29:23 +00:00
|
|
|
6: 'daffodil',
|
2017-03-06 23:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mutation_dict = {
|
|
|
|
0: '',
|
|
|
|
1: 'humming',
|
|
|
|
2: 'noxious',
|
|
|
|
3: 'vorpal',
|
2017-03-06 23:29:23 +00:00
|
|
|
4: 'glowing',
|
|
|
|
5: 'electric',
|
2017-03-07 00:57:11 +00:00
|
|
|
6: 'icy',
|
2017-03-06 23:29:23 +00:00
|
|
|
7: 'flaming',
|
|
|
|
8: 'psychic',
|
2017-03-07 00:57:11 +00:00
|
|
|
9: 'screaming',
|
|
|
|
10: 'chaos',
|
|
|
|
11: 'hissing',
|
|
|
|
12: 'gelatinous',
|
|
|
|
13: 'deformed',
|
|
|
|
14: 'shaggy',
|
|
|
|
15: 'scaly',
|
|
|
|
16: 'depressed',
|
|
|
|
17: 'anxious',
|
|
|
|
18: 'metallic',
|
|
|
|
19: 'glossy',
|
2017-03-06 23:20:31 +00:00
|
|
|
}
|
|
|
|
|
2017-03-07 21:04:14 +00:00
|
|
|
def __init__(self, this_filename):
|
|
|
|
# Constructor
|
2017-03-06 21:38:31 +00:00
|
|
|
self.stage = 0
|
|
|
|
self.mutation = 0
|
2017-03-06 23:20:31 +00:00
|
|
|
self.species = random.randint(0,len(self.species_dict)-1)
|
2017-03-07 00:57:11 +00:00
|
|
|
self.color = random.randint(0,len(self.color_dict)-1)
|
2017-03-06 21:38:31 +00:00
|
|
|
self.rarity = self.rarity_check()
|
2017-03-07 00:57:11 +00:00
|
|
|
self.ticks = 0
|
2017-03-07 18:07:13 +00:00
|
|
|
self.dead = False
|
2017-03-08 08:18:45 +00:00
|
|
|
self.file_name = this_filename
|
|
|
|
self.start_time = int(time.time())
|
|
|
|
self.last_time = int(time.time())
|
|
|
|
self.watered_date = 0
|
2017-03-06 21:38:31 +00:00
|
|
|
|
|
|
|
def rarity_check(self):
|
2017-03-07 21:04:14 +00:00
|
|
|
# Generate plant rarity
|
2017-03-06 22:22:13 +00:00
|
|
|
CONST_RARITY_MAX = 256.0
|
|
|
|
rare_seed = random.randint(1,CONST_RARITY_MAX)
|
|
|
|
common_range = round((2/3)*CONST_RARITY_MAX)
|
|
|
|
uncommon_range = round((2/3)*(CONST_RARITY_MAX-common_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))
|
2017-03-08 08:18:45 +00:00
|
|
|
# godly_range = round((2/3)*(CONST_RARITY_MAX-common_range-uncommon_range-rare_range-legendary_range))
|
2017-03-06 22:22:13 +00:00
|
|
|
|
|
|
|
# print common_range, uncommon_range, rare_range, legendary_range, godly_range
|
|
|
|
|
|
|
|
common_max = common_range
|
|
|
|
uncommon_max = common_max + uncommon_range
|
|
|
|
rare_max = uncommon_max + rare_range
|
|
|
|
legendary_max = rare_max + legendary_range
|
2017-03-08 08:18:45 +00:00
|
|
|
godly_max = CONST_RARITY_MAX
|
2017-03-06 22:22:13 +00:00
|
|
|
|
|
|
|
# print common_max, uncommon_max, rare_max, legendary_max, godly_max
|
|
|
|
if 0 <= rare_seed <= common_max:
|
2017-03-06 21:38:31 +00:00
|
|
|
rarity = 0
|
2017-03-06 22:22:13 +00:00
|
|
|
elif common_max < rare_seed <= uncommon_max:
|
2017-03-06 21:38:31 +00:00
|
|
|
rarity = 1
|
2017-03-06 22:22:13 +00:00
|
|
|
elif uncommon_max < rare_seed <= rare_max:
|
2017-03-06 21:38:31 +00:00
|
|
|
rarity = 2
|
2017-03-06 22:22:13 +00:00
|
|
|
elif rare_max < rare_seed <= legendary_max:
|
2017-03-06 21:38:31 +00:00
|
|
|
rarity = 3
|
2017-03-08 08:18:45 +00:00
|
|
|
elif legendary_max < rare_seed <= godly_max:
|
2017-03-06 21:38:31 +00:00
|
|
|
rarity = 4
|
|
|
|
return rarity
|
|
|
|
|
|
|
|
def growth(self):
|
2017-03-07 21:04:14 +00:00
|
|
|
# Increase plant growth stage
|
2017-03-07 00:57:11 +00:00
|
|
|
if self.stage < (len(self.stage_dict)-1):
|
2017-03-06 21:38:31 +00:00
|
|
|
self.stage += 1
|
|
|
|
# do stage growth stuff
|
|
|
|
else:
|
|
|
|
# do stage 5 stuff (after fruiting)
|
|
|
|
1==1
|
2017-03-07 21:04:14 +00:00
|
|
|
|
2017-03-08 08:18:45 +00:00
|
|
|
def water(self):
|
|
|
|
# Increase plant growth stage
|
|
|
|
self.watered_date = datetime.datetime.now().date()
|
|
|
|
|
2017-03-07 21:04:14 +00:00
|
|
|
def mutate_check(self):
|
|
|
|
# Create plant mutation
|
|
|
|
# TODO: when out of debug this needs to be set to high number (1000
|
|
|
|
# even maybe)
|
|
|
|
CONST_MUTATION_RARITY = 10 # Increase this # to make mutation rarer (chance 1 out of x)
|
|
|
|
mutation_seed = random.randint(1,CONST_MUTATION_RARITY)
|
|
|
|
if mutation_seed == CONST_MUTATION_RARITY:
|
|
|
|
# mutation gained!
|
|
|
|
mutation = random.randint(0,len(self.mutation_dict)-1)
|
|
|
|
if self.mutation == 0:
|
|
|
|
self.mutation = mutation
|
2017-03-08 08:18:45 +00:00
|
|
|
#print "mutation!"
|
2017-03-07 21:04:14 +00:00
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
2017-03-06 21:38:31 +00:00
|
|
|
def parse_plant(self):
|
2017-03-07 21:04:14 +00:00
|
|
|
# reads plant info (maybe want to reorg this into a different class
|
|
|
|
# with the reader dicts...)
|
2017-03-07 02:14:47 +00:00
|
|
|
output = ""
|
|
|
|
output += self.rarity_dict[self.rarity] + " "
|
|
|
|
if self.mutation != 0:
|
|
|
|
output += self.mutation_dict[self.mutation] + " "
|
|
|
|
if self.stage >= 4:
|
|
|
|
output += self.color_dict[self.color] + " "
|
|
|
|
output += self.stage_dict[self.stage] + " "
|
|
|
|
if self.stage >= 2:
|
|
|
|
output += self.species_dict[self.species] + " "
|
2017-03-08 02:35:04 +00:00
|
|
|
# print output
|
|
|
|
return output
|
2017-03-06 21:38:31 +00:00
|
|
|
|
2017-03-07 18:07:13 +00:00
|
|
|
def start_life(self):
|
2017-03-07 21:04:14 +00:00
|
|
|
# runs life on a thread
|
2017-03-07 18:07:13 +00:00
|
|
|
thread = threading.Thread(target=self.life, args=())
|
|
|
|
thread.daemon = True
|
|
|
|
thread.start()
|
|
|
|
|
|
|
|
def life(self):
|
2017-03-07 00:57:11 +00:00
|
|
|
# I've created life :)
|
2017-03-07 21:04:14 +00:00
|
|
|
# TODO: change out of debug
|
2017-03-07 00:57:11 +00:00
|
|
|
# life_stages = (5, 15, 30, 45, 60)
|
2017-03-07 02:14:47 +00:00
|
|
|
life_stages = (1, 2, 3, 4, 5)
|
2017-03-07 18:07:13 +00:00
|
|
|
# leave this untouched bc it works for now
|
|
|
|
while (self.stage < 5) or (self.dead == False):
|
2017-03-07 02:14:47 +00:00
|
|
|
time.sleep(1)
|
|
|
|
self.ticks += 1
|
2017-03-08 02:35:04 +00:00
|
|
|
# print self.ticks
|
2017-03-07 02:14:47 +00:00
|
|
|
if self.stage < len(self.stage_dict)-1:
|
|
|
|
if self.ticks == life_stages[self.stage]:
|
|
|
|
self.growth()
|
2017-03-08 08:18:45 +00:00
|
|
|
#print self.parse_plant()
|
2017-03-07 21:04:14 +00:00
|
|
|
if self.mutate_check():
|
2017-03-08 08:18:45 +00:00
|
|
|
1==1
|
|
|
|
#print self.parse_plant()
|
2017-03-07 18:07:13 +00:00
|
|
|
|
|
|
|
# what kills the plant?
|
2017-03-07 01:56:11 +00:00
|
|
|
|
|
|
|
## DEBUG:
|
2017-03-07 02:14:47 +00:00
|
|
|
# while my_plant.stage < len(my_plant.stage_dict)-1:
|
|
|
|
# raw_input("...")
|
|
|
|
# my_plant.growth()
|
|
|
|
# my_plant.parse_plant()
|
2017-03-07 01:56:11 +00:00
|
|
|
|
|
|
|
class DataManager(object):
|
2017-03-07 21:04:14 +00:00
|
|
|
# handles user data, puts a .botany dir in user's home dir (OSX/Linux)
|
|
|
|
# TODO: windows... lol
|
|
|
|
user_dir = os.path.expanduser("~")
|
|
|
|
botany_dir = os.path.join(user_dir,'.botany')
|
|
|
|
this_user = getpass.getuser()
|
|
|
|
savefile_name = this_user + '_plant.dat'
|
|
|
|
savefile_path = os.path.join(botany_dir,savefile_name)
|
|
|
|
|
2017-03-07 01:56:11 +00:00
|
|
|
def __init__(self):
|
|
|
|
self.this_user = getpass.getuser()
|
2017-03-08 02:35:04 +00:00
|
|
|
# check for .botany dir in home
|
|
|
|
try:
|
2017-03-07 21:04:14 +00:00
|
|
|
os.makedirs(self.botany_dir)
|
2017-03-08 02:35:04 +00:00
|
|
|
except OSError as exception:
|
|
|
|
if exception.errno != errno.EEXIST:
|
|
|
|
raise
|
|
|
|
|
2017-03-07 01:56:11 +00:00
|
|
|
self.savefile_name = self.this_user + '_plant.dat'
|
|
|
|
|
|
|
|
def check_plant(self):
|
2017-03-07 21:04:14 +00:00
|
|
|
# check for existing save file
|
|
|
|
if os.path.isfile(self.savefile_path):
|
2017-03-07 01:56:11 +00:00
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def save_plant(self, this_plant):
|
2017-03-07 21:04:14 +00:00
|
|
|
# create savefile
|
2017-03-08 08:18:45 +00:00
|
|
|
this_plant.last_time = int(time.time())
|
2017-03-07 21:04:14 +00:00
|
|
|
with open(self.savefile_path, 'wb') as f:
|
2017-03-07 01:56:11 +00:00
|
|
|
pickle.dump(this_plant, f, protocol=2)
|
|
|
|
|
|
|
|
def load_plant(self):
|
2017-03-07 21:04:14 +00:00
|
|
|
# load savefile
|
|
|
|
with open(self.savefile_path, 'rb') as f:
|
2017-03-07 01:56:11 +00:00
|
|
|
this_plant = pickle.load(f)
|
|
|
|
return this_plant
|
|
|
|
|
|
|
|
def data_write_json(self, this_plant):
|
2017-03-07 21:04:14 +00:00
|
|
|
# create json file for user to use outside of the game (website?)
|
2017-03-08 08:18:45 +00:00
|
|
|
this_plant.watered_date = this_plant.watered_date.strftime("%Y-%m-%d")
|
2017-03-07 21:04:14 +00:00
|
|
|
json_file = os.path.join(self.botany_dir,self.this_user + '_plant_data.json')
|
|
|
|
with open(json_file, 'w') as outfile:
|
2017-03-07 01:56:11 +00:00
|
|
|
json.dump(this_plant.__dict__, outfile)
|
2017-03-07 00:57:11 +00:00
|
|
|
|
2017-03-08 08:18:45 +00:00
|
|
|
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
|
2017-03-07 18:07:13 +00:00
|
|
|
|
2017-03-06 21:38:31 +00:00
|
|
|
if __name__ == '__main__':
|
2017-03-07 01:56:11 +00:00
|
|
|
my_data = DataManager()
|
2017-03-07 21:04:14 +00:00
|
|
|
# if plant save file exists
|
2017-03-07 01:56:11 +00:00
|
|
|
if my_data.check_plant():
|
2017-03-08 08:18:45 +00:00
|
|
|
#print "Welcome back, " + getpass.getuser()
|
2017-03-07 01:56:11 +00:00
|
|
|
my_plant = my_data.load_plant()
|
2017-03-08 08:18:45 +00:00
|
|
|
#print my_plant.parse_plant()
|
2017-03-07 01:56:11 +00:00
|
|
|
# otherwise create new plant
|
|
|
|
else:
|
2017-03-08 08:18:45 +00:00
|
|
|
#print "Welcome, " + getpass.getuser()
|
2017-03-07 21:04:14 +00:00
|
|
|
#TODO: onboarding, select seed, select whatever else
|
|
|
|
my_plant = Plant(my_data.savefile_path)
|
2017-03-07 18:07:13 +00:00
|
|
|
my_plant.start_life()
|
2017-03-08 08:18:45 +00:00
|
|
|
#print "Your plant is living :)"
|
2017-03-08 02:35:04 +00:00
|
|
|
botany_menu = CursedMenu(my_plant)
|
2017-03-08 08:18:45 +00:00
|
|
|
botany_menu.show([1,"water",3], title=' botany ', subtitle='Options')
|
2017-03-08 02:35:04 +00:00
|
|
|
#raw_input('Press return to save and exit...\n')
|
2017-03-07 01:56:11 +00:00
|
|
|
my_data.save_plant(my_plant)
|
|
|
|
my_data.data_write_json(my_plant)
|
2017-03-08 08:18:45 +00:00
|
|
|
#print "end"
|
|
|
|
|