How to translate the algorithm from Javascript to Lua correctly?

  • 0
    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 constructions, 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, and all the difficulties follow from this. At first, everything went well, 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 loop iteration is skipped per loop (not the first and not the last). After a long time of debugging, I found out at what stage the data discrepancy occurs (in the comments of the code, I marked this). 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 me to it. And if there are craftsmen who themselves translate this algorithm into lua, I will be infinitely grateful.

    The source to be translated into lua (the 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++;
        // }
    }
    JavaScript Julia Raymond, Sep 22, 2019

  • 1 Answers
  • 0
    Alternatively, quickly translate the code into a typescript and transpile it to 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 it was last updated 4 years ago.

    https://www.npmjs.com/package/castl
    Leo Bird

Your Answer
To place the code, please use CodePen or similar tool. Thanks you!