dungeon.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import cv2
  2. import os
  3. import time
  4. import numpy as np
  5. import random
  6. from helper import (
  7. tap as tap_helper,
  8. look_for_templates,
  9. first_template,
  10. capture_current_screen,
  11. get_current_screen,
  12. )
  13. fire_or_earth = os.getenv("FIRE_OR_EARTH", "earth").lower()
  14. stop_at_first_death = os.getenv("FIRST_DEATH_STOP", "False").lower() == "true"
  15. swap_tank_at_low_health = (
  16. os.getenv("SWAP_TANK_AT_LOW_HEALTH", "False").lower() == "true"
  17. )
  18. # templates
  19. templates = {
  20. "to_battle": cv2.imread("templates/dungeon/to_battle.png"),
  21. "attack": cv2.imread("templates/dungeon/attack.png"),
  22. "auto_battle": cv2.imread("templates/dungeon/auto_battle.png"),
  23. "ok": cv2.imread("templates/dungeon/ok.png"),
  24. "lock": cv2.imread("templates/dungeon/lock.png"),
  25. "collect": cv2.imread("templates/dungeon/collect.png"),
  26. }
  27. tpl_mixed = cv2.imread("templates/dungeon/mixed.png")
  28. tpl_water = cv2.imread("templates/dungeon/water.png")
  29. tpl_earth = cv2.imread("templates/dungeon/earth.png")
  30. tpl_fire = cv2.imread("templates/dungeon/fire.png")
  31. tpl_angus = cv2.imread("templates/dungeon/angus.png")
  32. tpl_moloch = cv2.imread("templates/dungeon/moloch.png")
  33. tpl_angus2 = cv2.imread("templates/dungeon/angus2.png")
  34. tpl_moloch2 = cv2.imread("templates/dungeon/moloch2.png")
  35. tpl_dead = cv2.imread("templates/dungeon/dead.png")
  36. def low_health(element, name):
  37. left = element[0] - 113
  38. right = element[0] + 108
  39. top = element[1] + 138
  40. bottom = top + 11
  41. screen = read_screen()
  42. health_bar = screen[top:bottom, left:right]
  43. # cv2.imwrite("test/health_bar.png", health_bar)
  44. health_bar_hsv = cv2.cvtColor(health_bar, cv2.COLOR_BGR2HSV)
  45. green_lower = np.array([40, 40, 40]) # Lower end of green in HSV
  46. green_upper = np.array([80, 255, 255]) # Upper end of green in HSV
  47. mask = cv2.inRange(health_bar_hsv, green_lower, green_upper)
  48. total_length = mask.shape[1]
  49. current_length = total_length - np.argmax(np.flip(mask[0]) > 0)
  50. health_percentage = (current_length / total_length) * 100
  51. print(f"Remaining Health ({name}): {health_percentage:.2f}%")
  52. return health_percentage < 70
  53. def read_screen():
  54. data = get_current_screen()
  55. image_data = np.frombuffer(data, dtype=np.uint8)
  56. return cv2.imdecode(image_data, cv2.IMREAD_COLOR)
  57. def tap(name, x, y=None):
  58. sleep = 0.5
  59. if name in ["ok", "lock"]:
  60. sleep = 2
  61. elif name in ["collect"]:
  62. sleep = 5
  63. elif name in ["remove angus", "remove moloch"]:
  64. sleep = 1
  65. sleep += random.uniform(0, 0.2)
  66. text = f"- {name} (pause for {sleep:.2f}s)"
  67. if y is None and isinstance(x, tuple):
  68. x, y, *_ = x
  69. tap_helper(x + random.randint(-3, 3), y + random.randint(-3, 3), text)
  70. time.sleep(sleep)
  71. print("watching the screen...")
  72. is_mixed = False
  73. idle_counter = 0
  74. while True:
  75. try:
  76. capture_current_screen()
  77. name, locations = look_for_templates(templates)
  78. if name is not None:
  79. if name in ["to_battle", "ok", "lock", "collect"]:
  80. tap(name, *locations[0])
  81. idle_counter = 0
  82. continue
  83. if name in ["auto_battle"]:
  84. dead = stop_at_first_death and first_template(tpl_dead)
  85. if dead:
  86. print("++++++++ at least one titan is dead. stopping")
  87. break
  88. if swap_tank_at_low_health and is_mixed:
  89. moloch = first_template(tpl_moloch)
  90. if (
  91. moloch
  92. and moloch[1] > 450
  93. and moloch[1] < 1350
  94. and low_health(moloch, "moloch")
  95. ):
  96. angus = first_template(tpl_angus2)
  97. if angus:
  98. tap("remove angus", angus)
  99. tap("add moloch", moloch)
  100. else:
  101. print(
  102. "######### seems like angus is dead already. stopping"
  103. )
  104. break
  105. else:
  106. angus = first_template(tpl_angus)
  107. if (
  108. angus
  109. and moloch[1] > 450
  110. and angus[1] < 1350
  111. and low_health(angus, "angus")
  112. ):
  113. moloch = first_template(tpl_moloch2)
  114. if moloch:
  115. tap("remove moloch", moloch)
  116. tap("add angus", angus)
  117. else:
  118. print(
  119. "######### seems like moloch is dead already. stopping"
  120. )
  121. break
  122. tap(name, *locations[0])
  123. idle_counter = 0
  124. continue
  125. if name == "attack":
  126. if len(locations) == 1:
  127. element = first_template(tpl_mixed)
  128. is_mixed = element is not None
  129. tap(name, *locations[0])
  130. continue
  131. if len(locations) == 2:
  132. element = first_template(tpl_mixed)
  133. if element:
  134. is_mixed = True
  135. else:
  136. is_mixed = False
  137. element = first_template(tpl_water)
  138. if element is None:
  139. if fire_or_earth == "earth":
  140. element = first_template(tpl_earth)
  141. else:
  142. element = first_template(tpl_fire)
  143. tap(name, element[0], locations[0][1])
  144. idle_counter = 0
  145. continue
  146. print("...")
  147. idle_counter += 1
  148. if idle_counter >= 3:
  149. print("######### stopping due to three idle loop iterations.")
  150. break
  151. except Exception as e:
  152. print(f"error: {e}")