Answer the question
In order to leave comments, you need to log in
How to correctly translate the algorithm from Javascript to Lua?
There is one algorithm for solving the game "Fifteen", written in JavaScript, which I want to translate into lua. There are almost no complex language constructs, elementary work with arrays. The main difficulty lies in the fact that in JS arrays start from the zero element, and in Lua from the first, all the difficulties follow from this. At first everything went well, I commented out the source code, and rewrote the lua code line by line, constantly debugging the data so that they match. And then I ran into a situation where all the data seems to match, but one iteration of the loop is skipped on the lua (not the first and not the last). After a long time of debugging, I found out at what stage the data discrepancy occurs (I noted this in the code comments). But I could not find a specific place where the problem arises, I have already tried everything, everything that can be debugged in all places. Maybe you, with a fresh mind, will understand what the problem is and point it out to me. And if there are craftsmen who themselves will translate this algorithm into lua, I will be infinitely grateful.
Source to be translated into lua (code that I have not yet translated into lua is commented out)
var posit = new Array ();
var maxhgh = 10; //maximum height of board
var maxwid = 10; //maximum width of board
var hgh = 4; //height of board; 2-maxhgh
var wid = 4; //width of board; 2-maxwid
var siz = (hgh*wid)-1; //Number of tiles, = wid*hgh-1. Only have provision for 2-digit numbers on display
var mode = 0; //0=normal 1=solving scrambled 2=edit 3=solving
var seq = new Array(); //solving sequence
var edt; //next piece to place in edit mode
var blnkx,blnky; //position of blank space
blnkx=wid-1;
blnky=hgh-1;
posit = [8, 13, 11, 14, 15, 10, 0, 4, 9, 1, 12, 5, 3, 2, 7, 6]
solve()
function push(){
//push list onto list of moves for solution. Also does moves without showing them.
for (var i=0;i<push.arguments.length;i++){
var c=push.arguments[i];
if(seq.length && seq[seq.length-1]+c==3) {
seq.length--;
}
else {
seq[seq.length]=c;
}
domove(c);
}
}
function domove(m){ //0=right, 1=down, 2=up, 3=left
//does move without showing it.
var d=blnkx+blnky*wid;
if(m==0) {
posit[d]=posit[d-1];
posit[d-1]=siz;
blnkx--;
}
else if(m==1){
posit[d]=posit[d-wid];
posit[d-wid]=siz;
blnky--;
}
else if(m==2){
posit[d]=posit[d+wid];
posit[d+wid]=siz;
blnky++;
}
else if(m==3){
posit[d]=posit[d+1 ];
posit[d+1 ]=siz;
blnkx++;
}
}
function solve(){
seq.length=0;
//no solution set up yet. Construct it!
//save pieces;
var back = new Array();
for(var i=0;i<=siz;i++) {
back[i] = posit[i];
}
//restore top rows
var rr=0;
for(var r=0; r<hgh-2;r++) {
// console.log('solveFor1')
for(var c=0;c<wid;c++) {
movepiece(rr + c, r, c);
}
rr+=wid;
}
// //restore left columns
// for(c=0;c<wid-2;c++){
// //restore top tile of column.
// movepiece(rr,hgh-2,c);
// //restore bottom tile of column
// if(blnkx==c) push(3); //fill destination spot
// if(posit[rr+wid]!=rr+wid){
// movepiece(rr+wid,hgh-1,c+1);
// if(blnky!=hgh-1) { //0=right, 1=down, 2=up, 3=left
// //A.X or AX.
// //XBX XBX
// if( blnkx==c+1 ) push(3);
// push(2);
// }
// //AXX
// //XB.
// while( blnkx>c+2 ) push(0);
// push(0,0,1,3,2,3,1,0,0,2,3);
// }
// rr++;
// }
// //last 2x2 square
// if(blnkx<wid-1) push(3);
// if(blnky<hgh-1) push(2);
// rr=siz-wid-1;
// if(posit[rr]==rr+1) push(1,0,2,3);
// if(posit[rr]==rr+wid) push(0,1,3,2);
// //restore pieces;
// for(var i=0;i<=siz;i++) posit[i]=back[i];
// blnkx=back[siz+1];
// blnky=back[siz+2];
}
function movepiece(p,y,x){
var c=-1;
for(var i=0;i<hgh;i++){
for(var j=0;j<wid;j++){
c++;
if(posit[c]==p) break;
}
if(posit[c]==p) break;
}
// Move piece to same column //0=right, 1=down, 2=up, 3=left
if(j<x && blnky==y) push(2); // move blank down if it might disturb solved pieces.
while(j>x){
//move piece to left
//First move blank to left hand side of it
if(blnky==i && blnkx>j){ //if blank on wrong side of piece
if(i==hgh-1) push(1); else push(2); //then move it to other row
}
while(blnkx>=j) {
push(0); // move blank to column left of piece
}
// while(blnkx<j-1) push(3);
// while(blnky<i) push(2); // move blank to same row as piece
// while(blnky>i) push(1);
// push(3); // move piece to left.
j--;
}
// while(j<x){
//move piece to right
//First move blank to right hand side of it
// if(blnky==i && blnkx<j){
// if(i==hgh-1) push(1); else push(2);
// }
// while(blnkx<=j) push(3);
// while(blnkx>j+1) push(0);
// while(blnky<i) push(2);
// while(blnky>i) push(1);
// push(0);
// j++;
// }
//Move piece up to same row //0=right, 1=down, 2=up, 3=left
// while(i>y){
// if(y<i-1){
// while(blnky<i-1) push(2);
// if(blnkx==j) push( j==wid-1? 0:3);
// while(blnky>i-1) push(1);
// while(blnkx<j) push(3);
// while(blnkx>j) push(0);
// push(2);
// }else{
// if(j!=wid-1){
// if(blnky==i) push(2);
// while(blnkx<j+1) push(3);
// while(blnkx>j+1) push(0);
// while(blnky>i-1) push(1);
// while(blnky<i-1) push(2);
// push(0,2);
// }else{
// if(blnky<i && blnkx==j){
// while(blnky<i) push(2);
// }else{
// while(blnky>i+1) push(1);
// while(blnky<i+1) push(2);
// while(blnkx<j) push(3);
// while(blnkx>j) push(0);
// push(1,1,0,2,3,2,0,1,1,3,2);
// }
// }
// }
// i--;
// }
// while(i<y){
// //move piece downwards
// //First move blank below tile
// if(blnkx==j && blnky<i){
// if(j==wid-1) push(0); else push(3);
// }
// while(blnky>i+1) push(1);
// while(blnky<i+1) push(2);
// while(blnkx<j) push(3);
// while(blnkx>j) push(0);
// push(1);
// i++;
// }
}
ins = require("inspect")
posit = {}
seq = {}
hgh = 4
wid = 4
siz = (hgh*wid)-1
blnkx=wid-1
blnky=hgh-1
function domove(m)
local d=blnkx+blnky*wid + 1
if m == 0 then
posit[d] = posit[d-1]
posit[d-1] = siz
blnkx = blnkx - 1
elseif m == 1 then
posit[d] = posit[d-wid]
posit[d-wid] = siz
blnky = blnky - 1
elseif m == 2 then
posit[d] = posit[d+wid]
posit[d+wid] = siz
blnky = blnky + 1
elseif m == 3 then
posit[d] = posit[d+1]
posit[d+1] = siz
blnkx = blnkx + 1
end
end
function push(...)
local args = {...}
for k, v in pairs(args) do
local c=v
if seq[#seq] then
if #seq and seq[#seq]+c == 3 then
table.remove(seq, #seq)
else
seq[#seq+1] = c
end
else
seq[#seq+1] = c
end
domove(c)
end
end
function movepiece(p, y, x)
local c = 0
local ki = 0
local kj = 0
for i=0, hgh-1 do
ki = i
for j=0, wid-1 do
kj = j
c = c + 1
if (posit[c]==p) then
break
end
end
if (posit[c]==p) then
break
end
end
print(kj) -- на одной из итераций эти данные будут отличаться
print(ki) -- от тех, которые выводятся в исходнике
if kj<x and blnky == y then push(2) end
while(kj > x) do
if blnky == ki and blnkx > kj then
if ki == hgh - 1 then
push(1)
else
push(2)
end
end
-- На этом моменте появляется проблема
while(blnkx >= kj) do -- Если это закомментировать,
push(0) -- то проблема возникать
end -- не будет
ins.inspect(seq) -- вот тут данные не совпадают с теми, которые выводятся в исходнике
-- while(blnkx < kj-1) do push(3) end
-- while(blnky < kj) do push(2) end
-- while(blnky > kj) do push(1) end
-- push(3)
kj = kj - 1
end
end
function solve()
seq = {}
local back = {}
for i=1, siz+1 do
back[i] = posit[i]
end
back[siz+2]=blnkx;
back[siz+3]=blnky;
local rr=0
for r=0, (hgh-3) do
for c=0, wid-1 do
movepiece(rr + c, r, c)
end
rr = rr + wid
end
end
posit = {8, 13, 11, 14, 15, 10, 0, 4, 9, 1, 12, 5, 3, 2, 7, 6}
solve()
Answer the question
In order to leave comments, you need to log in
As an option, quickly translate the code into typescript and transpile it into lua:
https://www.npmjs.com/package/typescript-to-lua
I think it will be many times faster and more efficient.
Or you can try the castle, but there was the last update 4 years ago.
https://www.npmjs.com/package/castl
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question