4112e223 by Barry

memory use improvements.

1 parent bb158dfa
......@@ -41,12 +41,15 @@ class CommandHandler(object):
command = cmd
ldict = locals()
with open('commands/{}.txt'.format(cmd), 'r', encoding='utf-8') as f:
exec(f.read(), globals(), ldict)
command_text = f.read()
exec(command_text, globals(), ldict)
del command_text
if ldict['next_command'] != None:
locals()['tokens'] = []
tokens = []
with open('commands/{}.txt'.format(ldict['next_command']), 'r', encoding='utf-8') as f:
exec(f.read())
del ldict
return True
# except Exception as e:
# print('Something happened...')
......
......@@ -23,4 +23,5 @@ def drop(id, tokens, players, mud):
else:
mud.send_message(id, 'You do not have {} in your inventory.'.format(tokens[0]))
drop(id, tokens, players, mud)
\ No newline at end of file
drop(id, tokens, players, mud)
del drop
\ No newline at end of file
......
......@@ -9,6 +9,9 @@ def get(id, tokens, players, mud):
players[id]['inventory'][tokens[0]] += 1
else:
players[id]['inventory'][tokens[0]] = 1
room_data['inventory'][tokens[0]] -= 1
if room_data['inventory'][tokens[0]] <= 0:
del room_data['inventory'][tokens[0]]
for pid, pl in players.items():
# if they're in the same room as the player
if players[pid]["room"] == players[id]["room"]:
......@@ -16,6 +19,7 @@ def get(id, tokens, players, mud):
mud.send_message(pid, "{} picked up a {}.".format(
players[id]["name"], tokens[0]))
utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
utils.save_object_to_file(room_data, 'rooms/' + room_name + '.json')
else:
mud.send_message(id, 'There is no {} here to get.'.format(tokens[0]))
......
......@@ -56,4 +56,5 @@ def go(id, params, players, mud, tokens, command):
mud.send_message(id, "Unknown exit '{}'".format(params))
if command is None and cmd is not None:
command = cmd
next_command = go(id, params, players, mud, tokens, command)
\ No newline at end of file
next_command = go(id, params, players, mud, tokens, command)
del go
\ No newline at end of file
......
......@@ -11,4 +11,5 @@ def help(id, tokens, mud):
except:
mud.send_message(id, 'No help topics available for \"{}\". A list\r\n of all commands is available at: help index'.format(tokens[0]))
help(id, tokens, mud)
\ No newline at end of file
help(id, tokens, mud)
del help
\ No newline at end of file
......
......@@ -4,4 +4,5 @@ def inventory(id, players, mud):
mud.send_message(id, '{} {}'.format("%-37s" % item, qty))
mud.send_message(id, '\r\n-----------------------------------------')
inventory(id, players, mud)
\ No newline at end of file
inventory(id, players, mud)
del inventory
\ No newline at end of file
......
......@@ -46,4 +46,5 @@ def look(id, mud, players, tokens):
room_monsters = utils.load_object_from_file('rooms/' + room_name + '_monsters.json')
mud.send_message(id, "Mobs here: {}".format( ", ".join(room_monsters.keys())))
look(id, mud, players, tokens)
\ No newline at end of file
look(id, mud, players, tokens)
del look
\ No newline at end of file
......
......@@ -5,4 +5,5 @@ def prompt(id, tokens, params, players, mud):
players[id]['prompt'] = params + ' '
utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
prompt(id, tokens, params, players, mud)
\ No newline at end of file
prompt(id, tokens, params, players, mud)
del prompt
\ No newline at end of file
......
......@@ -4,4 +4,5 @@ def quit(id, players, mud):
utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
mud.disconnect_player(id)
quit(id, players, mud)
\ No newline at end of file
quit(id, players, mud)
del quit
\ No newline at end of file
......
......@@ -4,4 +4,5 @@ def save(id, players, mud):
utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
mud.send_message(id, "Save complete")
save(id, players, mud)
\ No newline at end of file
save(id, players, mud)
del save
\ No newline at end of file
......
......@@ -6,4 +6,5 @@ def say(id, params, players, mud):
# send them a message telling them what the player said
mud.send_message(pid, "{} says: {}".format(
players[id]["name"], params))
say(id, params, players, mud)
\ No newline at end of file
say(id, params, players, mud)
del say
\ No newline at end of file
......
......@@ -7,4 +7,5 @@ def whisper(id, tokens, players, mud):
mud.send_message(pid, "{} whispers: {}".format(
players[id]["name"], ' '.join(tokens[1:])))
whisper(id, tokens, players, mud)
\ No newline at end of file
whisper(id, tokens, players, mud)
del whisper
\ No newline at end of file
......
......@@ -5,4 +5,5 @@ def who(id, players, mud):
mud.send_message(id, " " + player["name"])
mud.send_message(id, "---------------------------------------------".format(len(players)))
mud.send_message(id, "")
who(id, players, mud)
\ No newline at end of file
who(id, players, mud)
del who
\ No newline at end of file
......
#!/usr/bin/env python
"""A simple Multi-User Dungeon (MUD) game. Players can talk to each
other, examine their surroundings and move between rooms.
Some ideas for things to try adding:
* More rooms to explore
* An 'emote' command e.g. 'emote laughs out loud' -> 'Mark laughs
out loud'
* A 'whisper' command for talking to individual players
* A 'shout' command for yelling to players in all rooms
* Items to look at in rooms e.g. 'look fireplace' -> 'You see a
roaring, glowing fire'
* Items to pick up e.g. 'take rock' -> 'You pick up the rock'
* Monsters to fight
* Loot to collect
* Saving players accounts between sessions
* A password login
* A shop from which to buy items
author: Mark Frimston - mfrimston@gmail.com
"""
MudServer author: Mark Frimston - mfrimston@gmail.com
import time
import sys
if 'esp' in sys.platform:
import gc
import machine
Micropython port and expansion author: Barry Ruffner - barryruffner@gmail.com
"""
from time import sleep
from sys import platform
if 'esp' in platform:
from gc import collect, mem_free
from machine import Pin
# import the MUD server class
from mudserver import MudServer
import utils
from utils import load_object_from_file, save_object_to_file
print('STARTING MUD\r\n\r\n\r\n')
if 'esp' in sys.platform:
flash_button = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
if 'esp' in platform:
flash_button = Pin(0, Pin.IN, Pin.PULL_UP)
# stores the players in the game
players = {}
......@@ -59,14 +44,13 @@ tick = 0.0
spawn = 0.0
# main game loop. We loop forever (i.e. until the program is terminated)
while True:
if 'esp' in sys.platform:
gc.collect()
if 'esp' in platform:
collect()
if flash_button.value() == 0:
break
# pause for 1/5 of a second on each loop, so that we don't constantly
# use 100% CPU time
time.sleep(0.001)
if 'esp' in sys.platform:
sleep(0.001)
if 'esp' in platform:
tick += 0.001
else:
tick += 0.0005
......@@ -80,6 +64,7 @@ while True:
print('spawner error:')
print(e)
if tick >= 1:
print(mem_free())
spawn += tick
tick = 0
# try:
......@@ -101,7 +86,7 @@ while True:
# The dictionary key is the player's id number. We set their room to
# None initially until they have entered a name
# Try adding more player stats - level, gold, inventory, etc
players[id] = utils.load_object_from_file("defaultplayer.json")
players[id] = load_object_from_file("defaultplayer.json")
with open('welcome.txt', 'r', encoding='utf-8') as f:
for line in f:
mud.send_message(id, line, "\r")
......@@ -121,12 +106,11 @@ while True:
# send each player a message to tell them about the diconnected
# player
if players[pid]["name"] != None:
mud.send_message(pid, "{} quit the game".format(
players[pid]["name"]))
mud.send_message(pid, "{} quit the game".format(players[pid]["name"]))
# remove the player's entry in the player dictionary
if players[id]["name"] != None:
utils.save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
save_object_to_file(players[id], "players/{}.json".format(players[id]["name"]))
del(players[id])
# go through any new commands sent from players
......@@ -151,7 +135,7 @@ while True:
already_logged_in = True
if already_logged_in:
continue
loaded_player = utils.load_object_from_file("players/{}.json".format(command))
loaded_player = load_object_from_file("players/{}.json".format(command))
if loaded_player is None:
players[id]["name"] = command
players[id]["room"] = "Tavern"
......@@ -171,7 +155,7 @@ while True:
# send the new player the description of their current room
mud.send_message(id, utils.load_object_from_file('rooms/' + players[id]["room"] + '.json')['description'])
mud.send_message(id, load_object_from_file('rooms/' + players[id]["room"] + '.json')['description'])
else:
from commandhandler import CommandHandler
......@@ -182,7 +166,7 @@ while True:
show_prompt(id)
# Start WIFI Setup
if 'esp' in sys.platform:
if 'esp' in platform:
if flash_button.value() == 0:
print('Starting WIFIWeb')
import wifiweb
......
def run_mobs(players, mud):
def get_att(d):
att = 0
if 'd' in d:
dice = d.split('d')
for d in range(int(dice[0])):
att += utils.randrange(int(dice[1])) + 1
else:
att = int(d)
return att
def calc_att(pid, attacks, bank):
v_att = []
att = 0
for attack in attacks:
if attack['cost'] < bank:
v_att.append(attack)
# Select a random attack
if len(v_att) > 0:
attack = v_att[utils.randrange(len(v_att))]
att = get_att(attack['dmg'])
mud.send_message(pid, "%s for %d" % (attack['desc'], att,))
bank -= attack['cost']
return att, bank
from utils import load_object_from_file, save_object_to_file, calc_att, get_att
for pid, player in players.items():
if not player['name']:
continue
room_monsters = utils.load_object_from_file('rooms/{}_monsters.json'.format(player['room']))
room_monsters = load_object_from_file('rooms/{}_monsters.json'.format(player['room']))
if not room_monsters:
continue
for mon_name, monster in room_monsters.items():
monster_template = utils.load_object_from_file('mobs/{}.json'.format(mon_name))
monster_template = load_object_from_file('mobs/{}.json'.format(mon_name))
if not monster_template:
continue
for active_monster_idx, active_monster in enumerate(monster['active']):
......@@ -44,40 +23,43 @@ def run_mobs(players, mud):
sta += monster_template['star']
active_monster['sta'] = sta
if active_monster['action'] == "attack" and active_monster['target'] == player['name']:
if player["weapon"]:
weapon = utils.load_object_from_file('inventory/{}.json'.format(player['weapon']))
if weapon:
att = get_att(weapon['damage'])
mud.send_message(pid, "Your %s strikes the %s for %d" % (weapon['title'], mon_name, att,))
else:
att = get_att(player['aa'])
if player.get("weapon"):
weapon = load_object_from_file('inventory/{}.json'.format(player['weapon']))
att = get_att(weapon['damage'])
mud.send_message(pid, "Your %s strikes the %s for %d" % (weapon['title'], mon_name, att,))
else:
att = get_att(player['aa'])
mud.send_message(pid, "You hit the %s for %d" % (mon_name, att,))
hp -= att
if hp == 0:
DEAD = 1
att = get_att(monster_template['aa'])
if active_monster.get("weapon"):
weapon = load_object_from_file('inventory/{}.json'.format(active_monster['weapon']))
att = get_att(weapon['damage'])
mud.send_message(pid, "The %s strikes you with a %s for %d" % (mon_name, weapon['title'], att,))
else:
att = get_att(monster_template['aa'])
mud.send_message(pid, "You were hit by a %s for %d" % (mon_name, att,))
players[pid]['hp'] -= att
mud.send_message(pid, "You were hit by a %s for %d" % (mon_name, att,))
# wait until at least 50% of stamina or mp are regenerated or hp is less than 25%
if (hp/active_monster['maxhp'] < 0.25) or (mp > 0 and mp/active_monster['maxmp'] > 0.5) or (sta > 0 and sta/active_monster['maxsta'] > 0.5):
magic_cast = False
if mp > 0:
att, mp = calc_att(pid, monster_template['sp'], mp)
att, mp = calc_att(mud, pid, monster_template['sp'], mp)
active_monster['mp'] = mp
players[pid]['hp'] -= att
if att > 0:
magic_cast = True
if not magic_cast:
if sta > 0:
att, sta = calc_att(pid, monster_template['at'], sta)
att, sta = calc_att(mud, pid, monster_template['at'], sta)
active_monster['sta'] = sta
players[pid]['hp'] -= att
room_monsters[mon_name]['active'][active_monster_idx] = active_monster
utils.save_object_to_file(room_monsters, 'rooms/{}_monsters.json'.format(player['room']))
save_object_to_file(room_monsters, 'rooms/{}_monsters.json'.format(player['room']))
run_mobs(players, mud)
\ No newline at end of file
run_mobs(players, mud)
del run_mobs
\ No newline at end of file
......
{"name": "test", "room": "Tavern", "inventory": {"candle": 1}, "prompt": "%hp> ", "aliases": {}, "hp": 596, "mp": 100, "sta": 10, "aa": "1d2", "mpr": 0.25, "star": 0.4, "maxhp": 953, "maxmp": 100, "maxsta": 10, "weapon": "sword"}
\ No newline at end of file
{"name": "test", "room": "Outside", "inventory": {"candle": 1}, "prompt": "%hp> ", "aliases": {}, "hp": 593, "mp": 100, "sta": 10, "aa": "1d2", "mpr": 0.25, "star": 0.4, "maxhp": 953, "maxmp": 100, "maxsta": 10, "weapon": "sword"}
\ No newline at end of file
......
......@@ -36,6 +36,7 @@ def run_command(sio, command, expected='>>>'):
with serial.Serial(PORT, BAUDRATE, timeout=1) as ser:
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
run_command(sio, '\x03')
run_command(sio, 'import os')
root = eval(run_command(sio, 'os.listdir()', expected=']'))
......@@ -52,13 +53,14 @@ with serial.Serial(PORT, BAUDRATE, timeout=1) as ser:
print('Folders already created.')
for folder in folders:
for f in os.listdir(folder):
files.append('{}/{}'.format(folder, f))
for folder in folders:
for f in os.listdir(folder):
files.append('{}/{}'.format(folder, f))
with open('releasepw.conf', 'r', encoding='utf-8') as f:
password = f.read()
with open('releasepw.conf', 'r', encoding='utf-8') as f:
password = f.read()
for file in files:
os.system("python webrepl\webrepl_cli.py -p {} {} {}:/{}".format(password, file, IPADDRESS, file))
for file in files:
os.system("python webrepl\webrepl_cli.py -p {} {} {}:/{}".format(password, file, IPADDRESS, file))
run_command(sio, 'import machine;machine.reset')
......
{"cricket": {"max": 1, "active": [{"hp": 100, "mp": 0.25, "sta": 2.7500000000000715, "maxhp": 100, "maxmp": 10, "maxsta": 10, "action": "attack", "target": "test"}]}}
\ No newline at end of file
{"cricket": {"max": 1, "active": [{"hp": 100, "mp": 2.0, "sta": 4.550000000000075, "maxhp": 100, "maxmp": 10, "maxsta": 10, "action": "attack", "target": "test"}]}}
\ No newline at end of file
......
......@@ -37,4 +37,27 @@ def randrange(start, stop=None):
break
return r + start
else:
return random.randrange(start)
\ No newline at end of file
return random.randrange(start)
def get_att(d):
att = 0
if 'd' in d:
dice = d.split('d')
for d in range(int(dice[0])):
att += randrange(int(dice[1])) + 1
else:
att = int(d)
return att
def calc_att(mud, pid, attacks, bank):
v_att = []
att = 0
for attack in attacks:
if attack['cost'] < bank:
v_att.append(attack)
# Select a random attack
if len(v_att) > 0:
attack = v_att[randrange(len(v_att))]
att = get_att(attack['dmg'])
mud.send_message(pid, "%s for %d" % (attack['desc'], att,))
bank -= attack['cost']
return att, bank
\ No newline at end of file
......