瀏覽代碼

EvilTrade: Added busts list

  Now all trade scripts should respectfully not trade at a port that's
know for a bust.

  For our next trick we add in the code so we can find_nearest_evilpair
and find_next_evilpair so we can get onto writing how to do evil
trading.
david 5 年之前
父節點
當前提交
70e035981b
共有 2 個文件被更改,包括 193 次插入8 次删除
  1. 9 0
      flexible.py
  2. 184 8
      galaxy.py

+ 9 - 0
flexible.py

@@ -3966,12 +3966,21 @@ class evilTrade(object):
                 self.send2game("\r\r")
                 # Oops, we are expecting the user to have enough money to buy it!
                 self.state = 3
+            elif re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt):
+                self.send2game("D")
+                self.state = 3
         elif self.state == 3:
             if prompt.startswith("Your offer"):
                 self.send2game("0\r")
                 self.deactivate(True)
             else:
                 # Now to go to evil trade pair \o/
+                self.target_sector = self.game.gamedata.find_nearest_evilpairs(
+                    self.sector, self
+                )
+                self.send2player(
+                    self.nl + Boxes.alert("{0}".format(self.target_sector))
+                )
                 self.send2player(self.nl + Boxes.alert("Done!"))
                 self.deactivate(True)
 

+ 184 - 8
galaxy.py

@@ -33,12 +33,15 @@ class GameData(object):
         self.usergame = usergame
         self.warps = {}
         self.ports = {}
+        self.busts = []  # Added for evilTrade, just contains sector of port
         self.config = {}
         # 10 = 300 bytes
         self.warp_groups = 10
         # 3 = 560 bytes
         # 5 = 930 bytes
         self.port_groups = 3
+        # Not sure, it's going to be small I know that
+        self.bust_groups = 10
 
     def storage_filename(self):
         """ return filename
@@ -54,6 +57,9 @@ class GameData(object):
     def reset_warps(self):
         self.warps = {}
 
+    def reset_busts(self):
+        self.busts = []
+
     def special_ports(self):
         """ Save the special class ports 0, 9 """
         return {
@@ -65,6 +71,7 @@ class GameData(object):
     def display(self):
         pprint(self.warps)
         pprint(self.ports)
+        pprint(self.busts)
 
     def save(self, *_):
         """ save gamedata as jsonlines.
@@ -112,9 +119,24 @@ class GameData(object):
             if len(p["port"]) > 0:
                 writer.write(p)
 
