Free Cell, in 1022 characters of code, and no sprites! twitter | itch
CONTROLS:
- click and drag cards around
- you cannot move stacks of cards; one at a time only!
- stack descending cards of alternating colors in the main play area
- any card may be placed in an empty column of the main area
- store any card in the four "free cells" at the top left
- make a stack of each suit A->K in the top right to win
- reset the cart to start a new game
ONE AT A TIME?
You can only move one card at a time; if you want to move a stack of cards you have to take it apart and put it back together manually. This is different from "standard" solitaire, and it makes Free Cell particularly interesting! It also makes the implementation a bit easier to fit into the tiny code-size constraint ;)
I WON!
Congrats! Enjoy the win animation here: https://pancelor.itch.io/solitaire-win-animation (I wanted to add a "you win" animation to this game, but I didn't have the room to fit it in... so I made it as a separate cartridge)
SOURCE CODE
The source is in the cart, of course, but it's here too. Remember to enable puny text mode (cmd-p) before pasting this into your local PICO-8 console:
A=add W=12w=13Z=16s={}B={}Q=1T=0M=9q=poke2 function F(i)S=s[i]J=i\W I=i\8O=1-I U=I*(i-8+J)*14+O*i*Z+2V=O*max(#S*6+22,28)+5end for i=0,51do s[i]={m=i\W}A(B,{x=i,y=400,k=i+i\w*3},rnd(i+1)+1)end q(-15-๐,264,2043,4,3843)D=rectfill::_::L=T%8T+=1K=B[T]N=not btn(5)X=stat(32)-6Y=stat(33)-8C=fillp if(T>52)q(14-๐,3)M=T%3 for i=15,0,-1do F(i)M|=S.m C(โ)a=5+O*28D(U,a,U+W,a+Z,2)C()for _ENV in all(S)do x=u+3*x+.5>>2y=v+3*y+.5>>2end G=abs(X-U)\8+abs(Y-V)\Z<<6v=S[#S]k=w if(v)k=v.k if(2>>k%Z>M+J*2)K=A(B,del(B,v))L=W+k\Z if(H and N and(J+G+#S<1or Z-I|k+G==Z|1+H.k^^32or H.k==J+k|G))K=H L=i if(btnp(5+J+G))H=A(B,del(B,v))end if(K)del(s[K.h],A(s[L],K))F(L)S.m/=2K.u,K.v,K.h=U,V,L?"โทi6v1d1" if(H)H.x,H.y=X,Y if(N)H=nil for r in all(B)do x=r.x y=r.y q(63-๐,244)D(x-1,y-1,x+W,y+Z,4)q(61-๐,-1,-1)D(x,y,x+W,y+Z,3)a=r.k%Z+1?(a==10and"³f|³f0 ³b"or sub("a23456789|jqk",a,a).." ³d")..split("♥,โ,โโต8f..³aแถ3.,โโต8fใ")[r.k\Z+1],x+1,y+1,r.k\32 for i=0,77do pset(x+W-i%w,y+Z-i\w,pget(x+i%w,y+i\w))end end?"โโถ1โถc6",X+2,Y+7,5 if(M< Q/โง)Q=0?"โทceg4" goto _ |
(there's an extra space in there near the end because the BBS text editor seems to choke on the < symbol)
An earlier, more readable, and much longer version of this code can be found here
SOME CODE HIGHLIGHTS
Some of the more bizarre tricks I used to squeeze every bit of functionality out of my 1024-character budget:
- set the palette with
poke2(-15-๐,264,2043,4,3843)
- update card positions with
for _ENV in all(S)do x=u+3*x+.5>>2y=v+3*y+.5>>2end
- dynamically cast shadows with a very particular palette and
poke2(63-๐,244)rectfill(x-1,y-1,x+W,y+Z,4)poke2(61-๐,-1,-1)
- draw the 4 suit icons with
split("♥,โ,โโต8f..³aแถ3.,โโต8fใ")[suit_id]
- check if you can drop your held card with
i\12+G+#S<1or 16-i\8|k+G==16|1+H.k^^32or H.k==i\12+k|G
-
wait until the next frame and clear the screen with
?"โถ1โถc6"
- (thanks to zep for pointing out that \^ can be written as โถ!)
- auto-move cards to the top right by tracking the minimum stack height with bitshifting (search for M (and m) to see the relevant code)
- check whether the game is won by taking advantage of the fact that
2^12<โง and โง<2^13
I'M SORRY, "poke2(63-๐,244)"???
Yeah! 63-๐ is 24414.5, which is the address I need to poke to get those slick shadows! Check out this post for more info.
I love freecell! And this is absolutely incredible how you did this. Thanks for the code highlights section, so wild!
first of all, love to play this whenever i'm bored; perfectly minimal rendition of my favourite solitaire type
however, "you may ask yourself,"
(this is the one and only time i've gotten this, though)
@Thego124 thank you :) That screenshot is fascinating! I can't figure out what's going on here. Where'd the queen go!? I assume this happened around 18 or 36 minutes into the game..? (there's a counter that wraps around at that point)
[Please log in to post a comment]