Puyo Puyo - algorithm

Previous topic - Next topic

Kitty Hello

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