Compare commits

...

194 Commits

Author SHA1 Message Date
7eed550797 Merge remote-tracking branch 'origin/master' 2023-08-24 09:43:27 +02:00
cc9789c65c ring fix 2023-08-24 09:43:13 +02:00
d64b704274 update menti 2023-08-06 16:36:52 +02:00
ed23f196a6 update menti 2023-08-06 16:32:45 +02:00
b8abdb690b update menti 2023-08-06 16:30:20 +02:00
8d2aad34b2 update menti 2023-08-06 16:25:52 +02:00
e70c7d2be9 update menti 2023-08-06 16:23:55 +02:00
5005670bd3 update menti 2023-08-06 16:21:48 +02:00
b1fc655c0b update menti 2023-08-06 16:12:13 +02:00
9cc4018747 update flappy 2023-07-30 18:46:40 +02:00
849aaf8e27 update flappy 2023-07-30 18:42:53 +02:00
804f178fbf update flappy 2023-07-30 15:08:29 +02:00
c1eecfd567 update flappy 2023-07-30 15:05:47 +02:00
99a2976b61 update flappy 2023-07-30 15:01:20 +02:00
cadcfe8103 update litris with board detection 2023-07-30 14:28:15 +02:00
ab0def9115 update litris with board detection 2023-07-30 10:57:43 +02:00
b24a835f18 update litris with board detection 2023-07-30 10:08:33 +02:00
0a15b57fe5 Merge remote-tracking branch 'origin/master' 2023-07-30 10:00:17 +02:00
a7d2a73b00 update litris with board detection 2023-07-30 10:00:07 +02:00
Thaloria@web.de
3d209ca811 litris update 2023-07-30 00:49:42 +02:00
Thaloria@web.de
01768dc115 litris update 2023-07-30 00:29:36 +02:00
f32cbb8f2d update litris with board detection 2023-07-30 00:08:39 +02:00
7a539e301b update litris with board detection 2023-07-29 21:43:48 +02:00
00461177de update litris with board detection 2023-07-29 21:36:31 +02:00
7c6af4411b update litris with board detection 2023-07-29 21:32:53 +02:00
c3e677ca0a update litris with board detection 2023-07-29 21:30:00 +02:00
332190394d update litris with board detection 2023-07-29 21:20:50 +02:00
d3ace50341 update litris with board detection 2023-07-29 21:14:13 +02:00
8918683e5a update litris with board detection 2023-07-29 21:07:22 +02:00
b08356b036 update litris with board detection 2023-07-29 21:01:51 +02:00
ffca884a25 update litris with board detection 2023-07-29 20:54:00 +02:00
d3d2e1e65e update litris with board detection 2023-07-29 20:46:25 +02:00
6ec1b71d28 update litris with board detection 2023-07-29 20:20:18 +02:00
07d00404d8 update litris with board detection 2023-07-29 20:20:11 +02:00
c9081bd371 update litris with board detection 2023-07-29 20:12:51 +02:00
a9b76cde97 flappy init 2023-07-29 19:42:17 +02:00
2fa0255761 flappy init 2023-07-29 19:34:12 +02:00
c7dd04590a flappy init 2023-07-28 15:31:16 +02:00
189b81b3a0 flappy init 2023-07-28 15:28:25 +02:00
545127dcbc flappy init 2023-07-28 13:26:54 +02:00
bfd8690535 flappy init 2023-07-28 13:13:20 +02:00
c43399ac2a flappy init 2023-07-27 21:16:19 +02:00
33c7400fa4 flappy init 2023-07-27 20:55:54 +02:00
862fbf8bc6 flappy init 2023-07-27 17:58:57 +02:00
8ded30d75a menti words init 2023-07-27 13:02:42 +02:00
eff65b3ca4 menti words init 2023-07-26 22:28:30 +02:00
ef7669f015 menti words init 2023-07-26 22:00:57 +02:00
2d23f8e311 menti words init 2023-07-26 17:11:30 +02:00
38ac30cc64 menti words init 2023-07-26 17:04:53 +02:00
fc965a5133 menti words init 2023-07-26 17:02:57 +02:00
e11b2b8e94 menti words init 2023-07-26 16:58:43 +02:00
a82c069048 menti words init 2023-07-26 16:55:41 +02:00
5c24629b85 menti words init 2023-07-26 16:52:43 +02:00
f1bb158b21 menti words init 2023-07-26 16:49:09 +02:00
95f87d1c2e menti words init 2023-07-26 16:46:15 +02:00
cde729f820 menti words init 2023-07-26 16:43:36 +02:00
9841d6fae4 menti words init 2023-07-26 16:41:08 +02:00
f4d7523c3d menti words init 2023-07-26 16:37:04 +02:00
fec2651930 menti words init 2023-07-26 16:30:14 +02:00
555d66c680 menti words init 2023-07-26 16:29:45 +02:00
2c4e51b44f menti words init 2023-07-26 16:29:15 +02:00
0fcf3d88a2 menti words init 2023-07-26 16:27:23 +02:00
12f86cc7fd menti words init 2023-07-26 16:19:41 +02:00
bdb448932d menti words init 2023-07-26 16:16:13 +02:00
1893d513f2 menti words init 2023-07-26 16:10:47 +02:00
5713422f49 threading update 2023-07-26 11:33:46 +02:00
1b9711a851 added async stone detection thread 2023-07-26 09:54:49 +02:00
7b63568fa5 added async stone detection thread 2023-07-26 09:46:33 +02:00
3c02d413a2 added async stone detection thread 2023-07-26 09:31:48 +02:00
84830e94a8 added async stone detection thread 2023-07-26 09:05:27 +02:00
d2c89cdc93 added async stone detection thread 2023-07-26 08:49:50 +02:00
3d2ce694e1 added async stone detection thread 2023-07-26 08:43:30 +02:00
e0a9cbc394 added async stone detection thread 2023-07-26 08:37:04 +02:00
fd6f17c3f8 added async stone detection thread 2023-07-26 08:25:39 +02:00
Thaloria@web.de
54cb23a923 litris update 2023-07-25 12:11:56 +02:00
Thaloria@web.de
de56e687f8 litris update 2023-07-25 11:54:05 +02:00
3fa581a935 added async stone detection thread 2023-07-25 10:02:32 +02:00
e7932f5762 added async stone detection thread 2023-07-25 09:59:20 +02:00
b570813c5a added async stone detection thread 2023-07-25 09:47:52 +02:00
8049e58e71 added async stone detection thread 2023-07-25 09:41:04 +02:00
5e201ea341 added async stone detection thread 2023-07-25 09:37:41 +02:00
37cf7f2f2f added async stone detection thread 2023-07-25 09:04:26 +02:00
e5cd8d6399 added async stone detection thread 2023-07-25 08:54:13 +02:00
Thaloria@web.de
3c723fb602 litris update 2023-07-25 08:43:04 +02:00
d3fa6fe807 added async stone detection thread 2023-07-24 13:54:42 +02:00
a2575370f9 added async stone detection thread 2023-07-24 13:51:16 +02:00
22edbe9a2f added async stone detection thread 2023-07-24 13:42:41 +02:00
e832ffe9ec added async stone detection thread 2023-07-24 13:34:49 +02:00
773aa5c765 added async stone detection thread 2023-07-24 13:33:41 +02:00
687218e29d added async stone detection thread 2023-07-24 13:22:44 +02:00
f35fe32264 litris fixes 2023-07-24 11:15:11 +02:00
a21f43fcfc added async stone detection thread 2023-07-24 10:14:41 +02:00
50ab6e17ef added async stone detection thread 2023-07-24 09:59:13 +02:00
761fa778c7 added async stone detection thread 2023-07-24 09:18:30 +02:00
62ff7cb40d added first draft litris 2023-07-23 18:38:50 +02:00
e614ba8dd0 added first draft litris 2023-07-23 18:13:21 +02:00
6d6081ec57 added first draft litris 2023-07-23 17:45:37 +02:00
c4f71f469b added first draft litris 2023-07-23 17:45:22 +02:00
17ff660069 added first draft litris 2023-07-23 17:25:03 +02:00
27f7638557 added first draft litris 2023-07-23 14:28:12 +02:00
Thaloria@web.de
6012a51538 litris update 2023-07-23 14:24:09 +02:00
ba2fd6c945 added first draft litris 2023-07-23 14:03:44 +02:00
f4b949c070 added first draft litris 2023-07-23 12:01:24 +02:00
0e265b0bb6 added first draft litris 2023-07-23 11:52:55 +02:00
b9d0e829bc added first draft litris 2023-07-23 11:32:23 +02:00
76d22227bf added first draft litris 2023-07-23 11:24:54 +02:00
ae752bdb7c added first draft litris 2023-07-22 21:22:44 +02:00
aa2662003d added first draft litris 2023-07-22 20:59:06 +02:00
47a7a50335 added first draft litris 2023-07-22 20:54:29 +02:00
2d35e032b5 added first draft litris 2023-07-22 20:52:36 +02:00
21237c3729 added first draft litris 2023-07-22 20:47:42 +02:00
1d4980eb95 added first draft litris 2023-07-22 20:45:30 +02:00
d78319a9f4 added first draft litris 2023-07-22 20:39:20 +02:00
fba0c2c506 litris fixes 2023-07-22 10:54:32 +02:00
704b1f462d added first draft litris 2023-07-22 09:49:15 +02:00
3176bf5269 added first draft litris 2023-07-22 09:44:48 +02:00
c2b5416542 added first draft litris 2023-07-21 15:28:22 +02:00
2906cb10e4 added first draft litris 2023-07-21 15:18:57 +02:00
93832d8bfc added first draft litris 2023-07-21 15:09:02 +02:00
ff173fea80 added first draft litris 2023-07-21 14:36:21 +02:00
d0f4937507 added first draft litris 2023-07-21 14:31:07 +02:00
403db80292 added first draft litris 2023-07-20 20:09:23 +02:00
b76ccf448e added first draft litris 2023-07-20 19:31:27 +02:00
b08b5fcb89 added first draft litris 2023-07-20 19:19:36 +02:00
0b97e346d8 added first draft litris 2023-07-20 19:17:38 +02:00
378259ab1c added first draft litris 2023-07-20 18:55:47 +02:00
597f7f426e added first draft litris 2023-07-20 18:51:12 +02:00
5eaa9ff5d4 added first draft litris 2023-07-19 21:30:52 +02:00
4d9ccbfd90 added first draft new pickaxe try 2023-07-17 20:44:03 +02:00
95abea3920 added first draft new pickaxe try 2023-07-17 20:33:14 +02:00
0df3f2d8a9 added first draft new pickaxe try 2023-07-17 20:31:24 +02:00
40fb6b7918 added first draft new pickaxe try 2023-07-17 14:18:45 +02:00
5cd1d63fc8 added first draft new pickaxe try 2023-07-17 14:14:46 +02:00
2d46fd65b9 added smaler mining area 2023-05-06 19:26:02 +02:00
Thaloria@web.de
a9e25527f5 update farm for 4.0 2023-05-05 19:17:40 +02:00
c7deaaf6c7 added sodoku to ui 2023-05-05 19:09:44 +02:00
f49087776e Merge remote-tracking branch 'origin/master' 2023-04-30 21:04:57 +02:00
b64dad8e5b added sodoku to ui 2023-04-30 21:04:40 +02:00
Thaloria@web.de
56cf726d4f timing changes 2023-04-30 20:31:41 +02:00
7af6f0c7ed fix equipment.py 2023-04-28 18:20:54 +02:00
71871d83f0 Merge branch 'master' of http://git.face-down.de/Thaloria/Litcraft_Python_B 2023-04-28 18:08:01 +02:00
bebcac9cf3 fix equipment.py 2023-04-28 17:59:55 +02:00
059712770a fix equipment.py 2023-04-28 17:58:51 +02:00
Thaloria@web.de
2264e0fb19 added fruit game support 2023-04-28 16:09:40 +02:00
86d2542edc added sodoku game first draft 2023-04-28 15:46:36 +02:00
088a4d9030 added sodoku game first draft 2023-04-28 15:42:03 +02:00
81d0c09003 added sodoku game first draft 2023-04-28 15:32:17 +02:00
07d3f5388e added sodoku game first draft 2023-04-28 15:25:03 +02:00
Thaloria@web.de
3772fbb843 Merge remote-tracking branch 'origin/master' 2023-04-28 15:12:10 +02:00
Thaloria@web.de
187cb80cf2 added fruit game support 2023-04-28 15:12:00 +02:00
33059b0a95 added sodoku game first draft 2023-04-28 15:11:21 +02:00
c4c6c34709 4.0 fixes to fruit game 2023-04-28 07:20:39 +02:00
4c6a3d04c7 added ok button check to magic 2023-04-28 06:47:12 +02:00
aa92f20758 added ok button check to magic 2022-11-17 12:28:18 +01:00
Thaloria@web.de
79db89b90b added fruit game support 2022-10-31 17:06:38 +01:00
ec7bdf6eb1 added fruit game support 2022-10-31 16:39:07 +01:00
90b7177273 added fruit game support 2022-10-31 16:29:41 +01:00
52e3fd001a added fruit game support 2022-10-31 16:24:21 +01:00
9931b9804e added fruit game support 2022-10-31 16:19:56 +01:00
25f9cb80e0 added fruit game support 2022-10-31 16:06:23 +01:00
60889a08c6 added fruit game support 2022-10-31 16:04:42 +01:00
16b34bf7b3 added fruit game support 2022-10-31 16:00:44 +01:00
2b425186d1 added fruit game support 2022-10-31 15:59:34 +01:00
8f7cc6a38e staff 1 fix revert 2022-10-24 19:41:52 +02:00
c10e4f94f2 staff 1 fix revert 2022-10-24 19:35:40 +02:00
70623a3e6f staff 1 fix 2022-10-24 19:18:59 +02:00
f1bde80746 refactoring
bug fix equip multi
2022-10-22 12:05:45 +02:00
4bfa9aa408 fixed instance bug with member variables 2022-10-19 17:05:11 +02:00
61fc1a2837 new ui elements for timing 2022-10-19 16:58:16 +02:00
ef3e9632f6 new ui elements for timing 2022-10-19 15:33:53 +02:00
81b7fe2871 new ui elements for timing 2022-10-19 08:58:58 +02:00
46aeba1b1b new ui elements for timing 2022-10-19 08:53:20 +02:00
8b8cc4f8e7 new ui elements for timing 2022-10-19 08:51:45 +02:00
22592e3a49 new ui elements for timing 2022-10-19 08:44:50 +02:00
84c1df4e9a new ui elements for timing 2022-10-19 00:36:37 +02:00
90ff452e10 new ui elements for timing 2022-10-19 00:25:59 +02:00
1992c549c1 new ui elements for timing 2022-10-18 23:27:41 +02:00
7a1cf3f009 new ui elements for timing 2022-10-18 23:19:33 +02:00
Thaloria@web.de
3a8c8568ac bug fix 5s 2022-10-18 23:07:43 +02:00
c5921b6657 added strategy parameter
new ui elements for timing
2022-10-18 22:19:14 +02:00
1d4d415a19 added strategy parameter
new ui elements for timing
2022-10-18 22:16:39 +02:00
a4617ed062 refactoring to game base class 2022-10-18 20:42:50 +02:00
90c6920296 refactoring to game base class 2022-10-17 22:17:16 +02:00
7723ca57c2 refactoring to game base class 2022-10-17 17:40:27 +02:00
c8e7c4d60c refactoring to game base class 2022-10-17 17:25:20 +02:00
d9b8434484 refactoring to game base class 2022-10-17 17:12:27 +02:00
14a5983d17 refactoring to game base class 2022-10-17 17:11:56 +02:00
433170b4c8 fixes 2022-10-17 12:02:47 +02:00
6941b2667a fixed instance bug with member variables 2022-10-17 11:57:15 +02:00
5aa2b59b37 Merge remote-tracking branch 'origin/master' 2022-10-17 08:19:24 +02:00
3601e30fe4 Merge remote-tracking branch 'origin/master' 2022-10-16 19:27:25 +02:00
e662739f57 Merge remote-tracking branch 'origin/master' 2022-10-16 18:07:15 +02:00
4a264c3439 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	craft_table/main_craft.py
2022-10-14 20:37:01 +02:00
aeb236abae fixed numerous bugs 2022-10-14 20:28:06 +02:00
179 changed files with 3356 additions and 942 deletions

3
.idea/misc.xml generated
View File

