summaryrefslogblamecommitdiff
path: root/projects/11/K/Board.jack
blob: 49d42d52e7a12696b939c8f09c3d648776b0d94f (plain) (tree)
















































































































































































































































































































                                                                              
class Board {
    field Array grid;
    field int nTurn;
    field int seed;

    constructor Board new() {
        var int i, j;
        var Array t;
        let grid = Array.new(4);
        let i = 0;
        while (i < 4) {
            let j = 0;
            let grid[i] = Array.new(4);
            let t = grid[i];
            while (j < 4) {
                let t[j] = 32;
                let j = j + 1;
            }
            let i = i + 1;
        }
        let t = grid[0];
        let t[0] = 65;
        let nTurn = 0;
        let seed = 0;
        return this;
    }

    method void arrange(Array xs, boolean isHorizontal) {
        if (isHorizontal) {
            do deepcopy(xs, grid);
        } else {
            do transpose(xs, grid);
        }
        do dispose4(xs);
        return;
    }


    method void copy(Array xs, Array ys) {
        var int i;
        let i = 0;
        while (i < 4) {
            let ys[i] = xs[i];
            let i = i + 1;
        }
        return;
    }

    method void deepcopy(Array xs, Array ys) {
        var int i;
        let i = 0;
        while (i < 4) {
            do copy(xs[i], ys[i]);
            let i = i + 1;
        }
        return;
    }

    method void transpose(Array xs, Array ys) {
        var int i, j;
        var Array t, s;
        let i = 0;
        while (i < 4) {
            let j = 0;
            let t = ys[i];
            while (j < 4) {
                let s = xs[j];
                let t[j] = s[i];
                let j = j + 1;
            }
            let i = i + 1;
        }
        return;
    }

    method void dispose4(Array xs){
        var int i;
        var Array t;
        let i = 0;
        while (i < 4) {
            let t = xs[i];
            do t.dispose();
            let i = i + 1;
        }
        do xs.dispose();
        return;
    }

    method Array new4(){
        var Array xs;
        var int i;
        let xs = Array.new(4);
        let i = 0;
        while (i < 4) {
            let xs[i] = Array.new(4);
            let i = i + 1;
        }
        return xs;
    }

    method Array getStrips(boolean isHorizontal){
        var Array xs;
        let xs = new4();
        if (isHorizontal) {
            do deepcopy(grid, xs);
        } else {
            do transpose(grid, xs);
        }
        return xs;
    }

    method Array align(Array xs, boolean left){
        var int i, j;
        let i = 0;
        let j = 0;
        if (left) {
            while (i < 4) {
                if (xs[i] > 64) {
                    let xs[j] = xs[i];
                    let j = j + 1;
                }
                let i = i + 1;
            }
            while (j < 4) {
                let xs[j] = 32;
                let j = j + 1;
            }
        } else {
            while (i < 4) {
                if (xs[3 - i] > 64) {
                    let xs[3 - j] = xs[3 - i];
                    let j = j + 1;
                }
                let i = i + 1;
            }
            while (j < 4) {
                let xs[3 - j] = 32;
                let j = j + 1;
            }
        }
        return xs;
    }

    method Array reduce(Array xs, boolean left){
        if ((xs[0] = xs[1]) & (xs[2] = xs[3]) & (xs[0] > 64) & (xs[2] > 64)) {
            if (left) {
                let xs[0] = xs[0] + 1;
                let xs[1] = xs[2] + 1; 
                let xs[2] = 32;
                let xs[3] = 32;
            } else {
                let xs[3] = xs[3] + 1;
                let xs[2] = xs[1] + 1;
                let xs[1] = 32;
                let xs[0] = 32;
            }
            return xs;
        }
        if ((xs[0] = xs[1]) & (xs[0] > 64)) {
            if (left) {
                let xs[0] = xs[0] + 1;
                let xs[1] = xs[2];
                let xs[2] = xs[3];
                let xs[3] = 32;
            } else {
                let xs[1] = xs[1] + 1;
                let xs[0] = 32;
            }
            return xs;
        }
        if ((xs[2] = xs[3]) & (xs[2] > 64)) {
            if (left) {
                let xs[2] = xs[2] + 1;
                let xs[3] = 32;
            } else {
                let xs[3] = xs[3] + 1;
                let xs[2] = xs[1];
                let xs[1] = xs[0];
                let xs[0] = 32;
            }
            return xs;
        }
        if ((xs[1] = xs[2]) & (xs[1] > 64)) {
            if (left) {
                let xs[1] = xs[1] + 1;
                let xs[2] = xs[3];
                let xs[3] = 32;
            } else {
                let xs[2] = xs[2] + 1;
                let xs[1] = xs[0];
                let xs[0] = 32;
            }
            return xs;
        }
        return xs;
    }

    method void addTile(){
        var Array t;
        var int r, c, parity, newTile;
        /*
        let t = grid[1];
        if (t[1] = 32) {
            let t[1] = 65;
        }
        */
        let seed = seed * 25173 + 13849;
        if (seed < 0) {
            let seed = - seed;
        }

        if (seed - (seed / 2 * 2) = 0) {
            let parity = 1;
        } else {
            let parity = -1;
        }

        let seed = seed - (seed / 16 * 16);
        let r = seed / 4;
        let c = seed - (4 * r);
        let t = grid[r];
        let newTile = 65;

        while (t[c] > 64){
            let seed = seed + parity;
            if (seed < 0) {
                let seed = 15;
            }
            let seed = seed - (seed / 16 * 16);
            let r = seed / 4;
            let c = seed - (4 * r);
            let t = grid[r];
            let newTile = 131 - newTile;
        }
        let t[c] = newTile;
        return;
    }

    method void transform(char dir){
        var boolean isHorizontal, left;
        var Array xs;
        var int i;
        if ((dir = 0) | (dir = 1)) {
            let left = true;
        } else {
            let left = false;
        }
        if ((dir = 0) | (dir = 2)) {
            let isHorizontal = true;
        } else {
            let isHorizontal = false;
        }
        let xs = getStrips(isHorizontal);
        let i = 0;
        while (i < 4) {
            let xs[i] = reduce(align(xs[i], left), left);
            let i = i + 1;
        }
        do arrange(xs, isHorizontal);
        return;
    }

    method void next(char dir){
        let nTurn = nTurn + 1;
        do transform(dir);
        do addTile();
        return;
    }

    method void draw(){
        var int r, c, i, j;
        var Array t;
        let r = 9;
        let c = 30;

        do Output.moveCursor(r - 1, c - 1);
        do Output.printString("+----+");
        do Output.moveCursor(r + 4, c - 1);
        do Output.printString("+----+");

        let i = 0;
        while (i < 4) {
            let j = 0;
            do Output.moveCursor(r + i, c - 1);
            do Output.printString("|");
            let t = grid[i];
            while (j < 4) {
                do Output.printChar(t[j]);
                let j = j + 1;
            }
            do Output.printString("|");
            let i = i + 1;
        }

        do Output.moveCursor(r + 6, c - 2);
        do Output.printString("Turn: ");
        do Output.printInt(nTurn);
        return;
    }

    method void dispose() {
        do Memory.deAlloc(this);
        return;
    }
}