Tetris

Game development specific discussions.
Deleter
Posts: 975
Joined: Jun 22, 2005 22:33

Tetris

Postby Deleter » Aug 01, 2007 4:53

This was from the "how would I make a simple tetris clone" thread in the beginners section, but I figured I'd throw it here too for people to see. Its a very simple Tetris clone (with only one or two bugs), coded in a little over 100 lines.

edit:w00t, now only 79 lines, who needs 100...sheesh

Code: Select all

screen 12
dim myblock(-1 to 16,31) as integer, score as integer ,px as integer=7 ,py as integer=3 , gameover as integer ,myblockdata(6,2,2) as integer={{{0,1,0},{0,1,0},{0,1,0}},{{0,0,0},{0,1,0},{1,1,1}},{{1,1,0},{1,0,0},{1,0,0}},{{0,1,1},{0,0,1},{0,0,1}},{{0,0,0},{1,1,0},{0,1,1}},{{0,0,0},{0,1,1},{1,1,0}},{{0,0,0},{1,1,0},{1,1,0}}},tm as double=timer,godown as integer,newblock as integer
for tmpy as integer  = 15 to 0 step -1
    for tmpx as integer =0 to 4
        if tmpx<3 and tmpy < 3 then if myblockdata(2,tmpy,tmpx) then myblock(px+tmpx,py+tmpy)=-1
        myblock(iif(tmpx<2,-1,iif(tmpx<4,16,tmpy)),iif(tmpx=1 or tmpx=3,tmpy+16,iif(tmpx=4,30,tmpy)))=1