+            # Added for evil
+            b = {"busts": []}
+            for bust in sorted(self.busts):
+                b["busts"].append(bust)
+                if len(b["busts"]) >= self.bust_groups:
+                    writer.write(b)
+                    b = {"busts": []}
+                    yield
+            if len(b["busts"]) > 0:
+                writer.write(b)
+
         log.info(
-            "Saved {0} {1}/{2}/{3}".format(
-                filename, len(self.ports), len(self.warps), len(self.config)
+            "Saved {0} {1}/{2}/{3}/{4}".format(
+                filename,
+                len(self.ports),
+                len(self.warps),
+                len(self.config),
+                len(self.busts),
             )
         )
 
@@ -162,9 +184,23 @@ class GameData(object):
             if len(p["port"]) > 0:
                 writer.write(p)
 
+            # Added for evil
+            b = {"busts": []}
+            for bust in sorted(self.busts):
+                b["busts"].append(bust)
+                if len(b["busts"]) >= self.bust_groups:
+                    writer.write(b)
+                    b = {"busts": []}
+            if len(b["busts"]) > 0:
+                writer.write(b)
+
         log.info(
-            "Saved {0} {1}/{2}/{3}".format(
-                filename, len(self.ports), len(self.warps), len(self.config)
+            "Saved {0} {1}/{2}/{3}/{4}".format(
+                filename,
+                len(self.ports),
+                len(self.warps),
+                len(self.config),
+                len(self.busts),
             )
         )
 
@@ -174,6 +210,7 @@ class GameData(object):
         self.warps = {}
         self.ports = {}
         self.config = {}
+        self.busts = []
         if os.path.exists(filename):
             # Load it
             with jsonlines.open(filename) as reader:
@@ -189,10 +226,17 @@ class GameData(object):
                         for s, p in obj["port"].items():
                             self.ports[int(s)] = p
                         # self.ports.update(obj["port"])
+                    if "busts" in obj:  # evil ports list
+                        for l in obj["busts"]:
+                            self.busts.append(l)
                     yield
         log.info(
-            "Loaded {0} {1}/{2}/{3}".format(
-                filename, len(self.ports), len(self.warps), len(self.config)
+            "Loaded {0} {1}/{2}/{3}/{4}".format(
+                filename,
+                len(self.ports),
+                len(self.warps),
+                len(self.config),
+                len(self.busts),
             )
         )
 
@@ -221,9 +265,16 @@ class GameData(object):
                         for s, p in obj["port"].items():
                             self.ports[int(s)] = p
                         # self.ports.update(obj["port"])
+                    if "busts" in obj:
+                        for l in obj["busts"]:
+                            self.busts.append(l)
         log.info(
-            "Loaded {0} {1}/{2}/{3}".format(
-                filename, len(self.ports), len(self.warps), len(self.config)
+            "Loaded {0} {1}/{2}/{3}/{4}".format(
+                filename,
+                len(self.ports),
+                len(self.warps),
+                len(self.config),
+                len(self.busts),
             )
         )
 
@@ -272,6 +323,13 @@ class GameData(object):
                 self.ports[sector]["class"] = CLASSES_PORT[port]
                 log.debug("completed {0} : {1}".format(sector, self.ports[sector]))
 
+    def set_bust(self, sect: int):
+        # Given sector we add it to busts (avoid using these ports)
+        log.debug("Bust {0}".format(sect))
+        if sect not in self.busts:
+            self.busts.append(sect)
+            log.debug("completed {0} : {1}".format(sect, self.busts))
+
     def port_buying(self, sector: int, cargo: str):
         """ Given a sector, is this port buying this? 
 
@@ -288,6 +346,13 @@ class GameData(object):
         if "port" not in port:
             log.warn("port_buying( {0}, {1}): port unknown!".format(sector, cargo))
             return True
+        if sector in self.busts:  # Abort! This given sector is a busted port!
+            log.warn(
+                "port_buying({0}, {1}): sector contains a busted port!".format(
+                    sector, cargo
+                )
+            )
+            return False
 
         cargo_index = cargo_to_index[cargo]
         if port["port"] in ("Special", "StarDock"):
@@ -355,6 +420,20 @@ class GameData(object):
         if port1 in ("Special", "StarDock") or port2 in ("Special", "StarDock"):
             return False
 
+        if port1 in self.busts:
+            log.warn("port_trading({0}, {1}) port1 is busted".format(port1, port2))
+            return False
+        elif port2 in self.busts:
+            log.warn("port_trading({0}, {1}) port2 is busted".format(port1, port2))
+            return False
+        elif port1 in self.busts and port2 in self.busts:
+            log.warn(
+                "port_trading({0}, {1}) both port1 and port2 are busted".format(
+                    port1, port2
+                )
+            )
+            return False
+
         p1 = [c for c in port1]
         p2 = [c for c in port2]
         rem = False
@@ -461,6 +540,10 @@ class GameData(object):
             log.warn(":Sector {0} not in warps.".format(sector))
             obj.target_sector = None
             return None
+        if sector in self.busts:
+            log.warn(":Sector {0} in busted".format(sector))
+            obj.target_sector = None
+            return None
 
         # Start with the current sector
         look = set((sector,))
@@ -478,6 +561,8 @@ class GameData(object):
                         continue
                     if "class" not in sp:
                         continue
+                    if s in self.busts:  # Check for busted port
+                        continue
                     sc = sp["class"]
 
                     if s not in self.warps:
@@ -502,6 +587,8 @@ class GameData(object):
                             continue
                         if "class" not in cp:
                             continue
+                        if w in self.busts:  # Check for busted
+                            continue
                         cc = cp["class"]
                         log.warn("{0} {1} - {2} {3}".format(s, sc, w, cc))
                         if sc in (1, 5) and cc in (2, 4):
@@ -529,6 +616,88 @@ class GameData(object):
         obj.target_sector = None
         return None
 
+    def find_nearest_evilpairs(self, sector: int, obj):
+        """ find nearest evilpair 
+            XXB -=- XXB
+        
+        When do we use good?  When do we use ok?
+        """
+        searched = set()
+        if sector not in self.warps:
+            log.warn(":Sector {0} not in warps.".format(sector))
+            obj.target_sector = None
+            return None
+        if sector in self.busts:
+            log.warn(":Sector {0} in busted".format(sector))
+            obj.target_sector = None
+            return None
+
+        # Start with the current sector
+        look = set((sector,))
+
+        while len(look) > 0:
+            log.warn("Searched [{0}]".format(searched))
+            log.warn("Checking [{0}]".format(look))
+            for s in look:
+                if s in self.ports:
+                    # Ok, there's a port at least
+                    sp = self.ports[s]
+                    if sp["port"] in ("Special", "StarDock"):
+                        continue
+                    if self.port_burnt(sp):
+                        continue
+                    if "class" not in sp:
+                        continue
+                    if s in self.busts:  # Check for busted port
+                        continue
+                    sc = sp["class"]
+
+                    if s not in self.warps:
+                        continue
+
+                    log.warn("{0} has warps {1}".format(s, self.warps[s]))
+
+                    # Ok, check for tradepairs.
+                    for w in self.warps[s]:
+                        if not w in self.warps:
+                            continue
+                        if not s in self.warps[w]:
+                            continue
+                        if not w in self.ports:
+                            continue
+
+                        # Ok, has possible port
+                        cp = self.ports[w]
+                        if cp["port"] in ("Special", "StarDock"):
+                            continue
+                        if self.port_burnt(cp):
+                            continue
+                        if "class" not in cp:
+                            continue
+                        if w in self.busts:  # Check for busted
+                            continue
+                        cc = cp["class"]
+                        log.warn("{0} {1} - {2} {3}".format(s, sc, w, cc))
+                        if sc in (2, 3, 4, 8) and cc in (2, 3, 4, 8):
+                            # Good!
+                            log.warn("GOOD: {0}".format(s))
+                            obj.target_sector = s
+                            return s
+                        # What about "OK" pairs?
+
+            # Ok, not found here.
+            searched.update(look)
+            step_from = look
+            look = set()
+            for s in step_from:
+                if s in self.warps:
+                    look.update(self.warps[s])
+            # Look only contains warps we haven't searched
+            look = look.difference(searched)
+            yield
+        obj.target_sector = None
+        return None
+
     def find_nearest_selling(
         self, sector: int, selling: str, at_least: int = 100
     ) -> int:
@@ -549,6 +718,11 @@ class GameData(object):
         if sector not in self.warps:
             log.warn("( {0}, {1}): sector not in warps".format(sector, selling))
             return 0
+        if sector in self.busts:
+            log.warn(
+                "({0}, {1}): sector is in busted ports list".format(sector, selling)
+            )
+            return 0
 
         # Start with the current sector
         look = set((sector,))
@@ -560,6 +734,8 @@ class GameData(object):
                     sp = self.ports[s]
                     if sp["port"] in ("Special", "StarDock"):
                         continue
+                    if s in self.busts:  # Busted!
+                        continue
                     if sp["port"][s_pos] == "S":
                         # Ok, they are selling!
                         if sell in sp: