Skip to content

Instantly share code, notes, and snippets.

@Woflox

Woflox/vxor.p8 Secret

Last active May 11, 2024 21:17
Show Gist options
  • Save Woflox/bd1b94e20da8c3feedeb1590ea299c87 to your computer and use it in GitHub Desktop.
Save Woflox/bd1b94e20da8c3feedeb1590ea299c87 to your computer and use it in GitHub Desktop.
VXOR unminified & commented source code
--vxor by eric billingsley
--released under cc by-nc-sa 4.0
--shift selection with wrapping (selection, board, and goal are each
--respresented as numbers, using 25 bits to represent the board positions)
function shift(button,mask,shiftamount)
--bitshift the selection. use a mask to shift the wrapping row/column
--separately and in the opposite direction by 4
if (getinput(button)) selection=(selection&~mask)>>>shiftamount|(selection&mask)<<shiftamount*4
end
--make moves based on inputs
function makemoves()
shift(0,0x8421.08,-1)--left
shift(1,0x842.108,1)--right
shift(2,-2048,-5)--up
shift(3,.06055,5)--down
--xor selection with board
--when pressing ❎
if (getinput(5)) board^^=selection
end
level=0
--generic draw board function, taking in a bitfield
--representing the positions to draw
function draw(board,glyph,colour)
for i=0,24 do
--if bit is set, calculate position based on index and draw glyph there
if (board&1<<15-i!=0) ?glyph,43+i%5*9,y+i\5*9,colour
end
end
::initlevel::
--every 5 levels, reset state to a single center light (board state 8)
--so things don't get out of control too quickly. also switch the colour
if (level%5==0) board=8 colour=9+level%6
--on new level, generate a random sound
--(gets a bit more complex-sounding at higher levels)
sound=rnd(level)
selection=board
level+=1
--while generating level, override getinput to be random
getinput=function()
--this probability gets higher as levels increase in order to generate
--more complex puzzles. things will break as the number reaches 0 at
--level 256 which is not ideal...
return rnd()>.96^level
end
initialstate=board
::generationloop::
--make a move with random inputs
makemoves()
--continue looping until the board is different from initial state and
--not empty. also loop back if we get a positive result from getinput(),
--which is a random probability that increases with level number.
--this means later levels tend to require more steps.
if(getinput() or board==0 or initialstate==board)goto generationloop
--now that the level is generated, set the board to initial state
--and set getinput to actually check button presses
goal=board
selection=initialstate
board=initialstate
getinput=btnp
::mainloop::
--if we have a sound, play it using a print command. the g is added
--because it sounds nice. ideally would also like to turn on reverb level 1
--using poke, but don't have the chars...
if(sound>0)?"⁷g"..sound
--refresh the screen & inputs
flip()
cls()
--print level number in top corner
?level
--if any button is pressed, a sound is generated based on the bitfield.
--3.5 was chosen through trial & error because it produced good sounds
sound=getinput()*3.5
--set vertical draw position for top board
y=13
--this string prints as a 7x7 circle outline,
--used to draw the grid & selection
o="(ᵇ~ノᵇk-)"
makemoves()
--reset puzzle when 🅾️ pressed.
--ideally we would reset selection also but don't have the characters.
if(getinput(4))board=initialstate
--draw top board
draw(~0,o,1)--grid (~0 is all 1s)
draw(board,"●",colour)--lights
draw(selection,o,7)--selection (white circle outlines)
--if we have the solution, generate a new puzzle.
--since we haven't drawn the bottom board yet, it will flash black
--for a frame, which gives some feedback to the player
if(board==goal)goto initlevel
--draw bottom board
y=73
draw(~0,o,1)--grid
draw(goal,"●",12)--lights
goto mainloop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment