Omnimaga

Calculator Community => TI Calculators => Lua => Topic started by: Jonius7 on March 27, 2012, 07:20:48 am

Title: Goplat's 15Puzzle for TI-nspire Lua
Post by: Jonius7 on March 27, 2012, 07:20:48 am
Well hi everyone, I have been slowly trying to learn TI-nspire Lua here.
I have thought for a bit, made some demo beginner programs with the help of jimbauwens :D, and learnt a lot along the way (also creating a batch file for Luna for quick lua -> tns conversion). But I still have a long way to go.

So I had the tns file for 15puzzle but it didn't work, probably because it was designed to work with OS<3.0.2.

Fortunately I have managed to extract Problem1.xml from the tns file (rename it as a zip), copy to Notepad++ save as a .lua file, then used this page (http://www.w3schools.com/tags/ref_entities.asp), to fix some errors/discrepancies with xml coding and tinspire Lua code, and got it working!
Played it, got it solved in 353 moves. :D

Now here I post the source code and tns file of 15Puzzle, edited by Jonius7 for OS 3.0.2 and above

And I think one of the best ways to learn is to analyse source code line by line and try to understand what it means.
So I shall try here with some help to dissect this source code:

Code: [Select]
function on.charIn(ch)
if ch == "r" then
board = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }

-- Randomize
local swaps = 0
for i = 1, 16 do
local j = math.random(i, 16)
if i ~= j then
board[i], board[j] = board[j], board[i]
swaps = swaps + 1
end
if board[i] == 16 then
empty = i
end
end

-- If the number of swaps plus the number of empty-space movements is odd,
-- then the puzzle is impossible, so do an impossible move to make it possible
-- (exchange the space with a tile two squares away)
if (swaps + (empty - 1) + math.floor((empty - 1) / 4)) % 2 == 1 then
local i = (empty + 7) % 16 + 1
board[empty] = board[i]
empty = i
board[empty] = 16
end

moves = 0
platform.window:invalidate()
end
end

on.charIn("r")

function on.paint(gc)
local won = true
for i, n in ipairs(board) do
if n ~= 16 then
local x = (platform.window:width() - 128) / 2 + 32*((i - 1) % 4)
local y = (platform.window:height() - 128) / 2 + 32*math.floor((i - 1) / 4)
gc:drawRect(x, y, 30, 30)
gc:drawString(n, x + (30 - gc:getStringWidth(n)) / 2, y + 15, "middle")
end
won = (won and n == i)
end

local str = moves .. " moves"
gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, 0, "top")
if won then
str = "You win! Press R to reset"
gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, platform.window:height(), "bottom")
end
end

function on.arrowKey(key)
local dir
if key == "left" and empty % 4 ~= 0 then
dir = 1
elseif key == "right" and empty % 4 ~= 1 then
dir = -1
elseif key == "up" and empty <= 12 then
dir = 4
elseif key == "down" and empty > 4 then
dir = -4
else
return
end
board[empty] = board[empty + dir]
empty = empty + dir
board[empty] = 16
moves = moves + 1
platform.window:invalidate()
end


Title: Re: 15Puzzle for TI-nspire Lua
Post by: Chockosta on March 27, 2012, 09:42:45 am
Good progress !
I hope you'll be able to create nice games soon :)

By the way, I already managed to get 15puzzle to work on OS 3.1, just by saving it under an older OS... (3.0.1 IIRC)
(and my highscore is 72 moves)

Good luck with lua !
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jim Bauwens on March 27, 2012, 11:07:12 am
3.2 is not yet released ..
I think you are mixing version numbers ;)

Here is a little list of versions:
3.0.0 -- Only on CX in shop
3.0.1
3.0.2 -- They added encryption to documents. Documents made with luna2tns and similar (for 3.0.1) don't work anymore
3.1    -- Present
3.2    -- Coming soon
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Chockosta on March 27, 2012, 12:35:45 pm
You're right, sorry.
I edited my post.
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Adriweb on March 27, 2012, 01:15:50 pm
Also, just to be clear, all .tns created with Luna work with all the versions :)
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jim Bauwens on March 27, 2012, 01:22:21 pm
They work on 3.2 without changes ;)
The changes I made are for something else :)
Title: Re: 15Puzzle for TI-nspire Lua
Post by: DJ Omnimaga on March 27, 2012, 02:25:41 pm
3.2 is not yet released ..
I think you are mixing version numbers ;)

Here is a little list of versions:
3.0.0 -- Only on CX in shop
3.0.1
3.0.2 -- They added encryption to documents. Documents made with luna2tns and similar (for 3.0.1) don't work anymore
3.1    -- Present
3.2    -- Coming soon


There's a 3.0.0?? O.O