next tmpx,tmpy
do
    locate 1,1
    ? "Level:"+str((int(score/2500)+1))+chr(13)+chr(10)+"Score:"+str(score)
    for tmpx as integer = 0 to 30*16-1
        if myblock((tmpx mod 16),int(tmpx/16))<>0 then line((tmpx mod 16)*20+160,(int(tmpx/16)-6)*20)-((tmpx mod 16)*20+20+158,(int(tmpx/16)-6)*20+20-2),7,bf else line((tmpx mod 16)*20+160,(int(tmpx/16)-6)*20)-((tmpx mod 16)*20+20+159,(int(tmpx/16)-6)*20+20-1),8,bf
    next tmpx
    sleep 50,1
    sleep 500-(int(score/2500)+1)*50
    newblock=int(rnd*5)
    if timer-tm>(.5-(int(score/2500)+1)*.05) or multikey(80) then godown=-1 else godown=0
    dim canrotate as integer =-1, donttouch as integer =0,canmove as integer =-1, rotdata(2,2,1) as integer=>{{{2,0},{1,0},{0,0}},{{2,1},{1,1},{0,1}},{{2,2},{1,2},{0,2}}},tmpblock(-1 to 3,2) as integer=>{{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}},myxdir as integer=multikey(75)*2+1
    if multikey(72) then
        for tmpx as integer=0 to 9-1
            if myblock(px+(tmpx mod 3),py+int(tmpx/3))<> 0 then
                if myblock(px+(tmpx mod 3),py+int(tmpx/3))=-1 then    tmpblock((tmpx mod 3),int(tmpx/3))=myblock(px+(tmpx mod 3),py+int(tmpx/3))
                if myblock(px+(tmpx mod 3),py+int(tmpx/3))=-1 then    if myblock(px+rotdata((tmpx mod 3),int(tmpx/3),0) , py+rotdata((tmpx mod 3),int(tmpx/3),1)  )<>0 then if myblock(px+rotdata((tmpx mod 3),int(tmpx/3),0),py+rotdata((tmpx mod 3),int(tmpx/3),1))=1 then canrotate=0
            end if
        next tmpx
        if canrotate=-1 then
            for tmpx as integer=0 to 9-1
                if myblock(px+rotdata((tmpx mod 3),int(tmpx/3),0),py+rotdata((tmpx mod 3),int(tmpx/3),1))<> 0 then if myblock(px+rotdata((tmpx mod 3),int(tmpx/3),0),py+rotdata((tmpx mod 3),int(tmpx/3),1))=1 then donttouch=-1
                if donttouch=0 then myblock(px+rotdata((tmpx mod 3),int(tmpx/3),0),py+rotdata((tmpx mod 3),int(tmpx/3),1))=tmpblock((tmpx mod 3),int(tmpx/3)) else donttouch=0
                tmpblock((tmpx mod 3),int(tmpx/3))=0
            next tmpx
        end if
    elseif (multikey(75) xor multikey(77)) and (px+multikey(75)*2+1 >-2 ) and (px + multikey(75)*2+1 < 15) then
        for tmpx as integer = 0 to 9-1
            if myblock(px+(tmpx mod 3),py+int(tmpx/3))<>0 then if myblock(px+(tmpx mod 3),py+int(tmpx/3))=-1 then if myblock(px+(tmpx mod 3)+myxdir,py+int(tmpx/3))<>0 then if myblock(px+(tmpx mod 3)+myxdir,py+int(tmpx/3))=1 then canmove=0
            if myblock(px+(tmpx mod 3),py+int(tmpx/3))<>0 then if myblock(px+(tmpx mod 3),py+int(tmpx/3))=-1 then tmpblock((tmpx mod 3),int(tmpx/3))=myblock(px+(tmpx mod 3),py+int(tmpx/3))
        next tmpx
        if canmove then
            px+=myxdir
            for tmpx as integer = iif(myxdir=-1,0,-1) to iif(myxdir=-1,3,2)
            for tmpy as integer =0 to 2
                if myblock(px+tmpx,py+tmpy)<>0 then if myblock(px+tmpx,py+tmpy)=1 then donttouch=-1
                if donttouch=0 then myblock(px+tmpx,py+tmpy)=tmpblock(tmpx,tmpy) else donttouch=0
            next tmpx,tmpy
        end if
    end if
    if godown=-1 then
        canmove=-1
        for tmpx as integer=0 to 9-1
            if myblock(px+(tmpx mod 3),py+int(tmpx/3))<>0 then if myblock(px+(tmpx mod 3),py+int(tmpx/3))=-1 then if myblock(px+(tmpx mod 3),py+int(tmpx/3)+1)<>0 then if myblock(px+(tmpx mod 3),py+int(tmpx/3)+1)=1 then canmove=0
        next tmpx
        for tmpx as integer = 4*3-1 to 0 step -1
            if canmove=0 then    if int(tmpx/3)<3 then if myblock(px+(tmpx mod 3),py+int(tmpx/3))<>0 then myblock(px+(tmpx mod 3),py+int(tmpx/3))=1
            if canmove=0 then    if int(tmpx/3)<3 then if myblockdata(newblock,int(tmpx/3),(tmpx mod 3)) then myblock(7+(tmpx mod 3),int(tmpx/3)+3)=-1
            if canmove<>0 then    if myblock((tmpx mod 3)+px,int(tmpx/3)+py)<>0 then if myblock((tmpx mod 3)+px,int(tmpx/3)+py)=1 then donttouch=-1
            if canmove<>0 then    if myblock((tmpx mod 3)+px,int(tmpx/3)+py-1)<> 0 then if myblock((tmpx mod 3)+px,int(tmpx/3)+py-1)=1 then donttouch=-1
            if canmove<>0 then    if myblock((tmpx mod 3)+px,int(tmpx/3)+py-1)<> 0 then if myblock((tmpx mod 3)+px,int(tmpx/3)+py-1)=1 then if myblock((tmpx mod 3)+px,int(tmpx/3)+py)<>0 then if myblock((tmpx mod 3)+px,int(tmpx/3)+py)=-1 then myblock((tmpx mod 3)+px,int(tmpx/3)+py)=0
            if canmove<>0 then    if donttouch=0 then myblock((tmpx mod 3)+px,int(tmpx/3)+py)=myblock((tmpx mod 3)+px,int(tmpx/3)+py-1) else donttouch=0
        next tmpx
        if canmove=0 then py=3 else py+=1
        if canmove=0 then px=7
    end if
    if timer-tm>(.5-(int(score/2500)+1)*.05) then tm=timer
    dim exists as integer , shiftdown as integer =0
    for tmpx as integer= 30*16-1 to 0 step -1
        if (tmpx mod 16)=15 then exists=-1
        if (myblock((tmpx mod 16),int(tmpx/16))<>0) then    if myblock((tmpx mod 16),int(tmpx/16))=-1 then exists=0 else if int(tmpx/16)=6 then gameover=-1
        if (myblock((tmpx mod 16),int(tmpx/16))<>0) then    if int(tmpx/16)<30-shiftdown then if myblock((tmpx mod 16),int(tmpx/16))=1 and shiftdown>0 then myblock((tmpx mod 16),int(tmpx/16)+shiftdown)=myblock((tmpx mod 16),int(tmpx/16))
        if (myblock((tmpx mod 16),int(tmpx/16))<>0) then    if int(tmpx/16)<30-shiftdown then if myblock((tmpx mod 16),int(tmpx/16))=1 and shiftdown>0 then myblock((tmpx mod 16),int(tmpx/16))=0
        if (myblock((tmpx mod 16),int(tmpx/16))=0) then    exists=0
        if (tmpx mod 16)=0 and exists=-1 then
            for tmpx2 as integer =0 to 15
                myblock(tmpx2,int(tmpx/16)+shiftdown)=0
                score+=10
            next
            shiftdown+=1
        end if
    next
