2048 moving steps

  • (2 Pages)
  • +
  • 1
  • 2

18 Replies - 593 Views - Last Post: 06 November 2018 - 09:47 AM Rate Topic: -----

#1 Chebs   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 30-October 18

2048 moving steps

Posted 30 October 2018 - 12:22 AM

Hi,
I need to write the 2048 game.
I need to use the same function for all player's mooving steps.
Let's say that if the player wants to slide to the left, first of all I need to check if there's a possibility for the the tiles to move left and then merge them. I just don't know hoe to write it.
Thank you for your help!
Is This A Good Question/Topic? 0
  • +

Replies To: 2048 moving steps

#2 wseng92   User is offline

  • D.I.C Addict

Reputation: 37
  • View blog
  • Posts: 570
  • Joined: 23-September 15

Re: 2048 moving steps

Posted 30 October 2018 - 12:27 AM

I saw there are some full sources code in github. Have you cloned it and read ?
Was This Post Helpful? 0
  • +
  • -

#3 andrewsw   User is offline

  • head thrashing
  • member icon

Reputation: 6645
  • View blog
  • Posts: 27,201
  • Joined: 12-December 12

Re: 2048 moving steps

Posted 30 October 2018 - 01:05 AM

And how is your programming knowledge? What progress have you made so far?
Was This Post Helpful? 0
  • +
  • -

#4 Chebs   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 30-October 18

Re: 2048 moving steps

Posted 30 October 2018 - 01:12 AM

All the sources in github are too complicated for my knowledge so I cant understand what's going on there... This task is my first project for my second java course. I need help with more intro coding.. My main problem ia hoe to write the nextMove() function
Was This Post Helpful? 0
  • +
  • -

#5 andrewsw   User is offline

  • head thrashing
  • member icon

Reputation: 6645
  • View blog
  • Posts: 27,201
  • Joined: 12-December 12

Re: 2048 moving steps

Posted 30 October 2018 - 01:28 AM

I don't know what sort of help you are expecting in a brief forum post. I've never heard of the game but, on a brief look, you would:

Detect whether the play pressed left, right, up or down;
Start iterating the squares that are in the direction of travel;
Stop when a side or another block is encountered;
Determine what action needs to happen.

But surely this is no more than you would have realised yourself?
Was This Post Helpful? 0
  • +
  • -

#6 Chebs   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 30-October 18

Re: 2048 moving steps

Posted 30 October 2018 - 03:55 AM

I wrote a code for moving left, i dont know how to shift it to other ways by using this one:
(and this one works to left side)
public static void Moveleft() {
		for(int i=0;i<board.length;i++) {
			for(int j=1;j<board.length;j++) {
				while(board[i][j]!=0) {
					while(j>0&& board[i][j-1]==0) {
						board[i][j-1]=board[i][j];
						board[i][j]=0;
						j--;
					}
					j++;
				}
			}
		}
	

	}
:code:

This post has been edited by modi123_1: 30 October 2018 - 06:50 AM
Reason for edit:: In the future, please use the [code] tag button in the editor.

Was This Post Helpful? 0
  • +
  • -

#7 jon.kiparsky   User is offline

  • Beginner
  • member icon


Reputation: 11325
  • View blog
  • Posts: 19,369
  • Joined: 19-March 11

Re: 2048 moving steps

Posted 30 October 2018 - 08:00 AM

What does a "move" mean? It means a combination of a vertical delta and a horizontal delta. Moving right means a horizontal delta of 1 and vertical delta of zero, moving left means horizontal delta of -1 and a vertical delta of zero. Up and down moves work similarly, numbers depend on your preferred orientation.
So essentially, a Move can be a data structure containing two numbers. To apply this move, you just ask it for its deltas and apply them to each piece's current position.
Was This Post Helpful? 1
  • +
  • -

#8 Piet Souris   User is offline

  • D.I.C Head

Reputation: 44
  • View blog
  • Posts: 197
  • Joined: 01-December 15

Re: 2048 moving steps

Posted 30 October 2018 - 11:52 PM

Your moveLeft method is not very OO, and it involves a lot of dreaded index juggling. There is a more OO way, that is also much easier. But if the following is using things you have not been told about yet, then forget this post.

