EXPORT HS; EXPORT SLVL; LOCAL ROWS:=24,COLS:=11,BORDC:=RGB(128,128,128); LOCAL PCLR:={RGB(255,0,0),RGB(0,255,0),RGB(0,0,255),RGB(255,255,0),RGB(255,0,255),RGB(0,255,255),RGB(128,0,255)}; //1=L1 2=L2 3=Z1 4=Z2 5=T 6=BLOCK 7=LINE LOCAL PCS:={ {{(0,1),(0,0),(0,−1),(1,−1)},{(−1,0),(0,0),(1,0),(1,1)},{(−1,1),(0,1),(0,0),(0,−1)},{(−1,0),(−1,−1),(0,0),(1,0)}}, {{(−1,−1),(0,1),(0,0),(0,−1)},{(−1,0),(0,0),(1,0),(1,−1)},{(0,1),(0,0),(0,−1),(1,1)},{(−1,1),(−1,0),(0,0),(1,0)}}, {{(−1,0),(0,1),(0,0),(1,1)},{(−1,1),(−1,0),(0,0),(0,−1)},{(−1,−1),(0,0),(0,−1),(1,0)},{(0,1),(0,0),(1,0),(1,−1)}}, {{(−1,1),(0,1),(0,0),(1,0)},{(−1,0),(−1,−1),(0,1),(0,0)},{(−1,0),(0,0),(0,−1),(1,−1)},{(0,0),(0,−1),(1,1),(1,0)}}, {{(0,1),(0,0),(0,−1),(1,0)},{(−1,0),(0,1),(0,0),(1,0)},{(−1,0),(0,1),(0,0),(0,−1)},{(−1,0),(0,0),(0,−1),(1,0)}}, {{(0,0),(1,0),(0,1),(1,1)},{(0,0),(1,0),(0,1),(1,1)},{(0,0),(1,0),(0,1),(1,1)},{(0,0),(1,0),(0,1),(1,1)}}, {{(0,1),(0,0),(0,−1),(0,−2)},{(−1,0),(0,0),(1,0),(2,0)},{(0,2),(0,1),(0,0),(0,−1)},{(−2,0),(−1,0),(0,0),(1,0)} }}; XC(C) BEGIN RETURN RE(C); END; YC(C) BEGIN RETURN IM(C); END; CANFIT(GAME,P,C) BEGIN FOR I FROM 1 TO SIZE(P) DO LOCAL CC:=P(I)+C; IF XC(CC)>COLS OR XC(CC)<1 THEN RETURN 0; END; IF YC(CC)>ROWS OR YC(CC)<1 THEN RETURN 0; END; IF GAME(XC(CC),YC(CC)) THEN RETURN 0; END; END; RETURN 1; END; FOREG(GAME) BEGIN BLIT_P(G2,G1); FOR X FROM 1 TO COLS DO FOR Y FROM 1 TO ROWS DO IF GAME(X,Y) THEN RECT_P(G2,16+8*X,16+8*Y,16+8*X+8,16+8*Y+8,PCLR(GAME(X,Y))) END; END; END; END; SCREEN(SC,LNS,LVL,P,C,PT,GAME) BEGIN BLIT_P(G2); TEXTOUT_P(SC,G0,240,70,5); TEXTOUT_P(LNS,G0,240,100,5); TEXTOUT_P(LVL,G0,240,130,5); FOR I FROM 1 TO SIZE(P) DO LOCAL CC:=P(I)+C; RECT_P(G0,16+8*XC(CC),16+8*YC(CC),16+8*XC(CC)+8,16+8*YC(CC)+8,PCLR(PT)) END; END; CALCHS(SC) BEGIN IF SIZE(HS)==0 THEN RETURN 1; END; FOR I FROM 1 TO SIZE(HS) DO LOCAL L:=HS(I); IF SC>L(2) THEN RETURN I; END; END; RETURN SIZE(HS)+1; END; ORDN(N) BEGIN CASE IF N==1 THEN RETURN "1st"; END; IF N==2 THEN RETURN "2nd"; END; IF N==3 THEN RETURN "3rd"; END; DEFAULT RETURN STRING(N)+"th"; END; END; SELPMENU(SEL) BEGIN BLIT_P(G3); INVERT_P(G0,320/2-60,240/2+SEL*30+16,320/2+60,240/2+SEL*30+46); END; PMENU() BEGIN DIMGROB_P(G3,320,240); BLIT_P(G3,G0); RECT_P(G3,320/2-70,240/2-30,320/2+70,240/2+80,BORDC); TEXTOUT_P("Paused",G3,320/2-(22*6/3),240/2-20,7,RGB(0,0,0)); TEXTOUT_P("Resume",G3,320/2-(16*6/3),240/2+20,4,RGB(0,0,0)); TEXTOUT_P("Quit",G3,320/2-(16*4/3),240/2+50,4,RGB(0,0,0)); SELPMENU(0); LOCAL SEL:=0; WHILE 1 DO LOCAL K:=WAIT(0); IF K==4 THEN RETURN 1; END; IF K==2 THEN SEL:=0; SELPMENU(0); END; IF K==12 THEN SEL:=1; SELPMENU(1); END; IF K==30 THEN IF SEL==0 THEN RETURN 0; ELSE RETURN 1; END; END; END; END; PLAY() BEGIN LOCAL SC:=0,TM:=0,LNS:=0,LVL:=SLVL,MTM:=MAX(250,2000 - 150*SLVL); LOCAL P,PT:=RANDINT(1,7),C:=(5,3),R:=1; P:=PCS(PT); P:=P(R); DIMGROB_P(G1,320,240); RECT(G1); DIMGROB_P(G2,320,240); TEXTOUT_P("TETRIS",G1,180,20,7); TEXTOUT_P("Score:",G1,180,70,5); TEXTOUT_P("Lines:",G1,180,100,5); TEXTOUT_P("Level:",G1,180,130,5); RECT_P(G1,16,16,16+8,16+8*(ROWS+1),BORDC); RECT_P(G1,16+8*(COLS+1),16,16+8*(COLS+1)+8,16+8*(ROWS+1),BORDC); RECT_P(G1,16,16+8*(ROWS+1),16+8*(COLS+1)+8,16+8*(ROWS+1)+8,BORDC); LOCAL GAME:=MAKEMAT(0,COLS,ROWS); FOREG(GAME); SCREEN(SC,LNS,LVL,P,C,PT,GAME); LOCAL LKD:=0,RKD:=0,UKD:=0,DKD:=0,EKD:=0; WHILE 1 DO //WAIT(.1); TM:=TM+1; IF ISKEYDOWN(4) THEN EKD:=1; IF PMENU()==1 THEN RETURN; END; SCREEN(SC,LNS,LVL,P,C,PT,GAME); END; IF ISKEYDOWN(7) THEN IF LKD==0 AND CANFIT(GAME,P,C-(1,0)) THEN C:=C-(1,0); SCREEN(SC,LNS,LVL,P,C,PT,GAME); LKD:=1; END; ELSE LKD:=0; END; IF ISKEYDOWN(8) THEN IF RKD==0 AND CANFIT(GAME,P,C+(1,0)) THEN C:=C+(1,0); SCREEN(SC,LNS,LVL,P,C,PT,GAME); RKD:=1; END; ELSE RKD:=0; END; IF ISKEYDOWN(12) AND (TM MOD 75)==0 THEN IF CANFIT(GAME,P,C+(0,1)) THEN C:=C+(0,1); SC:=SC+1; SCREEN(SC,LNS,LVL,P,C,PT,GAME); END; END; IF ISKEYDOWN(2) THEN LOCAL NR:=R+1,NP; IF NR>4 THEN NR:=1 END; NP:=PCS(PT); NP:=NP(NR); IF UKD==0 AND CANFIT(GAME,NP,C) THEN P:=NP; R:=NR; SCREEN(SC,LNS,LVL,P,C,PT,GAME); UKD:=1; END; ELSE UKD:=0; END; LOCAL CHK; IF ISKEYDOWN(30) AND TM>500 THEN IF EKD==0 THEN WHILE CANFIT(GAME,P,C) DO SC:=SC+1; C:=C+(0,1); END; C:=C-(0,1); CHK=1; SCREEN(SC,LNS,LVL,P,C,PT,GAME); EKD:=1; END; ELSE EKD:=0; END; IF (TM MOD MTM)==0 OR CHK==1 THEN IF CANFIT(GAME,P,C+(0,1)) THEN C:=C+(0,1); ELSE //add blocks to game FOR I FROM 1 TO SIZE(P) DO LOCAL CC:=P(I)+C; GAME(XC(CC),YC(CC)):=PT; END; LOCAL CLN; //check for clear lines FOR Y FROM 1 TO ROWS DO LOCAL CLR:=1; FOR X FROM 1 TO COLS DO IF GAME(X,Y)==0 THEN CLR:=0; BREAK; END; END; IF CLR==1 THEN CLN:=CLN+1; LNS:=LNS+1; FOR X FROM 1 TO COLS DO GAME(X,Y):=0; END; FOR J FROM Y DOWNTO 2 DO FOR I FROM 1 TO COLS DO GAME(I,J):=GAME(I,J-1) END; END; FOR X FROM 1 TO COLS DO GAME(X,1):=0; END; END; END; IF CLN==1 THEN SC:=SC+40*LVL; END; IF CLN==2 THEN SC:=SC+100*LVL; END; IF CLN==3 THEN SC:=SC+300*LVL; END; IF CLN==4 THEN SC:=SC+1200*LVL; END; LVL:=FLOOR((LNS+(SLVL-1)*10)/10)+1; MTM:=MAX(250,2000 - 150*LVL); PT:=RANDINT(1,7); C:=(5,3); R:=1; P:=PCS(PT); P:=P(R); IF NOT CANFIT(GAME,P,C) THEN //Handle loss FOR I FROM 1 TO 1000 DO WAIT(.0005); LOCAL X:=RANDINT(1,COLS),Y:=RANDINT(1,ROWS); RECT_P(G0,16+8*X,16+8*Y,16+8*X+8,16+8*Y+8,PCLR(RANDINT(1,7))); END; WAIT(.5); TEXTOUT_P("GAME OVER",G0,320/2-(22*9/3),80,7,RGB(0,0,0),1000,RGB(128,128,128)); WAIT(0); RECT_P(G1); TEXTOUT_P("GAME OVER",G1,320/2-(22*9/3),20,7); TEXTOUT_P("Your score was: "+STRING(SC),G1,320/2-(16*14/3),60,5); LOCAL PLC:=CALCHS(SC); IF PLC>0 AND PLC<6 THEN TEXTOUT_P("High score! You're in "+ORDN(PLC)+" place!",G1,320/2-(14*22/3),100,4); HS:=CONCAT(HS,{{"",0}}); FOR I FROM SIZE(HS)-1 DOWNTO PLC DO HS(I+1):=HS(I); END; HS(PLC):={"Someone",SC}; END; BLIT_P(G1); WAIT(0); IF PLC>0 AND PLC<6 THEN LOCAL NM:=""; INPUT(NM,"Enter your name:","Name","",""); HS(PLC):={NM,SC}; END; RETURN; END; FOREG(GAME); END; SCREEN(SC,LNS,LVL,P,C,PT,GAME); END; END; RETURN; END; SELMENU(SEL) BEGIN BLIT_P(G1); INVERT_P(G0,320/2-60,240/2+SEL*30+1,320/2+60,240/2+SEL*30+22); END; OPTMENU() BEGIN LOCAL ISOK = INPUT({SLVL},"TETRIS - Options",{"Starting Level"},{"How fast the game is when you start."},{1}); BLIT_P(G1); SELMENU(2); END; HSMENU() BEGIN RECT_P(G0); TEXTOUT_P("HIGH SCORES",G0,320/2-(22*10/3),20,7); FOR I FROM 1 TO 5 DO TEXTOUT_P(STRING(I)+":",G0,100,30+30*I,4); IF I≤SIZE(HS) THEN LOCAL L:=HS(I); TEXTOUT_P(L(1)+" - "+STRING(L(2)),G0,130,30+30*I,4); END; END; WAIT(0); BLIT_P(G1); SELMENU(1); END; MAINMENU() BEGIN DIMGROB_P(G1,320,240); RECT(G1); TEXTOUT_P("TETRIS",G1,320/2-(22*6/3),20,7); TEXTOUT_P("Play",G1,320/2-(16*4/3),240/2,4); TEXTOUT_P("High Scores",G1,320/2-(16*9/3),240/2+30,4); TEXTOUT_P("Options",G1,320/2-(16*6/3),240/2+60,4); TEXTOUT_P("Exit",G1,320/2-(16*4/3),240/2+90,4); LOCAL SEL:=0; SELMENU(0); WHILE 1 DO LOCAL K; K:=WAIT(0); IF K==4 THEN RETURN; END; IF K==2 AND SEL≠0 THEN SEL:=SEL-1; SELMENU(SEL); END; IF K==12 AND SEL≠3 THEN SEL:=SEL+1; SELMENU(SEL); END; IF K==30 THEN CASE IF SEL==0 THEN PLAY(); MAINMENU(); RETURN; END; IF SEL==1 THEN HSMENU(); END; IF SEL==2 THEN OPTMENU(); END; IF SEL==3 THEN RETURN; END; END; END; END; END; EXPORT TETRIS() BEGIN IF TYPE(HS)≠6 THEN HS:={}; END; SLVL:=MAX(SLVL,1); MAINMENU(); END;