loop until multikey(1) or gameover
Last edited by Deleter on Aug 06, 2007 18:50, edited 3 times in total.
Pritchard
Posts: 5425
Joined: Sep 12, 2005 20:06
Location: Ohio, USA

Postby Pritchard » Aug 01, 2007 5:37

Neat. I didn't manage mine to work. I ended up being at 50 lines and things were looking good, but the next things I knew, I was at 90 with several features left to implement ;_;
rdc
Posts: 1713
Joined: May 27, 2005 17:22
Location: Texas, USA
Contact:

Postby rdc » Aug 01, 2007 14:51

Nice one.
Lachie Dazdarian
Posts: 2230
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Postby Lachie Dazdarian » Aug 01, 2007 21:13

I ended up being at 50 lines and things were looking good, but the next things I knew, I was at 90 with several features left to implement ;_;


And if you cross 100 lines of code...the world will explode?

Seriously, I find these restrictions silly, unless we are talking about some competition.

Anyway, nice work Deleter. Looks and plays very...clean.

If some of you are interested in Tetris code solutions, perhaps checking some of the QBasic Tetris games wouldn't hurt:

http://www.petesqbsite.com/sections/exp ... tml#tetris
Deleter
Posts: 975
Joined: Jun 22, 2005 22:33

Postby Deleter » Aug 01, 2007 23:11

Edited original post, I fixed the one bug I knew of. Which was if you have an overhang, and then you slide the piece right under it, it would spawn blocks under the overhang

ie

OO
O
O
O

OOPP
OPP
O
O

OO
OM
OMPP
OPP


Where O=fixed pieces, P=player piece, and M=mysteriously appearing pieces.
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario
Contact:

Postby axipher » Aug 02, 2007 3:10

Ya, that was a weird glitch, the M-blocks allowed for lines until they disapeared.
Basic Coder
Posts: 180
Joined: Aug 02, 2006 23:37
Location: Australia

Postby Basic Coder » Aug 02, 2007 13:27

Lachie Dazdarian wrote:
I ended up being at 50 lines and things were looking good, but the next things I knew, I was at 90 with several features left to implement ;_;


And if you cross 100 lines of code...the world will explode?

Seriously, I find these restrictions silly, unless we are talking about some competition.



