Title: Swell Foop (in C7420 Basic) Post by: gertk on May 06, 2012, 02:43:14 PM Just some small trial to convert one of my favorite strategy games: Swell Foop also know as 'Same Game' or 'Chain Shot!'
Here is a sneak preview. It is already quite playable, but there is no end game detection yet. Conversion to assembler should be possible but since it uses recursion originally to detect adjacent pieces ram space could be a problem. I tackled this by creating a 'stack' system. The program is not optimized at all. Use the joystick to move around, the piece which you are on is blinking. After pressing the fire button it will detect adjacent pieces and make them blink while recalculating the board. After that the board is redrawn. Some info on how the rules are: http://library.gnome.org/users/swell-foop/stable/introduction.html.en (http://library.gnome.org/users/swell-foop/stable/introduction.html.en) Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 06, 2012, 02:44:55 PM Use the source...
Code: REM ASCII dump 01000 REM * Swell Foop Clone * 01010 REM * by gertk(at)xs4all.nl * 01020 MX=14:MY=9:NC=4 01030 INIT 0 01040 PRINTCHR$(150); 01050 SC=0 01500 SETET 37,"003e7f7f7f7f7f7f3e00" 02000 DIM BD(MX,MY) 02001 DIM SX(MX*MY),SY(MX*MY) 02005 REM * fill arry with numbers 1-4 02010 FOR T=0 TO MX 02020 FOR S=0 TO MY 02030 BD(T,S)=1+INT(RND(1)*NC) 02040 NEXT S 02050 NEXT T 02060 GOSUB 3000 02070 GOTO 4000 03000 REM* display board 03007 STORE 03008 M=0 03010 FOR U=0 TO MX 03020 FOR V=0 TO MY 03030 GOSUB 9100 03050 NEXT V 03060 NEXT U 03090 DISPLAY:SCREEN 03099 RETURN 04000 REM * now evaluate joystick 04010 S=0:T=0 04030 JY=ACTION(0):IF JY=0 THEN 4030 04035 M=0:GOSUB 9000 04040 IF JY AND 8 THEN S=S+1 04045 IF S>MY THEN S=MY 04050 IF JY AND 16 THEN S=S-1 04055 IF S<0 THEN S=0 04060 IF JY AND 2 THEN T=T+1 04065 IF T>MX THEN T=MX 04070 IF JY AND 4 THEN T=T-1 04075 IF T<0 THEN T=0 04076 M=1:GOSUB 9000 04077 IF JY AND 1 THEN 4500 04499 GOTO 4030 04500 PC=BD(T,S) 04507 FT=T:FS=S 04508 CN=1 04509 STORE 04510 GOSUB 5000 04515 TX 7,0,0 04520 CURSORY 10:CURSORX 34 04530 PRINT"Yield:"; 04535 CURSORY 12:CURSORX 34 04537 PRINTCN;" "; 04540 DISPLAY:SCREEN 04550 GOSUB 5100 04560 GOSUB 3000 04565 IF CN>1 THEN SC=SC+(CN-2)^2 04570 CURSORY 0:CURSORX 34 04580 TX 6,0,0 04581 PRINT"Score:"; 04590 CURSORY 2:CURSORX 34 04600 PRINTSC; 04999 GOTO 4030 05000 REM clear stack 05005 SP=0 05007 REM search right 05010 X=FT+1:Y=FS:GOSUB 5500 05020 REM search left 05030 X=FT-1:Y=FS:GOSUB 5500 05040 REM search up 05050 X=FT:Y=FS-1:GOSUB 5500 05060 REM search down 05070 X=FT:Y=FS+1:GOSUB 5500 05080 IF BD(FT,FS)=0 THEN 5087 05083 REM if more than 1 piece found 05084 U=FT:V=FS:M=1:GOSUB 9100 05085 BD(FT,FS)=0 05087 IF SP=0 THEN RETURN 05090 SP=SP-1:FT=SX(SP):FS=SY(SP) 05095 GOTO 5010 05100 REM swoop or fall 05105 REM for all rows 05110 FOR X=0 TO MX 05119 REM start y at top 05120 Y=MY 05122 REM set max counter 05125 C=MY 05130 IF BD(X,Y)=0 THEN 5200 05140 Y=Y-1 05150 IF Y<1 THEN 5300 05160 GOTO 5130 05190 REM shift row down 05200 FOR Z=Y TO 1 STEP -1 05210 BD(X,Z)=BD(X,Z-1) 05220 NEXT Z 05225 BD(X,Z)=0 05230 C=C-1 05240 IF C>0 THEN 5130 05300 NEXT X 05310 REM now check for empty rows 05320 FOR X=0 TO MX-1 05324 REM limit maximum nr of shifts 05325 C=MX-X 05330 Y=0 05340 IF BD(X,Y) THEN 5470 05350 Y=Y+1:IF Y<=MY THEN 5340 05380 REM move rows left 05390 FOR Z=X TO MX-1 05400 FOR Y=0 TO MY 05410 BD(Z,Y)=BD(Z+1,Y) 05420 NEXT Y 05430 NEXT Z 05435 REM clear last row 05440 FOR Y=0 TO MY:BD(MX,Y)=0:NEXT Y 05450 REM check again 05460 C=C-1:IF C THEN 5330 05470 NEXT X 05499 RETURN 05500 REM clear if same else adjust sp 05510 IF Y>MY OR Y<0 THEN RETURN 05520 IF X>MX OR X<0 THEN RETURN 05530 IF BD(X,Y)<>PC THEN RETURN 05550 SX(SP)=X:SY(SP)=Y:SP=SP+1 05555 CN=CN+1 05560 RETURN 09000 REM display single piece 09001 STORE 09005 ET BD(T,S),3,M 09010 CURSORX T*2+1:CURSORY S*2 09020 PRINT"%%"; 09030 CURSORX T*2+1:CURSORY S*2+1 09040 PRINT"%%"; 09045 SCREEN:DISPLAY 09050 RETURN 09100 REM update single piece 09105 ET BD(U,V),3,M 09110 CURSORX U*2+1:CURSORY V*2 09120 PRINT"%%"; 09130 CURSORX U*2+1:CURSORY V*2+1 09140 PRINT"%%"; 09150 RETURN Title: Re: Swell Foop (in C7420 Basic) Post by: Rafael on May 06, 2012, 04:30:16 PM Starting the week with really hot news :D
Will possible to keep basic games saved on your multcart project? Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 07, 2012, 07:26:54 AM Starting the week with really hot news :D Will possible to keep basic games saved on your multcart project? The Basic emulator part in the multicart will be the same as the C7420 emulator I did earlier (and which I tested this code on) and that cloads and csaves from and to the sd card. So basically yes :) Title: Re: Swell Foop (in C7420 Basic) Post by: ccc--- on May 07, 2012, 10:07:24 PM We need your multicart urgently gert ;D
Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 12, 2012, 11:49:31 PM Some cosmetic and program changes, some sound added and a visible 'cursor' when you are on an empty space, score and yield display, alas no endgame detection yet. The empty row detection must be optimized too, the game gets slower the emptier the board gets....
Code: 01000 REM Swell Foop for Videopac+ 01010 REM by gertk(at)xs4all.nl 01020 REM board dimensions and nr. of colors 01030 MX=14:MY=9:NC=3 01040 REM clear screen, disable status line 01050 INIT 0 01060 PRINTCHR$(150); 01070 REM reset score 01080 SC=0 01090 REM define graphics characters 01100 SETET 37,"003e7f7f7f7f7f7f3e00" 01110 SETET 38,"00412214080814224100" 01120 DIM BD(MX,MY) 01130 REM pseudo stack for search 01140 DIM SX(MX*MY),SY(MX*MY) 01150 REM fill array 01160 FOR X=0 TO MX 01170 FOR Y=0 TO MY 01180 BD(X,Y)=1+INT(RND(1)*NC) 01190 NEXT Y 01200 NEXT X 01210 PY=MY:PX=0 01220 REM main loop 01230 GOSUB 2440 01240 FOR T=1 TO 10:NEXT T 01250 SOUND 6 01260 STORE 01270 MD=1:DX=PX:DY=PY:GOSUB 2290 01280 SCREEN:DISPLAY 01290 REM wait for joystick movement 01300 JS=ACTION(0):IF JS=0 THEN 1300 01310 REM action button pressed 01320 IF JS AND 1 THEN 1470 01330 STORE 01340 MD=0:DX=PX:DY=PY:GOSUB 2290 01350 SCREEN:DISPLAY 01360 REM check directional movement 01370 IF JS AND 8 THEN PY=PY+1 01380 IF PY>MY THEN PY=MY 01390 IF JS AND 16 THEN PY=PY-1 01400 IF PY<0 THEN PY=0 01410 IF JS AND 2 THEN PX=PX+1 01420 IF PX>MX THEN PX=MX 01430 IF JS AND 4 THEN PX=PX-1 01440 IF PX<0 THEN PX=0 01450 GOTO 1260 01460 REM action ! 01470 FC=BD(PX,PY) 01480 REM check for empty space 01490 IF FC=0 THEN SOUND 5:GOTO 1260 01500 REM set search coordinates 01510 FX=PX:FY=PY 01520 REM reset yield 01530 YD=0 01540 STORE 01550 GOSUB 1760 01560 SOUND 1 01570 REM show yield in double height 01580 TX 7,1,0 01590 CURSORY 10:CURSORX 33 01600 PRINT"Yield:"; 01610 CURSORY 11:CURSORX 33 01620 PRINT"Yield:"; 01630 CURSORY 12:CURSORX 33 01640 PRINT STR$(YD);" "; 01650 CURSORY 13:CURSORX 33 01660 PRINT STR$(YD);" "; 01670 REM force screen update and redraw 01680 DISPLAY:SCREEN 01690 REM check fall or swoop 01700 GOSUB 1880 01710 REM calculate score 01720 IF YD<2 THEN SOUND 8:GOTO 1230 01730 SC=SC+(YD-2)^2 01740 GOTO 1230 01750 REM search start 01760 SP=0 01770 REM searchloop 01780 X=FX+1:Y=FY:GOSUB 2180 01790 X=FX-1:Y=FY:GOSUB 2180 01800 X=FX:Y=FY-1:GOSUB 2180 01810 X=FX:Y=FY+1:GOSUB 2180 01820 REM if no adjacent pieces found 01830 IF SP=0 THEN RETURN 01840 REM get next coordinates from stack 01850 FX=SX(SP):FY=SY(SP):SP=SP-1 01860 GOTO 1780 01870 REM swoop or fall 01880 FOR X=0 TO MX 01890 Y=MY 01900 CC=MY 01910 IF BD(X,Y)=0 THEN 1950 01920 Y=Y-1 01930 IF Y<1 THEN 2010 01940 GOTO 1910 01950 FOR Z=Y TO 1 STEP -1 01960 BD(X,Z)=BD(X,Z-1) 01970 NEXT Z 01980 BD(X,Z)=0 01990 CC=CC-1 02000 IF CC>0 THEN 1910 02010 NEXT X 02020 REM check for empty rows 02030 FOR X=0 TO MX-1 02040 C=MX-X 02050 Y=0 02060 IF BD(X,Y) THEN 2150 02070 Y=Y+1:IF Y<=MY THEN 2060 02080 FOR Z=X TO MX-1 02090 FOR Y=0 TO MY 02100 BD(Z,Y)=BD(Z+1,Y) 02110 NEXT Y 02120 NEXT Z 02130 FOR Y=0 TO MY:BD(MX,Y)=0:NEXT Y 02140 C=C-1:IF C THEN 2050 02150 NEXT X 02160 RETURN 02170 REM check limits and piece for color 02180 IF Y>MY OR Y<0 THEN RETURN 02190 IF X>MX OR X<0 THEN RETURN 02200 IF BD(X,Y)<>FC THEN RETURN 02210 REM found same color, push on stack 02220 SP=SP+1:SX(SP)=X:SY(SP)=Y 02230 DX=X:DY=Y:MD=1:GOSUB 2290 02240 BD(X,Y)=0 02250 REM increase yield counter 02260 YD=YD+1 02270 RETURN 02280 REM display white cross if empty 02290 IF BD(DX,DY) THEN 2370 02300 ET 7*MD,3,MD 02310 CURSORX DX*2+1:CURSORY DY*2 02320 PRINT"&&"; 02330 CURSORX DX*2+1:CURSORY DY*2+1 02340 PRINT"&&"; 02350 RETURN 02360 REM display single piece 02370 ET BD(DX,DY),3,MD 02380 CURSORX DX*2+1:CURSORY DY*2 02390 PRINT"%%"; 02400 CURSORX DX*2+1:CURSORY DY*2+1 02410 PRINT"%%"; 02420 RETURN 02430 REM draw board 02440 STORE 02450 REM display score 02460 CURSORY 0:CURSORX 33 02470 TX 6,1,0 02480 PRINT"Score:"; 02490 CURSORY 1:CURSORX 33 02500 PRINT"Score:"; 02510 CURSORY 2:CURSORX 33 02520 PRINT STR$(SC); 02530 CURSORY 3:CURSORX 33 02540 PRINT STR$(SC); 02550 REM draw all pieces in mode 0 02560 MD=0 02570 FOR DX=0 TO MX 02580 FOR DY=0 TO MY 02590 GOSUB 2370 02600 NEXT DY 02610 NEXT DX 02620 DISPLAY:SCREEN 02630 RETURN Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 13, 2012, 07:30:52 PM Maybe someone could try this binary basic file of swell_foop in Windows o2em.
In the Linux version 120B5 I keep struggling with the keyboard and joysticks on the laptop (scroll lock is not recognized so I can not disable the joysticks). If I read in this .k7 file with F9 key it seems to run OK but if I try to LIST it crashes the output. Could be that my converter from text to binary messes up but I tried to read in the text version in o2em but it needs a header of some sort. Even with the header attached it makes a mess of LIST... Would be nice to have a uniform format for Basic binaries or have o2em read in headerless basic sources. Title: Re: Swell Foop (in C7420 Basic) Post by: manopac on May 13, 2012, 08:16:48 PM Hey
I was able to load and run it using quickload, I did have a problem listing it though ... I think I also found out why - all your basic-lines have lots of trailing spaces, which seem to confuse the interpreter ... (look into the binary and you will find lots of 0x20 at the end of each line) - actually the same thing happend when I took the sourcecode from your previous post and pasted it into a text-file - yes, this works :-) O2EM can just load a textfile without a header ... what I had to do (using a texteditor) was deleting all the trailing spaces of each line ... see above :-) there are still some small differences between Quickload and using CLOAD btw, I still need to figure those out and eliminate them, to make it work better ... Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 13, 2012, 09:07:51 PM Hey I was able to load and run it using quickload, I did have a problem listing it though ... I think I also found out why - all your basic-lines have lots of trailing spaces, which seem to confuse the interpreter ... (look into the binary and you will find lots of 0x20 at the end of each line) - actually the same thing happend when I took the sourcecode from your previous post and pasted it into a text-file - yes, this works :-) O2EM can just load a textfile without a header ... what I had to do (using a texteditor) was deleting all the trailing spaces of each line ... see above :-) Ah, that explains a lot. The source which I copy/pasted to the forum came from the terminal (the ASCII dump function) and that might also explain the whitespace. I will modify the converter to trim these spaces off. Quote there are still some small differences between Quickload and using CLOAD btw, I still need to figure those out and eliminate them, to make it work better ... I am contemplating a similar system for the multicart: let the LPC do the testing for binary/ascii of the requested file so you can use source code and binaries. Too bad in C7420 Basic you can only use 6 characters for the filename, maybe I can catch that function and use longer filenames with extensions. Anyway, thanks for testing! Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 13, 2012, 10:19:13 PM Just cleaned up the converter and it creates better binaries now. Still your C7420 seems to dislike the last line.
I tried with the converted binary and a clean basic source code file. As soon as the last line is LIST-ed the emulator starts to act goofy: screen starts to flash and becomes unresponsive. The last line being line 2630 and that line number is displayed twice. Could this have anything to do with the length of the program calculation ? I am not sure if this length value is in- or excluding the filler bytes at the end (the 10 bytes 0x00) Another small bug is that when I load the source code file (swell.lst) in o2em with F9, in REM statements the keywords are converted to uppercase. I downloaded the windows o2em zip version from the link in the forum and ran it with Wine. Attached are both the new binary and the source (.lst) Title: Re: Swell Foop (in C7420 Basic) Post by: Rafael on May 14, 2012, 01:20:21 AM Here I had error on 1100 ???
Edit: Anyway the .k7 work nice :) Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 14, 2012, 07:33:14 AM Here I had error on 1100 ??? Hmm.. which version of o2em did you use ?Quote Edit: Anyway the .k7 work nice :) Thanks, the search routine and the dropping down/shifting empty rows can be optimized a lot and then it will be perfectly playable. Title: Re: Swell Foop (in C7420 Basic) Post by: manopac on May 14, 2012, 09:27:39 AM Here I had error on 1100 ??? Hmm.. which version of o2em did you use ?I think it was the long lines problem - for me it also got a syntax error in 1100 with the long lines, after trimming it worked I guess I will have to rework the migration code in O2EM to trim a line before reading it, which is a big change, as I read the file currently byte by byte, not line by line ;-) Title: Re: Swell Foop (in C7420 Basic) Post by: Rafael on May 14, 2012, 10:31:06 PM [Hmm.. which version of o2em did you use ? Hi, I tested in version 1.20.01b and 1.20b5. Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 28, 2012, 11:16:51 PM This one is fully working, let me know what you think of this game.
Code: 1000 REM Swell Foop for Videopac+ 1010 REM by gertk(at)xs4all.nl 1020 REM clear screen, disable status line 1030 INIT 0 1040 PRINTCHR$(150); 1050 STORE 1060 TX 2,3,0 1070 PRINT "VViiddeeooppaacc "; 1080 PRINT "CC77442200" 1090 PRINT "VViiddeeooppaacc "; 1100 PRINT "CC77442200" 1110 TX 3,3,0 1120 PRINT 1130 PRINT 1140 PRINT "SSwweellll FFoooopp" 1150 PRINT "SSwweellll FFoooopp" 1160 PRINT 1170 PRINT 1180 TX 4,0,0 1190 PRINT "(c)2012 gertk@xs4all.nl"; 1200 DISPLAY:SCREEN 1210 GOSUB 3570 1220 INIT 0 1230 PRINTCHR$(150); 1240 STORE 1250 TX 7,0,0 1260 PRINT "Swell Foop is a puzzle "; 1270 PRINT "game." 1280 PRINT 1290 PRINT "The goal is to remove"; 1300 PRINT " as many objects" 1310 PRINT "as possible in "; 1320 PRINT "as few moves as" 1330 PRINT "possible." 1340 PRINT "Objects adjacent to each"; 1350 PRINT " other get" 1360 PRINT "removed as as a group." 1370 PRINT "The remaining objects"; 1380 PRINT " then collapse" 1390 PRINT "to fill in the gaps and"; 1400 PRINT " new groups are" 1410 PRINT "formed." 1420 PRINT "You cannot remove single"; 1430 PRINT " objects." 1440 PRINT 1450 REM reset score 1460 SC=0 1470 REM board dimensions and nr. of colors 1480 MX=14:MY=9:NC=3 1490 REM define graphics characters 1500 SETET 37,"003e7f7f7f7f7f7f3e00" 1510 SETET 38,"00412214080814224100" 1520 DIM BD(MX,MY) 1530 REM pseudo stack for search 1540 DIM SX(MX*MY),SY(MX*MY) 1550 REM fill array 1560 FOR X=0 TO MX 1570 FOR Y=0 TO MY 1580 BD(X,Y)=1+INT(RND(1)*NC) 1590 NEXT Y 1600 NEXT X 1610 PY=MY:PX=0 1620 EX=MX 1630 TX 2,0,0 1640 PRINT "press button to start.." 1650 DISPLAY:SCREEN 1660 GOSUB 3570 1670 INIT 0 1680 PRINTCHR$(150); 1690 REM main loop 1700 GOSUB 2990 1710 GOSUB 3190 1720 SOUND 6 1730 STORE 1740 MD=1:DX=PX:DY=PY:GOSUB 2840 1750 SCREEN:DISPLAY 1760 REM wait for joystick movement 1770 JS=ACTION(0):IF JS=0 THEN 1770 1780 REM action button pressed 1790 IF JS AND 1 THEN 1940 1800 STORE 1810 MD=0:DX=PX:DY=PY:GOSUB 2840 1820 SCREEN:DISPLAY 1830 REM check directional movement 1840 IF JS AND 8 THEN PY=PY+1 1850 IF PY>MY THEN PY=MY 1860 IF JS AND 16 THEN PY=PY-1 1870 IF PY<0 THEN PY=0 1880 IF JS AND 2 THEN PX=PX+1 1890 IF PX>MX THEN PX=MX 1900 IF JS AND 4 THEN PX=PX-1 1910 IF PX<0 THEN PX=0 1920 GOTO 1730 1930 REM action ! 1940 FC=BD(PX,PY) 1950 REM check for empty space 1960 IF FC=0 THEN SOUND 5:GOTO 1730 1970 REM set search coordinates 1980 FX=PX:FY=PY 1990 REM reset yield 2000 YD=0 2010 STORE 2020 GOSUB 2230 2030 SOUND 1 2040 REM show yield in double height 2050 TX 7,1,0 2060 CURSORY 10:CURSORX 33 2070 PRINT"Yield:"; 2080 CURSORY 11:CURSORX 33 2090 PRINT"Yield:"; 2100 CURSORY 12:CURSORX 33 2110 PRINT STR$(YD);" "; 2120 CURSORY 13:CURSORX 33 2130 PRINT STR$(YD);" "; 2140 REM force screen update and redraw 2150 DISPLAY:SCREEN 2160 REM check fall or swoop 2170 GOSUB 2350 2180 REM calculate score 2190 IF YD<2 THEN SOUND 8:GOTO 1730 2200 SC=SC+(YD-2)^2 2210 GOTO 1700 2220 REM search start 2230 SP=0 2240 REM searchloop 2250 X=FX+1:Y=FY:GOSUB 2730 2260 X=FX-1:Y=FY:GOSUB 2730 2270 X=FX:Y=FY-1:GOSUB 2730 2280 X=FX:Y=FY+1:GOSUB 2730 2290 REM if no adjacent pieces found 2300 IF SP=0 THEN RETURN 2310 REM get next coordinates from stack 2320 FX=SX(SP):FY=SY(SP):SP=SP-1 2330 GOTO 2250 2340 REM swoop or fall 2350 FOR X=0 TO EX 2360 Y=MY 2370 CC=0 2380 IF BD(X,Y)=0 THEN 2430 2390 IF CC>0 THEN 2450 2400 Y=Y-1 2410 IF Y<0 THEN 2530 2420 GOTO 2380 2430 CC=CC+1 2440 GOTO 2400 2450 FOR Z=Y TO 0 STEP -1 2460 BD(X,Z+CC)=BD(X,Z) 2470 NEXT Z 2480 Y=Y+CC 2490 CC=CC-1 2500 BD(X,CC)=0 2510 IF CC=0 THEN 2400 2520 GOTO 2490 2530 NEXT X 2540 REM check for empty rows 2550 X=0 2560 IF BD(X,MY) THEN 2690 2570 IF X>EX THEN 2710 2580 FOR S=X TO EX-1 2590 FOR T=0 TO MY 2600 BD(S,T)=BD(S+1,T) 2610 NEXT T 2620 NEXT S 2630 FOR T=0 TO MY 2640 BD(EX,T)=0 2650 NEXT T 2660 EX=EX-1 2670 if EX<0 THEN 2710 2680 GOTO 2560 2690 X=X+1 2700 IF X<EX THEN 2560 2710 RETURN 2720 REM check limits and piece for color 2730 IF Y>MY OR Y<0 THEN RETURN 2740 IF X>EX OR X<0 THEN RETURN 2750 IF BD(X,Y)<>FC THEN RETURN 2760 REM found same color, push on stack 2770 SP=SP+1:SX(SP)=X:SY(SP)=Y 2780 DX=X:DY=Y:MD=1:GOSUB 2840 2790 BD(X,Y)=0 2800 REM increase yield counter 2810 YD=YD+1 2820 RETURN 2830 REM display white cross if empty 2840 IF BD(DX,DY) THEN 2920 2850 ET 7*MD,3,MD 2860 CURSORX DX*2+1:CURSORY DY*2 2870 PRINT"&&"; 2880 CURSORX DX*2+1:CURSORY DY*2+1 2890 PRINT"&&"; 2900 RETURN 2910 REM display single piece 2920 ET BD(DX,DY),3,MD 2930 CURSORX DX*2+1:CURSORY DY*2 2940 PRINT"%%"; 2950 CURSORX DX*2+1:CURSORY DY*2+1 2960 PRINT"%%"; 2970 RETURN 2980 REM draw board 2990 STORE 3000 REM display score 3010 CURSORY 0:CURSORX 33 3020 TX 6,1,0 3030 PRINT"Score:"; 3040 CURSORY 1:CURSORX 33 3050 PRINT"Score:"; 3060 CURSORY 2:CURSORX 33 3070 PRINT STR$(SC); 3080 CURSORY 3:CURSORX 33 3090 PRINT STR$(SC); 3100 REM draw all pieces in mode 0 3110 MD=0 3120 FOR DY=0 TO MY 3130 FOR DX=0 TO MX 3140 GOSUB 2920 3150 NEXT DX 3160 NEXT DY 3170 DISPLAY:SCREEN 3180 RETURN 3190 X=0 3200 Y=MY 3210 C=0 3220 IF BD(X,Y)=0 THEN 3280 3230 GOSUB 3320 3240 IF C>0 THEN RETURN 3250 Y=Y-1 3260 IF Y>=0 THEN 3210 3270 GOTO 3290 3280 IF X=0 AND Y=MY THEN 3440 3290 X=X+1 3300 IF X>EX THEN 3450 3310 GOTO 3200 3320 FC=BD(X,Y) 3330 IF (X-1)<0 THEN 3350 3340 IF BD(X-1,Y)=FC THEN 3420 3350 IF (X+1)>EX THEN 3370 3360 IF BD(X+1,Y)=FC THEN 3420 3370 IF (Y-1)<0 THEN 3390 3380 IF BD(X,Y-1)=FC THEN 3420 3390 IF (Y+1)>MY THEN 3410 3400 IF BD(X,Y+1)=FC THEN 3420 3410 RETURN 3420 C=C+1 3430 RETURN 3440 SC=SC+1000 3450 TX 6,1,0 3460 CURSORY 2:CURSORX 33 3470 PRINT STR$(SC); 3480 CURSORY 3:CURSORX 33 3490 PRINT STR$(SC); 3500 TX 2,1,1 3510 CURSORY 4:CURSORX 10 3520 PRINT "GAME OVER"; 3530 CURSORY 5:CURSORX 10 3540 PRINT "GAME OVER" 3550 GOSUB 3570 3560 RUN 3570 JS=ACTION(0) 3580 IF JS<>0 THEN 3570 3590 JS=ACTION(0) 3600 IF (JS AND 1)=0 THEN 3590 3610 RETURN 3620 END Title: Re: Swell Foop (in C7420 Basic) Post by: manopac on May 28, 2012, 11:43:41 PM cool game :-)
Title: Re: Swell Foop (in C7420 Basic) Post by: Rafael on May 29, 2012, 02:02:27 AM Great :D
No more a long time wait for the last movements, and also cleaning bonus. Thereīs no chance to include a kind of grid on it ??? Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on May 29, 2012, 07:21:44 AM Great :D Speed improved a lot by some rethinking of the test routines, at first I was testing a whole column piece by piece to check if it was empty realizing later that I only needed to test the bottom piece :)No more a long time wait for the last movements, and also cleaning bonus. Quote Thereīs no chance to include a kind of grid on it ??? Yes that should be possible, I used a single redefined character as object and then display it double height and width, by using 4 redefined characters at normal size it is possible to make an outline and smoother objects. The background color is also not used yet. I first concentrated on the game algorithms which proved much more of a challenge than I thought :)BTW, to make the game a bit more difficult try setting NC to a number greater than 3 (and less than 7) in line 1480 The more different colors the lesser the chance you have large fields of the same color. You can also set the board dimensions MX and MY Code: 1480 MX=14:MY=9:NC=3 The structure of the code is such that it should be possible to translate the whole game into 8048 assembler. Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on June 03, 2012, 05:59:51 PM Some minor changes, endgame detection sped up a bit by removing redundant checks.
And a grid is visible too :D Enjoy! Code: 1000 REM Swell Foop for Videopac+ 1010 REM by gertk(at)xs4all.nl 1020 REM clear screen, disable top line 1030 INIT 0 1040 PRINTCHR$(150); 1050 STORE 1060 TX 2,3,0 1070 PRINT "VViiddeeooppaacc "; 1080 PRINT "CC77442200" 1090 PRINT "VViiddeeooppaacc "; 1100 PRINT "CC77442200" 1110 TX 3,3,0 1120 PRINT 1130 PRINT 1140 PRINT "SSwweellll FFoooopp" 1150 PRINT "SSwweellll FFoooopp" 1160 PRINT 1170 PRINT 1180 TX 4,0,0 1190 PRINT "(c)2012 gertk@xs4all.nl"; 1200 DISPLAY:SCREEN 1210 FOR T=1 TO 2000:NEXT T 1220 INIT 0 1230 PRINTCHR$(150); 1240 STORE 1250 TX 7,0,0 1260 PRINT "Swell Foop is a puzzle "; 1270 PRINT "game." 1280 PRINT 1290 PRINT "The goal is to remove"; 1300 PRINT " as many objects" 1310 PRINT "as possible in "; 1320 PRINT "as few moves as" 1330 PRINT "possible." 1340 PRINT "Objects adjacent to each"; 1350 PRINT " other get" 1360 PRINT "removed as a group." 1370 PRINT "The remaining objects"; 1380 PRINT " then collapse" 1390 PRINT "to fill in the gaps and"; 1400 PRINT " new groups are" 1410 PRINT "formed." 1420 PRINT "You cannot remove single"; 1430 PRINT " objects." 1440 PRINT 1450 TX 2,0,0 1460 PRINT "press button to start.." 1470 DISPLAY:SCREEN 1480 GOSUB 3570 1490 REM reset score 1500 SC=0 1510 REM board dimensions and nr. of colors 1520 MX=15:MY=10:NC=4 1530 REM define graphics characters 1540 SETET 37,"00fefefefefefefefefe" 1550 SETET 38,"00412214080814224100" 1560 DIM BD(MX,MY) 1570 REM pseudo stack for search 1580 DIM SX(MX*MY),SY(MX*MY) 1590 REM fill array 1600 FOR X=0 TO MX 1610 FOR Y=0 TO MY 1620 BD(X,Y)=1+INT(RND(1)*NC) 1630 NEXT Y 1640 NEXT X 1650 PY=MY:PX=0 1660 EX=MX 1670 INIT 4 1680 PRINTCHR$(150); 1690 REM main loop 1700 GOSUB 3010 1710 GOSUB 3210 1720 SOUND 6 1730 STORE 1740 MD=1:DX=PX:DY=PY:GOSUB 2840 1750 SCREEN:DISPLAY 1760 REM wait for joystick movement 1770 JS=ACTION(0):IF JS=0 THEN 1770 1780 REM action button pressed 1790 IF JS AND 1 THEN 1940 1800 STORE 1810 MD=0:DX=PX:DY=PY:GOSUB 2840 1820 SCREEN:DISPLAY 1830 REM check directional movement 1840 IF JS AND 8 THEN PY=PY+1 1850 IF PY>MY THEN PY=MY 1860 IF JS AND 16 THEN PY=PY-1 1870 IF PY<0 THEN PY=0 1880 IF JS AND 2 THEN PX=PX+1 1890 IF PX>MX THEN PX=MX 1900 IF JS AND 4 THEN PX=PX-1 1910 IF PX<0 THEN PX=0 1920 GOTO 1730 1930 REM action ! 1940 FC=BD(PX,PY) 1950 REM check for empty space 1960 IF FC=0 THEN SOUND 5:GOTO 1730 1970 REM set search coordinates 1980 FX=PX:FY=PY 1990 REM reset yield 2000 YD=0 2010 STORE 2020 GOSUB 2230 2030 SOUND 1 2040 REM show yield in double height 2050 TX 7,1,0 2060 CURSORY 10:CURSORX 33 2070 PRINT"Yield:"; 2080 CURSORY 11:CURSORX 33 2090 PRINT"Yield:"; 2100 CURSORY 12:CURSORX 33 2110 PRINT STR$(YD);" "; 2120 CURSORY 13:CURSORX 33 2130 PRINT STR$(YD);" "; 2140 REM force screen update and redraw 2150 DISPLAY:SCREEN 2160 REM check fall or swoop 2170 GOSUB 2350 2180 REM calculate score 2190 IF YD<2 THEN SOUND 8:GOTO 1730 2200 SC=SC+(YD-2)^2 2210 GOTO 1700 2220 REM search start 2230 SP=0 2240 REM searchloop 2250 X=FX+1:Y=FY:GOSUB 2730 2260 X=FX-1:Y=FY:GOSUB 2730 2270 X=FX:Y=FY-1:GOSUB 2730 2280 X=FX:Y=FY+1:GOSUB 2730 2290 REM if no adjacent pieces found 2300 IF SP=0 THEN RETURN 2310 REM get next coordinates from stack 2320 FX=SX(SP):FY=SY(SP):SP=SP-1 2330 GOTO 2250 2340 REM swoop or fall 2350 FOR X=0 TO EX 2360 Y=MY 2370 CC=0 2380 IF BD(X,Y)=0 THEN 2430 2390 IF CC>0 THEN 2450 2400 Y=Y-1 2410 IF Y<0 THEN 2530 2420 GOTO 2380 2430 CC=CC+1 2440 GOTO 2400 2450 FOR Z=Y TO 0 STEP -1 2460 BD(X,Z+CC)=BD(X,Z) 2470 NEXT Z 2480 Y=Y+CC 2490 CC=CC-1 2500 BD(X,CC)=0 2510 IF CC=0 THEN 2400 2520 GOTO 2490 2530 NEXT X 2540 REM check for empty columns 2550 X=0 2560 IF BD(X,MY) THEN 2690 2570 IF X>EX THEN 2710 2580 FOR S=X TO EX-1 2590 FOR T=0 TO MY 2600 BD(S,T)=BD(S+1,T) 2610 NEXT T 2620 NEXT S 2630 FOR T=0 TO MY 2640 BD(EX,T)=0 2650 NEXT T 2660 EX=EX-1 2670 if EX<0 THEN 2710 2680 GOTO 2560 2690 X=X+1 2700 IF X<EX THEN 2560 2710 RETURN 2720 REM check limits and piece for color 2730 IF Y>MY OR Y<0 THEN RETURN 2740 IF X>EX OR X<0 THEN RETURN 2750 IF BD(X,Y)<>FC THEN RETURN 2760 REM found same color, push on stack 2770 SP=SP+1:SX(SP)=X:SY(SP)=Y 2780 DX=X:DY=Y:MD=1:GOSUB 2840 2790 BD(X,Y)=0 2800 REM increase yield counter 2810 YD=YD+1 2820 RETURN 2830 REM display white cross if empty 2840 IF BD(DX,DY) OR MD=0 THEN 2920 2850 ET 7,3,MD 2860 CURSORX DX*2+1:CURSORY DY*2 2870 PRINT"&&"; 2880 CURSORX DX*2+1:CURSORY DY*2+1 2890 PRINT"&&"; 2900 RETURN 2910 REM display single piece 2920 DC=BD(DX,DY) 2930 IF DC>3 THEN DC=DC+1 2940 ET DC,3,MD 2950 CURSORX DX*2+1:CURSORY DY*2 2960 PRINT"%%"; 2970 CURSORX DX*2+1:CURSORY DY*2+1 2980 PRINT"%%"; 2990 RETURN 3000 REM draw board 3010 STORE 3020 REM display score 3030 CURSORY 0:CURSORX 33 3040 TX 6,1,0 3050 PRINT"Score:"; 3060 CURSORY 1:CURSORX 33 3070 PRINT"Score:"; 3080 CURSORY 2:CURSORX 33 3090 PRINT STR$(SC); 3100 CURSORY 3:CURSORX 33 3110 PRINT STR$(SC); 3120 REM draw all pieces in mode 0 3130 MD=0 3140 FOR DY=0 TO MY 3150 FOR DX=0 TO MX 3160 GOSUB 2920 3170 NEXT DX 3180 NEXT DY 3190 DISPLAY:SCREEN 3200 RETURN 3210 X=0 3220 Y=MY 3230 C=0 3240 IF BD(X,Y)=0 THEN 3300 3250 GOSUB 3340 3260 IF C>0 THEN RETURN 3270 Y=Y-1 3280 IF Y>=0 THEN 3230 3290 GOTO 3310 3300 IF X=0 AND Y=MY THEN 3420 3310 X=X+1 3320 IF X>EX THEN 3430 3330 GOTO 3220 3340 FC=BD(X,Y) 3350 IF (X+1)>EX THEN 3370 3360 IF BD(X+1,Y)=FC THEN 3400 3370 IF (Y-1)<0 THEN 3390 3380 IF BD(X,Y-1)=FC THEN 3400 3390 RETURN 3400 C=C+1 3410 RETURN 3420 SC=SC+1000 3430 STORE 3440 TX 6,1,0 3450 CURSORY 2:CURSORX 33 3460 PRINT STR$(SC); 3470 CURSORY 3:CURSORX 33 3480 PRINT STR$(SC); 3490 TX 7,3,1 3500 CURSORY 4:CURSORX 7 3510 PRINT "GGAAMMEE OOVVEERR"; 3520 CURSORY 5:CURSORX 7 3530 PRINT "GGAAMMEE OOVVEERR"; 3540 DISPLAY:SCREEN 3550 GOSUB 3570 3560 RUN 1490 3570 JS=ACTION(0) 3580 IF JS<>0 THEN 3570 3590 JS=ACTION(0) 3600 IF (JS AND 1)=0 THEN 3590 3610 RETURN 3620 END Title: Re: Swell Foop (in C7420 Basic) Post by: Rafael on June 03, 2012, 08:44:43 PM Beautifull, Gert :)
Now, with 4 colors itīs hardest, too. Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on June 03, 2012, 10:27:17 PM Indeed with 4 colors you need to plan your moves a lot more :)
BTW: The Basic source above is generated by a pre-processor. I write the program with a text-editor and use labels instead of line numbers which makes it a lot easier to add and remove code. The pre-processor then replaces all the labels by linenumbers. I wrote that pre-processor a long long time ago for another basic computer. The input code is attached for anyone interested and is probably a lot more readable as it contains lots of comment :) If I can find some time I will try and translate the program to 8048 assembler. I will leave this code as it is for now. First I want to concentrate on my Multicartridge PCB design and get to grips with either Eagle or Designspark ;:) Title: Re: Swell Foop (in C7420 Basic) Post by: Rafael on June 04, 2012, 12:17:11 AM Indeed with 4 colors you need to plan your moves a lot more :) Itīs just because you not included an undo button :) Do you have an idea when the multcart will be ready? Title: Re: Swell Foop (in C7420 Basic) Post by: timdu on June 20, 2012, 03:25:21 PM Hi
First, let me say that GertK has been extremely helpful. I have been sending him messages for the past few days and he has been answering me quite promptly. I figured I would move my question to the public forum so others can see. I read about Swell Foop and I became curious and wanted to try it out. I'm in the USA so I have to use the new O2EM emulator 1.20 Anyway, here is what I do: I load O2EM, and then go into the Videopac folder and choose the C7420 Basic cartridge. That loads and I get the SELECT GAME, SELECT GAME, SELECT GAME, SELECT GAME screen in different colors. Then I press 0. I get the Videopac BASIC and OK prompt. Press F9 and I load the swell.txt file that I saved which has GertK's BASIC listing. I get a message that it loaded successfully and then I type RUN I get the Title screen and instructions... press button to continue. I press SCROLL LOCK on my keyboard and to emulate the joysticks... then I press L ( for the fire button) the program looks like it is going to continue and then I get ? SN ERROR IN 3370 Anyone have any ideas? thanks Tim Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on June 20, 2012, 06:32:26 PM Hi Tim,
What does LIST 3370 (enter) say ? You need to press BREAK to keep the listing from scrolling too far but you should be able to see what is going on on that line. Title: Re: Swell Foop (in C7420 Basic) Post by: timdu on June 21, 2012, 03:48:18 PM This was my fault ;:)
When I looked at that line, it was incomplete. I compared it to your code and it was missing some of the text. Strange. Perhaps it didn't copy and paste correctly when I was making the text file. It is running fine. Thank you! Tim Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on June 21, 2012, 06:54:04 PM Great! :)
Title: Re: Swell Foop (in C7420 Basic) Post by: Rafael on July 05, 2012, 11:09:42 PM I Swell the game starts with the pieces totally randomly. Do you know if is possible to clean the pieces in every game?
Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on July 06, 2012, 07:33:25 AM I Swell the game starts with the pieces totally randomly. Do you know if is possible to clean the pieces in every game? Since the pieces are layed out randomly it could be that a board is impossible to clean. If there is a way to set the random 'seed' it might be possible to generate the same board over and over and then try different strategies to clear the board. I am not sure if this is possible with the random function in C7420 basic. I did notice that if I reset the G7400 and press '0' to start the Basic, load the game and type RUN, then the first board always looks the same. Title: Re: Swell Foop (in C7420 Basic) Post by: manopac on July 06, 2012, 09:03:23 AM of course it does :-) the emulator runs deterministic, i.e. the program always behaves the same every time you start it (which means that the seed value is always set to the same value in the beginning, if you don't do anything that is dependent on external values (like user input) that changes the number of executed cycles until the first randomizer is started - if you would wait for a joystick input BEFORE you first use the random, the board should be different ...
Title: Re: Swell Foop (in C7420 Basic) Post by: gertk on July 06, 2012, 07:47:22 PM of course it does :-) the emulator runs deterministic, i.e. the program always behaves the same every time you start it (which means that the seed value is always set to the same value in the beginning I know, but maybe we can use this to our advantage to generate random boards but from a known seed so you can try different strategies to solve it. That way you can share 'seeds' and see who can get the best score for that board. Quote if you don't do anything that is dependent on external values (like user input) that changes the number of executed cycles until the first randomizer is started - if you would wait for a joystick input BEFORE you first use the random, the board should be different ... And I have never seen a 'familiar' board after the first one, maybe we can find out where the seed is stored. On my mbed C7420 emulator it behaves consistent too so the random routine may be tricked/spoofed. Title: Re: Swell Foop (in C7420 Basic) Post by: manopac on July 07, 2012, 12:04:39 AM well - my guess is that it can only work with the values the BASIC calculates and wouldn't access any other hardware registers
its probably something simple like "add one for every basic command executed" ;-) it also shouldn't be too difficult to find out the location it is stored at ... write a program that only calculates random numbers and dump the memory after each loop - then compare the memory dumps and look for the values that changed ;-) |