V
V
vladmany2020-10-11 14:45:08
JavaScript
vladmany, 2020-10-11 14:45:08

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)

spoiler
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++;
    // }
}


My work and what I'm stuck on:
spoiler
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()

To display tables, I used the inspect library .

Perhaps it will be easier for you to rewrite the code from scratch to the point where I'm stuck.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
W
WbICHA, 2020-10-11
@vladmany

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 question

Ask a Question

731 491 924 answers to any question