This site requires JavaScript, please enable it in your browser!
Greenfoot back
whattheheck
whattheheck wrote ...

2020/3/1

Help with programming 2048?

whattheheck whattheheck

2020/3/1

#
I'm trying to program 2048, but I can't seem to finish my merge method to combine squares. My getValue method should be used to get the value of the square a square is moving into, and if its the same the squares merge. But I don't understand how I would use the getValue method to get the value of the square being moved into. World.GameBoard class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;

    //Instance Constants
    
   
    //Define some directions to make it easier to reference which way the blocks are moving
    private static final int UP = 0;
    private static final int RIGHT = 1;
    private static final int DOWN = 2;
    private static final int LEFT = 3;
    int sqrCount = 0;
    
    
    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    public GameBoard()
    {    
        // Create a new world with 4x4 cells with a cell size of 50x50 pixels.
        super(4, 4, 50); 
        
        //populate gameboard with x randomly placed objects
        while(sqrCount<1) {
            if(placeRandomBlock()){
                sqrCount++;
            } else {
                continue;
            }
        }
    }
    
    
    /**
     * Place a block on a random location on the board
     * 
     * @return Returns true if successful, false if not successful
     */
    private boolean placeRandomBlock()
    {
        //Generate Random Location
        GameSquare gamesquare = new GameSquare(); //make new game square
        int x = (Greenfoot.getRandomNumber(4)); //Get random num from 0-3, and add 1
        int y = (Greenfoot.getRandomNumber(4));
        
        //Check to ensure random location is not yet taken, if the spot is free add it to the world
        if (getObjectsAt(x, y, GameSquare.class).isEmpty()) {
            addObject(gamesquare,x,y);
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * Act - Check for key presses and tell each block to move itself.
     */
    public void act() 
    {
        //Add key press actoins here
        String key = Greenfoot.getKey();
        //If a key was pressed...do something
        if (key != null) {
            
            switch(key) {
                case "up": 
                    //Tell the blocks to move up
                    //Start checking from the top, then move downwards

                    for (int i=0; i<getWidth(); i++) {
                        for (int j=0; j<getHeight(); j++) {
                            //Get a list containing all of the GameSquare objects at position (i,j)
                            List blockList = getObjectsAt(i,j,GameSquare.class);
            
                            if (blockList.size() == 1) { //Error checking
                                ( (GameSquare)( blockList.get(0) )).move(UP);  
                            }
                        }
                    }
                    break;
                case "right":
                    //Tell the blocks to move right
                    //Start checking from the right most col, then move left                    
                    for (int i=3; i>=0; i--) {
                        for (int j=0; j<getHeight(); j++) {
                            //Get a list containing all of the GameSquare objects at position (i,j)
                            List blockList = getObjectsAt(i,j,GameSquare.class);
            
                            //Tell the other block object we wish to merge with it.  If successful, delete this block from the game
                            if (blockList.size() == 1) { //Error checking
                                ( (GameSquare)( blockList.get(0) )).move(RIGHT);  
                            }
                        }
                    }
                    break;

                case "down":
                    //Tell the blocks to move down
                    //Start checking from the bottom, then move up
                    for (int i=3; i>=0; i--) {
                        for (int j=3; j>=0; j--) {
                            //Get a list containing all of the GameSquare objects at position (i,j)
                            List blockList = getObjectsAt(j,i,GameSquare.class);
            
                            //Tell the other block object we wish to merge with it.  If successful, delete this block from the game
                            if (blockList.size() == 1) { //Error checking
                                ( (GameSquare)( blockList.get(0) )).move(DOWN);  
                            }
                        }
                    }
                    break;

                case "left":
                    //Tell the blocks to move left
                    //Start checking from the left, then move right
                    for (int i=0; i<getWidth(); i++) {
                        for (int j=0; j<getHeight(); j++) {
                            //Get a list containing all of the GameSquare objects at position (i,j)
                            List blockList = getObjectsAt(j,i,GameSquare.class);
            
                            //Tell the other block object we wish to merge with it.  If successful, delete this block from the game
                            if (blockList.size() == 1) { //Error checking
                                ((GameSquare)(blockList.get(0))).move(LEFT);  
                            }
                        }
                    }
                    break;

                }
                

            int count = 0;
            if(numberOfObjects() < 16) {
                while (count < 1) {
                    if (placeRandomBlock()) {
                        count++;
                    }
                }
            }
        }
        
    }
}
Actor.GameSquare.class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;


public class GameSquare extends Actor
{
    //Instance Constants
    
    //Define some directions to make it easier to reference which way the blocks are moving
    private static final int UP = 0;
    private static final int RIGHT = 1;
    private static final int DOWN = 2;
    private static final int LEFT = 3;
    
    //Instance Variables    
    private int value;
        
    //Constructor
    public GameSquare()
    {
        this(2);
    }
    
    public GameSquare(int valueIn)
    {
        setValue(num);
        displayValue();
    }
    
    /**
     * Tell the block to move in the given direction until it hits an obstacle
     * 
     * @param The direction in which the block is to move (UP = 0; RIGHT = 1; DOWN = 2; LEFT = 3;
     */
    public void move(int direction) 
    {
        //check if can move
        int movable = canMove(direction);
        if (debug == true) {
            System.out.print(movable);
        }
        
        //if moveable, start a loop
        while (movable > 0)
        {
            //Get current coordinates
            int xval = getX();
            int yval = getY();
            
            //Change x and y values to the "new" location based on direction
            if (direction == 0) {
                yval-=1;
                setLocation(xval,yval);
            } else if (direction == 1) {
                xval+=1;
                setLocation(xval,yval);
            } else if (direction == 2) {
                yval+=1;
                setLocation(xval,yval);
            } else if (direction == 3) {
                xval-=1;
                setLocation(xval,yval);
            }
            
            //If Nothing in the way - move the block
            if (movable == 1) {  
                
                movable = canMove(direction);
                continue;
                //return;
            }
            //Merge the blocks
            else {
                //Find which block we need to merge with

                
                //Tell the other block object we wish to merge with it.  If successful, delete this block from the game


                return;
            }
        }
        
        
        //can't move, so don't move.
        return;
    }

    /**
     * Sets the value of the game square to the value of the input parameter.
     * Will only work if the value is a factor of 2
     * 
     * @param The number to use as the new value
     * @return If the number was set correctly return true, otherwise return false
     */
    
    boolean setValue(int valueIn) {
        if(valueIn % 2 != 0) {
            return false;
        } else {
            value = valueIn;
            return true;
        }
    }
    
    /**
     * Merge with another block and combine values.
     * Will only work if the two blocks are of the same value
     * 
     * @param The value of the block to be added
     * 
     * @return Return true if the merge is successful.
     */

    public boolean merge(int valueIn) {
        return setValue(valueIn*2);
    }
    
    /**
     * Returns the current value of the gameSquare
     * 
     * @return The current value (int) of the game square
     */
    
    public int getValue() {
        return this.value;
    }

    /**
     * Checks to see if the block can move
     * 
     * @return int value representing what is in the space to be moved to.  0 -> Path Blocked, 1 -> Empty Space, int>1 value of block in the space to be moved to.
     */
    private int canMove(int direction)
    {
        //Get World
        World world = getWorld();
        
        //Get x and y values of current object
        int xval = getX();
        int yval = getY();
        
        //Change x and y values to the "new" location based on direction
        if (direction == 0) {
            yval-=1;
        } else if (direction == 1) {
            xval+=1;
        } else if (direction == 2) {
            yval+=1;
        } else if (direction == 3) {
            xval-=1;
        }
        
        //Test for outside border
        if(xval<0 || xval>3 || yval<0 || yval>3) {
            return 0;
        }
        
        //Check to see if there is a block in the way
        
        if (direction == 0) {
            if(!world.getObjectsAt(xval, yval-1, GameSquare.class).isEmpty()) {
                //return value of square in pos xval,yval-1
            }
        } else if (direction == 1) {
            if(!world.getObjectsAt(xval+1, yval, GameSquare.class).isEmpty()) {
                //return value of square in pos xval,yval-1
            }
        } else if (direction == 2) {
            if(!world.getObjectsAt(xval, yval+1, GameSquare.class).isEmpty()) {
                //return value of square in pos xval,yval-1
            }
        } else if (direction == 3) {
            if(!world.getObjectsAt(xval-1, yval, GameSquare.class).isEmpty()) {
                //return value of square in pos xval,yval-1
            }
        }
        
        return 1;
    }
    
    /**
     * displayValue - Displays the current value of a block in an image, then sets that image to the block display image
     */    
    private void displayValue() 
    {
        //Create an image consisting of the display value using built in greenfoot commands
        GreenfootImage displayImage;
        displayImage = new GreenfootImage( Integer.toString(value), 20, Color.BLACK, Color.WHITE);
        
        //Add the image as the new image for this object
        setImage(displayImage);
        
    }
}
danpost danpost

2020/3/1

#
Here are examples:
GameSquare gs = (GameSquare)getObjectsAt(xval, yval+1, GameSquare.class).get(0);
int otherValue = gs.getValue();
or (combined)
int otherValue = ((GameSquare)getObjectsAt(xval, yval+1, GameSquare.class).get(0)).getValue();
You need to login to post a reply.