3
\$\begingroup\$

I want to post my tiny program here and hope to get feedback improving the performance of my code and understanding Python better. My main issue is the slowness of the program and the corresponding bugs due to incorrect image checking since the game has already advanced in that time.

It's a slow 2D game that I try to control. Images are not switching too fast but also standing images won't always get recognized. After resizing the cut image or move the boundary by 1 pixel it gets realized more often.

I would also like to ask how I can get multi threaded here. I currently let the whole program sleep. After finishing the current function it takes a new screen shot and analyses it again. You can see those screenshot popping up in the Terminal Title bar.

Here is my experience in coding before, which took place in Java. As soon as one of the apps is testable, I will upload a version. In fact, a small map engine is shown on some forum I will attach if interested.

Finally, my current Python state.

import pyautogui
import time
pyautogui.FAILSAFE = True
DETECTED = False
ATTACK = True
LOOTED = 0
alive = True
DECIDED = False
detectedHand = False
im = pyautogui.screenshot()
#  warspear online bot --- RAILWANDERER 2016
def detecting():
    """Detect a mob x=800-1040"""
    im = pyautogui.screenshot(region=(840,150,1250,300))
    mobLocation = pyautogui.locate('side.png', im, grayscale=False)
    if mobLocation != None:
        mobx, moby = pyautogui.center(mobLocation)
        if mobx +840 < 1000:
            print('mob detected')
            pyautogui.click(mobx+810,moby+200,button='left')
            pyautogui.mouseDown(mobx+810,moby+200,button='left')
            pyautogui.mouseUp(mobx+810,moby+200,button='left')
            time.sleep(2)
            pyautogui.click(900,260,button='left')
            pyautogui.mouseDown(900,260,button='left')
            pyautogui.mouseUp(900,260,button='left')
            time.sleep(1)
            pyautogui.click(1160,210,button='left')
            pyautogui.mouseDown(1160,210,button='left')
            pyautogui.mouseUp(1160,210,button='left')
            time.sleep(5)
            im = pyautogui.screenshot(region=(1000,100,1250,300))
            mobLocation = pyautogui.locate('side.png', im, grayscale=False)
            if mobLocation != None:
                if mobx +1000 > 1070:
                    hiddenSpot()
                    detectHand()

        elif mobx+840 > 1070:
            print('check for sure')
            detectSword()
            detectHand()
            time.sleep(1)
            print('reset')
            pyautogui.click(1110,210,button='left')
            pyautogui.mouseDown(1110,210,button='left')
            pyautogui.mouseUp(1110,210,button='left')
            time.sleep(1)
            detectHand()
            pyautogui.click(1160,210,button='left')
            pyautogui.mouseDown(1160,210,button='left')
            pyautogui.mouseUp(1160,210,button='left')
        else:
            print('no mobs')
            pyautogui.click(1160,210,button='left')
            pyautogui.mouseDown(1160,210,button='left')
            pyautogui.mouseUp(1160,210,button='left')

# -------ATTACK
def attack():
    """attack"""
    print('attack')
    pyautogui.typewrite('6')
    time.sleep(2)
    pyautogui.typewrite('7')
    pyautogui.click(1111,210,button='left')
    pyautogui.mouseDown(1111,210,button='left')
    pyautogui.mouseUp(1111,210,button='left')
    pyautogui.typewrite('3')
    time.sleep(3)
    pyautogui.typewrite('3')
    pyautogui.typewrite('8')
# -------SWORD
def detectSword():
    """detectSword"""
    print('sword Check')
    pyautogui.click(1110,210,button='left')
    pyautogui.mouseDown(1110,210,button='left')
    pyautogui.mouseUp(1110,210,button='left')
    time.sleep(1)
    im = pyautogui.screenshot(region=(1070,180,1140,240))
    mobLocation = pyautogui.locate('best.png', im, grayscale=False)
    if(mobLocation != None):
        print('swordfound')
        mobx, moby = pyautogui.center(mobLocation)
        pyautogui.click(mobx+1070,moby+180,button='left')
        pyautogui.mouseDown(mobx+1070,moby+180,button='left')
        pyautogui.mouseUp(mobx+1070,moby+180,button='left')

        time.sleep(1)
        hiddenSpot()
# -------DETECT HAND
def detectHand():
    """hand"""
    im = pyautogui.screenshot(region=(1050,150,1150,250))
    mobLocation = pyautogui.locate('handd.png', im, grayscale=False)
    if(mobLocation != None):
        print('hand')
        mobx, moby = pyautogui.center(mobLocation)
        pyautogui.click(mobx+1050,moby+150,button='left')
        pyautogui.mouseDown(mobx+1050,moby+150,button='left')
        pyautogui.mouseUp(mobx+1050,moby+150,button='left')
        time.sleep(1)
        bag()
# -------BAG
def bag():
    """bag"""
    im = pyautogui.screenshot()
    mobLocation = pyautogui.locate('bag.png', im, grayscale=False)
    if mobLocation != None:
        print('bag')
        mobx, moby = pyautogui.center(mobLocation)
        pyautogui.click(mobx,moby,button='left')
        detectedMob = False
        ATTACK = False
        time.sleep(0.5)
        pyautogui.click(1160,210,button='left')
        global LOOTED
        LOOTED+=1
        print(str(LOOTED))
        time.sleep(0.5)
        DECIDED = True
