A generator for *Star Wars* interstellar shipping and passenger jobs, based loosely on the missions you can take on in *Escape Velocity* and *Endless Space*.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

swjg.py 8.3KB

il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
il y a 2 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import argparse
  2. import re
  3. from enum import Enum
  4. from string import Template
  5. from typing import NamedTuple
  6. from jinja2 import Environment, PackageLoader, select_autoescape
  7. import items
  8. from destinations import DESTINATIONS, Destination
  9. # global variables
  10. env = Environment(loader=PackageLoader("swjg"), autoescape=select_autoescape)
  11. parser = argparse.ArgumentParser()
  12. # helper definitions
  13. def get_identifiers_from_template(template):
  14. # Template.get_identifiers() doesn't appear until Python 3.11
  15. # Don't substitute anything; get the raw string
  16. template_str = Template.safe_substitute()
  17. matches = re.findall("\$[a-z0-9_\.]+", template_str)
  18. matches = [x[1:] for x in matches]
  19. return matches
  20. def get_destination_type_from_enum(destination):
  21. dtype = destination.type
  22. dtype_name = dtype._name_
  23. dtype_name_lower = dtype_name.lower()
  24. dtype_name_nou = dtype_name_lower.replace("_", " ")
  25. return dtype_name_nou
  26. class DangerLevel(Enum):
  27. NONE = 1
  28. LOW = 2
  29. MODERATE = 3
  30. HIGH = 4
  31. EXTREME = 5
  32. class DangerType(Enum):
  33. HOSTILE = 1
  34. AT_WAR = 2
  35. DESERT = 3
  36. JUNGLE = 4
  37. OCEAN = 5
  38. ATMOSPHERE = 6
  39. # Class definitions
  40. class Mission:
  41. output_destination_template = Template(
  42. "to $world, a $destination_type in the $system system"
  43. )
  44. output_sector_template = Template(", part of the $sector,")
  45. value_template = Template("for $value credits")
  46. error_template = Template(
  47. "You haven't given this mission some of the values it needs. Please check: $potential_values"
  48. )
  49. def __init__(self, destination: Destination, value: int, *args, **kwargs):
  50. # destination: Destination (see above)
  51. self.world = destination.name if destination.name is not None else None
  52. self.system = (
  53. destination.system if destination.system is not None else destination.name
  54. )
  55. self.sector = destination.sector if destination.sector is not None else None
  56. self.destination_type = get_destination_type_from_enum(destination)
  57. self.value = value
  58. def assemble_templates(self) -> list:
  59. # Override this in children
  60. template_list = []
  61. if self.world != None:
  62. template_list.append(self.output_destination_template)
  63. if self.sector != None:
  64. template_list.append(self.output_sector_template)
  65. template_list.append(self.value_template)
  66. return template_list
  67. def get_current_values(self) -> dict:
  68. return {
  69. "world": self.world,
  70. "system": self.system,
  71. "sector": self.sector,
  72. "destination_type": self.destination_type,
  73. "value": self.value,
  74. }
  75. def missing_values(self) -> list:
  76. object_vars = vars(self)
  77. missing = []
  78. for key, val in object_vars.items():
  79. if val is None and key != "time": # time is optional
  80. missing.append(key)
  81. return missing
  82. def assemble_text(self) -> str:
  83. missing_vals = self.missing_values()
  84. templates = self.assemble_templates()
  85. if (
  86. len(templates) == 0 or len(missing_vals) != 0
  87. ): # either both of these should be true or neither should
  88. raise ValueError(
  89. self.error_template.substitute(potential_values=missing_vals)
  90. )
  91. current_values = self.get_current_values()
  92. output = []
  93. for template in templates:
  94. output.append(template.substitute(**current_values))
  95. out_text = " ".join(output)
  96. out_text = out_text.replace(" ,", ",")
  97. out_text += "."
  98. return out_text
  99. class PassengerMission(Mission):
  100. output_initial_template = Template("Bring $number passengers")
  101. def __init__(self, number: int, *args, **kwargs):
  102. super(PassengerMission, self).__init__(*args, **kwargs)
  103. self.number = number
  104. def get_current_values(self) -> dict:
  105. base_dict = super(PassengerMission, self).get_current_values()
  106. new_dict = {"number": self.number}
  107. base_dict.update(new_dict)
  108. return base_dict
  109. def assemble_templates(self):
  110. template_list = [self.output_initial_template]
  111. template_list.extend(super(PassengerMission, self).assemble_templates())
  112. return template_list
  113. def assemble_text(self) -> str:
  114. return super(PassengerMission, self).assemble_text()
  115. class CargoMission(Mission):
  116. output_initial_template = Template("Deliver $tons tons of $item")
  117. output_time_timeplate = Template("in the next $time days")
  118. def __init__(self, tons: int, item: str, time: int | None, *args, **kwargs):
  119. # tons: integer
  120. # item: string (this will not be pluralized in the text)
  121. # time: integer (number of days the crew have to complete delivery)
  122. # value: integer (value in credits)
  123. super(CargoMission, self).__init__(*args, **kwargs)
  124. self.tons = tons
  125. self.item = item
  126. self.time = time
  127. def get_current_values(self) -> dict:
  128. base_dict = super(CargoMission, self).get_current_values()
  129. new_dict = {"tons": self.tons, "item": self.item, "time": self.time}
  130. base_dict.update(new_dict)
  131. return base_dict
  132. def assemble_templates(self):
  133. template_list = [self.output_initial_template]
  134. if self.time is not None:
  135. template_list.append(self.output_time_timeplate)
  136. template_list.extend(super(CargoMission, self).assemble_templates())
  137. return template_list
  138. def assemble_text(self) -> str:
  139. return super(CargoMission, self).assemble_text()
  140. class GroupMission(Mission):
  141. output_initial_template = Template("Bring $number members of a $group")
  142. def __init__(self, number: int, group: str, *args, **kwargs):
  143. super(GroupMission, self).__init__(*args, **kwargs)
  144. self.number = number
  145. self.group = group
  146. def get_current_values(self) -> dict:
  147. base_dict = super(GroupMission, self).get_current_values()
  148. new_dict = {"number": self.number, "group": self.group}
  149. base_dict.update(new_dict)
  150. return base_dict
  151. def assemble_templates(self):
  152. template_list = [self.output_initial_template]
  153. template_list.extend(super(GroupMission, self).assemble_templates())
  154. return template_list
  155. def assemble_text(self) -> str:
  156. return super(GroupMission, self).assemble_text()
  157. # the function that does the thing
  158. def main():
  159. import random
  160. mission_types = [PassengerMission, CargoMission, GroupMission]
  161. missions = []
  162. for _ in range(5):
  163. current_mission = random.choice(mission_types)
  164. destination = random.choice(DESTINATIONS)
  165. item, time, tons, number, value, group = [None] * 6
  166. if current_mission == CargoMission:
  167. current_item = random.choice(items.ITEMS)
  168. tons = random.randint(
  169. current_item.potential_tons[0], current_item.potential_tons[1]
  170. )
  171. value = random.randint(*current_item.potential_values) * 1000
  172. item = current_item.name
  173. if current_item.potential_times is not None:
  174. if current_item.chance_for_time is not None:
  175. is_there_a_time = random.random() * 100
  176. # print(current_item.chance_for_time, is_there_a_time, is_there_a_time < current_item.chance_for_time)
  177. if is_there_a_time < current_item.chance_for_time:
  178. time = random.randint(
  179. current_item.potential_times[0],
  180. current_item.potential_times[1],
  181. )
  182. else:
  183. number = random.randint(1, 8)
  184. time = random.randint(7, 31)
  185. value = random.randint(20, 120) * 1000
  186. if current_mission == GroupMission:
  187. group = random.choice(["family", "performing troupe", "acrobatic troupe"])
  188. missions.append(
  189. current_mission(
  190. destination=destination,
  191. number=number,
  192. tons=tons,
  193. item=item,
  194. time=time,
  195. value=value,
  196. group=group,
  197. )
  198. )
  199. for mission in missions:
  200. # print(mission, mission.__dict__)
  201. print(mission.assemble_text())
  202. # Don't do anything if the module is loaded wholesale into something else
  203. if __name__ == "__main__":
  204. main()