Suppose that your 2D array is not int[][], but Integer[][], in Java meaning that we have an array of Integer arrays. When we want to do a shift, we simply sort the individual arrays. Now, that cannot be done straight away, since if our array = {4, 2} we don't want to have it turned into {2, 4}. So we need a special Comparator for the sorting: one that considers every number to be equal. So we could get:
Comparator<Integer> intcomp = (p1, p2) -> 0;
Comparator<Integer> shiftLeft = Comparator.nullsLast(intcomp);
Comparator<Integer>shiftRright = Comparator.nullsFirst(intcomp);

and having this, we can write:
Integer[] row = {4, null, 2, null};
System.out.println(Arrays.toString(row));
Arrays.sort(row, shiftLeft);
System.out.println(Arrays.toString(row));
Arrays.sort(row, shiftRight);
System.out.println(Arrays.toString(row));

Well, if that is not beyond your current knowledge, then we can implement something likewise for shifting up and down.
Was This Post Helpful? 0
  • +
  • -

#9 snoopy11   User is offline

  • Engineering ● Software
  • member icon

Reputation: 1554
  • View blog
  • Posts: 4,930
  • Joined: 20-March 10

Re: 2048 moving steps

Posted 31 October 2018 - 11:13 AM

Your Move Left function could be written as

public static int Moveleft(int current_x, int current_y) {
		
			for(int j=current_x;j>=0;j--) {
				if(board[current_y][j]!=0) {
					
						break;
					}
					
				}
			return j; // return the new current_x position.
	}



A move down function could be written as
public static int Movedown(int current_x, int current_y) {
		
			for(int j=current_y;j<=board_height;j++) {
				if(board[j][current_x]!=0) {
					
						break;
					}
					
				}
			return j; // return the new current_y position
	}



How are you going to physically handle the Animation side of things, have you used swing ? for instance ?
Was This Post Helpful? 0
  • +
  • -

#10 snoopy11   User is offline

  • Engineering ● Software
  • member icon

Reputation: 1554
  • View blog
  • Posts: 4,930
  • Joined: 20-March 10

Re: 2048 moving steps

Posted 03 November 2018 - 12:54 AM

My answer was actually a bit naive this was in part due to not understanding the true nature of the problem,

anyway Chebs, I have now written a Tutorial on how to make a 2048 game in Java Swing which you may or may not be interested in reading,

In it, I cover your question in some detail ie how you go about moving left, up or down or even right and check all logical squares for interactions.


Best Of Luck.

Tut can be found here

https://www.dreaminc...g/#entry2380818
Was This Post Helpful? 1
  • +
  • -

#11 Piet Souris   User is offline

  • D.I.C Head

Reputation: 44
  • View blog
  • Posts: 197
  • Joined: 01-December 15

Re: 2048 moving steps

Posted 05 November 2018 - 03:59 AM

+1 for your code. It will give many an idea how to write such a thing.

From a Java point of view: why did you use Java? You are hardly using any specific Java topics, and no java8(+) at all. The same holds for the use of Swing (no JLabels for instance).
Was This Post Helpful? 0
  • +
  • -

#12 snoopy11   User is offline

  • Engineering ● Software
  • member icon

Reputation: 1554
  • View blog
  • Posts: 4,930
  • Joined: 20-March 10

Re: 2048 moving steps

Posted 05 November 2018 - 06:00 AM

Well Piet Souris,

I have many failings in Java, you don't need to inform me about them, I am like a little Java Baby and you must treat me as such. Why no JLabels?, well I just went with JPanels that's why I suppose. You are free to rewrite the code as you would see fit as the original game is open source why not keep it that way !!

Bon Chance !!

This post has been edited by snoopy11: 05 November 2018 - 06:01 AM

Was This Post Helpful? 0
  • +
  • -

#13 baavgai   User is online

  • Dreaming Coder
  • member icon


Reputation: 7327
  • View blog
  • Posts: 15,239
  • Joined: 16-October 07

Re: 2048 moving steps

Posted 05 November 2018 - 06:44 AM

I'll admit, I did plunk at that code a bit. I thought it might be rude to fire it back.

However, in the interests of a design challenge:
// I'm not 100% with this one.
enum TileValue {
    None(0,0x0), V2(2, 0xeee4da), V4(4, 0xede0c8), ...
    public final int intValue;
    public final Color color;
    TileValue(int n, int colorValue) { intValue = n; color = new Color(colorValue); }
}

// Your tile need only offer this
interface Tile {
    TileValue getValue();
    void setValue(TileValue value);
}

// make the moves clear
enum Move {
    Up, Down, Left, Right;
}

// the game itself
interface Tiles {
    int getRows();
    int getCols();
    TileValue getTile(int row, int col);
    void makeMove(Move move);
    void newGame();
    boolean isDone();
}

// and, I suppose, a reasonable class for a Tile
final class TileImpl extends JLabel implements Tile {
    private static final Font font = new Font("Arial", Font.BOLD, 36);
    private final int row, col;
    private TileValue value;
    TileImpl(int row, int col) {
        this.row = row;
        this.col = col;
        setFont(font);
        setForeground(Color.BLACK);
        setHorizontalAlignment(JLabel.CENTER);
        setVerticalAlignment(JLabel.CENTER);        
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        setOpaque(true);
        setValue(TileValue.None);
    }
    
    public TileValue getValue() { return value; }
    
    public void setValue(TileValue value) {
        this.value = value;
        this.setBackground(value.color);
        this.setText("" + value.intValue);
    }
}



Reasonably, if the actual goal is to show how movement works, you could follow the interfaces and just do something in the console. Indeed, the exercise of separating your model view and controller is probably of value in its own right.
Was This Post Helpful? 0
  • +
  • -

#14 snoopy11   User is offline

  • Engineering ● Software
  • member icon

Reputation: 1554
  • View blog
  • Posts: 4,930
  • Joined: 20-March 10

Re: 2048 moving steps

Posted 06 November 2018 - 01:19 AM

No baavgai, its not rude if your motives are pure, you have a gleam in your eye and it improves understanding.

'You Go Girl !!' ;)
Was This Post Helpful? 0
  • +
  • -

#15 Chebs   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 30-October 18

Re: 2048 moving steps

Posted 06 November 2018 - 08:27 AM

thank you everyone for your help. as I said before, this is just my first project of my second java course. The main purpose of this project is to learn hoe to write top down, using one class. so after alot of work, heres my code:

import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class assignment1 {

	static Scanner sc = new Scanner(System.in);
	public static int [][] board = new int[4][4];
	public static int score=0;
	public static int best=0;
	public static int oldScore=0;
	public static int newTileStart = 2; //start the game with 2 random tiles
	public static int [][] oldBoard = new int [4][4]; // a copy of the board


	public static boolean startGame() { // first menu to start the game
		System.out.println("Welcome, would you like to start the game? \r\n"
				+ "press y to start \r\n"
				+ "press n to and grogram");
		if (answerIsYorN()== 'n') {

			return false;
		}
		return true;
	}

	public static void initBoard (int numOfTiles) { // to start the game
		int countEmpty =0;
		int countZiros =chooseRandomTile();
		for (int i=0; i<board.length ; i++ ) {
			for(int j=0; j<board.length; j++) {
				if (board[i][j] ==0) {
					countEmpty++;
				}
				if (countEmpty == countZiros) {// put the number in the tile number #countZiros
					board[i][j] = random2or4 ();
					if (numOfTiles ==2) { // if you start a new game then fill the board with 2 random tiles
						initBoard(1);
					}
					//printBoard(); 
				}
			}
		}
	}
	public static void cleanBoard () { //clean tiles to start a new game
		for (int i=0; i<board.length; i++ ) {
			for(int j=0; j<board.length; j++) {
				board[i][j] =0;
			}
		}
		score =0;
	}

	public static int chooseRandomTile() { // the chosen tile will be the empty tile number #randomTile
		int numOfEmptyTiles =countEmptyTile ();
		int randomTile = (int) ((int)numOfEmptyTiles*Math.random());
		return randomTile;
	}


	public static int random2or4 () { // random 2 or 4 for the tile
		double prob = Math.random(); // different probability for 2 or 4
		if (prob >0.7) {
			return 4;
		}
		else return 2;
	}

	public static int countEmptyTile () { // count how many empty tiles is
		int countEmptyTile =0;
		for (int i=0; i<board.length; i++ ) {
			for(int j=0; j<board.length; j++) {
				if (board[i][j]==0) {
				countEmptyTile++;
			}
		}
		}
		return countEmptyTile;
	}

	public static int checkWinLose () { // check all options to win or lose the game
		if (reached2048 ()) {
			return 1;
		}

		if (possibleMoves() == false) {
			return -1;
		}
		return 0;
	}

	public static boolean printWinLoseMessage(int num) { // print message for losing or winning
		if (num ==1) {
			printBoard();
			System.out.println ("You won! 2048!would you like to continue? Press y if yes, n if not ");
			if (answerIsYorN()=='y') {
		
				return true;
			}

		}
		if (num== -1) {
			System.out.println ("Game over your score is "+score+". For a new game press y, n if not");
			if (answerIsYorN()== 'y') {
				playerWantsToContinue();
				return true;
			}


		}
		return false;
	}
	public static void playerWantsToContinue() {// preparation for a new game 
		cleanBoard();
		initBoard(newTileStart);
	}
	public static char answerIsYorN() { // choose to continue or end the game
		char plaerChoice = sc.next().charAt(0);
		if(plaerChoice =='y') {
			return plaerChoice ;
		}
		if(plaerChoice =='n') {
			System.out.println("end program");
			return plaerChoice;
		}
		return plaerChoice;
	}

	public static boolean reached2048 () { //check if win
		for (int i=0; i<board.length; i++ ) {
			for(int j=0; j<board.length; j++) {
				if (board[i][j]==2048) {
					return true;
				}
			}

		}
		return false;
	}
	public static char stepsMenu() { // print the steps options menu
		System.out.println("for moving up, press w\r\n"
				+ "for moving down, press s\r\n"
				+ "for moving left, press a\r\n"
				+"for moving right, press d\r\n"
				+ "for returning one step back, press r\r\n"
				+"for ending the game, press e\r\n"
				+"for starting a new game, press n");
		char StepChoice = sc.next().charAt(0);
		return StepChoice;
	}


	public static void printBoard() {
		System.out.println ("score ="+ score + " best ="+ best);
		for (int i=0; i<board.length; i++ ) {
			for(int j=0; j<board.length; j++) {
				System.out.print ("["+board[i][j]+"]"+ " " );
			}
			System.out.println();
		}

		//nextMove(stepsMenu());
	}

	public static boolean possibleMoves() {// check if there are possible moves
		if (countEmptyTile ()==0) { //if there are no empty tiles
			for (int i=0; i<board.length; i++) {
				for( int j=0; j<board.length-1; j++) {
					if (identical(i,j,i,j+1)) {// if there are identical tiles so you can move
						return false;
					}
				}
			}
			for( int j=0; j<board.length; j++) {
				for (int i=0; i<board.length-1; i++) {
					if (identical(i,j,i+1,j)) {
						return false; 
					}
				}
			}	
		}
		return true;// he can move
	}

	public static boolean identical(int i, int j , int k, int l) { //check if there are identical tiles to sum
		if (board[i][j] == board[k][l]) {
			return true;
		}
		return false;

	}


	public static void nextMove( char choosenDirction){
		if (choosenDirction == 'd') { //right
			moveRight();
		}
		if (choosenDirction == 'a') { //left
			moveLeft();
		}

		if (choosenDirction == 's') { //down
			moveDown();
		}
		if (choosenDirction == 'w') { //up
			moveUp();
		}
		if (choosenDirction == 'r') { //return
			stepBack();
		}

		if (choosenDirction == 'e') { //end game
			System.out.println("end program");
			System.exit(0);

		}

		if (choosenDirction == 'n') { //new game
			cleanBoard();
			initBoard(newTileStart);
		}
	}


	public static void moveRight () {
		cloneBoard(); // copy board after single move
		for(int r=0 ; r<board.length; r++) {//row
			for ( int m=3 ; m>0; m--) { 
				for (int t=2; t>=0; t--) {
					moveNow (r,0,t,1);// move all numbers to the right
				}
			}
			for (int i=3; i>0; i--) {// check if there are identical tiles 
				if (identical(r,i,r,i-1)) {
					sumTiles (r,i,r,i-1);// sum the identical tiles
					for (int t=2; t>=0; t--) {
						moveNow (r,0,t,1);// move right again
					}//for

				}//if
			}// for i
		}//for r
		changeScoreToBest();
		checkBoards ();
	}

	public static void moveLeft () {
		cloneBoard(); // copy board after single move
		for(int r=0 ; r<board.length; r++) {//row
			for ( int m=0 ; m<3; m++ ) { 
				for (int t=1; t<board.length; t++) {
					moveNow (r,0,t,-1);// move all tiles to the left
				}
			}
			for (int i=0; i<board.length-1; i++) {
				if (identical(r,i,r,i+1)) {// check if there are identical tiles
					sumTiles (r,i,r,i+1);// sum the identical tiles 
					for (int t=1; t<board.length; t++) {
						moveNow (r,0,t,-1);// move again to the left
					}//for t
				}//if
			}// for i
		}//for r
		changeScoreToBest();
		checkBoards ();
	}

	public static void moveDown () {
		cloneBoard(); // copy board after single move
		for(int j=0 ; j<board.length; j++) {//col
			for ( int m=2 ; m>0; m-- ) { //row
				for (int t=0; t<board.length-1; t++) {
					moveNow (t,1,j,0);// move all numbers dowm
				}
			}
			for (int i=2; i>0; i--) {
				if (identical(i+1,j,i,j)) {// check if there are identical tiles
					sumTiles (i+1,j,i,j);// sum the identical tiles
					for (int t=2; t>0; t--) {
						moveNow (t,1,j,0);// move again down
					}//for t
				}//if
			}// for i
		}//for j
		changeScoreToBest();
		checkBoards ();
	}

	public static void moveUp () {
		cloneBoard(); // copy board after single move
		for(int j=0 ; j<board.length; j++) {//col
			for ( int m=0 ; m<3; m++ ) { //row
				for (int t=1; t<board.length; t++) {
					moveNow (t,-1,j,0);// move all tiles up
				}
			}
			for (int i=0; i<board.length-1; i++) {
				if (identical(i,j,i+1,j)) {// check if there are identical ti
					sumTiles (i,j,i+1,j);// sum the identical tiles
					for (int t=1; t<board.length; t++) {
						moveNow (t,-1,j,0);// move again up
					}//for
				}//if
			}// for i
		}//for j
		changeScoreToBest () ;
		checkBoards ();
	}

	public static void moveNow (int i,int x, int j,  int y) { // move the number to another tile according to the direction
		if (board[i+x][j+y] == 0) { //if the tile is empty
			board[i+x][j+y]= board[i][j];// x and y change according to the direction we want
			board[i][j]=0;		
		}

	}
	public static void changeScoreToBest () { // change score to best
		if (score>best) {
			best = score;
		}

	}
	public static void checkBoards () { 
		if (compereBoards() == true) { //  if we did a move and there was nothing changed it means we cant move
			System.out.println ("can not move to this direction. choose a different direction ");
			printBoard();
		}
		initBoard(1);
	}
	
	public static void  sumTiles (int i, int j, int row, int col ) { //sum the identical tiles

		if (board[i][j]== board[row][col]) {
			board[i][j]= board[i][j]+board[row][col];
			board[row][col]=0;
			score = score+board[i][j]; //add the sum to the score
		}
	}

	public static void  cloneBoard() { //copy of the board
		for (int i=0; i<board.length;i++) {
			for( int j=0; j<board.length; j++){
				oldBoard[i][j] = board[i][j];
			}
		}
		oldScore=score;
	}

	public static boolean  compereBoards() { //compare the old and the new board
		for (int i=0; i<board.length;i++) {
			for( int j=0; j<board.length; j++){
				if (oldBoard[i][j] != board[i][j]) {
					return false;
				}
			}
		}
		return true;
	}


	public static void  stepBack(){// go one step back 
		for (int i=0; i<board.length;i++) {
			for( int j=0; j<board.length; j++){
				board[i][j]=oldBoard[i][j];
			}
		}
		score=oldScore;// change the score to the old one
	}




	public static void main(String[] args) {
		boolean gameOver = false;// check if game is over and why 

		if (startGame()== true) {
			initBoard(newTileStart); // Set the location of 2 and 4 

			while (gameOver == false) {
				printBoard();
				nextMove(stepsMenu());
				if (checkWinLose() != 0) {
					if (printWinLoseMessage(checkWinLose()) == false) {
						gameOver = true;
					}

				}
			}
		}
	}
}
:code:

This post has been edited by modi123_1: 06 November 2018 - 08:29 AM
Reason for edit:: In the future, please use the [code] tag button in the editor.

Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2