# -------SPOT
def hiddenSpot():
    """hidden Spot"""
    im = pyautogui.screenshot(region=(1050,150,1150,250))
    if pyautogui.locate('empty.png', im, grayscale=False) == None:
        print('hidden spot')
        pyautogui.click(1111,210,button='left')
        pyautogui.mouseDown(1110,210,button='left')
        pyautogui.mouseUp(1110,210,button='left')
        attack()
        time.sleep(1)
        pyautogui.typewrite('3')
        pyautogui.typewrite('8')
        time.sleep(1)
        pyautogui.typewrite('8')
        time.sleep(9)
        print('attack finished')

        detectHand()
# -------NO
def no():
    """no"""
    im = pyautogui.screenshot()
    if pyautogui.locate('no.png',im,grayscale=False) != None:
        print('no')
        mobLocation = pyautogui.locate('no.png', im, grayscale=False)
        mobx, moby = pyautogui.center(mobLocation)
        pyautogui.click(mobx,moby,button='left')
        DECIDED = True
# -------AD
def ad():
    """ad"""
    im = pyautogui.screenshot()
    if pyautogui.locate('close.png',im,grayscale=False) != None:
        print('close')
        mobLocation = pyautogui.locate('close.png', im, grayscale=False)
        mobx, moby = pyautogui.center(mobLocation)
        pyautogui.click(mobx,moby,button='left')
        DECIDED = True
# -------INVITE
def invite():
    """invite"""
    im = pyautogui.screenshot()
    print('invite')
    print('no')
    pyautogui.click(720,390,button='left')
    time.sleep(1)
    DECIDED = True
# -------DEAL
def deal():
    """ad"""
    im = pyautogui.screenshot()
    if pyautogui.locate('close.png', im, grayscale=False) != None:
        print('ad')
        mobLocation = pyautogui.locate('close.png', im, grayscale=False)
        mobx, moby = pyautogui.center(mobLocation)
        pyautogui.click(mobx,moby,button='left')
        pyautogui.mouseDown(1160,210,button='left')
        pyautogui.mouseUp(1160,210,button='left')
        time.sleep(1)
        DECIDED = True
    print('Press Ctrl-C to quit.')
    try:
        while alive:
            #x, y = pyautogui.position()
            #positionStr = 'X: ' + str(x).rjust(4) + ' Y: ' + str(y).rjust(4)
            #print(positionStr, end='')
            #print('\b' * len(positionStr), end='', flush=True)

            #take screenshot
            global LOOTED
            LOOTED= 0
            while True:
                # -------DETECT DEATH
                if pyautogui.locate('revive.png',im,grayscale=False) != None:
                    print('death')
                    print('revive')
                    mobLocation = pyautogui.locate('revive.png', im, grayscale=False)
                    mobx, moby = pyautogui.center(mobLocation)
                    pyautogui.click(mobx,moby,button='left')
                    alive = False
                    decided = True

                # -------DETECT MOB
                detecting()
                im = pyautogui.screenshot()

                # -------DETECT BUY
                if pyautogui.locate('buy.png',im,grayscale=False) != None:
                    print('ad detected')
                    ad()
                # -------DETECT BUY
                if pyautogui.locate('no.png',im,grayscale=False) != None:
                    print('ad detected')
                    no()


                # -------DETECT INVITE
                if pyautogui.locate('invite.png', im, grayscale=False) != None:
                    invite()

                # -------DETECT DEAL
                if pyautogui.locate('deal.png', im, grayscale=False) != None:
                    deal()
        except KeyboardInterrupt:
        print('\nDone.')
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Asking for how to make the game multithreaded is off-topic here; we review what you wrote, we don't write code for you. \$\endgroup\$ Commented Feb 1, 2016 at 20:38
  • \$\begingroup\$ yes that would be nice! I will code myself, just give me a hint on how to structure this project in the future. I know i need to tell the loop to stop somehow while another loop constantly analyses screenshots as fast as possible. But I don't know how to interrupt so a keyword to find the basics would be kind :) \$\endgroup\$ Commented Feb 1, 2016 at 20:43

1 Answer 1

1
\$\begingroup\$

Layout

There should be blank lines between functions. The black program can be used to automatically reformat the code for you.

Comments

Remove all commented-out code to reduce clutter:

#x, y = pyautogui.position()
#positionStr = 'X: ' + str(x).rjust(4) + ' Y: ' + str(y).rjust(4)
#print(positionStr, end='')
#print('\b' * len(positionStr), end='', flush=True)

Comments like this can be deleted:

# -------INVITE
def invite():
    """invite"""

Comments are intended to explain the code, not merely repeat it.

Documentation

While it is good that you added docstrings to your functions, they do not serve their intended purpose. Like comments, docstrings should describe what the code is doing. There is no point in simply copying the name of the function as the entire docstring.

The PEP 8 style guide recommends adding a docstring at the top of the code to summarize its purpose.

Unused code

The following code is unused and can be deleted:

DETECTED = False

Globals

Avoiding using global variables like LOOTED. You should pass values into your functions and return values from functions.

Naming

PEP 8 recommends snake_case for function and variable names.

detectSword would be detect_sword.

Use meaningful names for variables. For example:

im = pyautogui.screenshot()

im is too vague. If it is an image, use image.

Simpler

This line:

if mobLocation != None:

is simpler as:

if not mobLocation:

ruff can be used to identify all the lines like that.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.