## Tetris

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

### Tetris

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 12dim 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 integerfor 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)))=1next tmpx,tmpydo    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    nextloop until multikey(1) or gameover`
Last edited by Deleter on Aug 06, 2007 18:50, edited 3 times in total.
Pritchard
Posts: 5477
Joined: Sep 12, 2005 20:06
Location: Ohio, USA
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:
Nice one.
Lachie Dazdarian
Posts: 2249
Joined: May 31, 2005 9:59
Location: Croatia
Contact:
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
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:
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
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
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
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:
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
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)
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:
@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
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: 2357
Joined: May 27, 2005 4:59
Contact:
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. ;)