Omnimaga
Calculator Community => TI Calculators => Lua => Topic started 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:
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
-
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 !
-
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
-
You're right, sorry.
I edited my post.
-
Also, just to be clear, all .tns created with Luna work with all the versions :)
-
They work on 3.2 without changes ;)
The changes I made are for something else :)
-
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.
-
TI has done excelent work in keeping compatibility :)
The 3.0.0 version was found on the first CX's .
-
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?
-
Well, it was preinstalled so we don't know :P
-
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.
-
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?
-
% Stands for modulo (though it can have other uses too)
a % b == a - math.floor(a/b)*b
-
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!
-
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...
-
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
-
Concatenates two strings (joins them together into a single one)
Edit: So for the following code:
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"
-
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)
-
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.
-
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!
-
Why do you need a bat file ?
Luna just works like that :
luna[.exe] source.lua output.tns
:)
-
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!
-
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:
@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:
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!
-
Hopefully, all the hassles so far to create Lua scripts won't exist anymore with the 3.2 Lua SDK ;)
-
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 :)
-
Hopefully, all the hassles so far to create Lua scripts won't exist anymore with the 3.2 Lua SDK ;)
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)...
-
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 :)
-
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
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