@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectPlainTextFileTypeManager">
<file url="file://$PROJECT_DIR$/sharpening.py" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (lc-py-b)" project-jdk-type="Python SDK" />
</project>

View File

@@ -7,6 +7,12 @@ from farm import Farm
from magic import Magic
from craft import Craft
from mine import Mine
from sodoku import Sodoku
from fruit import Fruit
from pickaxe import Pickaxe_Field
from litris import Litris
from menti_words import MentiWords
from flappy import Flappy
def run():
@@ -30,7 +36,6 @@ def run():
overlay.run_mode = 'init'
continue
elif overlay.run_mode == 'quit':
overlay.destroy()
return
else:
break
@@ -53,6 +58,26 @@ def run():
elif overlay.rb_int.get() == 6:
mine = Mine(overlay)
mine.execute_main_loop()
elif overlay.rb_int.get() == 7:
fruit = Fruit(overlay)
fruit.execute_main_loop()
elif overlay.rb_int.get() == 8:
sodo = Sodoku(overlay)
sodo.execute_main_loop()
elif overlay.rb_int.get() == 9:
paxe = Pickaxe_Field(overlay)
paxe.execute_main_loop()
elif overlay.rb_int.get() == 10:
ltris = Litris(overlay)
ltris.execute_main_loop()
ltris.stone_id_thread.run_mode = 'stop'
elif overlay.rb_int.get() == 11:
menti = MentiWords(overlay)
menti.execute_main_loop()
elif overlay.rb_int.get() == 12:
flappy = Flappy(overlay)
flappy.execute_main_loop()
flappy.flappy_pos_disc.run_mode = 'stop'
if __name__ == "__main__":
run()

View File

@@ -1,6 +1,7 @@
# Run tkinter code in another thread
import threading
import tkinter as tk
import game_base_class
from tkinter import ttk
from mine_overlay import DiggingOverlay
@@ -17,6 +18,7 @@ class PrimaryOverlay(threading.Thread):
self.ButtonFrame = tk.Frame
self.parameter_frame = tk.Frame
self.parameter_label_frame = tk.Frame
self.timing_frame = tk.Frame
self.rb_int = tk.IntVar
self.energy_use = tk.StringVar
@@ -31,35 +33,53 @@ class PrimaryOverlay(threading.Thread):
self.Emitter_Box = ttk.Combobox
self.RadioButtons = dict
self.RadioButtonNames = ["Equip", "Crops", "Farm", "Magic", "Craft", "Mine"]
self.RadioButtonNames = ["Equip", "Crops", "Farm", "Magic", "Craft", "Mine", "Fruit", "Sodo", "PAxe", "Ltris", "Menti", "Flapp"]
self.RadioButton1 = tk.Radiobutton
self.RadioButton2 = tk.Radiobutton
self.RadioButton3 = tk.Radiobutton
self.RadioButton4 = tk.Radiobutton
self.RadioButton5 = tk.Radiobutton
self.RadioButton6 = tk.Radiobutton
self.RadioButton7 = tk.Radiobutton
self.RadioButton8 = tk.Radiobutton
self.RadioButton9 = tk.Radiobutton
self.RadioButton10 = tk.Radiobutton
self.RadioButton11 = tk.Radiobutton
self.RadioButton12 = tk.Radiobutton
self.StartButton = tk.Button
self.StopButton = tk.Button
self.PauseButton = tk.Button
self.QuitButton = tk.Button
self.TkPosition = '133x239+60+600'
self.TkPosition = '133x454+60+600'
self.setDaemon(True)
self.StatusLabel = tk.Label
self.global_timeout_label = tk.Label
self.hourly_breaks_label = tk.Label
self.break_duration_label = tk.Label
self.global_timeout_entry = tk.Entry
self.hourly_breaks_entry = tk.Entry
self.break_duration_entry = tk.Entry
self.global_timeout_use = tk.StringVar
self.hourly_breaks_use = tk.StringVar
self.break_duration_use = tk.StringVar
# self.TkPosition = config.returnEnemyPlayerOverlayPos()
#
self.start()
def run(self):
self.MiningOverlay = DiggingOverlay()
self.MiningOverlay = DiggingOverlay(game_base_class.MINING_LARGE)
self.root = tk.Tk()
self.rb_frame = tk.Frame(self.root)
self.rb_int = tk.IntVar(self.root, value=1)
self.RadioButtons = dict()
# var = tk.IntVar(value=1)
for i in range(1, 7):
for i in range(1, 13):
self.RadioButtons[i] = tk.Radiobutton(self.rb_frame, text=self.RadioButtonNames[i - 1],
variable=self.rb_int,
value=i, command=self.radio_button_callback)
@@ -109,10 +129,41 @@ class PrimaryOverlay(threading.Thread):
self.StatusLabel = tk.Label(self.root, text="Nothing to see here", font=("Helvetica", 10, "bold"),
background="grey", anchor=tk.CENTER)
self.timing_frame = tk.Frame(self.root)
self.global_timeout_use = tk.StringVar(self.root, value='0')
self.hourly_breaks_use = tk.StringVar(self.root, value='0')
self.break_duration_use = tk.StringVar(self.root, value='1-3')
self.global_timeout_label = tk.Label(self.timing_frame, text="Stop after (h):", font=("Helvetica", 10, "bold"),
background="grey", width='12')
self.hourly_breaks_label = tk.Label(self.timing_frame, text="Breaks:", font=("Helvetica", 10, "bold"),
background="grey", width='12')
self.break_duration_label = tk.Label(self.timing_frame, text="Break time (m):", font=("Helvetica", 10, "bold"),
background="grey", width='12')
self.global_timeout_entry = tk.Entry(self.timing_frame, textvariable=self.global_timeout_use, font=("Helvetica", 10, "bold"),
width='3')
self.hourly_breaks_entry = tk.Entry(self.timing_frame, textvariable=self.hourly_breaks_use, font=("Helvetica", 10, "bold"),
width='3')
self.break_duration_entry = tk.Entry(self.timing_frame, textvariable=self.break_duration_use, font=("Helvetica", 10, "bold"),
width='3', state=tk.DISABLED)
self.global_timeout_label.grid(row=0, column=0, sticky='w', columnspan=2 )
self.global_timeout_entry.grid(row=0, column=3)
self.hourly_breaks_label.grid(row=1, column=0, sticky='w', columnspan=2)
self.hourly_breaks_entry.grid(row=1, column=3)
self.break_duration_label.grid(row=2, column=0, sticky='w', columnspan=2)
self.break_duration_entry.grid(row=2, column=3)
self.rb_frame.grid(row=0, column=0, sticky='w')
self.ButtonFrame.grid(row=0, column=1, sticky='w')
self.parameter_frame.grid(row=1, column=0, columnspan=2, sticky='w')
self.StatusLabel.grid(row=2, column=0, columnspan=2)
self.timing_frame.grid(row=2, column=0, columnspan=2, sticky='w')
self.StatusLabel.grid(row=3, column=0, columnspan=2)
# self.ClearButton.pack(side="top")
self.root.geometry(self.TkPosition)
@@ -129,6 +180,7 @@ class PrimaryOverlay(threading.Thread):
def destroy(self):
self.hide_mining_overlay()
del self.MiningOverlay
self.root.destroy()
def start_button_callback(self):
@@ -136,7 +188,7 @@ class PrimaryOverlay(threading.Thread):
self.StopButton.configure(state=tk.NORMAL)
self.PauseButton.configure(state=tk.NORMAL)
self.QuitButton.configure(state=tk.DISABLED)
for i in range(1, 7):
for i in range(1, 9):
tt = self.rb_int.get()
if self.rb_int.get() != i:
(self.RadioButtons[i]).configure(state=tk.DISABLED)
@@ -148,7 +200,7 @@ class PrimaryOverlay(threading.Thread):
self.StopButton.configure(state=tk.DISABLED)
self.PauseButton.configure(state=tk.DISABLED)
self.QuitButton.configure(state=tk.NORMAL)
for i in range(1, 7):
for i in range(1, 9):
self.RadioButtons[i].configure(state=tk.NORMAL)
self.run_mode = 'stopped'
@@ -175,7 +227,19 @@ class PrimaryOverlay(threading.Thread):
self.EnergyLabel.configure(text="Runs:")
self.emitter_use.set('multi')
self.hide_mining_overlay()
elif self.rb_int.get() == 2 or self.rb_int.get() == 3:
elif self.rb_int.get() == 2:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
self.spawn_use.set('')
self.Emitter_Box.configure(state=tk.NORMAL)
self.Emitter_Box.configure(values=('rainbow', 'bigbomb', 'rocket', 'bomb'))
self.emitter_use.set('rainbow')
self.EmitterLabel.configure(text="Strat:")
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="")
self.hide_mining_overlay()
elif self.rb_int.get() == 3:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
@@ -220,8 +284,72 @@ class PrimaryOverlay(threading.Thread):
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="Runs:")
self.show_mining_overlay()
#
elif self.rb_int.get() == 7:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
self.spawn_use.set('')
self.Emitter_Box.configure(state=tk.DISABLED)
self.emitter_use.set('')
self.EmitterLabel.configure(text="")
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="")
self.hide_mining_overlay()
elif self.rb_int.get() == 8:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
self.spawn_use.set('')
self.Emitter_Box.configure(state=tk.DISABLED)
self.emitter_use.set('')
self.EmitterLabel.configure(text="")
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="")
self.hide_mining_overlay()
elif self.rb_int.get() == 9:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
self.spawn_use.set('')
self.Emitter_Box.configure(state=tk.DISABLED)
self.emitter_use.set('')
self.EmitterLabel.configure(text="")
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="")
self.hide_mining_overlay()
elif self.rb_int.get() == 10:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
self.spawn_use.set('')
self.Emitter_Box.configure(state=tk.DISABLED)
self.emitter_use.set('')
self.EmitterLabel.configure(text="")
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="")
self.hide_mining_overlay()
elif self.rb_int.get() == 11:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
self.spawn_use.set('')
self.Emitter_Box.configure(state=tk.DISABLED)
self.emitter_use.set('')
self.EmitterLabel.configure(text="")
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="")
self.hide_mining_overlay()
elif self.rb_int.get() == 12:
self.EnergyEntry.configure(state=tk.DISABLED)
self.energy_use.set('')
self.SpawnEntry.configure(state=tk.DISABLED)
self.spawn_use.set('')
self.Emitter_Box.configure(state=tk.DISABLED)
self.emitter_use.set('')
self.EmitterLabel.configure(text="")
self.SpawnLabel.configure(text="")
self.EnergyLabel.configure(text="")
self.hide_mining_overlay()
def get_run_mode(self):
return self.run_mode
@@ -233,3 +361,15 @@ class PrimaryOverlay(threading.Thread):
def show_mining_overlay(self):
self.MiningOverlay.show_window()
def get_strategy_value_as_int(self):
if self.emitter_use.get() == "rainbow":
return 11
elif self.emitter_use.get() == "bigbomb":
return 9
elif self.emitter_use.get() == "rocket":
return 7
elif self.emitter_use.get() == "bomb":
return 5
else:
return 11

View File

@@ -59,9 +59,12 @@ class UserConfigs:
else:
pass
def returnDiggingWindowPos2(self):
def returnDiggingWindowPos2(self, large=True):
if self.user == self.THALOUSER:
return [1440, 1150, 570, 22]
if large:
return [1440, 1150, 570, 22]
else:
return [1440, 210, 560, 700]
elif self.user == self.ADWAUSER:
return [740, 450, 1625, 985]
elif self.user == self.EDDIEUSER:

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
control_elements/play.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

500
craft.py
View File

