home · contact · privacy
Server/py: Further optimizations by putting stuff into libplomrogue.
[plomrogue] / plomrogue-server.py
index a0210126188f3b67e91321441153e7f51fcce1c0..204c131282d512fc20459c78ed32b21dde70a67c 100755 (executable)
@@ -1,3 +1,10 @@
+#!/usr/bin/python3
+
+# This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
+# or any later version. For details on its copyright, license, and warranties,
+# see the file NOTICE in the root directory of the PlomRogue source package.
+
+
 import argparse
 import errno
 import os
@@ -29,30 +36,7 @@ def prep_library():
         raise SystemExit("No library " + libpath +
                          ", run ./compile-server.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
-    libpr.set_maplength.argtypes = [ctypes.c_uint16]
-    libpr.mv_yx_in_dir_legal_wrap.argtypes = [ctypes.c_char, ctypes.c_uint8,
-                                              ctypes.c_uint8]
-    libpr.mv_yx_in_dir_legal_wrap.restype = ctypes.c_uint8
-    libpr.result_y.restype = ctypes.c_uint8
-    libpr.result_x.restype = ctypes.c_uint8
-    libpr.set_maplength(world_db["MAP_LENGTH"])
-    libpr.build_fov_map.argtypes = [ctypes.c_uint8, ctypes.c_uint8,
-                                    ctypes.c_char_p, ctypes.c_char_p]
-    libpr.build_fov_map.restype = ctypes.c_uint8
-    libpr.init_score_map.restype = ctypes.c_uint8
-    libpr.set_map_score.argtypes = [ctypes.c_uint16, ctypes.c_uint16]
-    libpr.set_map_score.restype = ctypes.c_uint8
-    libpr.get_map_score.argtypes = [ctypes.c_uint16]
-    libpr.get_map_score.restype = ctypes.c_int32
-    libpr.get_neighbor_score.argtypes = [ctypes.c_uint8]
-    libpr.get_neighbor_score.restype = ctypes.c_uint16
-    libpr.ready_neighbor_scores.argtpes = [ctypes.c_uint16]
-    libpr.ready_neighbor_scores.restype = ctypes.c_uint8
-    libpr.dijkstra_map.restype = ctypes.c_uint8
     return libpr
 
 
@@ -256,6 +240,8 @@ def parse_command_line_arguments():
     parser = argparse.ArgumentParser()
     parser.add_argument('-s', nargs='?', type=int, dest='replay', const=1,
                         action='store')
+    parser.add_argument('-l', nargs="?", const="save", dest='savefile',
+                        action="store")
     parser.add_argument('-v', dest='verbose', action='store_true')
     opts, unknown = parser.parse_known_args()
     return opts
@@ -484,20 +470,24 @@ def update_map_memory(t, age_map=True):
         t["T_MEMMAP"] = bytearray(b' ' * (world_db["MAP_LENGTH"] ** 2))
     if not t["T_MEMDEPTHMAP"]:
         t["T_MEMDEPTHMAP"] = bytearray(b' ' * (world_db["MAP_LENGTH"] ** 2))
-    for pos in range(world_db["MAP_LENGTH"] ** 2):
-        if "v" == chr(t["fovmap"][pos]):
-            t["T_MEMDEPTHMAP"][pos] = ord("0")
-            if " " == chr(t["T_MEMMAP"][pos]):
-                t["T_MEMMAP"][pos] = world_db["MAP"][pos]
-            continue
-        if age_map and ord('0') <= t["T_MEMDEPTHMAP"][pos] \
-           and ord('9') > t["T_MEMDEPTHMAP"][pos] \
-           and not rand.next() % (2 ** (t["T_MEMDEPTHMAP"][pos] - 48)):
-            t["T_MEMDEPTHMAP"][pos] += 1
+    ord_v = ord("v")
+    ord_0 = ord("0")
+    ord_9 = ord("9")
+    ord_space = ord(" ")
+    for pos in [pos for pos in range(world_db["MAP_LENGTH"] ** 2)
+                if ord_v == t["fovmap"][pos]]:
+        t["T_MEMDEPTHMAP"][pos] = ord_0
+        if ord_space == t["T_MEMMAP"][pos]:
+            t["T_MEMMAP"][pos] = world_db["MAP"][pos]
+    if age_map:
+        maptype = ctypes.c_char * len(t["T_MEMDEPTHMAP"])
+        memdepthmap = maptype.from_buffer(t["T_MEMDEPTHMAP"])
+        fovmap = maptype.from_buffer(t["fovmap"])
+        libpr.age_some_memdepthmap_on_nonfov_cells(memdepthmap, fovmap)
     for mt in [mt for mt in t["T_MEMTHING"]
                if "v" == chr(t["fovmap"][(mt[1] * world_db["MAP_LENGTH"])
                                          + mt[2]])]:
-            t["T_MEMTHING"].remove(mt)
+         t["T_MEMTHING"].remove(mt)
     for id in [id for id in world_db["Things"]
                if not world_db["Things"][id]["carried"]]:
         type = world_db["Things"][id]["T_TYPE"]
@@ -788,6 +778,14 @@ def get_dir_to_target(t, filter):
     "s": memory map cell with greatest-reachable degree of unexploredness
     """
 
+    def zero_score_map_where_char_on_memdepthmap(c):
+        maptype = ctypes.c_char * len(t["T_MEMDEPTHMAP"])
+        map = maptype.from_buffer(t["T_MEMDEPTHMAP"])
+        test = libpr.zero_score_map_where_char_on_memdepthmap(c, map)
+        if test:
+            raise RuntimeError("No score map allocated for "
+                               "zero_score_map_where_char_on_memdepthmap().")
+
     def set_map_score(pos, score):
         test = libpr.set_map_score(pos, score)
         if test:
@@ -826,8 +824,11 @@ def get_dir_to_target(t, filter):
         test = libpr.init_score_map()
         if test:
             raise RuntimeError("Malloc error in init_score_map().")
+        ord_dot = ord(".")
+        ord_v = ord("v")
+        ord_blank = ord(" ")
         for i in [i for i in range(world_db["MAP_LENGTH"] ** 2)
-                  if '.' == chr(t["T_MEMMAP"][i])]:
+                  if ord_dot == t["T_MEMMAP"][i]]:
             set_map_score(i, 65535 - 1)
         if "a" == filter:
             for id in world_db["Things"]:
@@ -836,7 +837,7 @@ def get_dir_to_target(t, filter):
                       + Thing["T_POSX"]
                 if t != Thing and Thing["T_LIFEPOINTS"] and \
                    t["T_TYPE"] != Thing["T_TYPE"] and \
-                   'v' == chr(t["fovmap"][pos]) and \
+                   ord_v == t["fovmap"][pos] and \
                    t["T_LIFEPOINTS"] > \
                    world_db["ThingTypes"][Thing["T_TYPE"]]["TT_LIFEPOINTS"]:
                     set_map_score(pos, 0)
@@ -849,21 +850,19 @@ def get_dir_to_target(t, filter):
                 pos = Thing["T_POSY"] * world_db["MAP_LENGTH"] \
                       + Thing["T_POSX"]
                 if t["T_TYPE"] != Thing["T_TYPE"] and \
-                   'v' == chr(t["fovmap"][pos]) and \
+                   ord_v == t["fovmap"][pos] and \
                    t["T_LIFEPOINTS"] <= \
                    world_db["ThingTypes"][Thing["T_TYPE"]]["TT_LIFEPOINTS"]:
                     set_map_score(pos, 0)
         elif "c" == filter:
             for mt in [mt for mt in t["T_MEMTHING"]
-                       if ' ' != chr(t["T_MEMMAP"][mt[1]
-                                                   * world_db["MAP_LENGTH"]
-                                                   + mt[2]])
+                       if ord_blank != t["T_MEMMAP"][mt[1]
+                                                    * world_db["MAP_LENGTH"]
+                                                    + mt[2]]
                        if world_db["ThingTypes"][mt[0]]["TT_CONSUMABLE"]]:
                 set_map_score(mt[1] * world_db["MAP_LENGTH"] + mt[2], 0)
         elif "s" == filter:
-            for i in [i for i in range(world_db["MAP_LENGTH"] ** 2)
-                      if t["T_MEMDEPTHMAP"][i] == mem_depth_c[0]]:
-                set_map_score(i, 0)
+            zero_score_map_where_char_on_memdepthmap(mem_depth_c[0])
 
     def rand_target_dir(neighbors, cmp, dirs):
         candidates = []
@@ -1599,7 +1598,7 @@ directions_db = {"east": "d", "south-east": "c", "south-west": "x",
 """File IO database."""
 io_db = {
     "path_save": "save",
-    "path_record": "history",
+    "path_record": "record_save",
     "path_worldconf": "confserver/world",
     "path_server": "server/",
     "path_in": "server/in",
@@ -1614,8 +1613,11 @@ io_db = {
 try:
     libpr = prep_library()
     rand = RandomnessIO()
-    setup_server_io()
     opts = parse_command_line_arguments()
+    if opts.savefile:
+        io_db["path_save"] = opts.savefile
+        io_db["path_record"] = "record_" + opts.savefile
+    setup_server_io()
     if opts.verbose:
         io_db["verbose"] = True
     if None != opts.replay: