package com.codegym.games.game2048;
import com.codegym.engine.cell.*;
import java.util.ArrayList;
import java.util.Arrays;
public class Game2048 extends Game {
//variables for class
private static final int SIDE = 4; //size of screen
private int[][] gameField = new int[SIDE][SIDE]; //gives each part of grid a location
private boolean isGameStopped = false;
//initializes game screen and begins game
@Override
public void initialize()
{
setScreenSize(SIDE, SIDE); //size of game
createGame();
drawScene(); //creates grid
}
private void createGame()
{
createNewNumber();//initial two numbers put in grid at start of game
createNewNumber();
}
//sets game board and puts numbers in grid.
private void drawScene()
{
for (int x = 0; x<SIDE; x++)
for (int y = 0; y<SIDE; y++)
setCellColoredNumber(x, y, gameField[y][x]); //prints number in grid
}
//creates a number, twice at beginning and each time player slides across grid and also finds the value of the max int on grid
private void createNewNumber()
{
int x = getRandomNumber(SIDE); //initializing blank coordinates
int y = getRandomNumber(SIDE);
int z = getRandomNumber(10);
//Sets a value to an empty coordinate within the grid at a 90% chance of 2 and 10% chance of a 4
if (gameField[x][y] == 0) {
if (z == 9)
gameField[x][y] = 4;
else
gameField[x][y] = 2;
} else createNewNumber();
if (getMaxTileValue() == 2048)
win();
}
//denotes color of each cell dependant on number value
private Color getColorByValue(int value)
{
if (value == 0)
return Color.ANTIQUEWHITE;
else if (value == 2)
return Color.LIGHTPINK;
else if (value == 4)
return Color.PURPLE;
else if (value == 8)
return Color.BLUE;
else if (value == 16)
return Color.LIGHTSEAGREEN;
else if (value == 32)
return Color.GREEN;
else if (value == 64)
return Color.LIGHTGREEN;
else if (value == 128)
return Color.ORANGE;
else if (value == 256)
return Color.CORAL;
else if (value == 512)
return Color.RED;
else if (value == 1024)
return Color.PINK;
else
return Color.DEEPPINK;
}
//sets color of cells based apon getColorByValue method
private void setCellColoredNumber(int x, int y, int value)
{
if (value != 0)
setCellValueEx(x, y, getColorByValue(value), Integer.toString(value) );
else
setCellValueEx(x, y, getColorByValue(value), "" );
}
//this method takes a row from the grid and then sorts empty fields to right and moves other
//numbers to left without changing there order. This is only the beginning
private boolean compressRow(int[] row) {
boolean isChanged = false;
for (int i = 0; i < row.length; i++)
{
for (int j = 1; j < row.length; j++)
{
if (row[j-1] == 0)
{
if(row[j] != 0)
isChanged = true;
row[j-1] = row[j];
row[j] = 0; // had to use this way because creating temp array did not fit task conditions
}
}
}
return isChanged; //variable used to discover whether the row was changed or not.
}
//puts adjoining cells of the same value together
private boolean mergeRow(int[] row)
{
boolean isChanged = false;
//int[] rowChange = new int[row.length];
for(int j = 1; j<row.length; j++)
if(row[j] == row[j-1] && row[j] != 0)
{
isChanged = true; //changing variable
row[j - 1] = row[j] + row[j - 1];
row[j] = 0; //where there is a gap from combined numbers a zero is inuptted
}
return isChanged;
}
@Override //pre-built method for keyboard input, we use it to "shift" our grid around
public void onKeyPress(Key key)
{
if (key == Key.LEFT)
{
moveLeft();
drawScene();
}
else if (key == Key.RIGHT)
{
moveRight();
drawScene();
}
else if (key == Key.UP)
{
moveUp();
drawScene();
}
else if (key == Key.DOWN)
{
moveDown();
drawScene();
}
}
//this method compresses and merges numbers if possible, checking each with a secondary boolean result and if either true creates a new number.
private void moveLeft()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
}
private void moveRight()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
rotateClockwise(); //As we have already set up the left move, by rotating the array we can
rotateClockwise(); // implement the "slide-to-the-left" method
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
rotateClockwise();
rotateClockwise();
}
private void moveUp()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
rotateClockwise();
rotateClockwise();
rotateClockwise();
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
rotateClockwise();
}
private void moveDown()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
rotateClockwise();
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
rotateClockwise();
rotateClockwise();
rotateClockwise();
}
private void rotateClockwise()
{
int[][] temp = new int[SIDE][SIDE];
for (int i = 0; i < SIDE; ++i)
for (int j = 0; j < SIDE; ++j)
temp[i][j] = gameField[SIDE - j - 1][i];
for (int i = 0; i < SIDE; ++i)
for (int j = 0; j < SIDE; ++j)
gameField[i][j] = temp[i][j];
}
//finds the max of the array
private int getMaxTileValue()
{
int max = 0;
for (int i = 0 ; i < SIDE; i++)
for (int j = 0 ; j<SIDE; j++)
if (gameField[i][j] > max)
max = gameField[i][j];
return max;
}
private void win()
{
isGameStopped = true;
showMessageDialog(Color.GOLD, "You are a Winner!", Color.BLACK, 45);
}
private boolean canUserMove()
{
boolean movesLeft = false;
//comparison loop, checking for empty cells and if all are full checking for any duplicates when all spaces are taken.
for (int i = 0 ; i < SIDE; i++)
for (int j = 0 ; j<SIDE; j++)
{
if (gameField[i][j] == 0)
{
movesLeft = true;
}
else if((i-1) > 0 && (gameField[i][j] == gameField[i-1][j]))
{
movesLeft = true;
}
else if ((i+1) > 4 && (gameField[i][j] == gameField[i+1][j]))
{
movesLeft = true;
}
else if ((j+1) < 4 && (gameField[i][j] == gameField[i][j+1]))
{
movesLeft = true;
}
else if ((j-1)>0 && (gameField[i][j] == gameField[i][j-1]))
{
movesLeft = true;
}
}
return movesLeft;
}
}
package com.codegym.games.game2048;
import com.codegym.engine.cell.*;
import java.util.ArrayList;
import java.util.Arrays;
public class Game2048 extends Game {
//variables for class
private static final int SIDE = 4; //size of screen
private int[][] gameField = new int[SIDE][SIDE]; //gives each part of grid a location
private boolean isGameStopped = false;
//initializes game screen and begins game
@Override
public void initialize()
{
setScreenSize(SIDE, SIDE); //size of game
createGame();
drawScene(); //creates grid
}
private void createGame()
{
createNewNumber();//initial two numbers put in grid at start of game
createNewNumber();
}
//sets game board and puts numbers in grid.
private void drawScene()
{
for (int x = 0; x<SIDE; x++)
for (int y = 0; y<SIDE; y++)
setCellColoredNumber(x, y, gameField[y][x]); //prints number in grid
}
//creates a number, twice at beginning and each time player slides across grid and also finds the value of the max int on grid
private void createNewNumber()
{
int x = getRandomNumber(SIDE); //initializing blank coordinates
int y = getRandomNumber(SIDE);
int z = getRandomNumber(10);
//Sets a value to an empty coordinate within the grid at a 90% chance of 2 and 10% chance of a 4
if (gameField[x][y] == 0) {
if (z == 9)
gameField[x][y] = 4;
else
gameField[x][y] = 2;
} else createNewNumber();
if (getMaxTileValue() == 2048)
win();
}
//denotes color of each cell dependant on number value
private Color getColorByValue(int value)
{
if (value == 0)
return Color.ANTIQUEWHITE;
else if (value == 2)
return Color.LIGHTPINK;
else if (value == 4)
return Color.PURPLE;
else if (value == 8)
return Color.BLUE;
else if (value == 16)
return Color.LIGHTSEAGREEN;
else if (value == 32)
return Color.GREEN;
else if (value == 64)
return Color.LIGHTGREEN;
else if (value == 128)
return Color.ORANGE;
else if (value == 256)
return Color.CORAL;
else if (value == 512)
return Color.RED;
else if (value == 1024)
return Color.PINK;
else
return Color.DEEPPINK;
}
//sets color of cells based apon getColorByValue method
private void setCellColoredNumber(int x, int y, int value)
{
if (value != 0)
setCellValueEx(x, y, getColorByValue(value), Integer.toString(value) );
else
setCellValueEx(x, y, getColorByValue(value), "" );
}
//this method takes a row from the grid and then sorts empty fields to right and moves other
//numbers to left without changing there order. This is only the beginning
private boolean compressRow(int[] row) {
boolean isChanged = false;
for (int i = 0; i < row.length; i++)
{
for (int j = 1; j < row.length; j++)
{
if (row[j-1] == 0)
{
if(row[j] != 0)
isChanged = true;
row[j-1] = row[j];
row[j] = 0; // had to use this way because creating temp array did not fit task conditions
}
}
}
return isChanged; //variable used to discover whether the row was changed or not.
}
//puts adjoining cells of the same value together
private boolean mergeRow(int[] row)
{
boolean isChanged = false;
//int[] rowChange = new int[row.length];
for(int j = 1; j<row.length; j++)
if(row[j] == row[j-1] && row[j] != 0)
{
isChanged = true; //changing variable
row[j - 1] = row[j] + row[j - 1];
row[j] = 0; //where there is a gap from combined numbers a zero is inuptted
}
return isChanged;
}
@Override //pre-built method for keyboard input, we use it to "shift" our grid around
public void onKeyPress(Key key)
{
if (key == Key.LEFT)
{
moveLeft();
drawScene();
}
else if (key == Key.RIGHT)
{
moveRight();
drawScene();
}
else if (key == Key.UP)
{
moveUp();
drawScene();
}
else if (key == Key.DOWN)
{
moveDown();
drawScene();
}
}
//this method compresses and merges numbers if possible, checking each with a secondary boolean result and if either true creates a new number.
private void moveLeft()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
}
private void moveRight()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
rotateClockwise(); //As we have already set up the left move, by rotating the array we can
rotateClockwise(); // implement the "slide-to-the-left" method
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
rotateClockwise();
rotateClockwise();
}
private void moveUp()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
rotateClockwise();
rotateClockwise();
rotateClockwise();
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
rotateClockwise();
}
private void moveDown()
{
boolean compressed = false;
boolean merged = false;
boolean compressed2 = false;
int move = 0; //counting integer to check movement on screen
rotateClockwise();
for (int i = 0; i < SIDE; i++)
{
compressed = compressRow(gameField[i]); //makes boolean results true
merged = mergeRow(gameField[i]);
compressed2 = compressRow(gameField[i]);
if (compressed || merged || compressed2)//if either action returned true move + 1
move ++;
}
if (move != 0)
createNewNumber();
rotateClockwise();
rotateClockwise();
rotateClockwise();
}
private void rotateClockwise()
{
int[][] temp = new int[SIDE][SIDE];
for (int i = 0; i < SIDE; ++i)
for (int j = 0; j < SIDE; ++j)
temp[i][j] = gameField[SIDE - j - 1][i];
for (int i = 0; i < SIDE; ++i)
for (int j = 0; j < SIDE; ++j)
gameField[i][j] = temp[i][j];
}
//finds the max of the array
private int getMaxTileValue()
{
int max = 0;
for (int i = 0 ; i < SIDE; i++)
for (int j = 0 ; j<SIDE; j++)
if (gameField[i][j] > max)
max = gameField[i][j];
return max;
}
private void win()
{
isGameStopped = true;
showMessageDialog(Color.GOLD, "You are a Winner!", Color.BLACK, 45);
}
private boolean canUserMove()
{
boolean movesLeft = false;
//comparison loop, checking for any duplicates when all spaces are taken.
for (int i = 0 ; i < SIDE; i++)
for (int j = 0 ; j<SIDE; j++)
{
if (gameField[i][j] == 0)
movesLeft = true;
if((gameField[i][j] == gameField[i+1][j]) || (gameField[i-1][j] == gameField[i][j]) || (gameField[i][j] == gameField[i][j+1]) || (gameField[i][j] == gameField[i][j-1]))
movesLeft = true;
}
//System.out.println(movesLeft);
return movesLeft;
}
}