X-Git-Url: https://plomlompom.com/repos/berlin_corona.txt?a=blobdiff_plain;f=plomrogue-server.py;h=b666d7f417b9a579264b21831c20626c86cb937e;hb=659685982349318d6aaa271259fef324dd5c8d30;hp=a66e2ae8e92f6376e97bde3d94181b6006ee9c3c;hpb=e7310e4bba2ebdc194f079e68530ddd73fe0ba51;p=plomrogue diff --git a/plomrogue-server.py b/plomrogue-server.py index a66e2ae..b666d7f 100755 --- a/plomrogue-server.py +++ b/plomrogue-server.py @@ -4,6 +4,35 @@ import os import shlex import shutil import time +import ctypes + + +class RandomnessIO: + """"Interface to libplomrogue's pseudo-randomness generator.""" + + def set_seed(self, seed): + libpr.seed_rrand(1, seed) + + def get_seed(self): + return libpr.seed_rrand(0, 0) + + def next(self): + return libpr.rrand() + + seed = property(get_seed, set_seed) + + +def prep_library(): + """Prepare ctypes library at ./libplomrogue.so""" + libpath = ("./libplomrogue.so") + if not os.access(libpath, os.F_OK): + raise SystemExit("No library " + libpath + ", run ./compile.sh first?") + libpr = ctypes.cdll.LoadLibrary(libpath) + libpr.seed_rrand.argtypes = [ctypes.c_uint8, ctypes.c_uint32] + libpr.seed_rrand.restype = ctypes.c_uint32 + libpr.rrand.argtypes = [] + libpr.rrand.restype = ctypes.c_uint16 + return libpr def strong_write(file, string): @@ -182,7 +211,8 @@ def save_world(): string = string + "T_ID " + str(id) + "\n" for carried_id in world_db["Things"][id]["T_CARRIES"]: string = string + "T_CARRIES " + str(carried_id) + "\n" - string = string + "WORLD_ACTIVE " + str(world_db["WORLD_ACTIVE"]) + string = string + "SEED_RANDOMNESS " + str(rand.seed) + "\n" + \ + "WORLD_ACTIVE " + str(world_db["WORLD_ACTIVE"]) atomic_write(io_db["path_save"], string) @@ -449,38 +479,65 @@ def build_fov_map(t): # DUMMY so far. Just builds an all-visible map. -def actor_wait(Thing): - """Do nothing (but loudly, if by player).""" - if Thing == world_db["Things"][0]: +def actor_wait(t): + """Make t do nothing (but loudly, if player avatar).""" + if t == world_db["Things"][0]: strong_write(io_db["file_out"], "LOG You wait.\n") -def actor_move(Thing): +def actor_move(t): pass -def actor_pick_up(Thing): - """Pick up (topmost?) thing from ground into inventory.""" +def actor_pick_up(t): + """Make t pick up (topmost?) Thing from ground into inventory.""" # Topmostness is actually not defined so far. - ids = [id for id in world_db["Things"] if world_db["Things"][id] != Thing + ids = [id for id in world_db["Things"] if world_db["Things"][id] != t if not world_db["Things"][id]["carried"] - if world_db["Things"][id]["T_POSY"] == Thing["T_POSY"] - if world_db["Things"][id]["T_POSX"] == Thing["T_POSX"]] - if ids: + if world_db["Things"][id]["T_POSY"] == t["T_POSY"] + if world_db["Things"][id]["T_POSX"] == t["T_POSX"]] + if len(ids): world_db["Things"][ids[0]]["carried"] = True - Thing["T_CARRIES"].append(ids[0]) - strong_write(io_db["file_out"], "LOG You pick up an object.\n") - else: + t["T_CARRIES"].append(ids[0]) + if t == world_db["Things"][0]: + strong_write(io_db["file_out"], "LOG You pick up an object.\n") + elif t == world_db["Things"][0]: err = "You try to pick up an object, but there is none." strong_write(io_db["file_out"], "LOG " + err + "\n") -def actor_drop(Thing): - pass +def actor_drop(t): + """Make t rop Thing from inventory to ground indexed by T_ARGUMENT.""" + # TODO: Handle case where T_ARGUMENT matches nothing. + if len(t["T_CARRIES"]): + id = t["T_CARRIES"][t["T_ARGUMENT"]] + t["T_CARRIES"].remove(id) + world_db["Things"][id]["carried"] = False + if t == world_db["Things"][0]: + strong_write(io_db["file_out"], "LOG You drop an object.\n") + elif t == world_db["Things"][0]: + err = "You try to drop an object, but you own none." + strong_write(io_db["file_out"], "LOG " + err + "\n") -def actor_use(Thing): - pass +def actor_use(t): + """Make t use (for now: consume) T_ARGUMENT-indexed Thing in inventory.""" + # Original wrongly featured lifepoints increase through consumable! + # TODO: Handle case where T_ARGUMENT matches nothing. + if len(t["T_CARRIES"]): + id = t["T_CARRIES"][t["T_ARGUMENT"]] + type = world_db["Things"][id]["T_TYPE"] + if world_db["ThingTypes"][type]["TT_CONSUMABLE"]: + t["T_CARRIES"].remove(id) + del world_db["Things"][id] + t["T_SATIATION"] += world_db["ThingTypes"][type]["TT_CONSUMABLE"] + strong_write(io_db["file_out"], "LOG You consume this object.\n") + else: + strong_write(io_db["file_out"], "LOG You try to use this object," + + "but fail.\n") + else: + strong_write(io_db["file_out"], "LOG You try to use an object, but " + + "you own none.\n") def turn_over(): @@ -650,6 +707,15 @@ def play_commander(action, args=False): return set_command +def command_seedrandomness(seed_string): + """Set rand seed to int(seed_string).""" + val = integer_test(seed_string, 0, 4294967295) + if None != val: + rand.seed = val + else: + print("Ignoring: Value must be integer >= 0, <= 4294967295.") + + def command_seedmap(seed_string): """Set world_db["SEED_MAP"] to int(seed_string), then (re-)make map.""" setter(None, "SEED_MAP", 0, 4294967295)(seed_string) @@ -659,16 +725,20 @@ def command_seedmap(seed_string): def command_makeworld(seed_string): """(Re-)build game world, i.e. map, things, to a new turn 1 from seed. - Make seed world_db["SEED_RANDOMNESS"] and world_db["SEED_MAP"]. Do more - only with a "wait" ThingAction and world["PLAYER_TYPE"] matching ThingType - of TT_START_NUMBER > 0. Then, world_db["Things"] emptied, call remake_map() + Seed rand with seed, fill it into world_db["SEED_MAP"]. Do more only with a + "wait" ThingAction and world["PLAYER_TYPE"] matching ThingType of + TT_START_NUMBER > 0. Then, world_db["Things"] emptied, call remake_map() and set world_db["WORLD_ACTIVE"], world_db["TURN"] to 1. Build new Things according to ThingTypes' TT_START_NUMBERS, with Thing of ID 0 to ThingType of ID = world["PLAYER_TYPE"]. Place Things randomly, and actors not on each other. Init player's memory map. Write "NEW_WORLD" line to out file. """ - setter(None, "SEED_RANDOMNESS", 0, 4294967295)(seed_string) - setter(None, "SEED_MAP", 0, 4294967295)(seed_string) + val = integer_test(seed_string, 0, 4294967295) + if None == val: + print("Ignoring: Value must be integer >= 0, <= 4294967295.") + return + rand.seed = val + world_db["SEED_MAP"] = val player_will_be_generated = False playertype = world_db["PLAYER_TYPE"] for ThingType in world_db["ThingTypes"]: @@ -985,8 +1055,7 @@ commands_db = { "THINGS_HERE": (2, True, command_thingshere), "MAKE_WORLD": (1, False, command_makeworld), "SEED_MAP": (1, False, command_seedmap), - "SEED_RANDOMNESS": (1, False, setter(None, "SEED_RANDOMNESS", - 0, 4294967295)), + "SEED_RANDOMNESS": (1, False, command_seedrandomness), "TURN": (1, False, setter(None, "TURN", 0, 65535)), "PLAYER_TYPE": (1, False, setter(None, "PLAYER_TYPE", 0, 255)), "MAP_LENGTH": (1, False, command_maplength), @@ -1026,11 +1095,10 @@ commands_db = { } -"""World state database. With sane default values.""" +"""World state database. With sane default values. (Randomness is in rand.)""" world_db = { "TURN": 0, "SEED_MAP": 0, - "SEED_RANDOMNESS": 0, "PLAYER_TYPE": 0, "MAP_LENGTH": 64, "WORLD_ACTIVE": 0, @@ -1056,6 +1124,8 @@ io_db = { try: + libpr = prep_library() + rand = RandomnessIO() opts = parse_command_line_arguments() setup_server_io() if None != opts.replay: