RaiMan's Examples, Tutorials and HowTo's

This page is used, to show examples that are referenced in an Answer on LaunchPad.
(responsible  RaiMan)

Answer  113975: Observing a Stopwatch

The goal: Wait until a Stopwatch has counted down to a specific value and then show popup and stop.

To use this approach, go to  http://www.online-stopwatch.com/online-countdown/ and set the timer to e.g. 40 seconds.
Then start the script and then start the timer.

The old way: using exists()

switchApp("Safari")
while True:
        if not Region(0,0,400,400).exists(,0):
                switchApp("Sikuli-IDE")
                popup("The End")
                break
        if Region(399,424,458,131).exists(Pattern().similar(0.99), 0):
                switchApp("Sikuli-IDE")
                popup("Stop!")
                break

The script: download stopwatch.sikuli.zip.

Comments:

  • this example is for a Mac and will not need the switchApp("Sikuli-IDE") on Windows. (you may use Env.getOS() to make it run on all systems)
  • the script will stop, if the timer reaches 29 seconds
  • I restrict the find's to a region, to gain performance
  • You may have to adjust the regions and capture the images again
  • I use exists() with a wait timer of 0, so it just looks once and returns None if not found
  • The first "if" assures that the loop will not run endless: to stop, just close the webpage
  • I found, that similar(1.0) does not work, but similar(0.99) does

The new way: Using an observer

I'm working on that.

Answer  114664: Playing 4-in-a-line

Version 0.1

These are the two web pages to connect:

Starting with the real game. Either plays the demo mode (random drop) or a run with the relevant functionality always dropping on the last blue button if possible. The user always has the first turn.

This is the solver app's gamepad, where we will take our moves:

next steps:

  • evaluate and script the solver app
  • implement the workflow

def startGame():
        wait(2)
        m = ctl.exists(, 0)
        while not play.exists(Pattern().similar(0.95), 0):
                click(m)
                wait(2)
        if not msg.exists(p1Turn,0):
                return False
        return True


def playSilly():
        # just randomly drops a button
        # may loop endless if gamepad is filled
        while True:
                while not msg.exists(p1Turn,0):
                        wait(1)
                hover(cClick); wait(0.5)
                mouseDown(Button.LEFT); mouseUp()
                i = random.randint(0, cols-1)
                cClick.x = colhead.getX()+int(fW/2)+i*fW
                wait(2)
                if not msg.exists(p1Turn,0): # game over?
                        break


def playMove(col):
        # we drop on the given column
        # return False if game over
        if msg.exists(p1Turn, 0):
                print "played", col
                loc = Location(colhead.getX()+int(fW/2)+col*fW, colhead.getY()+int(fH/2))
                hover(loc); wait(0.5)
                mouseDown(Button.LEFT); mouseUp()
                wait(2)
                return True
        else:
                return False

def checkGame():
        # we check the gamepad
        # r, b contain the count of red / blue buttons
        # rx, ry contain the fieldnumbers of the last move
        # full is True if all fields are occupied
        r=0; b=0
        rx=-1; bx=-1
        full = True
        for i in range(cols-1, -1, -1):
                emptyRow[i]=-1
                for k in range(rows-1, -1, -1):
                        ix = i*(cols-1)+k
                        ib = fields[ix][1]
                        if ib < 0:
                                b +=1
                                continue
                        elif ib > 0:
                                r +=1
                                continue
                        if fields[ix][0].exists(p1Btn,0):
                                fields[ix][1] = 1
                                r+=1
                                rx = ix
                        elif fields[ix][0].exists(p2Btn,0):
                                fields[ix][1] = -1
                                b+=1
                                bx = ix
                        else:
                                emptyRow[i]=k
                                full = False
                                break
        return r, b, rx, bx, full

import random

r = selectRegion("Show me the gamepad!")
print r
gp = r.exists(,0)
if not gp:
        popup("Sorry, no gamepad!")
        exit()

# upper left corner of gamepad  
pX = int(gp.getCenter().getX())-186
pY = int(gp.getCenter().getY())-311

p1Turn = 
p1Btn = 
p2Btn = 

cols = 7; rows = 6
fW = 50; fH = 50
xW = 7 * fW; xH = 6 * fH
play = Region(pX, pY, 7 * fW, 6 * fH) # region of gamepad

cH = 60
colhead = Region(pX, pY-cH, xW, cH) # drop region above gamepad
cClick = Location(colhead.getX()+int(fW/2), colhead.getY()+int(fH/2))

mH = 40
msg = Region(pX, pY-cH-mH, xW, mH) # message region

sW = 250; sH = 420
ctl = Region(pX-sW, msg.getY(), sW, sH) # region containing the controls

# prepare the container for the buttons
# each field is a region
# fields[i][1]: -1, 0, 1 means: contains blue, empty, red
# fields[i][2] contains column number
x=pX; y=pY
fields = []
for i in range(0, cols):
        for k in range(0,rows):
                fields.append([Region(x-2, y-2, fW+4, fH+4), 0, i])
                y += fH
        x += fW
        y = pY

#print fields; exit()

emptyRow=[]
for i in range(0,cols):
        emptyRow.append(0)

if not None == input("Want a Demo? Yes - click OK"):
        popup('Please select a level in menu "Difficult" and then click OK')
        switchApp("Safari") # or your browser
        # we start a new game
        # the user has the first move
        if not startGame():
                switchApp("Sikuli-IDE")
                popup("Sorry, could not start a new game!")
                exit()
        playSilly()
        exit()

switchApp("Safari") # or your browser
# we start a new game
# the user has the first move
if not startGame():
        switchApp("Sikuli-IDE")
        popup("Sorry, could not start a new game!")
        exit()

# pos = random.randint(0, cols-1)
pos = 3
while True:
        if not playMove(pos):
                break
        gameLast = checkGame(); print gameLast; print emptyRow
        if gameLast[4]: # gamepad filled?
                break
        pos = fields[gameLast[3]][2] # we drop on last blue
        while emptyRow[pos] < 0:
                pos = random.randint(0, cols-1)

switchApp("Sikuli-IDE")

The script: download game.sikuli.zip.

Comments:

  • developing on Mac
  • the game must be the frontmost page in the browser. the script adjusts itself, you only need to select the pink area with some space around, when asked after starting the script

Attachments