PurePuzzle (it's a Puzzle Game, duh)

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
diceman
User
User
Posts: 34
Joined: Tue Apr 10, 2018 9:42 pm

PurePuzzle (it's a Puzzle Game, duh)

Post by diceman »

Hello everyone, I haven't been posting a lot in this forum, been busy in the german version of the board, though. :)
I've made a litte puzzle game, which I wanted to share with you guys. I challenged myself to get something done during Global GameJam, in less than 500 Lines of Code. In the end I got a lot of lines left so I've put all sorts of fancy stuff in it, like a difficulty selection menu, and animated tiles.

I'm posting the barebones code here (~480 lines total), so you can copy/paste it and try it for yourself. I hope that's not to big?
If you want to have the full experience with sounds, I urge you to download the current version, though. I've linked it farther down this thread (source code is still included):

- You need to provide a .jpg image for the program to reckognize. Any .jpg image will do, the program will adjust it to a proper size and keep the aspect ratio intact (FileRequester() will ask you to pick a .jpg)
- Select a difficulty
- Mind that, depending on measurements of your image, there might be a fixed border layout. The interactive puzzle part will be located in it's center.
- Right clicking a tile will rotate it by 90° clockwise
- Left-Clicking a tile tags/untags it.
- As soon as there are 2 tiles tagged, they will swap positions.
- The program will reckognize, once the puzzle has been completed successfully.
- Press ESC or close the window to exit the game.

Now have fun, and thanks for having me! :)

Code: Select all

EnableExplicit
UseJPEGImageDecoder()

Declare selectDifficulty()
Declare ini()
Declare aspectResize(picID,newX,newY)
Declare loop()
Declare processInput()
Declare processTimer()
Declare checkPuzzle()
Declare checkTile(*pointer)
Declare clearTags()
Declare yay()
Declare inRange(value,min,max)

Structure TILE
	index.i
	trueX.i
	trueY.i
	x.i
	y.i
	xMicro.i
	yMicro.i
	xMicroDir.i
	yMicroDir.i
	rotation.i
	tagged.i
EndStructure
Global NewList tile.TILE()

#xRes = 1024
#yRes = 768
Global screen
Global pic
Global difficulty
Global selectSPR
Global selectX,selectY
Global marginSPR
Global Dim tileSPR(0)
Global tagSPR
Global frameSPR
Global xMax, yMax
Global xOffset, yOffset
Global xMargin, yMargin
Global tileSize
Global autoSnap
Global swapping
Global targetAngle
Global gameOver
Global Dim *tag.TILE(1)
Global frameDuration, frameFinished
Global perSecond.f

Enumeration
	#nullTag
	#tagged
	#locked
EndEnumeration

ini()
loop()
End





Procedure selectDifficulty()
	Define event
	Define diffSelection
	
	diffSelection = OpenWindow(#PB_Any, 0, 0, 160, 310, "Select Difficulty", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ButtonGadget(2,30,20,100,20,"Why even play")
	ButtonGadget(3,30,45,100,20,"I hate Puzzles")
	ButtonGadget(4,30,70,100,20,"Easy")
	ButtonGadget(5,30,95,100,20,"Medium")
	ButtonGadget(6,30,120,100,20,"Harder")
	ButtonGadget(7,30,145,100,20,"Challenge me")
	ButtonGadget(8,30,170,100,20,"Master")
	ButtonGadget(9,30,195,100,20,"This is work")
	ButtonGadget(10,30,220,100,20,"Masochistic")
	ButtonGadget(11,30,245,100,20,"Impossible")
	CheckBoxGadget(12,30,280,100,20,"AutoSnap",#PB_CheckBox_Center)
	SetGadgetState(12,#True)
	SetActiveWindow(diffSelection)
	Repeat
		event = WaitWindowEvent(16)
		difficulty = EventGadget()
	Until inRange(difficulty,2,11) Or event = #PB_Event_CloseWindow
	autoSnap = GetGadgetState(12)
	CloseWindow(diffSelection)
	If event = #PB_Event_CloseWindow
		End
	EndIf
EndProcedure



Procedure ini()
	Define fileName$	
	Define x, y
	Define xSize
	Define ySize
	Define factor.f
	Define newX, newY
	Define defSide
	Define count
	Dim puzzle(0,0)
	
	fileName$ = OpenFileRequester("Choose any JPG", "", "JPG|*.jpg", 0)
	If fileName$ = ""
		End
	EndIf
	
	selectDifficulty()
	
	If InitSprite()
		screen = OpenWindow(#PB_Any,0,0,#xRes,#yRes,"PurePuzzle (©diceman, 2018) v1.13",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
		If OpenWindowedScreen(WindowID(screen),0,0,#xRes,#yRes)
			InitKeyboard()
			InitMouse()
		EndIf
	EndIf 	
	
	;Bild laden und Größe anpassen
	pic = LoadImage(#PB_Any,fileName$)
	xSize = ImageWidth(pic)
	ySize = ImageHeight(pic)
	
	newX = #xRes
	factor = ySize/xSize
	newY = newX*factor
	If newY > #yRes
		newX = 0
		newY = #yRes
	Else
		newY = 0
	EndIf	
	aspectResize(pic,newX,newY)
	
	;Anzahl der Teile bestimmen
	xSize = ImageWidth(pic)
	ySize = ImageHeight(pic)
	If xSize > ySize
		defSide = ySize
	Else
		defSide = xSize
	EndIf
	tileSize = defSide/difficulty
	xMax = (xSize/tileSize)-1
	yMax = (ySize/tileSize)-1
	
	;Bild im Hintergrund zeichnen für weitere Operationen
	If StartDrawing(ScreenOutput())
		DrawImage(ImageID(pic),0,0)
		StopDrawing()
	EndIf
	
	;Rahmen erkennen
	xMargin = (xSize - ((xMax+1)*tileSize))/2
	yMargin = (ySize - ((yMax+1)*tileSize))/2
	xOffset = (#xRes-xSize)/2
	yOffset = (#yRes-ySize)/2
	
	;Teile als Sprites speichern
	count = -1
	For x = 0 To xMax
		For y = 0 To yMax
			count +1
			ReDim tileSPR(count)
			tileSPR(count) = GrabSprite(#PB_Any,(x*tileSize)+xMargin,(y*tileSize)+yMargin,tileSize,tileSize)
			AddElement(tile())
			tile()\index = count
			tile()\trueX = x
			tile()\trueY = y
		Next
	Next
	
	;Rahmen speichern
	If StartDrawing(ScreenOutput())
		DrawingMode(#PB_2DDrawing_Default)
		Box(xMargin,yMargin,(xMax+1)*tileSize,(yMax+1)*tileSize,RGB(0,0,0))
		StopDrawing()
	EndIf
	GrabSprite(marginSPR,0,0,xSize,ySize) ;Der Einfachheit halber wird das komplette Bild als Rahmen gespeichert und als unterste Ebene gezeichnet. Die Puzzleteile liegen darüber.
	
	;Puzzle mischen
	Dim puzzle(xMax,yMax)
	ForEach tile()
		Repeat
			tile()\x = Random(xMax)
			tile()\y = Random(yMax)
			tile()\rotation = Random(3)*90
		Until puzzle(tile()\x,tile()\y) = 0
		puzzle(tile()\x,tile()\y) = #True
	Next
	
	;übrige Sprites initialisieren
	tagSPR = CreateSprite(#PB_Any,tileSize,tileSize)
	If StartDrawing(SpriteOutput(tagSPR))
		DrawingMode(#PB_2DDrawing_Outlined)
		Box(0,0,tileSize,tileSize,RGB(255,0,0))
		Box(1,1,tileSize-2,tileSize-2,RGB(255,0,0))
		Box(3,3,tileSize-6,tileSize-6,RGB(255,0,0))
		StopDrawing()
	EndIf
	
	selectSPR = CreateSprite(#PB_Any,tileSize,tileSize)
	TransparentSpriteColor(selectSPR,RGB(255,0,0))
	
	frameSPR = CreateSprite(#PB_Any,tileSize,tileSize)
	If StartDrawing(SpriteOutput(frameSPR))
		DrawingMode(#PB_2DDrawing_Outlined)
		Box(0,0,tileSize,tileSize,RGB(255,255,255))
		StopDrawing()
	EndIf
EndProcedure



Procedure processInput()
	Define *pointer.TILE
	Define x, y
	Define count
	Define event
	Define absCount
	
	selectX = -1
	selectY = -1
	ForEach tile()
		If tile()\tagged <> #locked
			If inRange(WindowMouseX(screen), xOffset+xMargin+(tile()\x*tileSize)+tile()\xMicro, xOffset+xMargin+((tile()\x+1)*tileSize)+tile()\xMicro) And inRange(WindowMouseY(screen), yOffset+yMargin+(tile()\y*tileSize)+tile()\yMicro,yOffset+yMargin+((tile()\y+1)*tileSize)+tile()\yMicro)
				*pointer = @tile()
				selectX = *pointer\x
				selectY = *pointer\y
				Break
			EndIf
		EndIf
	Next
	
	event = WaitWindowEvent(16)   
	If swapping Or targetAngle
		ProcedureReturn #False
	EndIf   
	
	
	If event = #PB_Event_CloseWindow
		gameOver = 2
	EndIf
	
	If *pointer   
		If event = #PB_Event_LeftClick
			Select *pointer\tagged
				Case #tagged
					*pointer\tagged = #nullTag
					*tag(0) = #Null
				Case #nullTag
					*pointer\tagged = #tagged
					If *tag(0)
						count = 1
					EndIf
					*tag(count) = *pointer
					checkTile(*pointer)
			EndSelect
			If *tag(0) And *tag(1)
				swapping = #True
				For count = 0 To 1
					ChangeCurrentElement(tile(),*tag(count))
					MoveElement(tile(),#PB_List_Last)
					absCount = Abs(count-1)
					If *tag(count)\x > *tag(absCount)\x
						*tag(count)\xMicroDir = -1
					EndIf
					If *tag(count)\x < *tag(absCount)\x
						*tag(count)\xMicroDir = 1
					EndIf
					If *tag(count)\y > *tag(absCount)\y
						*tag(count)\yMicroDir = -1
					EndIf
					If *tag(count)\y < *tag(absCount)\y
						*tag(count)\yMicroDir = 1
					EndIf
				Next
			EndIf
		EndIf
		If event = #PB_Event_RightClick
			clearTags()
			*tag(0) = *pointer
			ChangeCurrentElement(tile(),*tag(0))
			MoveElement(tile(),#PB_List_Last)
			targetAngle = *tag(0)\rotation +90
		EndIf
	EndIf
EndProcedure



Procedure processTimer()
	Define count
	Define absCount
	
	If swapping
		For count = 0 To 1
			absCount = Abs(count-1)
			*tag(count)\xMicro + (*tag(count)\xMicroDir*Abs((*tag(count)\x*tileSize)-(*tag(absCount)\x*tileSize))*perSecond*4)
			*tag(count)\yMicro + (*tag(count)\yMicroDir*Abs((*tag(count)\y*tileSize)-(*tag(absCount)\y*tileSize))*perSecond*4)
			If *tag(count)\xMicroDir = -1 And (*tag(count)\x*tileSize)+*tag(count)\xMicro <= *tag(absCount)\x*tileSize
				*tag(count)\xMicroDir = 0
			EndIf
			If *tag(count)\xMicroDir = 1 And (*tag(count)\x*tileSize)+*tag(count)\xMicro >= *tag(absCount)\x*tileSize
				*tag(count)\xMicroDir = 0
			EndIf
			If *tag(count)\yMicroDir = -1 And (*tag(count)\y*tileSize)+*tag(count)\yMicro <= *tag(absCount)\y*tileSize
				*tag(count)\yMicroDir = 0
			EndIf
			If *tag(count)\yMicroDir = 1 And (*tag(count)\y*tileSize)+*tag(count)\yMicro >= *tag(absCount)\y*tileSize
				*tag(count)\yMicroDir = 0
			EndIf
		Next
		If *tag(0)\xMicroDir = 0 And *tag(0)\yMicroDir = 0 And *tag(1)\xMicroDir = 0 And *tag(1)\yMicroDir = 0
			For count = 0 To 1
				*tag(count)\xMicro = 0
				*tag(count)\yMicro = 0
			Next
			swapping = #False
			
			;markierte Teile tauschen
			Swap *tag(0)\x, *tag(1)\x
			Swap *tag(0)\y, *tag(1)\y
			
			checkTile(*tag(0))
			checkTile(*tag(1))
			clearTags()
			checkPuzzle()         
		EndIf
	EndIf
	
	If targetAngle
		*tag(0)\rotation+(1000*perSecond)
		If *tag(0)\rotation >= targetAngle
			*tag(0)\rotation = targetAngle
			If *tag(0)\rotation = 360
				*tag(0)\rotation = 0
			EndIf
			targetAngle = 0
			checkTile(*tag(0))
			clearTags()
			checkPuzzle()
		EndIf
	EndIf   
EndProcedure



Procedure clearTags()
	Define count
	
	For count = 0 To 1
		If *tag(count)
			*tag(count)\tagged = #nullTag
			*tag(count) = #Null
		EndIf
	Next
EndProcedure



Procedure loop()
	Define event
	Define x, y

	Repeat
		ClearScreen(RGB(0,0,0))
		DisplaySprite(marginSPR,xOffset,yOffset)
		ForEach tile()
			RotateSprite(tileSPR(tile()\index),tile()\rotation,#PB_Absolute)
			DisplaySprite(tileSPR(tile()\index),xOffset+xMargin+(tile()\x*tileSize)+tile()\xMicro,yOffset+yMargin+(tile()\y*tileSize)+tile()\yMicro)
			If autoSnap And tile()\tagged <> #locked
				RotateSprite(frameSPR,tile()\rotation,#PB_Absolute)
				DisplayTransparentSprite(frameSPR,xOffset+xMargin+(tile()\x*tileSize)+tile()\xMicro,yOffset+yMargin+(tile()\y*tileSize)+tile()\yMicro,90)
			EndIf
			If selectX = tile()\x And selectY = tile()\y
				RotateSprite(selectSPR,tile()\rotation,#PB_Absolute)
				DisplayTransparentSprite(selectSPR,xOffset+xMargin+(selectX*tileSize)+tile()\xMicro,yOffset+yMargin+(selectY*tileSize)+tile()\yMicro,100)
			EndIf
			If tile()\tagged = #tagged
				DisplayTransparentSprite(tagSPR,xOffset+xMargin+(tile()\x*tileSize),yOffset+yMargin+(tile()\y*tileSize))
			EndIf
		Next
		FlipBuffers()   
		ExamineKeyboard()
		
		If Not gameOver
			processInput()
			processTimer()
		Else
			yay()
		EndIf
		
		;Delta Time
		perSecond = frameDuration/1000      
		frameDuration = ElapsedMilliseconds() - frameFinished
		frameFinished = ElapsedMilliseconds()            
	Until KeyboardPushed(#PB_Key_Escape) Or gameOver = 2
EndProcedure



Procedure checkPuzzle()
	ForEach tile()
		If tile()\x <> tile()\trueX Or tile()\y <> tile()\trueY Or tile()\rotation <> 0
			ProcedureReturn #False
		EndIf
	Next
	
	ForEach tile()
		tile()\tagged = #locked
	Next
	selectX = -1
	selectY = -1
	gameOver = 1
EndProcedure



Procedure checkTile(*pointer.TILE)
	Define count
	
	If Not autoSnap
		ProcedureReturn #False
	EndIf
	If *pointer\x = *pointer\trueX And *pointer\y = *pointer\trueY And *pointer\rotation = 0
		*pointer\tagged = #locked
		For count = 0 To 1
			If *tag(count) = *pointer
				*tag(count) = #Null
			EndIf
		Next
		*pointer = #Null
	EndIf
EndProcedure



Procedure yay()
	Define confirm
	Define event
	
	confirm = OpenWindow(#PB_Any, 0, 0, 180, 70, "* * * * * * * * * * * * * * * * * * * * *",#PB_Window_WindowCentered)
	TextGadget(0,45,10,200,20,"Congratulations!")
	ButtonGadget(1,30,35,100,20,"Yay")
	Repeat
		SetActiveWindow(confirm)
		event = WaitWindowEvent(16)
	Until EventGadget() = 1 Or event = #PB_Event_CloseWindow
	gameOver = 2
EndProcedure



Procedure aspectResize(picID,newX,newY)
	Define x = ImageWidth(picID)
	Define y = ImageHeight(picID)
	Define factor.f
	
	If newX And newY = 0
		factor = y/x
		newY = newX*factor
	EndIf
	If newX = 0 And newY
		factor = x/y
		newX = newY*factor
	EndIf
	
	ResizeImage(picID,newX,newY)
EndProcedure



Procedure inRange(value,min,max)
	If value >= min And value <= max
		ProcedureReturn #True
	EndIf
	ProcedureReturn #False
EndProcedure
Last edited by diceman on Fri Feb 08, 2019 2:55 pm, edited 4 times in total.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by infratec »

Hi,

a small improvement:

Code: Select all

Procedure ini()
   Define Filename$
   Define x, y
   Define xSize
   Define ySize
   Define newX, newY
   Define defSide
   Define count
   Dim puzzle(0,0)
   Define event
   
   Filename$ = OpenFileRequester("Choose a JPG", "", "JPG|*.jpg", 0)
   
   If Filename$ = ""
     End
   EndIf
   
   selectDifficulty()
   
   If InitSprite()
      screen = OpenWindow(#PB_Any,0,0,#xRes,#yRes,"PurePuzzle (©diceman, 2018) --- Press ESC to Quit",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
      If OpenWindowedScreen(WindowID(screen),0,0,#xRes,#yRes)
         InitKeyboard()
         InitMouse()
      EndIf
   EndIf   
   
   
   ;Bild laden und Größe anpassen
   pic = LoadImage(#PB_Any, Filename$)



Then you can choose any jpg.

Bernd
User avatar
diceman
User
User
Posts: 34
Joined: Tue Apr 10, 2018 9:42 pm

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by diceman »

Oh, thanks a lot for that. :-)
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by davido »

@diceman,
Very nice, thank you for sharing.
I found it rather more difficult than I expected! :D
So I'll enjoy getting better at it.
DE AA EB
User avatar
diceman
User
User
Posts: 34
Joined: Tue Apr 10, 2018 9:42 pm

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by diceman »

Here is a final version (in compiled form).

Changes:
- FileRequester added, you can now conveniently load any .jpg (thanks @infratec)
- Sounds added ("snap", "click" and "woosh", no annoying background music, mind, but please DO enjoy that victory jingle) ... they're all from freesounds.org
- QoL Feature: When AutoSnap is enabled, the program will detect, whenever a tile is correctly in place, and snap it in. From then on it's locked and can not be selected anymore.
This makes solving bigger puzzle considerably easier
- Tiles that have not been locked in yet have a transparent border

https://workupload.com/file/h4MSUcFA

Have fun!

//EDIT:
"AutoSnap" is now an optional feature, that can be checked in the difficulty selection menu.
Last edited by diceman on Thu Feb 07, 2019 5:18 pm, edited 2 times in total.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
dige
Addict
Addict
Posts: 1247
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by dige »

@Diceman: nice game! :D

The compiled source works, but the the PurePuzzle.exe ends immediately after the first click on a tile.
"Daddy, I'll run faster, then it is not so far..."
User avatar
diceman
User
User
Posts: 34
Joined: Tue Apr 10, 2018 9:42 pm

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by diceman »

Hey, thanks for trying! :)
I can't replicate that error (tried it on Windows 7 and Windows 10 on my Laptop), however I've stumbled upon another issue which is now resolved, maybe that's related to your problem?
You see, I've sloppily assumed, that all images are either very wide or very high. The program looks for the greater value, x or y, and stretches that to the maximum of the respective Window Resolution (1024*768); the other side will be adjusted accordingly to keep the aspect ratio. Now this works with very wide or very high images. However, with dimensions that are tending to be more square, like 625*500, after calling aspectResize(), the new ySide would still be over 800 pixels high, and then, when trying to grab the image, the program would throw an error.
This I managed to fix, as the program now primarily calculates for xSide, and then, when ySide would be larger than 768, it'll reroll values and stretch ySide instead.
I've included the updated Source Code into the .zip, maybe you can try to run again and see, if there are any error messages after clicking a tile. :)
Thanks a lot!

https://workupload.com/file/h4MSUcFA
Last edited by diceman on Thu Feb 07, 2019 5:18 pm, edited 1 time in total.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
dige
Addict
Addict
Posts: 1247
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by dige »

Thx for the update diceman! With the included source code, I was now able to identify the problem. It's PlaySound() that crashes, because InitSound() has failed.
The sound output on my computer only works if I have headphones connected. And I didn't have it :-)
"Daddy, I'll run faster, then it is not so far..."
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by Kwai chang caine »

Really nice, and works here on W7 x86 :wink:
Funny also, several text level choice "I hate puzzle", "Masochistic" :lol:
Thanks fo sharing this nice code 8)
ImageThe happiness is a road...
Not a destination
User avatar
diceman
User
User
Posts: 34
Joined: Tue Apr 10, 2018 9:42 pm

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by diceman »

dige wrote:Thx for the update diceman! With the included source code, I was now able to identify the problem. It's PlaySound() that crashes, because InitSound() has failed.
The sound output on my computer only works if I have headphones connected. And I didn't have it :-)
That's good to know!
I'll include a condition then, if InitSound() fails, all audio will be disabled and an appropriate message will be shown, but you'll still be able to play the game.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
User avatar
diceman
User
User
Posts: 34
Joined: Tue Apr 10, 2018 9:42 pm

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by diceman »

Updated version 1.13 (not much to add anymore, this is pretty much finished):
- Should InitSound() fail, the program won't crash anymore, but will display an appropriate message and continue with audio disabled.
- Source File is included.

https://workupload.com/file/h4MSUcFA
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by Dude »

Very good! I did a similar rotate-tile game once but not swapping the tiles. Good to see how you did it. Well done!
coco2
Enthusiast
Enthusiast
Posts: 368
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by coco2 »

I can't compile, I get:

[ERROR] The specified #Sprite is not initialised.

Line 383

Code: Select all

DisplaySprite(marginSPR,0,0)
User avatar
diceman
User
User
Posts: 34
Joined: Tue Apr 10, 2018 9:42 pm

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by diceman »

This had something to do with GrabSprite() trying to reach beyond the Window Resolution, because aspectResize() failed to reckognize the proper side to adjust.
It's fixed now. Initial barebones code should work correctly.
I'll strongly urge you to download the final version, though, that I've linked a couple of times in this thread. It's way better, cuz sounds!

Thanks for playing, y'all, hugely appreciate the feedback! :)
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: PurePuzzle (it's a Puzzle Game, duh)

Post by BasicallyPure »

I find this code very puzzling.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Post Reply