@@ -4,6 +4,7 @@ import pydirectinput
from config_file import UserConfigs
from window_capture import WindowCapture
from vision import Vision
from game_base_class import GameBase
MODE25X1 = "m25x1"
MODE10X2 = "m10x2"
@@ -14,11 +15,10 @@ MODE1X5_X = "m1x5_X"
MODE_HOUSE = "house"
class Craft:
class Craft(GameBase):
def __init__(self, overlay):
self.overlay = overlay
self.config = UserConfigs()
super().__init__(overlay)
self.mode = str(overlay.emitter_use.get())
self.run_target = int(overlay.energy_use.get())
@@ -26,277 +26,293 @@ class Craft:
self.run_counter = 0
self.dimension = 172
def execute_main_loop(self):
def assess_playfield_and_make_move(self):
if self.run_counter >= self.run_target:
self.run_counter = 0
self.overlay.run_mode = 'finished'
return
while True:
if self.overlay.run_mode == 'paused':
cv.waitKey(1)
continue
elif self.overlay.run_mode == 'stopped':
break
ab1 = [420, 1180, 142, 142]
ab2 = [562, 1180, 142, 142]
ab3 = [704, 1180, 142, 142]
ab4 = [846, 1180, 142, 142]
ab5 = [986, 1180, 142, 142]
ab6 = [1128, 1180, 142, 142]
ab10 = [1698, 1180, 142, 142]
if self.run_counter >= self.run_target:
self.run_counter = 0
self.overlay.run_mode = 'finished'
break
if self.mode == MODE25X1:
self.click_square_center(ab1)
ab1 = [420, 1180, 142, 142]
ab2 = [562, 1180, 142, 142]
ab3 = [704, 1180, 142, 142]
ab4 = [846, 1180, 142, 142]
ab5 = [986, 1180, 142, 142]
ab6 = [1128, 1180, 142, 142]
ab10 = [1698, 1180, 142, 142]
# grid 770 1630 160 1020 172 o
self.dimension = 172
for i in range(0, 5, 1):
for e in range(0, 5, 1):
self.click_square_center(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.mode == MODE25X1:
self.click_square_center(ab1)
self.click_craft_button()
# grid 770 1630 160 1020 172 o
self.dimension = 172
for i in range(0, 5, 1):
for i in range(0, 5, 1):
for e in range(0, 5, 1):
self.collect_grid_reverse_click(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_square_center(ab10)
elif self.mode == MODE10X2:
for r in range(0, 2, 1):
# grid 770 1630 160 1020 172
if r == 0:
self.click_square_center(ab1)
start = 0
target = 3
else:
self.click_square_center(ab2)
start = 1
target = 4
for i in range(start, target, 2):
for e in range(0, 5, 1):
self.click_square_center(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension,
self.dimension])
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_craft_button()
for i in range(0, 5, 1):
for e in range(0, 5, 1):
self.collect_grid_reverse_click(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab10)
elif self.mode == MODE10X2:
for r in range(0, 2, 1):
# grid 770 1630 160 1020 172
if r == 0:
self.click_square_center(ab1)
start = 0
target = 3
else:
self.click_square_center(ab2)
start = 1
target = 4
for i in range(start, target, 2):
for e in range(0, 5, 1):
self.click_square_center(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension,
self.dimension])
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_craft_button()
for i in range(0, 4, 2):
for e in range(0, 5, 1):
self.collect_grid_reverse_click(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab10)
elif self.mode == MODE5X3:
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
for r in range(0, 3, 1):
# grid 770 1630 160 1020 172oo
self.dimension = 172
if r == 0:
self.click_square_center(ab1)
start = 0
target = 1
elif r == 1:
self.click_square_center(ab2)
start = 1
target = 2
else:
self.click_square_center(ab3)
start = 2
target = 3
for i in range(start, target, 1):
for e in range(0, 5, 1):
self.click_square_center(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension,
self.dimension])
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_craft_button()
for i in range(0, 1, 1):
if self.overlay.run_mode == 'stopped':
break
for e in range(0, 5, 1):
self.collect_grid_reverse_click(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab10)
elif self.mode == MODE1X5_T:
tps = [ab1,
[770 + (0 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
ab2,
[770 + (2 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension]]
result_tp = [770 + (0 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension]
for tp in tps:
self.click_square_center(tp)
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_craft_button()
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(result_tp)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab10)
return
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
self.click_craft_button()
for i in range(0, 4, 2):
for e in range(0, 5, 1):
self.collect_grid_reverse_click(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
elif self.mode == MODE1X5_X:
tps = [ab1,
[770 + (0 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
return
self.click_square_center(ab10)
elif self.mode == MODE5X3:
for r in range(0, 3, 1):
# grid 770 1630 160 1020 172oo
self.dimension = 172
if r == 0:
self.click_square_center(ab1)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
start = 0
target = 1
elif r == 1:
self.click_square_center(ab2)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
start = 1
target = 2
else:
self.click_square_center(ab3)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
start = 2
target = 3
for i in range(start, target, 1):
for e in range(0, 5, 1):
self.click_square_center(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension,
self.dimension])
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_craft_button()
for i in range(0, 1, 1):
if self.overlay.run_mode == 'stopped':
return
for e in range(0, 5, 1):
self.collect_grid_reverse_click(
[770 + (i * self.dimension), 160 + (e * self.dimension), self.dimension, self.dimension])
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_square_center(ab10)
elif self.mode == MODE1X5_T:
tps = [ab1,
[770 + (0 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
ab2,
[770 + (2 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension]]
result_tp = [770 + (0 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension]
for tp in tps:
self.click_square_center(tp)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_craft_button()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_square_center(result_tp)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_square_center(ab10)
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
elif self.mode == MODE1X5_X:
tps = [ab1,
[770 + (0 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension]]
result_tp = [770 + (0 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension]
for tp in tps:
self.click_square_center(tp)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_craft_button()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_square_center(result_tp)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_square_center(ab10)
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
elif self.mode == MODE_HOUSE:
cements = [[770 + (0 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension]]
[770 + (2 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension]]
result_tp = [770 + (0 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension]
bricks = [[770 + (0 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (0 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension]]
for tp in tps:
self.click_square_center(tp)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
boards = [[770 + (2 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (0 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (0 * self.dimension), self.dimension, self.dimension]]
self.click_craft_button()
glasses = [[770 + (1 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension]]
tp_hammer = [770 + (1 * self.dimension), 160 + (0 * self.dimension), self.dimension, self.dimension]
tp_nails = [770 + (3 * self.dimension), 160 + (0 * self.dimension), self.dimension, self.dimension]
tp_result = [770 + (0 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension]
self.click_square_center(ab1)
for cement in cements:
self.click_square_center(cement)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(result_tp)
return
self.click_square_center(ab2)
for brick in bricks:
self.click_square_center(brick)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab10)
return
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
self.click_square_center(ab3)
for board in boards:
self.click_square_center(board)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
elif self.mode == MODE_HOUSE:
cements = [[770 + (0 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension]]
return
bricks = [[770 + (0 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (0 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension]]
self.click_square_center(ab4)
boards = [[770 + (2 * self.dimension), 160 + (3 * self.dimension), self.dimension, self.dimension],
[770 + (0 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (1 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (4 * self.dimension), 160 + (1 * self.dimension), self.dimension, self.dimension],
[770 + (2 * self.dimension), 160 + (0 * self.dimension), self.dimension, self.dimension]]
glasses = [[770 + (1 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension],
[770 + (3 * self.dimension), 160 + (2 * self.dimension), self.dimension, self.dimension]]
tp_hammer = [770 + (1 * self.dimension), 160 + (0 * self.dimension), self.dimension, self.dimension]
tp_nails = [770 + (3 * self.dimension), 160 + (0 * self.dimension), self.dimension, self.dimension]
tp_result = [770 + (0 * self.dimension), 160 + (4 * self.dimension), self.dimension, self.dimension]
self.click_square_center(ab1)
for cement in cements:
self.click_square_center(cement)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab2)
for brick in bricks:
self.click_square_center(brick)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab3)
for board in boards:
self.click_square_center(board)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab4)
for glass in glasses:
self.click_square_center(glass)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab5)
self.click_square_center(tp_hammer)
for glass in glasses:
self.click_square_center(glass)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
self.click_square_center(ab6)
self.click_square_center(tp_nails)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab5)
self.click_square_center(tp_hammer)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_craft_button()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_square_center(ab6)
self.click_square_center(tp_nails)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.click_square_center(tp_result)
self.click_square_center(ab10)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
self.click_craft_button()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
self.click_square_center(tp_result)
self.click_square_center(ab10)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
elif self.mode == MODE_SIMPLE_STACK:
# initialize the StunWindowCapture class
capture_config = UserConfigs()
# capture_window = WindowCapture(None, "screen_conf", capture_config)
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
capture_window2 = WindowCapture(None, "bla", capture_config)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
elif self.mode == MODE_SIMPLE_STACK:
# initialize the StunWindowCapture class
capture_config = UserConfigs()
# capture_window = WindowCapture(None, "screen_conf", capture_config)
# initialize the StunVision class
vision_stun = Vision()
# odig_overlay = DiggingOverlay(config)
check_for_craft_button(capture_window2, vision_stun, capture_config)
check_for_craft_ok_button(capture_window2, vision_stun)
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
# check_for_ok_button(capture_window, vision_stun, capture_config)
capture_window2 = WindowCapture(None, "bla", capture_config)
# initialize the StunVision class
vision_stun = Vision()
# dig_overlay = DiggingOverlay(config)
check_for_craft_button(capture_window2, vision_stun)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
check_for_craft_ok_button(capture_window2, vision_stun)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
self.run_counter = self.run_counter + 1
self.overlay.update_status_label(self.mode + ": " + str(self.run_target - self.run_counter))
# check_for_ok_button(capture_window, vision_stun, capture_config)
def collect_grid_reverse_click(self, square):
pydirectinput.moveTo(get_click_point(square)[0], get_click_point(square)[1])

View File

@@ -10,7 +10,7 @@ from config_file import UserConfigs
# load the original input image and display it to our screen
#filename = "equip/chests/chest_23_32"
path = "equip/wands/"
path = "flappy/"
os.chdir(path)
for entry in os.listdir():

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1013 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 986 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 726 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 KiB

276
crops.py
View File

@@ -2,12 +2,10 @@ import random
import cv2 as cv
import numpy as np
import pydirectinput
from window_capture import WindowCapture
from vision import Vision
from config_file import UserConfigs
from utils import mse
from utils import get_click_point
from hsvfilter import HsvFilter
from game_base_class import GameBase
GREEN = 1
YELLOW = 2
@@ -40,60 +38,25 @@ BIGBOMB_STRATEGY = 9
ROCKET_STRATEGY = 7
BOMB_STRATEGY = 5
class Crops:
data_value_grid = []
data_coordinates = []
screenshot = []
next_level = cv.imread("crop/next_level.jpg", cv.IMREAD_COLOR)
next_level_x = cv.imread("crop/next_level_x.jpg", cv.IMREAD_COLOR)
reset_board = cv.imread("crop/reset_button.jpg", cv.IMREAD_COLOR)
reset_confirm = cv.imread("crop/reset_confirm.jpg", cv.IMREAD_COLOR)
reset_counter = 0
colors_at_standard = True
needles = {}
hsh_needles = {}
explosives = [RAINBOW, ARROW_RIGHT, ARROW_DOWN, BIGBOMB, BOMB]
colors = [GREEN, YELLOW, RED, BLUE, PURPLE, MAGINENT, CHEMTRANT, TENESENT, CIBUTRANT, ARTISENT]
class Crops(GameBase):
def __init__(self, overlay):
self.overlay = overlay
self.data_value_grid = np.zeros((8, 14), dtype=int)
self.data_coordinates = np.zeros((8, 14), dtype=object)
self.data_score_map = np.zeros((8, 14), dtype=int)
self.observation = np.zeros((8, 14), dtype=int)
super().__init__(overlay)
self.current_strategy = RAINBOW_STRATEGY
self.screenshot = []
# 230 to 2110 = 1883 / 14 = 134.5
# 60 to 1130 = 1076 / 8 = 134.5
dim = 134.5
for e in range(0, 8, 1):
for i in range(0, 14, 1):
self.data_coordinates[e][i] = [i * dim, e * dim, dim, dim]
self.needles = {}
self.hsh_needles = {}
# initialize the user-class
self.config = UserConfigs()
self.colors.append(PURPLE)
# initialize the StunWindowCapture class
self.capture_window = WindowCapture(None, None, self.config)
# initialize the StunVision class
self.vision_stun = Vision()
self.current_strategy = overlay.get_strategy_value_as_int()
self.fill_data_coordinates()
self.set_color_order((GREEN, YELLOW, RED, BLUE, PURPLE))
def execute_main_loop(self):
while True:
if self.overlay.run_mode == 'paused':
cv.waitKey(1)
continue
elif self.overlay.run_mode == 'stopped':
break
self.assess_playfield_and_make_move()
def reset(self):
self.observation = []
def set_color_order(self, order):
self.needles.clear()
self.needles = {order[0]: cv.imread("crop/green.jpg", cv.IMREAD_COLOR),
@@ -163,7 +126,8 @@ class Crops:
color_list = [PURPLE, BLUE, RED, YELLOW, GREEN]
random.shuffle(color_list)
self.set_color_order(color_list)
self.current_strategy = random.choice([RAINBOW_STRATEGY, BIGBOMB_STRATEGY, ROCKET_STRATEGY, BOMB_STRATEGY])
self.current_strategy = random.choice([RAINBOW_STRATEGY, BIGBOMB_STRATEGY,
ROCKET_STRATEGY, BOMB_STRATEGY])
self.reset_counter = 0
return
else:
@@ -173,70 +137,33 @@ class Crops:
self.observation = new_observation
return new_observation
def move_to(self, x, y):
point_src = (1113, 598)
pydirectinput.moveTo(point_src[0], point_src[1])
pydirectinput.mouseDown()
w = random.randint(1, 100)
cv.waitKey(150 + w)
pydirectinput.moveTo(x, y)
pydirectinput.mouseUp()
cv.waitKey(500 + w)
def change_value(self, x, y, val):
self.data_value_grid[x][y] = val
def point_in_rect(self, point):
for e in range(0, 8, 1):
for i in range(0, 14, 1):
x1, y1, w, h = self.data_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if x1 < x and x < x2:
if y1 < y and y < y2:
return e, i
return None, None
def check_for_button_and_execute(self, screen, needle, offset_left=0, offset_down=0):
rectangles = self.vision_stun.find(screen, needle, 0.70, 1)
if len(rectangles) == 0:
return False
point = self.vision_stun.get_click_points(rectangles)[0]
self.dig_point(point[0] + offset_left, point[1] + offset_down, 500)
return True
def get_current_board_state(self):
try:
# get an updated image of the game
screenshot = self.capture_window.get_screenshot()
# screenshot = cv.imread("playfield.jpg")
screenshot = screenshot[58:1134, 230:2113] # 1883,1076
self.screenshot = screenshot
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
offset_left = 230
offset_down = 58
if self.check_for_button_and_execute(screenshot, self.next_level, offset_left, offset_down):
self.set_color_order((GREEN, YELLOW, RED, BLUE, PURPLE))
self.current_strategy = RAINBOW_STRATEGY
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[58:1134, 230:2113]
if self.check_for_button_and_execute(screenshot, self.next_level_x, offset_left, offset_down):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[58:1134, 230:2113]
except:
# self.capture_window.release()
# print("Game window not available - shutting down application")
# return None
pass
# get an updated image of the game
screenshot = self.capture_window.get_screenshot()
# screenshot = cv.imread("playfield.jpg")
screenshot = screenshot[190:1230, 260:2090]
self.screenshot = screenshot
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
offset_left = 230
offset_down = 58
if self.check_for_button_and_execute(screenshot, self.next_level, offset_left, offset_down):
self.set_color_order((GREEN, YELLOW, RED, BLUE, PURPLE))
self.current_strategy = RAINBOW_STRATEGY
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[190:1230, 260:2090]
if self.check_for_button_and_execute(screenshot, self.next_level_x, offset_left, offset_down):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[190:1230, 260:2090]
# cv.imshow("screenshot", screenshot)
# cv.waitKey(150)
# continue
data_coords = np.zeros((8, 14), dtype=object)
# field = Field()
# field = Pickaxe_Field()
for needle_key in self.needles.keys():
# gray_needle = cv.cvtColor(self.needles[needle_key], cv.COLOR_BGR2GRAY)
@@ -271,65 +198,15 @@ class Crops:
return data_coords, screenshot
def detonate_explosive_when_stuck(self, state):
for e in range(0, 8, 1):
for i in range(0, 14, 1):
for explosive in self.explosives:
if self.local_pos_check(state, e, i, 0, 0, explosive):
src_pt = self.get_click_point(self.data_coordinates[e, i])
if self.local_pos_checks(state, e, i, 1, 0, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e + 1, i])
self.move_tile(src_pt, dest_pt)
return True
elif self.local_pos_checks(state, e, i, 0, 1, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e, i + 1])
self.move_tile(src_pt, dest_pt)
return True
elif self.local_pos_checks(state, e, i, -1, 0, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
return True
elif self.local_pos_checks(state, e, i, 0, -1, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
return True
else:
continue
return False
def check_explosives(self, state, e, i):
for explosive in self.explosives:
if self.local_pos_check(state, e, i, 0, 0, explosive):
dest_pt = self.get_click_point(self.data_coordinates[e, i])
if self.local_pos_checks(state, e, i, 1, 0, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e + 1, i])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, 0, 1, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e, i + 1])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, -1, 0, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, 0, -1, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
else:
continue
return True
else:
continue
return False
def find_patterns_and_valid_moves(self, state):
# score_map = np.zeros((8, 14), dtype=object)
for x in range(0, 8, 1):
for y in range(0, 14, 1):
self.data_score_map[x, y] = self.score_for_attached_same_color_all_directions(state, x, y)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
full_moves = []
reserve_moves = []
@@ -347,18 +224,18 @@ class Crops:
if len(path_option) >= 5:
full_moves.append((state[x, y], path_option))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.data_score_map[x, y] >= 1:
path_option = [[x, y]]
self.find_next_same_color_all_directions_recursion2(state, x, y, path_option)
if len(path_option) >= 3:
reserve_moves.append((state[x, y], path_option))
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
# print(self.data_score_map)
# screenshot = cv.imread("screenshot_scored.jpg")
@@ -380,7 +257,8 @@ class Crops:
self.execute_move(res_dic[key])
break
def convert_moves_to_dic_by_color(self, reserve_moves):
@staticmethod
def convert_moves_to_dic_by_color(reserve_moves):
dic = {}
for color, move in reserve_moves:
if color in dic:
@@ -419,7 +297,8 @@ class Crops:
pydirectinput.mouseUp()
cv.waitKey(50)
def get_directions_array(self, current_x, current_y):
@staticmethod
def get_directions_array(current_x, current_y):
left_x = current_x
left_y = current_y - 1
@@ -513,70 +392,3 @@ class Crops:
score = score + self.is_direction_in_bounce_and_same_color(state, direction, color)
return score
def is_direction_in_bounce_and_same_color(self, state, loc, color):
x, y = loc
if x <= 7 and x >= 0 and y <= 13 and y >= 0:
if state[x, y] == color:
return 1
return 0
def local_pos_check(self, state, e, i, e_check, i_check, needle):
if e + e_check >= 0 and e + e_check <= 7 and i + i_check >= 0 and i + i_check <= 13:
if state[e + e_check, i + i_check] == needle:
return True
else:
return False
def local_pos_checks(self, state, e, i, e_check, i_check, needles):
if e + e_check >= 0 and e + e_check <= 7 and i + i_check >= 0 and i + i_check <= 13:
for needle in needles:
if state[e + e_check, i + i_check] == needle:
return True
else:
continue
return False
def move_tile(self, point_source, point_dest):
offset_left = 230
offset_down = 58
pydirectinput.moveTo(point_source[0] + offset_left, point_source[1] + offset_down)
# pydirectinput.moveTo(0,0)
pydirectinput.mouseDown()
w = random.randint(25, 50)
cv.waitKey(100 + w)
pydirectinput.moveTo(point_dest[0] + offset_left, point_dest[1] + offset_down)
pydirectinput.mouseUp()
cv.waitKey(400 + w)
def check_for_button_and_click_it(self, button_url):
screenshot = self.capture_window.get_screenshot()
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
# gray_needle = cv.cvtColor(cv.imread(button_url, cv.IMREAD_UNCHANGED), cv.COLOR_BGR2GRAY)
# thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
needle = cv.imread(button_url, cv.IMREAD_UNCHANGED)
# rectangles = self.vision_stun.find(thresh, thresh_needle, 0.4, 1)
rectangles = self.vision_stun.find(screenshot, needle, 0.7, 1)
if len(rectangles) == 1:
pointis = self.vision_stun.get_click_points(rectangles)
for pointi in pointis:
self.dig_point(pointi[0], pointi[1], 150)
def dig_point(self, point1, point2, dig_time):
pydirectinput.moveTo(point1, point2)
cv.waitKey(dig_time)
pydirectinput.mouseDown()
w = random.randint(50, 100)
cv.waitKey(w)
pydirectinput.mouseUp()
def get_click_point(self, rectangle):
# Loop over all the rectangles
x, y, w, h = rectangle
# Determine the center position
center_x = x + int(w / 2)
center_y = y + int(h / 2)
# Save the points
return int(center_x), int(center_y)

View File

@@ -1,13 +1,12 @@
import random
from operator import itemgetter
from time import time
from window_capture import WindowCapture
from vision import Vision
import cv2 as cv
from hsvfilter import HsvFilter
from config_file import UserConfigs
import pydirectinput
from utils import dig_point
from game_base_class import GameBase
from window_capture import WindowCapture
EMITTER_MAIN = "main"
EMITTER_MUSH = "mushroom"
@@ -21,7 +20,7 @@ EMITTER_MULTI = "multi"
HSV_DEFAULT = HsvFilter(0, 0, 0, 179, 255, 255, 0, 0, 0, 0)
class Equipment:
class Equipment(GameBase):
needles = []
hsvs = []
tresholds = []
@@ -29,62 +28,16 @@ class Equipment:
emitters = []
def __init__(self, overlay):
self.overlay = overlay
self.config = UserConfigs()
super().__init__(overlay)
# initialize the StunWindowCapture class
self.capture_window = WindowCapture(None, "equip", self.config)
self.EMITTER_TO_USE = str(overlay.emitter_use.get())
self.SPAWN_COUNT = int(overlay.spawn_use.get())
self.ENERGY_TO_USE = int(overlay.energy_use.get())
# initialize the StunWindowCapture class
self.capture_window = WindowCapture(None, "equip", self.config)
# initialize the StunVision class
self.vision_stun = Vision()
if self.EMITTER_TO_USE == EMITTER_MULTI:
self.emitters.append(EMITTER_RING)
self.emitters.append(EMITTER_WAND)
self.emitters.append(EMITTER_SWORD)
self.emitters.append(EMITTER_AMU)
self.emitters.append(EMITTER_STAFF)
else:
self.emitters.append(self.EMITTER_TO_USE)
for emitter in self.emitters:
if emitter == EMITTER_MUSH:
self.include_books()
self.include_mushs()
self.include_pots()
self.include_bags()
elif emitter == EMITTER_AMU:
self.include_books()
self.include_amus()
self.include_bags()
elif emitter == EMITTER_MAIN:
self.include_books()
self.include_chests()
self.include_keys()
self.include_pots()
self.include_bags()
self.include_coins()
self.include_runes()
elif emitter == EMITTER_SWORD:
self.include_books()
self.include_swords()
self.include_bags()
elif emitter == EMITTER_STAFF:
self.include_books()
self.include_staffs()
self.include_bags()
elif emitter == EMITTER_RING:
self.include_books()
self.include_rings()
self.include_bags()
elif emitter == EMITTER_WAND:
self.include_books()
self.include_wands()
self.include_bags()
self.init_emitters_to_use()
self.c_needle = cv.imread("equip/chests/chest_4_32.jpg", cv.IMREAD_UNCHANGED)
self.c_mask = cv.imread("equip/chests/chest_4_32-mask.png", cv.IMREAD_COLOR)
@@ -94,11 +47,55 @@ class Equipment:
self.energy_counter = 0
def init_emitters_to_use(self):
self.emitters.clear()
if self.EMITTER_TO_USE == EMITTER_MULTI:
self.emitters.append(EMITTER_RING)
self.emitters.append(EMITTER_WAND)
self.emitters.append(EMITTER_SWORD)
self.emitters.append(EMITTER_AMU)
self.emitters.append(EMITTER_STAFF)
else:
self.emitters.append(self.EMITTER_TO_USE)
def init_needles_for_emitter_to_use(self, emitter):
self.needles.clear()
self.hsvs.clear()
self.tresholds.clear()
self.masks.clear()
self.include_books()
self.include_bags()
if emitter == EMITTER_MUSH:
self.include_mushs()
self.include_pots()
elif emitter == EMITTER_AMU:
self.include_amus()
elif emitter == EMITTER_MAIN:
self.include_chests()
self.include_keys()
self.include_pots()
#self.include_coins()
self.include_runes()
elif emitter == EMITTER_SWORD:
self.include_swords()
elif emitter == EMITTER_STAFF:
self.include_staffs()
elif emitter == EMITTER_RING:
self.include_rings()
elif emitter == EMITTER_WAND:
self.include_wands()
def execute_main_loop(self):
start_time = time()
breaks = self.init_breaks()
for emitter in self.emitters:
self.init_needles_for_emitter_to_use(emitter)
while True:
self.check_breaks(start_time, breaks)
if self.overlay.run_mode == 'paused':
cv.waitKey(1)
cv.waitKey(10)
continue
elif self.overlay.run_mode == 'stopped':
break
@@ -115,6 +112,9 @@ class Equipment:
spawn_1 = self.find_emitter(emitter, screenshot, 1)
if len(spawn_1) == 1:
#output_by_area = self.vision_stun.draw_rectangles(screenshot, spawn_1)
#cv.imshow("spawn_1", output_by_area)
#cv.waitKey(150)
points = self.vision_stun.get_click_points(spawn_1)
for i in range(0, self.SPAWN_COUNT, 1):
self.click_point(points[0][0], points[0][1])
@@ -125,17 +125,19 @@ class Equipment:
else:
spawn_0 = self.find_emitter(emitter, screenshot, 0)
points = self.vision_stun.get_click_points(spawn_0)
for point in points:
if len(points) >= 1:
self.click_point(points[0][0], points[0][1])
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
continue
continue
cv.waitKey(500)
if emitter == EMITTER_MAIN:
loop_time = time()
while True:
if (time() - loop_time) >= 10:
break
screenshot = self.capture_window.get_screenshot()
c_rectangles = self.vision_stun.find(screenshot, self.c_needle, 0.95, 1, True, self.c_mask)
k_rectangles = self.vision_stun.find(screenshot, self.k_needle, 0.95, 1, True, self.k_mask)
@@ -143,13 +145,17 @@ class Equipment:
c_point = self.vision_stun.get_click_points(c_rectangles)[0]
k_point = self.vision_stun.get_click_points(k_rectangles)[0]
self.move_tile(k_point, c_point)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
else:
break
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
continue
for rer in range(0, len(self.needles), 1):
loop_time = time()
while True:
if (time() - loop_time) >= 60:
if (time() - loop_time) >= 20:
break
screenshot = self.capture_window.get_screenshot_by_area(self.config.returnOKWindowPos())
rectangles = self.vision_stun.find(screenshot, self.dig_button, 0.5, 1)
@@ -207,7 +213,7 @@ class Equipment:
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
cv.waitKey(150)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
if self.overlay.run_mode == 'stopped':
break
if self.overlay.run_mode == 'stopped':
break
@@ -313,7 +319,7 @@ class Equipment:
else:
needle = cv.imread("equip/emitters/ring_e2_32.jpg", cv.IMREAD_UNCHANGED)
mask = cv.imread("equip/emitters/ring_e2_32-mask.png", cv.IMREAD_COLOR)
return self.vision_stun.find(screen, needle, 0.95, 1, True, mask)
return self.vision_stun.find(screen, needle, 0.95, 1, False, mask)
elif emitter_to_use == EMITTER_WAND:
if layer == 0:
needle = cv.imread("equip/emitters/wand_e1_32.jpg", cv.IMREAD_UNCHANGED)
@@ -622,12 +628,12 @@ class Equipment:
def include_staffs(self):
self.needles.append(cv.imread("equip/staffs/staff_1_32.jpg", cv.IMREAD_UNCHANGED))
self.hsvs.append(HSV_DEFAULT)
self.tresholds.append(0.93)
self.tresholds.append(0.94)
self.masks.append(cv.imread("equip/staffs/staff_1_32-mask.png", cv.IMREAD_COLOR))
self.needles.append(cv.imread("equip/staffs/staff_2_32.jpg", cv.IMREAD_UNCHANGED))
self.hsvs.append(HSV_DEFAULT)
self.tresholds.append(0.93)
self.tresholds.append(0.94)
self.masks.append(cv.imread("equip/staffs/staff_2_32-mask.png", cv.IMREAD_COLOR))
self.needles.append(cv.imread("equip/staffs/staff_3_32.jpg", cv.IMREAD_UNCHANGED))

332
farm.py
View File

@@ -1,11 +1,7 @@
import random
import cv2 as cv
import numpy as np
import pydirectinput
from window_capture import WindowCapture
from vision import Vision
from config_file import UserConfigs
from utils import mse
from game_base_class import GameBase
GREEN = 1
YELLOW = 2
@@ -30,54 +26,16 @@ CIBUTRANT = 24
ARTISENT = 25
class Farm:
data_value_grid = []
data_coordinates = []
next_level = cv.imread("farm/next_level.jpg", cv.IMREAD_COLOR)
next_level_x = cv.imread("farm/next_level_x.jpg", cv.IMREAD_COLOR)
reset_board = cv.imread("farm/reset_button.jpg", cv.IMREAD_COLOR)
reset_confirm = cv.imread("farm/reset_confirm.jpg", cv.IMREAD_COLOR)
reset_counter = 0
explosives = []
explosives.append(RAINBOW)
explosives.append(ARROW_RIGHT)
explosives.append(ARROW_DOWN)
explosives.append(BIGBOMB)
explosives.append(BOMB)
colors = []
colors.append(GREEN)
colors.append(YELLOW)
colors.append(BLUE)
colors.append(RED)
colors.append(PINK)
colors.append(MAGINENT)
colors.append(CHEMTRANT)
colors.append(TENESENT)
colors.append(CIBUTRANT)
colors.append(ARTISENT)
class Farm(GameBase):
def __init__(self, overlay):
self.overlay = overlay
self.data_value_grid = np.zeros((8, 14), dtype=int)
self.data_coordinates = np.zeros((8, 14), dtype=object)
self.observation = np.zeros((8, 14), dtype=int)
super().__init__(overlay)
# 230 to 2110 = 1883 / 14 = 134.5
# 60 to 1130 = 1076 / 8 = 134.5
dim = 134.5
for e in range(0, 8, 1):
for i in range(0, 14, 1):
self.data_coordinates[e][i] = [i * dim, e * dim, dim, dim]
self.farm_reset_board = cv.imread("control_elements/farm_reset_button.jpg", cv.IMREAD_COLOR)
# initialize the user-class
self.config = UserConfigs()
self.colors.append(PINK)
# initialize the StunWindowCapture class
self.capture_window = WindowCapture(None, None, self.config)
# initialize the StunVision class
self.vision_stun = Vision()
self.fill_data_coordinates()
self.needles = {GREEN: cv.imread("farm/green.jpg", cv.IMREAD_COLOR),
YELLOW: cv.imread("farm/yellow.jpg", cv.IMREAD_COLOR),
@@ -102,19 +60,6 @@ class Farm:
ARTISENT: cv.imread("farm/artisent.jpg", cv.IMREAD_COLOR)
}
def execute_main_loop(self):
while True:
if self.overlay.run_mode == 'paused':
cv.waitKey(1)
continue
elif self.overlay.run_mode == 'stopped':
break
self.assess_playfield_and_make_move()
def reset(self):
self.observation = []
def assess_playfield_and_make_move(self):
new_observation, new_screenshot = self.get_current_board_state()
@@ -135,7 +80,7 @@ class Farm:
return
elif self.reset_counter >= 3:
screenshot = self.capture_window.get_screenshot()
if self.check_for_button_and_execute(screenshot, self.reset_board):
if self.check_for_button_and_execute(screenshot, self.farm_reset_board):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
if self.check_for_button_and_execute(screenshot, self.reset_confirm):
@@ -150,86 +95,38 @@ class Farm:
self.observation = new_observation
return new_observation
def check_for_button_and_execute(self, screen, needle, offset_left=0, offset_down=0):
rectangles = self.vision_stun.find(screen, needle, 0.70, 1)
if len(rectangles) == 0:
return False
point = self.vision_stun.get_click_points(rectangles)[0]
self.dig_point(point[0] + offset_left, point[1] + offset_down, 500)
return True
def move_to(self, x, y):
point_src = (1113, 598)
pydirectinput.moveTo(point_src[0], point_src[1])
pydirectinput.mouseDown()
w = random.randint(1, 100)
cv.waitKey(150 + w)
pydirectinput.moveTo(x, y)
pydirectinput.mouseUp()
cv.waitKey(500 + w)
def change_value(self, x, y, val):
self.data_value_grid[x][y] = val
def pointInRect(self, point):
for e in range(0, 8, 1):
for i in range(0, 14, 1):
x1, y1, w, h = self.data_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if (x1 < x and x < x2):
if (y1 < y and y < y2):
return e, i
return None, None
def check_for_next_level(self, screen, needle):
offset_left = 230
offset_down = 58
rectangles = self.vision_stun.find(screen, needle, 0.70, 1)
if len(rectangles) == 0:
return False
if self.detonate_explosive_when_stuck(self.observation):
return True
point = self.vision_stun.get_click_points(rectangles)[0]
self.dig_point(point[0]+ offset_left, point[1] + offset_down, 500)
return True
def get_current_board_state(self):
try:
# get an updated image of the game
# get an updated image of the game
screenshot = self.capture_window.get_screenshot()
# screenshot = cv.imread("field_farm.jpg")
screenshot = screenshot[190:1230, 260:2090] # 1883,1076
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
if self.check_for_next_level(screenshot, self.next_level):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
#screenshot = cv.imread("field_farm.jpg")
screenshot = screenshot[58:1134, 230:2113] # 1883,1076
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
if self.check_for_next_level(screenshot, self.next_level):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[58:1134, 230:2113]
if self.check_for_next_level(screenshot, self.next_level_x):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[58:1134, 230:2113]
screenshot = screenshot[190:1230, 260:2090]
if self.check_for_next_level(screenshot, self.next_level_x):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[190:1230, 260:2090]
except:
self.capture_window.release()
print("Game window not available - shutting down application")
return None
# cv.imshow("screenshot", screenshot)
# cv.waitKey(150)
# continue
#cv.imshow("screenshot", screenshot)
#cv.waitKey(150)
#return
#continue
data_coords = np.zeros((8, 14), dtype=object)
# field = Field()
# field = Pickaxe_Field()
for needle_key in self.needles.keys():
# gray_needle = cv.cvtColor(self.needles[needle_key], cv.COLOR_BGR2GRAY)
# thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.70, 56)
rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.74, 56)
if len(rectangles) == 0:
continue
points = self.vision_stun.get_click_points(rectangles)
for point in points:
x, y = self.pointInRect(point)
x, y = self.point_in_rect(point)
if x is not None and y is not None:
data_coords[x][y] = int(needle_key)
# self.change_value(x, y, int(needle_key))
@@ -246,23 +143,21 @@ class Farm:
if self.check_explosives(state, e, i):
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
for e in range(0, 8, 1):
for i in range(0, 14, 1):
for color in self.colors:
if self.check_5_horizontal(state, e, i, color):
return
if self.check_5_vertical(state, e, i, color):
if self.check_5s(state, e, i, color):
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
for e in range(0, 8, 1):
for i in range(0, 14, 1):
@@ -274,11 +169,11 @@ class Farm:
if self.check_3_with_gap(state, e, i, color):
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
def detonate_explosive_when_stuck(self, state):
for e in range(0, 8, 1):
@@ -306,82 +201,33 @@ class Farm:
continue
return False
def check_explosives(self, state, e, i):
for explosive in self.explosives:
if self.local_pos_check(state, e, i, 0, 0, explosive):
dest_pt = self.get_click_point(self.data_coordinates[e, i])
if self.local_pos_checks(state, e, i, 1, 0, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e + 1, i])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, 0, 1, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e, i + 1])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, -1, 0, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, 0, -1, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
else:
continue
return True
else:
continue
return False
def local_pos_check(self, state, e, i, e_check, i_check, needle):
if e + e_check >= 0 and e + e_check <=7 and i + i_check >= 0 and i + i_check <=13:
if state[e + e_check, i + i_check] == needle:
return True
else:
return False
def local_pos_checks(self, state, e, i, e_check, i_check, needles):
if e + e_check >= 0 and e + e_check <=7 and i + i_check >= 0 and i + i_check <=13:
for needle in needles:
if state[e + e_check, i + i_check] == needle:
return True
else:
continue
return False
def check_5_horizontal(self, state, e, i, color):
def check_5s(self, state, e, i, color):
try:
#
if state[e, i] == color and state[e, i + 1] == color and state[e, i + 3] == color and state[
e, i + 4] == color:
if state[e, i + 2] <= 0 or state[e, i + 2] >= 6:
return False
#
if e - 1 >= 0 and i + 2 <= 13:
if state[e - 1, i + 2] == color:
return True
return False
except:
return False
def check_5_vertical(self, state, e, i, color):
try:
#
if state[e, i] == color and state[e + 1, i] == color and state[e + 3, i] == color and state[
e + 4, i] == color:
if state[e + 2, i] <= 0 or state[e + 2, i] >= 6:
return False
# third left upper
if e + 2 <= 7 and i - 1 >= 0:
if state[e + 2, i - 1] == color:
#print("upper left", color, e, i)
if state[e, i] == color and state[e + 1, i] == color and state[e + 3, i] == color and state[e + 4, i] == color:
if state[e + 2, i] in self.colors:
if self.is_direction_in_bounce_and_same_color(state, (e + 2, i - 1), color):
src_pt = self.get_click_point(self.data_coordinates[e + 2, i - 1])
dest_pt = self.get_click_point(self.data_coordinates[e + 2, i])
self.move_tile(src_pt, dest_pt)
return True
if e + 2 <= 7 and i + 1 <= 13:
if state[e + 2, i + 1] == color:
#print("upper left", color, e, i)
if self.is_direction_in_bounce_and_same_color(state, (e + 2, i + 1), color):
src_pt = self.get_click_point(self.data_coordinates[e + 2, i + 1])
dest_pt = self.get_click_point(self.data_coordinates[e + 2, i])
self.move_tile(src_pt, dest_pt)
return True
elif state[e, i] == color and state[e, i + 1] == color and state[e, i + 3] == color and state[e, i + 4] == color:
if state[e, i + 2] in self.colors:
if self.is_direction_in_bounce_and_same_color(state, (e + 1, i +2), color):
src_pt = self.get_click_point(self.data_coordinates[e + 1, i + 2])
dest_pt = self.get_click_point(self.data_coordinates[e, i + 2])
self.move_tile(src_pt, dest_pt)
return True
if self.is_direction_in_bounce_and_same_color(state, (e - 1, i + 2), color):
src_pt = self.get_click_point(self.data_coordinates[e - 1, i + 2])
dest_pt = self.get_click_point(self.data_coordinates[e, i + 2])
self.move_tile(src_pt, dest_pt)
return True
return False
except:
return False
@@ -393,7 +239,7 @@ class Farm:
if state[e, i] == color and state[e, i + 2] == color:
# third upper
if e - 1 >= 0 and i + 1 <= 13:
#if state[e - 1, i - 1] == color and (state[e, i - 1] >= 1 and state[e, i - 1] <= 5):
# if state[e - 1, i - 1] == color and (state[e, i - 1] >= 1 and state[e, i - 1] <= 5):
if state[e - 1, i + 1] == color and (state[e, i + 1] in self.colors):
src_pt = self.get_click_point(self.data_coordinates[e - 1, i + 1])
dest_pt = self.get_click_point(self.data_coordinates[e, i + 1])
@@ -410,7 +256,7 @@ class Farm:
if state[e, i] == color and state[e + 2, i] == color:
# third upper
if e + 1 >= 0 and i + 1 <= 13:
#if state[e - 1, i - 1] == color and (state[e, i - 1] >= 1 and state[e, i - 1] <= 5):
# if state[e - 1, i - 1] == color and (state[e, i - 1] >= 1 and state[e, i - 1] <= 5):
if state[e + 1, i + 1] == color and (state[e + 1, i] in self.colors):
src_pt = self.get_click_point(self.data_coordinates[e + 1, i + 1])
dest_pt = self.get_click_point(self.data_coordinates[e + 1, i])
@@ -433,7 +279,7 @@ class Farm:
# third left upper
if e - 1 >= 0 and i - 1 >= 0:
if state[e - 1, i - 1] == color and (state[e, i - 1] in self.colors):
#print("upper left", color, e, i)
# print("upper left", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e - 1, i - 1])
dest_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
@@ -441,7 +287,7 @@ class Farm:
# third left lower
if e + 1 <= 7 and i - 1 >= 0:
if state[e + 1, i - 1] == color and (state[e, i - 1] in self.colors):
#print("lower left", color, e, i)
# print("lower left", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e + 1, i - 1])
dest_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
@@ -449,7 +295,7 @@ class Farm:
# third left with gap
if i - 2 >= 0:
if state[e, i - 2] == color and (state[e, i - 1] in self.colors):
#print("left gap ", color, e, i)
# print("left gap ", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e, i - 2])
dest_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
@@ -457,7 +303,7 @@ class Farm:
# third right upper
if e - 1 >= 0 and i + 2 <= 13:
if state[e - 1, i + 2] == color and (state[e, i + 2] in self.colors):
#print("upper right", color, e, i)
# print("upper right", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e - 1, i + 2])
dest_pt = self.get_click_point(self.data_coordinates[e, i + 2])
self.move_tile(src_pt, dest_pt)
@@ -465,7 +311,7 @@ class Farm:
# third right lower
if e + 1 <= 7 and i + 2 <= 13:
if state[e + 1, i + 2] == color and (state[e, i + 2] in self.colors):
#print("upper lower", color, e, i)
# print("upper lower", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e + 1, i + 2])
dest_pt = self.get_click_point(self.data_coordinates[e, i + 2])
self.move_tile(src_pt, dest_pt)
@@ -474,7 +320,7 @@ class Farm:
# third right with gap
if i + 3 <= 13:
if state[e, i + 3] == color and (state[e, i + 2] in self.colors):
#print("right gap ", color, e, i)
# print("right gap ", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e, i + 3])
dest_pt = self.get_click_point(self.data_coordinates[e, i + 2])
self.move_tile(src_pt, dest_pt)
@@ -489,7 +335,7 @@ class Farm:
# third left upper
if e - 1 >= 0 and i - 1 >= 0:
if state[e - 1, i - 1] == color and (state[e - 1, i] in self.colors):
#print("upper left", color, e, i)
# print("upper left", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e - 1, i - 1])
dest_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
@@ -497,7 +343,7 @@ class Farm:
# third left lower
if e + 2 <= 7 and i - 1 >= 0:
if state[e + 2, i - 1] == color and (state[e + 2, i] in self.colors):
print("lower left", color, e, i)
# print("lower left", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e + 2, i - 1])
dest_pt = self.get_click_point(self.data_coordinates[e + 2, i])
self.move_tile(src_pt, dest_pt)
@@ -505,7 +351,7 @@ class Farm:
# third right upper
if e - 1 >= 0 and i + 1 <= 13:
if state[e - 1, i + 1] == color and (state[e - 1, i] in self.colors):
#print("upper right", color, e, i)
# print("upper right", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e - 1, i + 1])
dest_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
@@ -513,7 +359,7 @@ class Farm:
# third right lower
if e + 2 <= 7 and i + 1 <= 13:
if state[e + 2, i + 1] == color and (state[e + 2, i] in self.colors):
#print("upper lower", color, e, i)
# print("upper lower", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e + 2, i + 1])
dest_pt = self.get_click_point(self.data_coordinates[e + 2, i])
self.move_tile(src_pt, dest_pt)
@@ -521,7 +367,7 @@ class Farm:
# third upper with gap
if e - 2 >= 0:
if state[e - 2, i] == color and (state[e - 1, i] in self.colors):
#print("upper gap ", color, e, i)
# print("upper gap ", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e - 2, i])
dest_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
@@ -529,54 +375,10 @@ class Farm:
# third lower with gap
if e + 3 <= 7:
if state[e + 3, i] == color and (state[e + 2, i] in self.colors):
#print("lower gap ", color, e, i)
# print("lower gap ", color, e, i)
src_pt = self.get_click_point(self.data_coordinates[e + 3, i])
dest_pt = self.get_click_point(self.data_coordinates[e + 2, i])
self.move_tile(src_pt, dest_pt)
return True
except:
return False
def move_tile(self, point_source, point_dest):
offset_left = 230
offset_down = 58
pydirectinput.moveTo(point_source[0] + offset_left, point_source[1] + offset_down)
# pydirectinput.moveTo(0,0)
pydirectinput.mouseDown()
w = random.randint(25, 50)
cv.waitKey(100 + w)
pydirectinput.moveTo(point_dest[0] + offset_left, point_dest[1] + offset_down)
pydirectinput.mouseUp()
cv.waitKey(400 + w)
def check_for_button_and_click_it(self, button_url):
screenshot = self.capture_window.get_screenshot()
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
# gray_needle = cv.cvtColor(cv.imread(button_url, cv.IMREAD_UNCHANGED), cv.COLOR_BGR2GRAY)
# thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
needle = cv.imread(button_url, cv.IMREAD_UNCHANGED)
# rectangles = self.vision_stun.find(thresh, thresh_needle, 0.4, 1)
rectangles = self.vision_stun.find(screenshot, needle, 0.7, 1)
if len(rectangles) == 1:
pointis = self.vision_stun.get_click_points(rectangles)
for pointi in pointis:
self.dig_point(pointi[0], pointi[1], 150)
def dig_point(self, point1, point2, dig_time):
pydirectinput.moveTo(point1, point2)
cv.waitKey(dig_time)
pydirectinput.mouseDown()
w = random.randint(50, 100)
cv.waitKey(w)
pydirectinput.mouseUp()
def get_click_point(self, rectangle):
# Loop over all the rectangles
x, y, w, h = rectangle
# Determine the center position
center_x = x + int(w / 2)
center_y = y + int(h / 2)
# Save the points
return int(center_x), int(center_y)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 928 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

213
field.py Normal file
View File

@@ -0,0 +1,213 @@
#!/usr/bin/python
from copy import copy
from tetromino import Tetromino
class Field():
WIDTH = 20
HEIGHT = 20
def __init__(self, state=None):
if state:
self.state = state
else:
self.state = [[' ' for cols in range(Field.WIDTH)]
for rows in range(Field.HEIGHT)]
self.cleared_rows = 1
def __str__(self):
BAR = ' ' + '-' * (Field.WIDTH * 2 + 1) + '\n ' + \
' '.join(map(str, range(Field.WIDTH))) + '\n'
return BAR + '\n'.join([
'{:2d} |'.format(i) + ' '.join(row) + '|'
for i, row in enumerate(self.state)]) + '\n' + BAR
@staticmethod
def matrixflip(m, d):
tempm = m.copy()
if d == 'h':
for i in range(0, len(tempm), 1):
tempm[i].reverse()
elif d == 'v':
tempm.reverse()
return (tempm)
@staticmethod
def rotate_90_degree_anticlckwise(matrix):
new_matrix = []
for i in range(len(matrix[0]), 0, -1):
new_matrix.append(list(map(lambda x: x[i - 1], matrix)))
return new_matrix
@staticmethod
def rotate_90_degree_clckwise(matrix):
new_matrix = []
for i in range(len(matrix[0])):
li = list(map(lambda x: x[i], matrix))
li.reverse()
new_matrix.append(li)
return new_matrix
def reset_field(self):
self.state = [[' ' for cols in range(Field.WIDTH)]
for rows in range(Field.HEIGHT)]
def reset_half_field(self):
for row in range(int(self.HEIGHT/2)):
self.state[row] = [' ' for cols in range(Field.WIDTH)]
def rotate_state(self):
self.state = Field.rotate_90_degree_anticlckwise(self.state)
def get_line_count(self):
return self.cleared_rows
def _test_tetromino(self, tetromino, row, column):
"""
Tests to see if a tetromino can be placed at the specified row and
column. It performs the test with the bottom left corner of the
tetromino at the specified row and column.
"""
assert column >= 0
assert column + tetromino.width() <= Field.WIDTH
assert row - tetromino.height() + 1 >= 0
assert row < Field.HEIGHT
for ti, si in list(enumerate(range(row - tetromino.height() + 1,
row + 1)))[::-1]:
for tj, sj in enumerate(range(column, column + tetromino.width())):
if tetromino[ti][tj] != ' ' and self.state[si][sj] != ' ':
return False
return True
def _place_tetromino(self, tetromino, row, column):
"""
Place a tetromino at the specified row and column.
The bottom left corner of the tetromino will be placed at the specified
row and column. This function does not perform checks and will overwrite
filled spaces in the field.
"""
assert column >= 0
assert column + tetromino.width() <= Field.WIDTH
assert row - tetromino.height() + 1 >= 0
assert row < Field.HEIGHT
for ti, si in list(enumerate(range(row - tetromino.height() + 1,
row + 1)))[::-1]:
for tj, sj in enumerate(range(column, column + tetromino.width())):
if tetromino[ti][tj] != ' ':
self.state[si][sj] = tetromino[ti][tj]
def _get_tetromino_drop_row(self, tetromino, column):
"""
Given a tetromino and a column, return the row that the tetromino
would end up in if it were dropped in that column.
Assumes the leftmost column of the tetromino will be aligned with the
specified column.
"""
assert isinstance(tetromino, Tetromino)
assert column >= 0
assert column + tetromino.width() <= Field.WIDTH
last_fit = -1
for row in range(tetromino.height(), Field.HEIGHT):
if self._test_tetromino(tetromino, row, column):
last_fit = row
else:
return last_fit
return last_fit
def _line_clear(self):
"""
Checks and removes all filled lines.
"""
self.state = list(filter(lambda row: row.count(' ') != 0, self.state))
while len(self.state) < Field.HEIGHT:
self.state.insert(0, [' ' for col in range(Field.WIDTH)])
self.cleared_rows = self.cleared_rows + 1
print("cleared rows: ", self.cleared_rows)
def copy(self):
"""
Returns a shallow copy of the field.
"""
return Field([row[:] for row in self.state])
def drop(self, tetromino, column):
"""
Drops a tetromino in the specified column.
The leftmost column of the tetromino will be aligned with the specified
column.
Returns the row it was dropped in for computations.
"""
assert isinstance(tetromino, Tetromino)
assert column >= 0
assert column + tetromino.width() <= Field.WIDTH
row = self._get_tetromino_drop_row(tetromino, column)
assert row != -1
self._place_tetromino(tetromino, row, column)
self._line_clear()
return row
def check_crucial_pos_to_be_free(self):
if self.state[19][9] == ' ' and self.state[19][10] == ' ' and self.state[18][9] == ' ' and self.state[18][10] == ' ':
return True
return False
def predict_gaps_in_next_rotation(self):
tmp_state = copy(self.state)
tmp_state = Field.rotate_90_degree_anticlckwise(tmp_state)
for row in range(int(self.HEIGHT/2)):
tmp_state[row] = [' ' for cols in range(Field.WIDTH)]
return sum(
["".join([row[col] for row in tmp_state]).lstrip().count(' ')
for col in range(Field.WIDTH)])
def count_gaps(self):
"""
Check each column one by one to make sure there are no gaps in the
column.
"""
return sum(
["".join([row[col] for row in self.state]).lstrip().count(' ')
for col in range(Field.WIDTH)])
def height(self):
"""
Returns the height on the field of the highest placed tetromino on the
field.
"""
for i, row in enumerate(self.state):
if ''.join(row).strip():
return Field.HEIGHT - i
if __name__ == '__main__':
import sys
f = Field()
if len(sys.argv) > 1 and sys.argv[1] == 'sim':
from optimizer import Optimizer
i = input()
while i != 'q':
t = Tetromino.create(i)
opt = Optimizer.get_optimal_drop(f, t)
t.rotate(opt['orientation'])
f.drop(t, opt['column'])
print(f)
i = input()
t = Tetromino.JTetromino().rotate_right()
print(t)
f.drop(t, 0)
print(f)
# f.drop(Tetromino.LTetromino(), 2)
# print(f)
# f.drop(Tetromino.JTetromino().rotate_left(), 5)
# print(f)
# t = Tetromino.LTetromino().flip()
# f.drop(t, 0)
# f.drop(Tetromino.TTetromino().flip(), 0)
# f.drop(Tetromino.JTetromino(), 4)
# print(f)

49
flappy.py Normal file
View File

@@ -0,0 +1,49 @@
import cv2 as cv
import pydirectinput
from game_base_class import GameBase
from flappy_pos_discovery_thread import FlappyPosDiscovery
from keyboard_thread import KeyboardEvent
class Flappy(GameBase):
def __init__(self, overlay):
super().__init__(overlay)
self.litris_reset_board = cv.imread("control_elements/sodoku_reset_button.jpg", cv.IMREAD_COLOR)
self.flappy_pos_disc = FlappyPosDiscovery()
self.keyboard_listener = KeyboardEvent()
def assess_playfield_and_make_move(self):
#last_letter_received = time()
while True:
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
wait_timer = 380 + self.keyboard_listener.offset_value
self.click()
cv.waitKey(wait_timer)
'''
if self.flappy_pos_disc.next_gate_height[0] is not 0:
offset = (self.flappy_pos_disc.next_gate_height[0] + 120) - self.flappy_pos_disc.get_actual_pet_height()
if offset > 50:
self.click()
cv.waitKey(int(wait_timer -100))
print("pet_pos: ", self.flappy_pos_disc.get_actual_pet_height())
if self.flappy_pos_disc.next_gate_height[0] is not 0:
offset = (self.flappy_pos_disc.next_gate_height[0] + 120) - self.flappy_pos_disc.current_pet_height
if offset > 50:
offset = 50
elif offset < -50:
offset = -50
print(offset)
wait_timer = 380 + offset
print(wait_timer)
print("pet_pos: ", self.flappy_pos_disc.current_pet_height)
print("next gate: ", self.flappy_pos_disc.next_gate_height[0] + 120) '''
def click(self):
pydirectinput.mouseDown()
cv.waitKey(50)
pydirectinput.mouseUp()

BIN
flappy/flappy-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

BIN
flappy/flappy.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
flappy/flappy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
flappy/gate-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
flappy/gate.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
flappy/gate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 KiB

BIN
flappy/screen.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

View File

@@ -0,0 +1,83 @@
import threading
import cv2 as cv
from window_capture import WindowCapture
from vision import Vision
from config_file import UserConfigs
class FlappyPosDiscovery(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.config = UserConfigs()
self.capture_window = WindowCapture(None, None, self.config)
self.vision_stun = Vision()
self.needle_f = self.scale_picture(cv.imread("flappy/flappy.jpg"), 50)
self.mask_f = self.scale_picture(cv.imread("flappy/flappy-mask.png"), 50)
self.needle_g = self.scale_picture(cv.imread("flappy/gate.jpg"), 50)
self.mask_g = self.scale_picture(cv.imread("flappy/gate-mask.png"), 50)
self.run_mode = 'run'
self.current_pet_height = []
self.next_gate_height = [0,0,0]
self.offset_down = 90
self.start()
def run(self):
while self.run_mode == 'run':
screenshot_g = self.scale_picture(self.capture_window.get_screenshot_by_area([700, 1200, 1860, 90]), 50)
screenshot_f = self.scale_picture(self.capture_window.get_screenshot_by_area([200, 1250, 610, 90]), 50)
#cv.imshow("screenshot_g", screenshot_f)
#cv.waitKey(150)
rectangles_g = self.vision_stun.find(screenshot_g, self.needle_g, 0.8, 1)
rectangles_f = self.vision_stun.find(screenshot_f, self.needle_f, 0.7, 1) #, True, self.mask_f)
if len(rectangles_g) is not 0:
height = rectangles_g[0][1] + rectangles_g[0][3] + (self.offset_down /2)
if self.next_gate_height[2] is not height:
self.next_gate_height.append(height)
if len(self.next_gate_height) > 3:
self.next_gate_height.pop(0)
#pro_screen = self.vision_stun.draw_rectangles(screenshot_g, rectangles_g)
#cv.imshow("screenshot_g", pro_screen)
#cv.waitKey(150)
else:
pass
if len(rectangles_f) is not 0:
self.current_pet_height.append(rectangles_f[0][1] + rectangles_f[0][3] + self.offset_down)
if len(self.current_pet_height) > 5:
self.current_pet_height.pop(0)
#print("pet_pos: ", self.current_pet_height)
#print("next gate: ", self.next_gate_height)
def scale_picture(self, img, scale_percent):
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
resized_img = cv.resize(img, (width, height), interpolation=4)
gray = cv.cvtColor(resized_img, cv.COLOR_BGR2GRAY)
thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
return thresh
def get_actual_pet_height(self):
return sum(self.current_pet_height) / len(self.current_pet_height)
def get_next_gate_height(self):
return self.next_gate_height

167
fruit.py Normal file
View File

@@ -0,0 +1,167 @@
import cv2 as cv
import numpy as np
from utils import mse
from game_base_class import GameBase
GREEN = 1
YELLOW = 2
RED = 3
BLUE = 4
ORANGE = 5
class Fruit(GameBase):
def __init__(self, overlay):
super().__init__(overlay)
self.data_coordinates = np.zeros((7, 11), dtype=object)
self.observation = np.zeros((7, 11), dtype=int)
self.colors = [GREEN, YELLOW, RED, BLUE, ORANGE]
self.offset_left = 390
self.offset_down = 188
self.fill_data_coordinates()
self.needles = {GREEN: cv.imread("fruit/green.jpg", cv.IMREAD_COLOR),
YELLOW: cv.imread("fruit/yellow.jpg", cv.IMREAD_COLOR),
BLUE: cv.imread("fruit/blue.jpg", cv.IMREAD_COLOR),
RED: cv.imread("fruit/red.jpg", cv.IMREAD_COLOR),
ORANGE: cv.imread("fruit/orange.jpg", cv.IMREAD_COLOR)
}
def fill_data_coordinates(self):
# 553 to 1861 = 1330 / 11 = 119
# 188 to 1022 = 1076 / 7 = 119
# 390 to 2000 = 1610 / 11 = 143
# 188 to 1210 = 1076 / 7 = 119
dim = 143
for e in range(0, 7, 1):
for i in range(0, 11, 1):
self.data_coordinates[e][i] = [i * dim, e * dim, dim, dim]
def assess_playfield_and_make_move(self):
new_observation, new_screenshot = self.get_current_board_state()
# wrong movement detection
# last board state is same as actual
if mse(new_observation, self.observation) == 0.0:
# no movement detected -> blow explosives or reset
self.reset_counter += 1
if self.reset_counter == 1:
pass
elif self.reset_counter == 2:
pass
elif self.reset_counter >= 3:
screenshot = self.capture_window.get_screenshot()
if self.check_for_button_and_execute(screenshot, self.reset_board):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
if self.check_for_button_and_execute(screenshot, self.reset_confirm):
cv.waitKey(500)
self.reset_counter = 0
return
else:
return
self.find_patterns_and_valid_moves(new_observation)
self.observation = new_observation
return new_observation
def get_current_board_state(self):
# get an updated image of the game
screenshot = self.capture_window.get_screenshot()
#screenshot = screenshot[900:1030, 540:1870]
# screenshot = cv.imread("field_farm.jpg")
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
if self.check_for_button_and_execute(screenshot, self.ok_button):
cv.waitKey(500)
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[188:1210, 390:2000]
# 553 to 1861 = 1330 / 11 = 119
# 188 to 1022
#cv.imshow("screenshot", screenshot)
#cv.waitKey(150)
# continue
data_coords = np.zeros((7, 11), dtype=object)
# field = Pickaxe_Field()
for needle_key in self.needles.keys():
# gray_needle = cv.cvtColor(self.needles[needle_key], cv.COLOR_BGR2GRAY)
# thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.78, 56)
#output_image = self.vision_stun.draw_rectangles(screenshot, rectangles)
#cv.imshow("output_image", output_image)
#cv.waitKey(150)
if len(rectangles) == 0:
continue
points = self.vision_stun.get_click_points(rectangles)
for point in points:
x, y = self.point_in_rect(point)
if x is not None and y is not None:
data_coords[x][y] = int(needle_key)
# self.change_value(x, y, int(needle_key))
# print(field.data_value_grid)
# cv.circle(screenshot, points[0], 7, (0, 255, 0), -1)
# output_image = vision_stun.draw_rectangles(screenshot, rectangles)
# cv.imshow("output_image", output_image)
# cv.waitKey(150)
return data_coords, screenshot
def point_in_rect(self, point):
for e in range(0, 7, 1):
for i in range(0, 11, 1):
x1, y1, w, h = self.data_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if x1 < x and x < x2:
if y1 < y and y < y2:
return e, i
return None, None
def find_patterns_and_valid_moves(self, state):
for e in range(0, 7, 1):
for i in range(0, 11, 1):
if state[e, i] in self.colors:
#color in self.colors:
if self.check_pairs_h(state, e, i):
return
if self.check_pairs_v(state, e, i):
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
def check_pairs_h(self, state, e, i):
try:
#
if state[e, i] == state[e + 1, i]:
click_pt = self.get_click_point(self.data_coordinates[e, i])
self.dig_point(click_pt[0] + self.offset_left, click_pt[1] + self.offset_down, 100)
return True
return False
except:
return False
def check_pairs_v(self, state, e, i):
try:
#
if state[e, i] == state[e, i + 1]:
click_pt = self.get_click_point(self.data_coordinates[e, i])
self.dig_point(click_pt[0] + self.offset_left, click_pt[1] + self.offset_down, 100)
return True
return False
except:
return False

BIN
fruit/blue.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
fruit/green.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
fruit/orange.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
fruit/red.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
fruit/yellow.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

279
game_base_class.py Normal file
View File

@@ -0,0 +1,279 @@
import pydirectinput
import random
import cv2 as cv
import numpy as np
from window_capture import WindowCapture
from vision import Vision
from config_file import UserConfigs
from time import time
GREEN = 1
YELLOW = 2
RED = 3
BLUE = 4
PURPLE = 5
RAINBOW = 6
BIGBOMB = 7
BOMB = 8
ARROW_DOWN = 9
ARROW_RIGHT = 10
ROCK_1 = 11
ROCK_2 = 12
ROCK_3 = 13
BURGER = 14
PAB1 = 15
GOLDBAR = 16
MAGINENT = 21
CHEMTRANT = 22
TENESENT = 23
CIBUTRANT = 24
ARTISENT = 25
MINING_LARGE = True
class GameBase:
def __init__(self, overlay):
self.overlay = overlay
self.data_value_grid = np.zeros((8, 14), dtype=int)
self.data_coordinates = np.zeros((8, 14), dtype=object)
self.observation = np.zeros((8, 14), dtype=int)
self.data_score_map = np.zeros((8, 14), dtype=int)
self.explosives = [RAINBOW, ARROW_RIGHT, ARROW_DOWN, BIGBOMB, BOMB]
self.colors = [GREEN, YELLOW, RED, BLUE, MAGINENT, CHEMTRANT, TENESENT, CIBUTRANT, ARTISENT]
self.next_level = cv.imread("control_elements/next_level.jpg", cv.IMREAD_COLOR)
self.next_level_x = cv.imread("control_elements/next_level_x.jpg", cv.IMREAD_COLOR)
self.reset_board = cv.imread("control_elements/reset_button.jpg", cv.IMREAD_COLOR)
self.reset_confirm = cv.imread("control_elements/reset_confirm.jpg", cv.IMREAD_COLOR)
self.ok_button = cv.imread("control_elements/ok_button.jpg", cv.IMREAD_COLOR)
self.reset_counter = 0
self.stop_time = overlay.global_timeout_use.get()
self.breaks = overlay.hourly_breaks_use.get()
self.break_time = overlay.break_duration_use.get()
# initialize the user-class
self.config = UserConfigs()
# initialize the StunWindowCapture class
self.capture_window = WindowCapture(None, None, self.config)
# initialize the StunVision class
self.vision_stun = Vision()
def execute_main_loop(self):
start_time = time()
breaks = self.init_breaks()
while True:
self.check_breaks(start_time, breaks)
if self.overlay.run_mode == 'paused':
cv.waitKey(1)
continue
elif self.overlay.run_mode == 'stopped':
break
elif self.overlay.run_mode == 'finished':
break
self.assess_playfield_and_make_move()
cv.waitKey(500)
def init_breaks(self):
breaks = []
if int(self.breaks) == 0:
return breaks
#breaks.append(7)
for i in range(1, int(self.breaks) + 1, 1):
avr_in_sec = int(self.stop_time) * 60 * 60 / int(self.breaks)
breaks.append(random.randint(int(i * avr_in_sec * 0.60), int(i * avr_in_sec)))
return breaks
def check_breaks(self, start_time, breaks):
if int(self.stop_time) == 0:
return
if (time() - start_time) > float(self.stop_time) * 60 * 60:
self.overlay.run_mode = 'stopped'
for break_ in breaks:
elapsed = int(time() - start_time)
if elapsed > break_:
pause = random.randint(1, 3)
self.overlay.update_status_label("Break: " + str(pause) + "m")
cv.waitKey(pause * 60 * 1000)
breaks.remove(break_)
self.overlay.update_status_label("running")
def assess_playfield_and_make_move(self):
pass
#screenshot = screenshot[190:1230, 260:2090]
#[58: 1134, 230: 2113]
def fill_data_coordinates(self):
# 260 to 2090 = 1883 / 14 = 130
# 190 to 1230 = 1076 / 8 = 130
dim = 130
for e in range(0, 8, 1):
for i in range(0, 14, 1):
self.data_coordinates[e][i] = [i * dim, e * dim, dim, dim]
def check_for_button_and_execute(self, screen, needle, offset_left=0, offset_down=0):
rectangles = self.vision_stun.find(screen, needle, 0.70, 1)
if len(rectangles) == 0:
return False
point = self.vision_stun.get_click_points(rectangles)[0]
self.dig_point(point[0] + offset_left, point[1] + offset_down, 500)
return True
def check_for_next_level(self, screen, needle):
offset_left = 260
offset_down = 190
rectangles = self.vision_stun.find(screen, needle, 0.70, 1)
if len(rectangles) == 0:
return False
if self.detonate_explosive_when_stuck(self.observation):
return True
point = self.vision_stun.get_click_points(rectangles)[0]
self.dig_point(point[0] + offset_left, point[1] + offset_down, 500)
return True
def detonate_explosive_when_stuck(self, state):
for e in range(0, 8, 1):
for i in range(0, 14, 1):
for explosive in self.explosives:
if self.local_pos_check(state, e, i, 0, 0, explosive):
src_pt = self.get_click_point(self.data_coordinates[e, i])
if self.local_pos_checks(state, e, i, 1, 0, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e + 1, i])
self.move_tile(src_pt, dest_pt)
return True
elif self.local_pos_checks(state, e, i, 0, 1, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e, i + 1])
self.move_tile(src_pt, dest_pt)
return True
elif self.local_pos_checks(state, e, i, -1, 0, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
return True
elif self.local_pos_checks(state, e, i, 0, -1, self.colors):
dest_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
return True
else:
continue
return False
def check_explosives(self, state, e, i):
for explosive in self.explosives:
if self.local_pos_check(state, e, i, 0, 0, explosive):
dest_pt = self.get_click_point(self.data_coordinates[e, i])
if self.local_pos_checks(state, e, i, 1, 0, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e + 1, i])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, 0, 1, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e, i + 1])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, -1, 0, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e - 1, i])
self.move_tile(src_pt, dest_pt)
elif self.local_pos_checks(state, e, i, 0, -1, self.explosives):
src_pt = self.get_click_point(self.data_coordinates[e, i - 1])
self.move_tile(src_pt, dest_pt)
else:
continue
return True
else:
continue
return False
@staticmethod
def is_direction_in_bounce_and_same_color(state, loc, color):
x, y = loc
if x <= 7 and x >= 0 and y <= 13 and y >= 0:
if state[x, y] == color:
return 1
return 0
@staticmethod
def local_pos_check(state, e, i, e_check, i_check, needle):
if e + e_check >= 0 and e + e_check <= 7 and i + i_check >= 0 and i + i_check <= 13:
if state[e + e_check, i + i_check] == needle:
return True
else:
return False
@staticmethod
def local_pos_checks(state, e, i, e_check, i_check, needles):
if e + e_check >= 0 and e + e_check <= 7 and i + i_check >= 0 and i + i_check <= 13:
for needle in needles:
if state[e + e_check, i + i_check] == needle:
return True
else:
continue
return False
@staticmethod
def get_click_point(rectangle):
# Loop over all the rectangles
x, y, w, h = rectangle
# Determine the center position
center_x = x + int(w / 2)
center_y = y + int(h / 2)
# Save the points
return int(center_x), int(center_y)
def move_tile(self, point_source, point_dest):
offset_left = 260
offset_down = 190
pydirectinput.moveTo(point_source[0] + offset_left, point_source[1] + offset_down)
# pydirectinput.moveTo(0,0)
pydirectinput.mouseDown()
w = random.randint(25, 50)
cv.waitKey(100 + w)
pydirectinput.moveTo(point_dest[0] + offset_left, point_dest[1] + offset_down)
pydirectinput.mouseUp()
cv.waitKey(400 + w)
def check_for_button_and_click_it(self, button_url):
screenshot = self.capture_window.get_screenshot()
# gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY)
# thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
# gray_needle = cv.cvtColor(cv.imread(button_url, cv.IMREAD_UNCHANGED), cv.COLOR_BGR2GRAY)
# thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
needle = cv.imread(button_url, cv.IMREAD_UNCHANGED)
# rectangles = self.vision_stun.find(thresh, thresh_needle, 0.4, 1)
rectangles = self.vision_stun.find(screenshot, needle, 0.7, 1)
if len(rectangles) == 1:
pointis = self.vision_stun.get_click_points(rectangles)
for pointi in pointis:
self.dig_point(pointi[0], pointi[1], 150)
@staticmethod
def dig_point(point1, point2, dig_time):
pydirectinput.moveTo(point1, point2)
cv.waitKey(dig_time)
pydirectinput.mouseDown()
w = random.randint(50, 100)
cv.waitKey(w)
pydirectinput.mouseUp()
@staticmethod
def move_to(x, y):
point_src = (1113, 598)
pydirectinput.moveTo(point_src[0], point_src[1])
pydirectinput.mouseDown()
w = random.randint(1, 100)
cv.waitKey(150 + w)
pydirectinput.moveTo(x, y)
pydirectinput.mouseUp()
cv.waitKey(500 + w)
def point_in_rect(self, point):
for e in range(0, 8, 1):
for i in range(0, 14, 1):
x1, y1, w, h = self.data_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if x1 < x and x < x2:
if y1 < y and y < y2:
return e, i
return None, None

32
keyboard_thread.py Normal file
View File

@@ -0,0 +1,32 @@
import threading
import cv2 as cv
import keyboard
class KeyboardEvent(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.run_mode = 'run'
self.offset_value = 0
self.start()
def run(self):
while self.run_mode == 'run':
if keyboard.is_pressed('up'): # if key 'q' is pressed
self.offset_value = -75
elif keyboard.is_pressed('down'):
self.offset_value = 75
elif keyboard.is_pressed('left') or keyboard.is_pressed('right'):
self.offset_value = 0
cv.waitKey(10)
def callback(self):
pass
def destroy(self):
self.destroy()
def get_run_mode(self):
return self.run_mode

235
litris.py Normal file
View File

@@ -0,0 +1,235 @@
from copy import copy
import cv2 as cv
import numpy as np
from time import time
from game_base_class import GameBase
from pynput.keyboard import Key, Controller
from field import Field
from tetromino import Tetromino
from optimizer import Optimizer
from litris_stone_id_thread import NewStoneID
class Litris(GameBase):
def __init__(self, overlay):
super().__init__(overlay)
self.keyboard = Controller()
self.offset_left = 610
self.offset_down = 40
self.field = Field()
self.litris_reset_board = cv.imread("control_elements/sodoku_reset_button.jpg", cv.IMREAD_COLOR)
self.stone_id_thread = NewStoneID()
self.move_mode = 1
self.moved_around_full = False
self.field_state_storage = {
1: self.field,
2: self.field,
3: self.field,
4: self.field
}
def reset(self):
self.field.reset_field()
self.field.cleared_rows = 1
self.move_mode = 1
self.moved_around_full = False
def assess_playfield_and_make_move(self):
last_letter_received = time()
while True:
if self.stone_id_thread.get_pick_up_status() == False:
if (time() - last_letter_received) >= 5:
self.reset()
last_letter_received = time()
self.dig_point(1500, 980, 100)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
continue
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
cv.waitKey(25)
continue
current_letter = self.stone_id_thread.get_actual_letter()
print("current_letter: ", current_letter)
last_letter_received = time()
current_tetromino = Tetromino.create(current_letter)
if self.move_mode == 2:
current_tetromino.rotate(3)
elif self.move_mode == 3:
current_tetromino.rotate(2)
elif self.move_mode == 4:
current_tetromino.rotate(1)
opt = Optimizer.get_optimal_drop(self.field, current_tetromino)
rotation = opt['tetromino_rotation']
column = opt['tetromino_column']
print("Rota:", rotation)
print("column:", column)
current_tetromino.rotate(rotation)
offset_col = current_tetromino.get_offset_column(rotation, self.move_mode)
print("offset column:", offset_col)
self.field.drop(current_tetromino, column)
self.move_stone(column - offset_col, rotation)
self.drop_down()
print(self.field)
if self.field.get_line_count() >= 6 and self.field.height() <= 2 and self.field.check_crucial_pos_to_be_free():
if self.field.predict_gaps_in_next_rotation() <= 3:
self.field_state_storage[self.move_mode] = copy(self.field)
self.update_move_mode()
#self.field.state = self.stone_id_thread.get_current_board_state()
self.field.rotate_state()
#self.update_move_mode()
self.field.reset_half_field()
self.update_field_with_stored_edges()
#field_mem = copy(self.field)
#self.field = copy(self.field_mem)
#self.field_mem = copy(field_mem)
self.field.cleared_rows = 1
cv.waitKey(100)
self.stone_id_thread.set_pick_up_status(False)
def update_field_with_stored_edges(self):
if self.move_mode == 1 and self.moved_around_full:
state_copy = Field.rotate_90_degree_clckwise(copy(self.field_state_storage[2].state))
for i in range(11,20,1):
for e in range(0,2,1):
self.field.state[i][e] = state_copy[i][e]
elif self.move_mode == 2 and self.moved_around_full:
state_copy = Field.rotate_90_degree_clckwise(copy(self.field_state_storage[3].state))
for i in range(11,20,1):
for e in range(0,2,1):
self.field.state[i][e] = state_copy[i][e]
elif self.move_mode == 3 and self.moved_around_full:
state_copy = Field.rotate_90_degree_clckwise(copy(self.field_state_storage[4].state))
for i in range(11, 20, 1):
for e in range(0, 2, 1):
self.field.state[i][e] = state_copy[i][e]
elif self.move_mode == 4:
state_copy = Field.rotate_90_degree_clckwise(copy(self.field_state_storage[1].state))
for i in range(11,20,1):
for e in range(0,2,1):
self.field.state[i][e] = state_copy[i][e]
self.moved_around_full = True
def drop_down(self):
if self.move_mode == 1:
down = Key.down
left = Key.left
right = Key.right
elif self.move_mode == 2:
down = Key.left
left = Key.up
right = Key.down
elif self.move_mode == 3:
down = Key.up
left = Key.right
right = Key.left
elif self.move_mode == 4:
down = Key.right
left = Key.down
right = Key.up
for i in range(1, 10, 1):
self.keyboard.press(down)
self.keyboard.release(down)
print("drop down pressed:", down)
cv.waitKey(40)
def update_move_mode(self):
if self.move_mode <=3:
self.move_mode = self.move_mode + 1
elif self.move_mode == 4:
self.move_mode = 1
def move_stone(self, col_movement, rotation):
if col_movement is None:
return
if self.move_mode == 1:
down = Key.down
left = Key.left
right = Key.right
elif self.move_mode == 2:
down = Key.left
left = Key.up
right = Key.down
elif self.move_mode == 3:
down = Key.up
left = Key.right
right = Key.left
elif self.move_mode == 4:
down = Key.right
left = Key.down
right = Key.up
# Press and release space
self.keyboard.press(down)
self.keyboard.release(down)
print("direction pressed: ", down)
cv.waitKey(60)
if rotation == 3:
self.keyboard.press('e')
self.keyboard.release('e')
print("rotation 1 pressed: e")
cv.waitKey(30)
elif rotation == 2:
self.keyboard.press('e')
self.keyboard.release('e')
print("rotation 2 pressed: e 1")
cv.waitKey(30)
self.keyboard.press('e')
self.keyboard.release('e')
print("rotation 2 pressed: e 2")
cv.waitKey(30)
elif rotation == 1:
self.keyboard.press('e')
self.keyboard.release('e')
print("rotation 3 pressed: e 1")
cv.waitKey(30)
self.keyboard.press('e')
self.keyboard.release('e')
print("rotation 3 pressed: e 2")
cv.waitKey(30)
self.keyboard.press('e')
self.keyboard.release('e')
print("rotation 3 pressed: e 3")
cv.waitKey(30)
if col_movement < 0:
for i in range(0, col_movement, - 1):
self.keyboard.press(left)
self.keyboard.release(left)
print("move left 3 pressed:", left)
cv.waitKey(30)
else:
for i in range(0, col_movement, 1):
self.keyboard.press(right)
self.keyboard.release(right)
print("move right 3 pressed:", right)
cv.waitKey(30)
def point_in_rect(self, point):
for e in range(0, 20, 1):
for i in range(0, 20, 1):
x1, y1, w, h = self.data_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if x1 < x and x < x2:
if y1 < y and y < y2:
return e, i
return None, None

BIN
litris/A-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

BIN
litris/A.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
litris/A.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
litris/B-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

BIN
litris/B.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
litris/B.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
litris/C-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

BIN
litris/C.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
litris/C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
litris/D-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
litris/D.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
litris/D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
litris/I-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

BIN
litris/I.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
litris/I.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
litris/J-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

BIN
litris/J.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
litris/J.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
litris/L-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

BIN
litris/L.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
litris/L.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
litris/O-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

BIN
litris/O.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
litris/O.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
litris/S-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

BIN
litris/S.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
litris/S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
litris/T-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

BIN
litris/T.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
litris/T.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
litris/Z-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

BIN
litris/Z.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
litris/Z.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
litris/blue_needle.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
litris/main_playfield.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

193
litris_stone_id_thread.py Normal file
View File

@@ -0,0 +1,193 @@
import threading
import cv2 as cv
import numpy as np
from window_capture import WindowCapture
from vision import Vision
from config_file import UserConfigs
O_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]
D_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0]]
L_FULL = [[0, 0, 0, 0], [0, 0, 1, 0], [1, 1, 1, 0], [0, 0, 0, 0]]
J_FULL = [[0, 0, 0, 0], [1, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0]]
I_FULL = [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]]
C_FULL = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
B_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
A_FULL = [[0, 0, 0, 0], [0, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]]
S_FULL = [[0, 0, 0, 0], [0, 0, 1, 1], [0, 1, 1, 0], [0, 0, 0, 0]]
Z_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 1, 1], [0, 0, 0, 0]]
T_FULL = [[0, 0, 0, 0], [0, 1, 1, 1], [0, 0, 1, 0], [0, 0, 0, 0]]
class NewStoneID(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.config = UserConfigs()
self.capture_window = WindowCapture(None, None, self.config)
self.vision_stun = Vision()
self.stone_coordinates = np.zeros((4, 4), dtype=object)
self.data_coordinates = np.zeros((20, 20), dtype=object)
self.fill_data_coordinates()
self.needles = {'Q': cv.imread("litris/blue_needle.jpg", cv.IMREAD_UNCHANGED)}
self.run_mode = 'run'
self.actual_letter = ""
self.to_pick_up = False
self.start()
def run(self):
while self.run_mode == 'run':
current_stone = self.new_stone_detection()
if current_stone is None:
cv.waitKey(50)
continue
else:
current_letter = self.get_letter_for_stone(current_stone)
if current_letter is None:
continue
else:
self.actual_letter = current_letter
self.to_pick_up = True
while self.to_pick_up:
cv.waitKey(10)
self.actual_letter = ""
def get_actual_letter(self):
return self.actual_letter
def set_pick_up_status(self, status):
self.to_pick_up = status
def get_pick_up_status(self):
return self.to_pick_up
def callback(self):
pass
def destroy(self):
self.destroy()
def get_run_mode(self):
return self.run_mode
def new_stone_detection(self):
screenshot = self.capture_window.get_screenshot()
screenshot = screenshot[580:845, 1148:1412]
rectangles = self.vision_stun.find(screenshot, self.needles['Q'], 0.85, 16)
if len(rectangles) == 0:
return None
points = self.vision_stun.get_click_points(rectangles)
stone_coords = np.zeros((4, 4), dtype=object)
for point in points:
x, y = self.point_in_small_rect(point)
if x is not None and y is not None:
stone_coords[x][y] = 1
# self.change_value(x, y, int(needle_key))
# print(field.data_value_grid)
#cv.circle(screenshot, points[0], 7, (0, 255, 0), -1)
#output_image = self.vision_stun.draw_rectangles(screenshot, rectangles)
#cv.imshow("output_image", output_image)
#cv.waitKey(150)
return stone_coords
def get_letter_for_stone(self, stone):
if np.array_equal(stone, O_FULL):
return "O"
elif np.array_equal(stone, D_FULL):
return "D"
elif np.array_equal(stone, L_FULL):
return "L"
elif np.array_equal(stone, J_FULL):
return "J"
elif np.array_equal(stone, I_FULL):
return "I"
elif np.array_equal(stone, C_FULL):
return "C"
elif np.array_equal(stone, B_FULL):
return "B"
elif np.array_equal(stone, A_FULL):
return "A"
elif np.array_equal(stone, S_FULL):
return "S"
elif np.array_equal(stone, Z_FULL):
return "Z"
elif np.array_equal(stone, T_FULL):
return "T"
else:
return None
def point_in_small_rect(self, point):
for e in range(0, 4, 1):
for i in range(0, 4, 1):
x1, y1, w, h = self.stone_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if x1 < x and x < x2:
if y1 < y and y < y2:
return e, i
return None, None
def get_current_board_state(self):
# get an updated image of the game
screenshot = self.capture_window.get_screenshot()
#screenshot = cv.imread("litris/main_playfield.jpg")
screenshot = screenshot[40:1380, 610:1950] # 1000,1000
# cv.imshow("screenshot", screenshot)
# cv.waitKey(150)
# continue
#data_coords = np.zeros((20, 20), dtype=object)
data_coords = np.full((20, 20), ' ', dtype=object)
#field = Pickaxe_Field()
for needle_key in self.needles.keys():
#gray_needle = cv.cvtColor(self.needles[needle_key], cv.COLOR_BGR2GRAY)
#thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.8, 200)
if len(rectangles) == 0:
continue
points = self.vision_stun.get_click_points(rectangles)
for point in points:
x, y = self.point_in_rect(point)
if x is not None and y is not None:
data_coords[x][y] = needle_key
#self.change_value(x, y, int(needle_key))
# print(field.data_value_grid)
# cv.circle(screenshot, points[0], 7, (0, 255, 0), -1)
#output_image = self.vision_stun.draw_rectangles(screenshot, rectangles)
#cv.imshow("output_image", output_image)
#cv.waitKey(150)
return data_coords.tolist()
def point_in_rect(self, point):
for e in range(0, 20, 1):
for i in range(0, 20, 1):
x1, y1, w, h = self.data_coordinates[e][i]
x2, y2 = x1 + w, y1 + h
x, y = point
if x1 < x and x < x2:
if y1 < y and y < y2:
return e, i
return None, None
def fill_data_coordinates(self):
# 610 to 1950 = 1340 - 76 / 20 = 63
# 40 to 1380 = 1340 - 76 / 20 = 63
# spacing 19 * 4
dim = 63
e_spacing = 4
i_spacing = 4
for e in range(0, 4, 1):
for i in range(0, 4, 1):
self.stone_coordinates[e][i] = [(i * dim) + (i * i_spacing), (e * dim) + (e * e_spacing), dim, dim]
for e in range(0, 20, 1):
for i in range(0, 20, 1):
self.data_coordinates[e][i] = [(i * dim) + (i * i_spacing), (e * dim) + (e * e_spacing), dim, dim]

192
magic.py
View File

@@ -1,25 +1,21 @@
import random
from window_capture import WindowCapture
from vision import Vision
import cv2 as cv
from hsvfilter import HsvFilter
from config_file import UserConfigs
import pydirectinput
from game_base_class import GameBase
from window_capture import WindowCapture
from utils import dig_point
class Magic:
class Magic(GameBase):
def __init__(self, overlay):
self.overlay = overlay
self.config = UserConfigs()
super().__init__(overlay)
self.SPAWN_COUNT = int(overlay.spawn_use.get())
self.capture_window = WindowCapture(None, "magic", self.config)
# initialize the StunVision class
self.vision_stun = Vision()
# initialize the StunOverlay class
hsv_filter_orange = HsvFilter(10, 156, 0, 17, 255, 255, 0, 0, 0, 0)
hsv_filter_p = HsvFilter(130, 156, 0, 179, 255, 255, 0, 0, 0, 0)
hsv_filter_b = HsvFilter(88, 156, 0, 128, 255, 255, 0, 0, 0, 0)
@@ -43,93 +39,104 @@ class Magic:
cv.IMREAD_UNCHANGED))
self.hsv_list.append(self.hsv_filter_list[key1])
def execute_main_loop(self):
def assess_playfield_and_make_move(self):
screenshot = self.capture_window.get_screenshot()
# screenshot = cv.imread("buffbar.jpg")
while True:
if self.overlay.run_mode == 'paused':
cv.waitKey(1)
continue
elif self.overlay.run_mode == 'stopped':
break
# cv.imshow("screenshot", screenshot)
# cv.waitKey(150)
# continue
screenshot = self.capture_window.get_screenshot()
# screenshot = cv.imread("buffbar.jpg")
spawn_1 = self.vision_stun.find(screenshot, cv.imread("magic/spawn_1.jpg", cv.IMREAD_UNCHANGED), 0.25, 1) #TODO fix emitter threshold
if len(spawn_1) == 1:
points = self.vision_stun.get_click_points(spawn_1)
for i in range(0, self.SPAWN_COUNT, 1):
pydirectinput.moveTo(points[0][0], points[0][1])
pydirectinput.mouseDown()
w = random.randint(1, 50)
cv.waitKey(30 + w)
pydirectinput.mouseUp()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
else:
spawn_0 = self.vision_stun.find(screenshot, cv.imread("magic/spawn_0.jpg", cv.IMREAD_UNCHANGED), 0.7, 1)
points = self.vision_stun.get_click_points(spawn_0)
for point in points:
pydirectinput.moveTo(point[0], point[1])
pydirectinput.mouseDown()
cv.waitKey(500)
pydirectinput.mouseUp()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
# for needles in needle_list:
for rer in range(0, len(self.needle_list), 1):
screenshot = self.capture_window.get_screenshot_by_area(self.config.returnOKWindowPos())
rectangles = self.vision_stun.find(screenshot, self.ok_button, 0.5, 1)
if len(rectangles) == 1:
pointis = self.vision_stun.get_click_points(rectangles)
for pointi in pointis:
dig_point(pointi[0] + self.config.returnOKWindowPos()[2],
pointi[1] + self.config.returnOKWindowPos()[3], 150)
cv.waitKey(2000)
while True:
screenshot = self.capture_window.get_screenshot()
processed_screenshot = self.vision_stun.apply_hsv_filter(screenshot, self.hsv_list[rer])
processed_needle = self.vision_stun.apply_hsv_filter(self.needle_list[rer], self.hsv_list[rer])
# cv.imshow("screenshot", screenshot)
# cv.waitKey(150)
# continue
rectangles = self.vision_stun.find(processed_screenshot, processed_needle, 0.7, 2)
# draw the detection results onto the original image
spawn_1 = self.vision_stun.find(screenshot, cv.imread("magic/spawn_1.jpg", cv.IMREAD_UNCHANGED), 0.4, 1)
if len(spawn_1) == 1:
points = self.vision_stun.get_click_points(spawn_1)
for i in range(0, self.SPAWN_COUNT, 1):
# only trigger ocr reading if a stun is detected
points = self.vision_stun.get_click_points(rectangles)
if len(points) == 2:
pydirectinput.moveTo(points[0][0], points[0][1])
pydirectinput.mouseDown()
w = random.randint(1, 50)
cv.waitKey(30 + w)
w = random.randint(1, 100)
cv.waitKey(250 + w)
pydirectinput.moveTo(points[1][0], points[1][1])
pydirectinput.mouseUp()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
else:
spawn_0 = self.vision_stun.find(screenshot, cv.imread("magic/spawn_0.jpg", cv.IMREAD_UNCHANGED), 0.7, 1)
points = self.vision_stun.get_click_points(spawn_0)
for point in points:
pydirectinput.moveTo(point[0], point[1])
pydirectinput.mouseDown()
cv.waitKey(500)
pydirectinput.mouseUp()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
continue
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
# for needles in needle_list:
for rer in range(0, len(self.needle_list), 1):
while True:
screenshot = self.capture_window.get_screenshot()
processed_screenshot = self.vision_stun.apply_hsv_filter(screenshot, self.hsv_list[rer])
processed_needle = self.vision_stun.apply_hsv_filter(self.needle_list[rer], self.hsv_list[rer])
rectangles = self.vision_stun.find(processed_screenshot, processed_needle, 0.7, 2)
# draw the detection results onto the original image
# only trigger ocr reading if a stun is detected
points = self.vision_stun.get_click_points(rectangles)
if len(points) == 2:
pydirectinput.moveTo(points[0][0], points[0][1])
pydirectinput.mouseDown()
w = random.randint(1, 100)
cv.waitKey(250 + w)
pydirectinput.moveTo(points[1][0], points[1][1])
pydirectinput.mouseUp()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
else:
break
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
else:
break
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
needles_white = [cv.imread("magic/body_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/finding_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/mind_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/perceiving_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/physical_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/seeing_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/spiritual_w.jpg", cv.IMREAD_UNCHANGED)]
needles_white = [cv.imread("magic/body_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/finding_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/mind_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/perceiving_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/physical_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/seeing_w.jpg", cv.IMREAD_UNCHANGED),
cv.imread("magic/spiritual_w.jpg", cv.IMREAD_UNCHANGED)]
for needle_w in needles_white:
# do object detection
for needle_w in needles_white:
# do object detection
screenshot = self.capture_window.get_screenshot()
processed_screenshot = self.vision_stun.apply_hsv_filter(screenshot, self.hsv_filter_w)
processed_needle = self.vision_stun.apply_hsv_filter(needle_w, self.hsv_filter_w)
rectangles = self.vision_stun.find(processed_screenshot, processed_needle, 0.7, 1)
# draw the detection results onto the original image
# output_image = vision_stun.draw_rectangles(screenshot, rectangles)
# cv.imshow("output_image", output_image)
# cv.waitKey(150)
points = self.vision_stun.get_click_points(rectangles)
if len(points) >= 1:
pydirectinput.moveTo(points[0][0], points[0][1])
pydirectinput.mouseDown()
w = random.randint(1, 100)
cv.waitKey(100 + w)
pydirectinput.mouseUp()
screenshot = self.capture_window.get_screenshot()
processed_screenshot = self.vision_stun.apply_hsv_filter(screenshot, self.hsv_filter_w)
processed_needle = self.vision_stun.apply_hsv_filter(needle_w, self.hsv_filter_w)
rectangles = self.vision_stun.find(processed_screenshot, processed_needle, 0.7, 1)
# draw the detection results onto the original image
# output_image = vision_stun.draw_rectangles(screenshot, rectangles)
# cv.imshow("output_image", output_image)
# cv.waitKey(150)
rectangles = self.vision_stun.find(screenshot, cv.imread("magic/collect.jpg", cv.IMREAD_UNCHANGED),
0.8,
1)
points = self.vision_stun.get_click_points(rectangles)
if len(points) >= 1:
pydirectinput.moveTo(points[0][0], points[0][1])
@@ -137,19 +144,8 @@ class Magic:
w = random.randint(1, 100)
cv.waitKey(100 + w)
pydirectinput.mouseUp()
screenshot = self.capture_window.get_screenshot()
rectangles = self.vision_stun.find(screenshot, cv.imread("magic/collect.jpg", cv.IMREAD_UNCHANGED),
0.8,
1)
points = self.vision_stun.get_click_points(rectangles)
if len(points) >= 1:
pydirectinput.moveTo(points[0][0], points[0][1])
pydirectinput.mouseDown()
w = random.randint(1, 100)
cv.waitKey(100 + w)
pydirectinput.mouseUp()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
break
return
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return

144
menti_dic Normal file
View File

@@ -0,0 +1,144 @@
HIT
IT
HI
POT
TOP
TO
HAS
ASH
HA
AS
AH
NOW
NO
ON
OWN
WON
WHEN
NEW
HE
WE
FORM
OR
OF
FROM
FOR
HIST
HIS
HITS
THIS
SIT
ITS
FIND
IF
FIN
IN
BEST
BET
SET
BE
HAT
NAT
TAN
ANT
AN
THAN
RACE
ACE
ACER
CARE
ERA
ARC
CAR
EAR
TEA
LATE
LET
ATE
EAT
TALE
HIRE
TIRE
THEIR
TIE
TIER
TAB
BOAT
BUT
OUT
ABOUT
AUTO
HER
HERO
OTHER
TOE
HOT
RICE
PRICE
RIP
PIE
RIPE
ICE
FIRST
FIST
SIR
FIT
FITS
SAT
TASTE
STATE
SEA
EAST
TEST
MAIL
EMAIL
MALE
LIE
AIM
MILE
FEAR
ART
RATE
AFTER
FAR
ARE
DEAF
FACE
CAFE
FED
FACED
INK
LINK
LINKS
SIN
SKIN
SKI
HERO

185
menti_words.py Normal file
View File

@@ -0,0 +1,185 @@
import cv2 as cv
import numpy as np
import pydirectinput
from nltk.corpus import words
from pytesseract import pytesseract
import utils
from utils import mse
from game_base_class import GameBase
import random
GREEN = 1
YELLOW = 2
RED = 3
BLUE = 4
ORANGE = 5
class MentiWords(GameBase):
def __init__(self, overlay):
super().__init__(overlay)
pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
self.observation = np.zeros((9, 9), dtype=int)
self.colors = [1, 2, 3, 4, 5, 6, 7, 8, 9]
self.offset_left = 1080
self.offset_down = 870
self.menti_play_button = cv.imread("control_elements/play.jpg", cv.IMREAD_COLOR)
self.needles = {
'A': cv.imread("menti_words/a.jpg", cv.IMREAD_COLOR),
'B': cv.imread("menti_words/b.jpg", cv.IMREAD_COLOR),
'C': cv.imread("menti_words/c.jpg", cv.IMREAD_COLOR),
'D': cv.imread("menti_words/d.jpg", cv.IMREAD_COLOR),
'E': cv.imread("menti_words/e.jpg", cv.IMREAD_COLOR),
'F': cv.imread("menti_words/f.jpg", cv.IMREAD_COLOR),
'H': cv.imread("menti_words/h.jpg", cv.IMREAD_COLOR),
'I': cv.imread("menti_words/i.jpg", cv.IMREAD_COLOR),
'L': cv.imread("menti_words/l.jpg", cv.IMREAD_COLOR),
'M': cv.imread("menti_words/m.jpg", cv.IMREAD_COLOR),
'N': cv.imread("menti_words/n.jpg", cv.IMREAD_COLOR),
'O': cv.imread("menti_words/o.jpg", cv.IMREAD_COLOR),
'P': cv.imread("menti_words/p.jpg", cv.IMREAD_COLOR),
'R': cv.imread("menti_words/r.jpg", cv.IMREAD_COLOR),
'S': cv.imread("menti_words/s.jpg", cv.IMREAD_COLOR),
'T': cv.imread("menti_words/t.jpg", cv.IMREAD_COLOR),
'U': cv.imread("menti_words/u.jpg", cv.IMREAD_COLOR),
'W': cv.imread("menti_words/w.jpg", cv.IMREAD_COLOR)
}
self.masks = {
'A': cv.imread("menti_words/a-mask.png", cv.IMREAD_COLOR),
'B': cv.imread("menti_words/b-mask.png", cv.IMREAD_COLOR),
'C': cv.imread("menti_words/c-mask.png", cv.IMREAD_COLOR),
'D': cv.imread("menti_words/d-mask.png", cv.IMREAD_COLOR),
'E': cv.imread("menti_words/e-mask.png", cv.IMREAD_COLOR),
'F': cv.imread("menti_words/f-mask.png", cv.IMREAD_COLOR),
'H': cv.imread("menti_words/h-mask.png", cv.IMREAD_COLOR),
'I': cv.imread("menti_words/i-mask.png", cv.IMREAD_COLOR),
'L': cv.imread("menti_words/l-mask.png", cv.IMREAD_COLOR),
'M': cv.imread("menti_words/m-mask.png", cv.IMREAD_COLOR),
'N': cv.imread("menti_words/n-mask.png", cv.IMREAD_COLOR),
'O': cv.imread("menti_words/o-mask.png", cv.IMREAD_COLOR),
'P': cv.imread("menti_words/p-mask.png", cv.IMREAD_COLOR),
'R': cv.imread("menti_words/r-mask.png", cv.IMREAD_COLOR),
'S': cv.imread("menti_words/s-mask.png", cv.IMREAD_COLOR),
'T': cv.imread("menti_words/t-mask.png", cv.IMREAD_COLOR),
'U': cv.imread("menti_words/u-mask.png", cv.IMREAD_COLOR),
'W': cv.imread("menti_words/w-mask.png", cv.IMREAD_COLOR)
}
self.current_letters = []
self.letter_coords = {}
with open("menti_dic") as file:
self.word_list = [line.rstrip() for line in file]
#self.word_list2 = words.words()
def reset_lists(self):
self.current_letters = []
self.letter_coords = {}
def assess_playfield_and_make_move(self):
if self.check_for_button_and_execute(self.capture_window.get_screenshot(), self.menti_play_button):
cv.waitKey(2000)
self.reset_lists()
self.get_current_board_state()
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
matches = self.possible_words(self.word_list, self.current_letters)
matches.sort()
new_matches = list(map(list,matches))
for letter_list in new_matches:
self.type_word_into_ui(letter_list)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
def type_word_into_ui(self, letters):
for letter in letters:
pydirectinput.moveTo(self.letter_coords[letter][0] + self.offset_left, self.letter_coords[letter][1] + self.offset_down)
pydirectinput.mouseDown()
w = random.randint(25, 50)
cv.waitKey(100 + w)
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
pydirectinput.mouseUp()
cv.waitKey(400)
def get_current_board_state(self):
#screenshot = cv.imread("menti_words/screenshot.jpg")
screenshot = self.capture_window.get_screenshot()
screenshot = utils.scale_screenshot(screenshot[870:1270, 1080:1480], 200, False)
#cv.imshow("screenshot", screenshot)
#cv.waitKey(150)
#continue
for needle_key in self.needles.keys():
# gray_needle = cv.cvtColor(self.needles[needle_key], cv.COLOR_BGR2GRAY)
# thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
thresh_needle = utils.scale_screenshot(self.needles[needle_key], 200, False)
rectangles = self.vision_stun.find(screenshot, thresh_needle , 0.85, 2)
#rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.95, 1 ,True, self.masks[needle_key])
if len(rectangles) == 0:
continue
points = self.vision_stun.get_click_points(rectangles)
for point in points:
self.current_letters.append(needle_key)
self.letter_coords[needle_key] = (int(point[0]/2), int(point[1]/2))
'''
cropped1 = self.vision_stun.draw_display_picture(screenshot, rectangles, 10)
#cropped1 = utils.scale_screenshot(cropped1)
cv.imshow("cropped1", cropped1)
cv.waitKey(150)
text_1 = pytesseract.image_to_string(cropped1, lang='eng', config='--psm 6').strip()
if str.isalpha(text_1):
#cv.imshow("cropped1", cropped1)
#cv.waitKey(150)
points = self.vision_stun.get_click_points(rectangles)
self.current_letters.append(text_1)
self.letter_coords[text_1] = points[0]'''
if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused':
return
def possible_words(self, lwords, charSet):
lst = []
for word in lwords:
if len(word) <= 1:
continue
flag = 1
chars = self.charCount(word)
for key in chars:
if key not in charSet:
flag = 0
else:
if charSet.count(key) != chars[key]:
flag = 0
if flag == 1:
lst.append(word)
#print(word)
return list(set(lst))
def charCount(self, word):
dict = {}
for i in word:
dict[i] = dict.get(i, 0) + 1
return dict

BIN
menti_words/a-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

BIN
menti_words/a.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
menti_words/a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
menti_words/b-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

BIN
menti_words/b.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
menti_words/b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
menti_words/c-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

BIN
menti_words/c.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
menti_words/c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
menti_words/d-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

BIN
menti_words/d.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
menti_words/d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
menti_words/e-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Some files were not shown because too many files have changed in this diff Show More