generate_tile_connection_array_cases.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!/usr/bin/env python3
  2. """Script for generating a TileConnectionArray test case Vector."""
  3. from collections import defaultdict
  4. import re
  5. SOURCE_FILE_PATH = "src/tiles/tests/tile_connection_array.rs"
  6. CASES = [
  7. {
  8. "name": "zero tiles",
  9. "tiles": [],
  10. "horizontal connector count": 1,
  11. "vertical connector count": 1,
  12. },
  13. {
  14. "name": "one tile, all connectors match their counterpart",
  15. "tiles": [{"name": 0, "connectors": (1, 1, 1, 1)}],
  16. "horizontal connector count": 2,
  17. "vertical connector count": 2,
  18. },
  19. {
  20. "name": "one tile, no connectors match their counterpart",
  21. "tiles": [{"name": 1, "connectors": (1, 2, 2, 1)}],
  22. "horizontal connector count": 3,
  23. "vertical connector count": 3,
  24. },
  25. {
  26. "name": "one tile, one connector matches its counterpart",
  27. "tiles": [{"name": 2, "connectors": (1, 1, 2, 1)}],
  28. "horizontal connector count": 2,
  29. "vertical connector count": 3,
  30. },
  31. {
  32. "name": "two tiles",
  33. "tiles": [
  34. {"name": 1, "connectors": (1, 2, 2, 1)},
  35. {"name": 3, "connectors": (2, 3, 1, 4)},
  36. ],
  37. "horizontal connector count": 5,
  38. "vertical connector count": 3,
  39. },
  40. {
  41. "name": "three tiles",
  42. "tiles": [
  43. {"name": 1, "connectors": (1, 2, 2, 1)},
  44. {"name": 3, "connectors": (2, 3, 1, 4)},
  45. {"name": 4, "connectors": (3, 3, 2, 4)},
  46. ],
  47. "horizontal connector count": 5,
  48. "vertical connector count": 4,
  49. },
  50. ]
  51. # noinspection PyTypeChecker
  52. def main():
  53. """Take the list of CASES and generate rstest cases for TileConnectionArray."""
  54. output = ""
  55. for case in CASES:
  56. tile_connections = defaultdict(list)
  57. for tile in case["tiles"]:
  58. for north in (0, tile["connectors"][0]):
  59. for east in (0, tile["connectors"][1]):
  60. for south in (0, tile["connectors"][2]):
  61. for west in (0, tile["connectors"][3]):
  62. tile_connections[(north, east, south, west)].append(
  63. tile["name"]
  64. )
  65. # Output
  66. case_name_normalized = case["name"].replace(" ", "_").replace(",", "")
  67. output += (
  68. f"// region {case['name']}\n#[case::{case_name_normalized}(\n vec!["
  69. )
  70. if len(case["tiles"]) > 2:
  71. output += "\n "
  72. output += (",\n " if len(case["tiles"]) > 2 else ", ").join(
  73. f"tests::TILE_CONNECTION_TILES[{tile['name']}].clone()" for tile in case["tiles"]
  74. )
  75. if len(case["tiles"]) > 2:
  76. output += ",\n "
  77. output += f"""],
  78. {case['horizontal connector count']},
  79. {case['vertical connector count']},
  80. vec![\n"""
  81. for north in range(case["vertical connector count"]):
  82. for east in range(case["horizontal connector count"]):
  83. for south in range(case["vertical connector count"]):
  84. for west in range(case["horizontal connector count"]):
  85. tiles = tile_connections[(north, east, south, west)]
  86. output += f"""\
  87. // tile_connection_array[{north}, {east}, {south}, {west}]
  88. TileConnection {{
  89. tiles: vec!"""
  90. tile_indices = []
  91. for tile_id in tiles:
  92. for tile_index, tile in enumerate(case["tiles"]):
  93. if tile["name"] == tile_id:
  94. tile_indices.append(tile_index)
  95. output += f"{tile_indices},\n weights: vec!["
  96. if len(tiles) > 1:
  97. output += "\n "
  98. output += (
  99. ",\n " if len(tiles) > 1 else ", "
  100. ).join(
  101. f"tests::TILE_CONNECTION_TILES[{tile}].weight"
  102. for tile in tiles
  103. )
  104. if len(tiles) > 1:
  105. output += "\n "
  106. output += "],\n },\n"
  107. output += " ]\n)]\n// endregion\n"
  108. with open(SOURCE_FILE_PATH) as source_file:
  109. file_content = source_file.read()
  110. file_content = re.sub(
  111. r"(?s)(// generated tests start\n).*?\n(// generated tests end)",
  112. f"\\1{output}\\2",
  113. file_content,
  114. )
  115. with open(SOURCE_FILE_PATH, "w") as source_file:
  116. source_file.write(file_content)
  117. if __name__ == "__main__":
  118. main()