tuxDB - linux gaming aggregate
TUXDB - LINUX GAMING AGGREGATE
 NEWS TOP_PLAYED GAMES ITCH.IO CALENDAR CHAT WINE SteamDeck
 STREAMERS CREATORS CROWDFUNDING DEALS WEBSITES ABOUT
 PODCASTS REDDIT 

 

SUPPORT TUXDB ON KO-FI

MENU

ON SALE

New Twitch streamer aggregation implemented (#FuckTwitch) due to Twitch's API issues (more info on my Discord )


https://pancelor.itch.io/free-cell-1k


A demake of one of my favorite solitaire variants: Free Cell

Made in just 1022 characters of code, with no pre-drawn sprites!


> RULES / 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
  • cmd-r to start a new game

The web version drops your cards if you accidentally move your mouse outside the game window; this behavior is less annoying in the downloaded versions.


> 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)



> 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 this out)
  • 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.


> SYMBOL SOUP

Here's the full code; 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 _

An earlier, more readable, and much longer version of this code can be found here