Nin Online için balık tutma botu yaptım, ama bazı kısımlarında problem var. Yardımcı olabilecek var mı ?

Üye
Katılım
14 Ağu 2025
Mesajlar
3
Tepki puanı
0
Yaş
20
oyunda balık tutmak için bot yaptım.(yapay zeka ile deneme yanılma yapa yapa) Ama mini game açıldığı zaman balığı yakalayacak kadar iyi çalıştıramadım.






import time
import pyautogui
import ctypes
import cv2
import numpy as np
from PIL import ImageGrab
import random
import os

# --- AYARLAR BÖLÜMÜ ---
MINI_GAME_SEARCH_REGION = (752, 580, 1157, 659)
FISH_HOOK_POINT = (669, 238)
MINIGAME_TEMPLATE_FILE = "minigame_template.png"
EXCLAMATION_TEMPLATE_FILE = "exclamation_mark.png"
# --------------------------------------------------------------------

# Windows API ve Tuş Kodları (Değiştirilmedi)
SendInput = ctypes.windll.user32.SendInput
PUL = ctypes.POINTER(ctypes.c_ulong)


class KeyBdInput(ctypes.Structure): _fields_ = [("wVk", ctypes.c_ushort), ("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong), ("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]


class HardwareInput(ctypes.Structure): _fields_ = [("uMsg", ctypes.c_ulong), ("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]


class MouseInput(ctypes.Structure): _fields_ = [("dx", ctypes.c_long), ("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong), ("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong), ("dwExtraInfo", PUL)]


class Input_I(ctypes.Union): _fields_ = [("ki", KeyBdInput), ("mi", MouseInput), ("hi", HardwareInput)]


class Input(ctypes.Structure): _fields_ = [("type", ctypes.c_ulong), ("ii", Input_I)]


def press_key(hexKeyCode): x = Input_I(); x.ki = KeyBdInput(0, hexKeyCode, 0x0008, 0,
ctypes.pointer(ctypes.c_ulong(0))); SendInput(1,
ctypes.pointer(
Input(1,
x)),
ctypes.sizeof(
Input))


def release_key(hexKeyCode): x = Input_I(); x.ki = KeyBdInput(0, hexKeyCode, 0x0008 | 0x0002, 0,
ctypes.pointer(ctypes.c_ulong(0))); SendInput(1,
ctypes.pointer(
Input(1,
x)),
ctypes.sizeof(
Input))


SCAN_5 = 0x06;
SCAN_SPACE = 0x39;
SCAN_LEFT = 0x4B;
SCAN_RIGHT = 0x4D;
SCAN_ESC = 0x01

# Şablon Yükleyiciler
MINIGAME_TEMPLATE = None
EXCLAMATION_TEMPLATE = None


def load_templates():
global MINIGAME_TEMPLATE, EXCLAMATION_TEMPLATE
if os.path.exists(MINIGAME_TEMPLATE_FILE):
MINIGAME_TEMPLATE = cv2.imread(MINIGAME_TEMPLATE_FILE, 0)
if MINIGAME_TEMPLATE is not None:
print(f"'{MINIGAME_TEMPLATE_FILE}' başarıyla yüklendi.")
else:
print(f"HATA: '{MINIGAME_TEMPLATE_FILE}' yüklenemedi.")
else:
print(f"HATA: '{MINIGAME_TEMPLATE_FILE}' dosyası bulunamadı!")
if os.path.exists(EXCLAMATION_TEMPLATE_FILE):
EXCLAMATION_TEMPLATE = cv2.imread(EXCLAMATION_TEMPLATE_FILE, 0)
if EXCLAMATION_TEMPLATE is not None: print(f"'{EXCLAMATION_TEMPLATE_FILE}' başarıyla yüklendi.")


# Mini Oyun Algılama Fonksiyonu (Değiştirilmedi)
def is_mini_game_started(confidence=0.8):
if MINIGAME_TEMPLATE is None: return False
try:
screenshot = ImageGrab.grab(bbox=MINI_GAME_SEARCH_REGION)
screenshot_gray = cv2.cvtColor(np.array(screenshot), cv2.COLOR_BGR2GRAY)
template_h, template_w = MINIGAME_TEMPLATE.shape
screenshot_h, screenshot_w = screenshot_gray.shape
if template_h > screenshot_h or template_w > screenshot_w:
print("\n\nHATA: 'minigame_template.png' dosyası arama bölgesinden daha büyük!");
print("Çözüm: 'MINI_GAME_SEARCH_REGION' koordinatlarını genişletin.")
time.sleep(10);
return False
result = cv2.matchTemplate(screenshot_gray, MINIGAME_TEMPLATE, cv2.TM_CCOEFF_NORMED)
_, max_val, _, _ = cv2.minMaxLoc(result)
print(f"\rDEBUG -> Mini oyun şablonu eşleşme skoru: {max_val:.2f}", end="")
if max_val >= confidence:
print(f"\nMini oyun şablonu bulundu! (Skor: {max_val:.2f} >= Eşik: {confidence}) Başlatılıyor...")
return True
except Exception as e:
print(f"\nis_mini_game_started hatası: {e}")
return False


# Balık Tutma ve Bekleme Fonksiyonları (Değiştirilmedi)
def find_exclamation_mark(x, y, search_radius=50, confidence=0.7):
if EXCLAMATION_TEMPLATE is None: return False
left, top = max(0, x - search_radius), max(0, y - search_radius)
right, bottom = pyautogui.size();
right, bottom = min(right, x + search_radius), min(bottom, y + search_radius)
screenshot = ImageGrab.grab(bbox=(left, top, right, bottom))
screenshot_gray = cv2.cvtColor(np.array(screenshot), cv2.COLOR_BGR2GRAY)
result = cv2.matchTemplate(screenshot_gray, EXCLAMATION_TEMPLATE, cv2.TM_CCOEFF_NORMED)
_, max_val, _, _ = cv2.minMaxLoc(result)
return max_val >= confidence


def throw_fishing_line():
press_key(SCAN_5);
time.sleep(random.uniform(0.04, 0.06));
release_key(SCAN_5)
time.sleep(random.uniform(1.4, 1.6))
press_key(SCAN_SPACE);
time.sleep(random.uniform(0.04, 0.06));
release_key(SCAN_SPACE)


def wait_for_fish_pixel(x, y, search_radius=75, confidence=0.7):
detection_count, required_detections = 0, 2
print("\nBalık ısırması bekleniyor...")
while True:
if find_exclamation_mark(x, y, search_radius, confidence):
detection_count += 1
if detection_count >= required_detections:
press_key(SCAN_SPACE);
time.sleep(random.uniform(0.04, 0.06));
release_key(SCAN_SPACE)
print("\nSpace tuşuna basıldı, balık çekiliyor...")
return True
else:
detection_count = 0
time.sleep(0.1)


# --- FİNAL NESNE BULMA MANTIĞI ---
def analyze_game_state(img_hsv):
lower_red1 = np.array([0, 120, 100]);
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([170, 120, 100]);
upper_red2 = np.array([180, 255, 255])
red_mask = cv2.bitwise_or(cv2.inRange(img_hsv, lower_red1, upper_red1),
cv2.inRange(img_hsv, lower_red2, upper_red2))
if cv2.countNonZero(red_mask) > 100:
return "TENSION", None, None

lower_blue = np.array([85, 50, 50]);
upper_blue = np.array([140, 255, 255])
background_mask = cv2.inRange(img_hsv, lower_blue, upper_blue)
object_mask = cv2.bitwise_not(background_mask)
kernel = np.ones((2, 2), np.uint8)
object_mask = cv2.morphologyEx(object_mask, cv2.MORPH_OPEN, kernel)
contours, _ = cv2.findContours(object_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

found_objects = []
for cnt in contours:
area = cv2.contourArea(cnt)
if 20 < area < 5000:
x, y, w, h = cv2.boundingRect(cnt)
M = cv2.moments(cnt)
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
found_objects.append({'cx': cx, 'width': w})

if len(found_objects) < 2: return "NORMAL", None, None

bar = max(found_objects, key=lambda obj: obj['width'])
target = min(found_objects, key=lambda obj: obj['width'])
return "NORMAL", bar['cx'], target['cx']


# --- FİNAL MİNİ OYUN MANTIĞI ---
def play_mini_game():
print("Mini oyun kontrolü devralınıyor...")
DEAD_ZONE = 4

# --- YENİ: Dinamik Bölgeyi Bulma Fonksiyonu ---
def find_real_game_region():
try:
screenshot = ImageGrab.grab(bbox=MINI_GAME_SEARCH_REGION)
screenshot_gray = cv2.cvtColor(np.array(screenshot), cv2.COLOR_BGR2GRAY)
result = cv2.matchTemplate(screenshot_gray, MINIGAME_TEMPLATE, cv2.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv2.minMaxLoc(result)
if max_val > 0.5: # Yeterli eşleşme varsa
game_x = MINI_GAME_SEARCH_REGION[0] + max_loc[0] - 5
game_y = MINI_GAME_SEARCH_REGION[1] + max_loc[1] - 5
game_w = 341;
game_h = 21
return (game_x, game_y, game_x + game_w, game_y + game_h)
except Exception:
return None
return None

REAL_MINI_GAME_REGION = find_real_game_region()
if REAL_MINI_GAME_REGION is None:
print("Mini oyun başlangıç konumu bulunamadı.")
return

time.sleep(0.1)

disappearance_counter = 0;
GAME_OVER_THRESHOLD = 50
last_print_time = time.time()
was_in_tension = False

while True:
img_bgr = cv2.cvtColor(np.array(ImageGrab.grab(bbox=REAL_MINI_GAME_REGION)), cv2.COLOR_RGB2BGR)
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
state, bar_cx, target_cx = analyze_game_state(img_hsv)

current_time = time.time()
if current_time - last_print_time >= 0.25:
print(f"DEBUG -> Durum: {state}, Bar: {bar_cx}, Hedef: {target_cx}")
last_print_time = current_time

if state == "TENSION":
disappearance_counter = 0
was_in_tension = True
time.sleep(0.05)
continue

if was_in_tension:
print("Yeniden odaklanılıyor...")
time.sleep(0.25)
# --- YENİ: BÖLGEYİ YENİDEN TARA ---
new_region = find_real_game_region()
if new_region:
REAL_MINI_GAME_REGION = new_region
print(f"Bölge güncellendi: {REAL_MINI_GAME_REGION}")
else:
print("Yeniden odaklanma sırasında bölge bulunamadı, oyun bitmiş olabilir.")
break
was_in_tension = False
continue

if bar_cx is not None and target_cx is not None:
disappearance_counter = 0
error = target_cx - bar_cx
if abs(error) > DEAD_ZONE:
tap_duration = max(0.01, min(abs(error) * 0.0012, 0.045))
if error > 0:
press_key(SCAN_RIGHT);
time.sleep(tap_duration);
release_key(SCAN_RIGHT)
else:
press_key(SCAN_LEFT);
time.sleep(tap_duration);
release_key(SCAN_LEFT)
else:
disappearance_counter += 1
if disappearance_counter > GAME_OVER_THRESHOLD:
print("\nNesneler kayboldu, mini oyunun bittiği varsayılıyor.")
break

print("\nMini oyun tamamlandı.")
press_key(SCAN_ESC);
time.sleep(0.05);
release_key(SCAN_ESC)
time.sleep(0.5)


# Ana Döngü
def main_loop():
x, y = FISH_HOOK_POINT
load_templates()
if MINIGAME_TEMPLATE is None: return

print("\nBot başlatıldı. 5 saniye içinde başlayacak...")
print("Botu durmak için terminalde CTRL+C tuşlarına basın.")
time.sleep(5)

while True:
try:
throw_fishing_line()
print("Oltayı attı...")
if wait_for_fish_pixel(x, y, search_radius=60, confidence=0.7):
print("\nMini oyun bekleniyor...")
time.sleep(1.2)
if is_mini_game_started(confidence=0.55):
play_mini_game()
else:
print("\nMini oyun başlamadı, devam ediliyor...")
time.sleep(random.uniform(1, 2))
except KeyboardInterrupt:
print("\nBot durduruldu.");
break
except Exception as e:
print(f"\nAna döngüde bir hata oluştu: {e}");
time.sleep(2)


if __name__ == "__main__":
main_loop()
 
Uzman Üye
Katılım
16 May 2018
Mesajlar
211
Çözümler
1
Tepki puanı
33
Ödüller
10
Yaş
30
8 HİZMET YILI
Oyunu bilmediğim için soruyom deneme yanılma yaptırmanı gerektircek bi bilgi mi var oyunda pozisyonu vs ekranda pixel olarak görmemiyon mu
 
Üst