I need help with finishing my 2048 code, I have trouble with my final merging, with the code below:
This code seems to cause error by just combining squares, not changing the value, and not moving them afterwards. It's like the square just gets stuck in place.
I don't quite see how to fix this issue of merging, what should the code be?
Full source code:
World.GameBoard:
Actor.GameSquare:
if(merge(sqr.getValue())) {
getWorld().removeObject(sqr);
setLocation(xval,yval);
movable = canMove(direction);
continue;
} else {
movable = canMove(direction);
continue;
}
} else {
movable = canMove(direction);
continue;
}
}
}import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
public class GameBoard extends World
{
//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()
{
GameSquare gs = 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(gs,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);
//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
Object tempObject;
tempObject = blockList.get(0);
GameSquare tempSquare;
tempSquare = (GameSquare)tempObject;
tempSquare.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
Object tempObject;
tempObject = blockList.get(0);
GameSquare tempSquare;
tempSquare = (GameSquare)tempObject;
tempSquare.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
Object tempObject;
tempObject = blockList.get(0);
GameSquare tempSquare;
tempSquare = (GameSquare)tempObject;
tempSquare.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
Object tempObject;
tempObject = blockList.get(0);
GameSquare tempSquare;
tempSquare = (GameSquare)tempObject;
tempSquare.move(LEFT);
}
}
}
break;
}
int count = 0;
if(numberOfObjects() < 16) {
while (count < 1) {
if (placeRandomBlock()) {
count++;
}
}
}
}
}
}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;
//Define a debugging variable (See video linked in assignment outline)
private final boolean debug = false;
//Instance Variables
private int value;
//Constructor
public GameSquare()
{
this(2);
}
public GameSquare(int valueIn)
{
setValue(valueIn);
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);
System.out.println(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;
} else if (direction == 1) {
xval+=1;
} else if (direction == 2) {
yval+=1;
} else if (direction == 3) {
xval-=1;
}
//If Nothing in the way - move the block
if (movable == 1) {
movable = canMove(direction);
setLocation(xval,yval);
continue;
//return;
}
//Merge the blocks
else {
if (!getWorld().getObjectsAt(xval,yval,GameSquare.class).isEmpty()) {
GameSquare sqr = (GameSquare)getWorld().getObjectsAt(xval,yval,GameSquare.class).get(0);
if(merge(sqr.getValue())) {
getWorld().removeObject(sqr);
setLocation(xval,yval);
movable = canMove(direction);
continue;
} else {
movable = canMove(direction);
continue;
}
} else {
movable = canMove(direction);
continue;
}
}
}
//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) {
int sqrVal = getValue();
if (sqrVal == valueIn) {
setValue((sqrVal*2));
return true;
} else {
return false;
}
}
/**
* 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(!world.getObjectsAt(xval, yval, GameSquare.class).isEmpty()) {
GameSquare sqr = (GameSquare)world.getObjectsAt(xval,yval,GameSquare.class).get(0);
return sqr.getValue();
}
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);
}
}
