BASIC

Author Topic: Puyo Puyo - algorithm  (Read 3777 times)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10697
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Puyo Puyo - algorithm
« on: 2006-Aug-07 »
Well, if you know Puyo Puyo http://en.wikipedia.org/wiki/Puyo_Puyo then you might want to re-write such a game. The problem of finding >3 connected, same-color blocks can be found in many ways. This one is not the most elegant or fastest, but it's the easiest to understand, I guess - if you exclude the recursion one, which might fail due to a stack overflow. Anyway. Just read this and maybe someone will make a game out of it?
Code: GLBasic [Select]
// Sticky4 algo


DIM hit[20][20] // Leave enough space for not out of DIM error

// Make a color table
DIM col[6]
        col[0]=0
        col[1]=RGB(255, 255, 128)
        col[2]=RGB(255,128,128)
        col[3]=RGB(128,255,255)
        col[4]=RGB(128, 128, 255)
        col[5]=RGB(255, 128, 255)

        // some random data for the blocks
        FOR x=0 TO 9; FOR y=0 TO 9; hit[x][y]=RND(5); NEXT; NEXT

        // remove air
        GOSUB Fall


        // ::MAINGAME::
        WHILE TRUE
                GOSUB ShowAll
                MOUSEWAIT
                GOSUB CheckCombos
                GOSUB ShowAll
                MOUSEWAIT
                GOSUB Fall
        WEND
END


// ------------------------------------------------------------- //
// -=#  SHOWALL  #=-
// display the data
// ------------------------------------------------------------- //
SUB ShowAll:
        FOR x=0 TO 9
                FOR y=0 TO 9
                        IF hit[x][y]<>0
                                FILLRECT x*64, y*32, x*64+63, y*32+31, col[hit[x][y]]
                                PRINT hit[x][y], x*64, y*32
                        ENDIF
                NEXT
        NEXT
        SHOWSCREEN
ENDSUB // SHOWALL


// ------------------------------------------------------------- //
// -=#  CHECKCOMBOS  #=-
// check if there is a 4-connection combo
// ------------------------------------------------------------- //
SUB CheckCombos:
LOCAL x, y, num
        FOR x=0 TO 9
                FOR y=0 TO 9
                        g_Count=0
                        IF hit[x][y]>0
                                num=CheckForCombo(x, y)
                                // IF num THEN INC score, POW(num,2)
                        ENDIF
                NEXT
        NEXT
ENDSUB // CHECKCOMBOS


// ------------------------------------------------------------- //
// -=#  CHECKFORCOMBO  #=-
// Check if the dot @ px,py forms a >4 combo
// ------------------------------------------------------------- //
FUNCTION CheckForCombo: px, py
LOCAL h, dx, dy, x, y, numhits
        numhits=1
        // get hit - color
        h=ABS(hit[px][py])
        // inverse at px,py
        hit[px][py]=-h

        found=TRUE
        WHILE found
                found=FALSE
                FOR x=0 TO 9
                        FOR y=0 TO 9
                                // good color at x,y
                                IF hit[x][y]=h
                                        FOR dx=-1 TO 1 STEP 2
                                                // look left/right of px,py
                                                // and see if the one has already
                                                // been invesed!
                                                IF x>0 AND hit[x+dx][y]=-h
                                                        found=TRUE
                                                        // inverse this one as well
                                                        hit[x][y]=-h
                                                        // add a hit
                                                        INC numhits, 1
                                                ENDIF
                                                // look above / below px,py
                                                IF y>0 AND hit[x][y+dx]=-h
                                                        found=TRUE
                                                        // inverse
                                                        hit[x][y]=-h
                                                        // count
                                                        INC numhits, 1
                                                ENDIF
                                        NEXT
                                ENDIF
                        NEXT
                NEXT
        WEND

        // Now remove if enough found
        FOR x=0 TO 9
                FOR y=0 TO 9
                        IF hit[x][y]<0
                                // did we find more than 3 connected
                                // ones?
                                IF numhits>3
                                        // make this a hole
                                        hit[x][y]=0
                                ELSE
                                        // re-inverse the thingy
                                        hit[x][y]=ABS(hit[x][y])
                                ENDIF
                        ENDIF
                NEXT
        NEXT
        RETURN numhits
ENDFUNCTION // CHECKFORCOMBO

// ------------------------------------------------------------- //
// -=#  FALL  #=-
// move each block that has "air" below one block down
// ------------------------------------------------------------- //
SUB Fall:
LOCAL Fall
        Fall=TRUE
        WHILE Fall
                Fall=FALSE
                FOR x=0 TO 9
                        FOR y=0 TO 8
                                IF hit[x][y+1]=0 AND hit[x][y]<>0
                                        hit[x][y+1]=hit[x][y]
                                        hit[x][y]=0
                                        Fall=TRUE
                                ENDIF
                        NEXT
                NEXT
        WEND
ENDSUB // FALL