summaryrefslogblamecommitdiff
path: root/projects/09/K/Board.jack
blob: e9ed8a6f6c201587739d1a2e93abd6b93333cc97 (plain) (tree)
1
2
3
4
5
6
7
8
9






                                         

                     

                                                                                               

                             
                  
                                

                       
                                       

                          
                       
                     


                    





                                                  
               

     
                             
                     
                    
                  
                       
                      
                            
                           
                              



                              



                        


               
 







                             

     








                                   

     
                                              


                     
                   
                           
                                 










                                      
                                     









                                              
               

     
                                               

                                                                              









                                       
                   
         

                                             







                                      
                   
         

                                             







                                      
                   
         

                                             




                                      
                                  

                               
                   
         
               


                          
                    

                                      



                          
          




                            













                                           
                        









                                               
                            
                                        
         
                           



                                    
                                     

                                    



                             
                                    
                                   
                



                                  
         

                       

                                     
                          
         


                           


               
                              

                              
                          


               


                           
 



                                 
 


                                       

                       
                            
                      
                           







                                   



                              















































                                                           
 



                                               
               



                                
               

     
/** 
improvments:
- do in place transposition
- add a static string boardBar = "+----+"
- change printString("|") to printChar
- change the grid to static variable?
*/
class Board {
    field Array grid;
    field int nTurn, seed, status;      // status: 0: begin game; 1: in game; 2: lose; 3: win; 
    static String boardBar, strLost, strCont, strGameOver, strWon;

    constructor Board new() {
        var int i;
        let grid = Array.new(4);
        let i = 0;
        while (i < 4) {
            let grid[i] = Array.new(4);
            let i = i + 1;
        }
        do initBoard();
        let seed = 0;
        return this;
    }

    function void init() {
        let boardBar = "+----+";
        let strLost = "You lost!";
        let strWon = "You won!";
        let strCont = "Press any key to continue";
        let strGameOver = "Game over!";
        return;
    }

    method void initBoard() {
        var int i, j;
        var Array t;
        let i = 0;
        while (i < 4) {
            let j = 0;
            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 status = 0;
        return;
    }


    method void transpose() {
        do exch(0, 1);
        do exch(0, 2);
        do exch(0, 3);
        do exch(1, 2);
        do exch(1, 3);
        do exch(2, 3);
        return;
    }

    method void exch(int i, int j){
        var int t;
        var Array s1, s2;
        let s1 = grid[i];
        let s2 = grid[j];
        let t = s1[j];
        let s1[j] = s2[i];
        let s2[i] = t;
        return;
    }

    method void 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;
    }

    method void 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;
        }
        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;
        }
        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;
        }
        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;
        }
        return;
    }

    method void addTile(){
        var Array t;
        var int r, c, parity, newTile;
        /*
        let t = grid[1];
        if (t[1] = 32) {
            let t[1] = 65;
        }
        */
        
        if (~(status = 1)) {
            return;
        }

        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 isVertical, left;
        var int i;
        if ((dir = 0) | (dir = 1)) {
            let left = true;
        } else {
            let left = false;
        }
        if ((dir = 0) | (dir = 2)) {
            let isVertical = false;
        } else {
            let isVertical = true;
        }
        if (isVertical) {
            do transpose();
        }
        let i = 0;
        while (i < 4) {
            do align(grid[i], left);
            do reduce(grid[i], left);
            let i = i + 1;
        }
        if (isVertical) {
            do transpose();
        }
        return;
    }

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

    method int getStatus(){
        return status;
    }

    method void setStatus(int x){
        let status = x;
        return;
    }

    method void updateStatus(){        
        var int i, j;
        var Array r;
        let i = 0;
        while (i < 4) {
            let r = grid[i];
            let j = 0;
            while (j < 4) {
                if (r[j] = 75) {
                    let status = 3;
                    return;
                }
                if (r[j] = 32) {
                    let status = 1;
                    return;
                }
                let j = j + 1;
            }
            let i = i + 1;
        }
        let status = 2;
        return;
    }

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

        if (status = 0) {
            do Output.moveCursor(r - 1, c - 1);
            do Output.printChar(75);
            do Output.moveCursor(r + 1, c - 1);
            do Output.printString(strCont);
        } else { if (status = 2) {
            do Output.moveCursor(r - 1, c - 1);
            do Output.printString(strGameOver);
            do Output.moveCursor(r + 1, c - 1);
            do Output.printString(strLost);
            do Output.moveCursor(r + 3, c - 1);
            do Output.printString(strCont);
        } else { if (status = 3) {
            do Output.moveCursor(r - 1, c - 1);
            do Output.printString(strGameOver);
            do Output.moveCursor(r + 1, c - 1);
            do Output.printString(strWon);
            do Output.moveCursor(r + 3, c - 1);
            do Output.printString(strCont);
        } else { 
            do Output.moveCursor(r - 1, c - 1);
            do Output.printString(boardBar);
            do Output.moveCursor(r + 4, c - 1);
            do Output.printString(boardBar);

            let i = 0;
            while (i < 4) {
                let j = 0;
                do Output.moveCursor(r + i, c - 1);
                do Output.printChar(124);       // 124 is |
                let t = grid[i];
                while (j < 4) {
                    do Output.printChar(t[j]);
                    let j = j + 1;
                }
                do Output.printChar(124);
                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;
    }
}