Anyway it would be great to check if all the cool old Lua games worked for newer OSes, and if someone could port them if the author left or doesn't plan to maintain them anymore. :) Also I guess this can be a good learning experience.
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jim Bauwens on March 27, 2012, 02:27:52 pm
TI has done excelent work in keeping compatibility :)
The 3.0.0 version was found on the first CX's .
Title: Re: 15Puzzle for TI-nspire Lua
Post by: DJ Omnimaga on March 27, 2012, 02:32:13 pm
Well they sure didn't with Print for example :P. Had any old game used sound or stuff like that, sound would no longer work on OS 3.1 without Ndless.

And ok about OS 3.0.0, any difference with 3.0.1 in it such as no Boot2 crash?
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jim Bauwens on March 27, 2012, 02:40:38 pm
Well, it was preinstalled so we don't know :P
Title: Re: 15Puzzle for TI-nspire Lua
Post by: DJ Omnimaga on March 27, 2012, 03:11:40 pm
Well I also meant about what it was missing from OS 3.0.1 or if it had any extra bugs. :P

For example I remember reading somewhere it still had leftovers from the 84+ emulator in the CX version, but I forgot if 3.0.1 still had those.
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jonius7 on March 27, 2012, 06:41:11 pm
3.2 is not yet released ..
I think you are mixing version numbers ;)

Here is a little list of versions:
3.0.0 -- Only on CX in shop
3.0.1
3.0.2 -- They added encryption to documents. Documents made with luna2tns and similar (for 3.0.1) don't work anymore
3.1    -- Present
3.2    -- Coming soon


I did say 3.0.2 didn't I?
But technically I tested it in 3.1.0
I understand about 60% of the code.

so what do the % signs do?
Title: Re: 15Puzzle for TI-nspire Lua
Post by: someone on March 27, 2012, 10:26:33 pm
% Stands for modulo (though it can have other uses too)

a % b == a - math.floor(a/b)*b
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jonius7 on March 27, 2012, 10:51:30 pm
Hmm, I suspected that it stood for the modulo/(or modulus?)
So a subtracted from  (a/b with remainder ignored * b) = modulo?

a=5
b=2
5- 2*2
% = 1

Interesting.
Still not completely sure how it works, but it works!
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Adriweb on March 28, 2012, 07:14:03 am
About compatibility, DJ_O :

print() is gone in 3.1 (I haven't checked in 3.2 on-calc though).
gc:setAlpha() is gone in 3.2, and it wasn't documented before
on.create() become on.construction()

There is a retrocompatibility thing with platform.apilevel

So, the last one will be quite (on.create change) is probably the most annoying change, since it has to be updated...
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jonius7 on March 28, 2012, 09:09:25 am
I think I know what modulus does now!
Created some sort of a guide here: http://ourl.ca/15687.new#new

Now, I did find a definition for .. but still have little idea what it means
Title: Re: 15Puzzle for TI-nspire Lua
Post by: someone on March 28, 2012, 11:30:47 am
Concatenates two strings (joins them together into a single one)


Edit: So for the following code:
Code: [Select]
local str = Moves .. " moves"
Moves is a variable that contains the number of times you've moved a piece
" moves" is a string & remains the same

Let say Moves = 200, so the string is equivalent to:
"200 moves"
Title: Re: 15Puzzle for TI-nspire Lua
Post by: DJ Omnimaga on March 28, 2012, 04:06:24 pm
Ah ok thanks for the info. I hope TI won't start breaking stuff in the future, like Notch is doing with Minecraft now x.x (or what TI did with OS 2.53MP)
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jim Bauwens on March 28, 2012, 04:34:54 pm
Well, I can assure you TI is did much work to keep <3.1 Lua scripts work fine on 3.2. They are clearly dedicated to this, so I wouldn't worry that much.
Title: Re: 15Puzzle for TI-nspire Lua
Post by: cyanophycean314 on March 28, 2012, 06:09:51 pm
Exactly how would you create a batch file for Luna? I don't really know how to take arguments for .bat

Nice job with the 15-puzzle, no wonder it didn't work before.  <_<

Good luck with learning Lua!
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Adriweb on March 28, 2012, 07:35:55 pm
Why do you need a bat file ?

Luna just works like that  :

luna[.exe] source.lua output.tns

:)
Title: Re: 15Puzzle for TI-nspire Lua
Post by: cyanophycean314 on March 28, 2012, 09:49:41 pm
Well, it'd be a lot easier if you don't have to open command prompt and type it in every time. Typing it in every time is slow... I run nspire_emu with a .bat too!
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jonius7 on March 29, 2012, 05:40:18 am
Why do you need a bat file ?

Luna just works like that  :

luna[.exe] source.lua output.tns