The number of lines means nothing unless you are using the same set
of statements or libraries. I have edited my Tetris effort in the
Beginner forum using a simpler set of statements which I think is
more beginner friendly. I don't have Deleter's advanced programming
skills :(



Basic Coder
Deleter
Posts: 975
Joined: Jun 22, 2005 22:33

Postby Deleter » Aug 02, 2007 13:37

Yeah well, that code is particularly ugly, because it has both crunched logic and optimized code. And it was written in fb with gfxlib, thats it no other libs. It was just because it was suggested it couldn't be done without using colons, which doesn't really count. So having nothing to do I figured I'd see if I could disprove that, and I came really close ;). And I am glad you are making a more user-friendly version of tetris, my code tends to usually be much more readable, if not beginner friendly (its oop, so how close can you get). Its just quickly written/optimized code of mine that tends to be cryptic.
Basic Coder
Posts: 180
Joined: Aug 02, 2006 23:37
Location: Australia

Postby Basic Coder » Aug 02, 2007 21:28

Deleter wrote:Yeah well, that code is particularly ugly, because it has both crunched logic and optimized code. And it was written in fb with gfxlib, thats it no other libs. It was just because it was suggested it couldn't be done without using colons, which doesn't really count. So having nothing to do I figured I'd see if I could disprove that, and I came really close ;). And I am glad you are making a more user-friendly version of tetris, my code tends to usually be much more readable, if not beginner friendly (its oop, so how close can you get). Its just quickly written/optimized code of mine that tends to be cryptic.




The game is not more user-friendly, just the code may
be easier to follow if you are unfamiliar with the
OOP nomenclature used in FreeBasic or OOP itself.

I just use the old methods because then not knowing
the latest programming techniques doesn't stand in
the way of converting idea to code. I don't advocate
my programming limitations to others. It seems to
me OOP lends itself well to writing computer games.


--
Basic Coder
notthecheatr
Posts: 1759
Joined: May 23, 2007 21:52
Location: Cut Bank, MT
Contact:

Postby notthecheatr » Aug 02, 2007 22:53

I think most people would rather have nice graphics than under 100 lines of code.

Still, it is impressive.
Deleter
Posts: 975
Joined: Jun 22, 2005 22:33

Postby Deleter » Aug 03, 2007 1:24

Well notice that I did dedicate ~7 lines of code to graphics, when I could have shrunk that down into 1, just a single box. ;) Besides, it was a personal challenge completed in a matter of hours, not a dedicated project aimed for fame ;).
ciw1973
Posts: 157
Joined: Jun 12, 2007 15:03
Location: Isle of Man (United Kingdom)

Postby ciw1973 » Aug 03, 2007 11:44

This reminds me, one Saturday afternoon at work many moons ago, I was sat around waiting for a client to call so I could carry out a remote upgrade (they didn't and I waited all afternoon) so I fired up the A86 assembler and wrote a graphics mode version of Breakout with anti-aliased blocks, inertia on the bat and the ability to slice the ball. The whole thing came in at 511 bytes.

That evening I also wrote a text mode version of Tetris in 430 or so bytes which was perfectly playable but needed polishing up, which I never got around to doing. It didn't have a score or any on-screen numbers, although it did have levels in the form of gradual speed increases every 10 lines.

I also remember writing a really simple but effective world terrain generator in around 100 bytes, which was just a trial and error thing to test out a random number generator I'd written.

Was pretty pleased with these at the time, but I've not thought about them for years, and now I want to look at the code again, so tonight I'm going to have a rummage around in the attic and see if I can find a floppy somewhere with them on.
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario
Contact:

Postby axipher » Aug 03, 2007 19:01

@ciw1973: If you find those ASM things, could you send them to me? I've been tinkering in ASM the last while.
Deleter
Posts: 975
Joined: Jun 22, 2005 22:33

Postby Deleter » Aug 03, 2007 20:26

Well thats one way to know no one else is really playing the game lol. I replaced the bug with a worse one and no one keyed me in haha. Its fixed again (hopefully for real), just incase someone finds this thread a year from now and actually wants to play ;).
Dr_D
Posts: 2345
Joined: May 27, 2005 4:59
Contact:

Postby Dr_D » Aug 03, 2007 21:52

Well, I tried it. I think it advances too slowly. I played for a long time and it was still moving slow. I was on level 3, around 6500 points. ;)

Return to “Game Dev”

Who is online

Users browsing this forum: No registered users and 0 guests