:)
I had an answer in quick reply ready to go but then I refreshed the page :( (This reply isn't as good as my original one)
With cmd you'd have to navigate to the particular folder every time just to run Luna! I do not want to do that!
A slightly quicker way is to Shift +Click the folder but you'd have to go up a directory and still type in the stuff. A bit fiddly

So using a .bat file makes sense, in fact I can see no way of me using the cmd due to the fiddly methods above.

Here is the bat file code:
Code: [Select]
@echo off
set /p luafile= Type the lua filename (without extension):
set /p tnsfile= Type the tns filename (without extension):
luna.exe %luafile%.lua %tnsfile%.tns
@cyanophycean314 I used Levak's Batch File as a guide and just modified it to suit Lua! Though I don't completely get what "set /p" means

Just a few lines of code makes things much easier and logical :)


Concatenates two strings (joins them together into a single one)


Edit: So for the following code:
Code: [Select]
local str = Moves .. " moves"
Moves is a variable that contains the number of times you've moved a piece
" moves" is a string & remains the same

Let say Moves = 200, so the string is equivalent to:
"200 moves"
Thanks someone, I did see the word concatenates when I was searching and had no idea what it meant!
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Adriweb on March 29, 2012, 11:39:10 am
Hopefully, all the hassles so far to create Lua scripts won't exist anymore with the 3.2 Lua SDK ;)
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jim Bauwens on March 29, 2012, 02:02:50 pm
Ha, I'll stilll use Luna+shellscripts+TiLP. Nothing beats that!
I have EEPro building integrated in my editor (geany), and with one press of a button it builds EEPro (which exists out of many seperate lua files) and uses TiLP to send it to my CX (or uses PCspire).
Just awesome :)
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Lionel Debroux on March 29, 2012, 02:10:05 pm
Quote from: Adriweb
Hopefully, all the hassles so far to create Lua scripts won't exist anymore with the 3.2 Lua SDK ;)
Quote from: jimbauwens
Ha, I'll stilll use Luna+shellscripts+TiLP. Nothing beats that!
Indeed, +1 Jim.

Until TI makes portable, scriptable tools that work for all of Windows, MacOS X, Linux and some popular BSDs - i.e. certainly never - there's no way all hassles can disappear ;)
Scriptability, and separation between GUI front-ends and worker backends with a CLI (or at the very least, libraries for encapsulating the worker backends), is a very important feature; the tools whose maintenance I have inherited are not scriptable enough (though TILP happens to be scriptable enough to fulfill Jim's use case, its CLI is very limited)...
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Adriweb on March 29, 2012, 06:08:42 pm
Lionel, totally agreeing with you about Linux... (but it's great they at least have a Mac version working...)

What I mean by the hassles disappearing, is that with one-click too, you are able to update your code within TINCS, and it can't be faster i any other way.
But of course, jim's scripts are better for "building" and on-calc testing all in one click :)
Title: Re: 15Puzzle for TI-nspire Lua
Post by: Jonius7 on April 04, 2012, 02:17:29 am
Anyway good to see that we won't have to take to such measures of making Lua scripts run in the future and can even edit the file directly (which means even better than Oclua on calc!). But to get back on topic
I want to try and understand completely what Goplat's 15 puzzle means. I've already learnt quite a bit, let's see what else there is. I have commented on this within the code :D
Code: [Select]
function on.charIn(ch) --called when a character key is pressed
if ch == "r" then --when r is pressed
board = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } --this is how you create arrays!
-- Randomize
local swaps = 0  -- a local variable (wonder why)
for i = 1, 16 do   -- ah this is the For...To syntax in TI-84 and Casio basic and other stuff
local j = math.random(i, 16)  -- local variable, random number from i to 16
if i ~= j then  -- i not equal to j
board[i], board[j] = board[j], board[i]     --swap number in position i and j?
swaps = swaps + 1  --swaps number of turns
end
if board[i] == 16 then  --reach the end
empty = i 
end
end

-- If the number of swaps plus the number of empty-space movements is odd,
-- then the puzzle is impossible, so do an impossible move to make it possible
-- (exchange the space with a tile two squares away)
if (swaps + (empty - 1) + math.floor((empty - 1) / 4)) % 2 == 1 then   -- not 100% how this works, I know this is a way to fix an impossible puzzle :P
local i = (empty + 7) % 16 + 1
board[empty] = board[i]
empty = i
board[empty] = 16
end

moves = 0
platform.window:invalidate()  --force redraw of the screen calls on.paint(gc)
end
end

on.charIn("r")

function on.paint(gc)
local won = true
for i, n in ipairs(board) do
if n ~= 16 then
local x = (platform.window:width() - 128) / 2 + 32*((i - 1) % 4)
local y = (platform.window:height() - 128) / 2 + 32*math.floor((i - 1) / 4)
gc:drawRect(x, y, 30, 30)
gc:drawString(n, x + (30 - gc:getStringWidth(n)) / 2, y + 15, "middle")
end
won = (won and n == i)
end

local str = moves .. " moves"
gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, 0, "top")
if won then
str = "You win! Press R to reset"
gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, platform.window:height(), "bottom")
end
end

function on.arrowKey(key)
local dir
if key == "left" and empty % 4 ~= 0 then
dir = 1
elseif key == "right" and empty % 4 ~= 1 then
dir = -1
elseif key == "up" and empty <= 12 then
dir = 4
elseif key == "down" and empty > 4 then
dir = -4
else
return
end
board[empty] = board[empty + dir]
empty = empty + dir
board[empty] = 16
moves = moves + 1
platform.window:invalidate()
end