Developing Android from scratch 2048 (three) logic judgment

Source: Internet
Author: User
Tags gety

Recently work relatively busy, so the update is a little slower, today's main content is about the Android version of the 2048 logical judgment, after the explanation of this article, basically completed the main part of the game.

First, let's look at some of the stored data structures I used when I implemented 2048. When I realized it, the main use of the variables in the process of storing the game was the list.

For example,:list<integer> spacelist = new arraylist<integer> (); This spacelist is mainly used for saving, the position of all the blank lattice, That is, the position of the blank lattice in the GridLayout (from 0 to 15)

For the number lattice, and the data for the lattice, I wrote a class like this:

Package Com.example.t2048;import Java.util.arraylist;import Java.util.list;import android.util.log;/** * For saving a number of cells, Numbers corresponding to the numbers * @author Mr.wang * */public class NumberList {//This List is used to hold all the coordinates of the non-empty lattice (in the GridLayout position from 0 to a) private list< integer> stufflist = new arraylist<integer> ();//This List is used to hold all non-empty lattices corresponding to the number (base 2) Private List<integer > numberlist = new arraylist<integer> ();/** * Newly added number grid * @param the position of the index cell * @param number (base 2) /public void Add (int index, int number) {Stufflist.add (index); numberlist.add (number);} /** * is used to determine if the current position is an array of numbers * @param index Current position * @return true to mean */public Boolean contains (int index) {return stufflist.contains (index);} /** * Remove the current grid from the list of numbers * @param index */public void Remove (int index) {int order = Stufflist.indexof (index); numberlist.remove (order); Stufflist.remove (order);} /** * The current lattice corresponding to the number upgrade, index plus 1 * @param index */public void levelup (int index) {int order = Stufflist.indexof (index); numberlist.se T (order, Numberlist.get (order) +1);} /*** Replace the position of the current grid with the new position * @param index Current position * @param newindex new position */public void Changeindex (int index, int newindex) {s Tufflist.set (Stufflist.indexof (index), newindex);} /** * gets its corresponding number by the grid corresponding to the position * @param index Current position * @return lattice corresponds to the exponent of the number */public int getnumberbyindex (int index) {int Orde R = Stufflist.indexof (index); return numberlist.get (order);} Public String toString () {return stufflist.tostring () +numberlist.tostring ();} public void Printlog () {log.i ("Stufflist", stufflist.tostring ()); LOG.I ("NumberList", numberlist.tostring ());}}

This class is mainly my number lattice, the number of numbers corresponding to the preservation of numbers, and additions and deletions and other operations. In fact, it is two lists, I am easy to operate, so write them in a class.


Then, let's talk about the logic of the game.

For example, we perform a right-swipe operation during the game, in which we judge and manipulate all the squares that can be moved and merged:

1, the right side of the number lattice if it is a blank lattice, then the number lattice and the white space exchange

2. If there are more than one blank lattice to the right of the number lattice, the number grid will be exchanged with the last blank space in a row.

3, the right side of the number grid if there is the same number lattice, then the grid is empty, the right of the number of the upgrade (index plus one)

4, if the sliding direction of continuous existence of more than the same number lattice, right lattice priority upgrade

5, in a sliding, each lattice up to upgrade once

When a lattice exists in any of the first four of the above, the operation is done

We try to translate the above rules into code, first of all, clear the coordinates in the GridLayout position, I used in the GridLayout is the horizontal layout, so each grid corresponding to the location of the following


On this basis, I set up the following axes, with the upper left corner as the origin, the x axis as the horizontal axis and the Y axis as the shaft:



When you swipe right, from the logic above, we should traverse the grid from right to left for convenience.

for (int y=0;y<4;y++) {for (int x=2;x>=0;x--) {int thisidx = 4*y +x; Change (thisidx,direction);}}

Every time a new grid is traversed, the change () method is executed once, in fact, every time you traverse to a non-empty grid, you perform a turn (). But for the sake of convenience, I add the non-null judgment to the code of the changed, and we look at the implementation of this method, This method is primarily used to determine whether a lattice needs to be moved, merged, or manipulated. :

/** * This method performs a change of operation for each qualifying lattice, such as permutation, upgrade, etc. * @param thisidx     The coordinates of the current grid * @param direction   sliding direction */public void change (int this Idx,int direction) {if (Numberlist.contains (THISIDX)) {int nextidx = GetLast (thisidx, direction); if (nextidx = = Thisidx) { Cannot move return;} else if (Spacelist.contains (NEXTIDX)) {//There is a blank space that can be replaced replace (THISIDX,NEXTIDX);} Else{if (Numberlist.getnumberbyindex (thisidx) = = Numberlist.getnumberbyindex (nextidx)) {//Can merge LevelUp (THISIDX, NEXTIDX);} Else{int before = Getbefore (nextidx, direction); if (before! = Thisidx) {//There are blank spaces replaceable (Thisidx,before);}}}}

where the GetLast () method is used to get the last lattice in which the current lattice can move or merge, and if the return value is the current lattice, it cannot be moved. The GetNext () method is called in order to get the position of the current lattice in the next lattice in the direction of movement.

/** * To get the position after the last empty cell in the direction of movement * @param index      The coordinates of the current grid * @param direction  Move direction * @return */public int getlast (int this IDX, int direction) {int nextidx = GetNext (thisidx, direction), if (Nextidx < 0) return thisidx; else{if (spacelist.cont Ains (NEXTIDX)) return GetLast (Nextidx, direction); else return nextidx; }}
then replace (int thisidx, int nextidx), this method is to perform two grid interchange position, the content is mainly the view of two lattice to replace the background image, and then manipulate the blank grid list of the lists and the list:

/** * This method is used to swap the current grid with the position of the target space * @param thisidx the coordinates of the current grid * @param nextidx The coordinates of the target blank grid */public void replace (int thisidx, int nextid X) {moved = true;//gets the view of the current lattice and place it into a blank grid view Thisview = Gridlayout.getchildat (THISIDX); ImageView image = (ImageView) Thisview.findviewbyid (R.id.image); Image.setbackgroundresource (icons[0]);//Get the view of a blank lattice and set its background to the current grid background view NextView = Gridlayout.getchildat (NEXTIDX); ImageView nextimage = (ImageView) Nextview.findviewbyid (r.id.image); Nextimage.setbackgroundresource (Icons[numberlist.getnumberbyindex (THISIDX));//In the blank column table, remove the target grid, Add the current lattice Spacelist.remove (Spacelist.indexof (NEXTIDX)); Spacelist.add (THISIDX);//In the Digital column table, The coordinates of the current grid are replaced with the coordinates of the target Numberlist.changeindex (Thisidx, nextidx);}


LevelUp (int thisidx, int nextidx) This method is to achieve the same number lattice of the merge operation, in fact, the current grid is placed into a blank lattice, the moving direction of the upper and lower one of the grid corresponding to the background of the next background:

/** * method is used to merge two identical lattices in the moving direction * @param thisidx coordinates of the current grid * @param nextidx The coordinates of the target lattice */public void LevelUp (int thisidx, int nextid x) {///on a move, each lattice can only be upgraded once if (!changelist.contains (NEXTIDX)) {moved = true;//get the view of the current lattice and place it into a blank grid view Thisview = Gridlayout.getchildat (THISIDX); ImageView image = (ImageView) Thisview.findviewbyid (r.id.image); Image.setbackgroundresource (Icons[0]);//Get the view of the target and set its background to the background view NextView = Gridlayout.getchildat (NEXTIDX) after the current grid upgrade ; ImageView nextimage = (ImageView) Nextview.findviewbyid (r.id.image); Nextimage.setbackgroundresource (icons[ Numberlist.getnumberbyindex (NEXTIDX) +1]);//Add the current lattice Spacelist.add (THISIDX) to the blank table, or delete the first lattice numberlist.remove in the number column ( THISIDX);//To upgrade the contents of the list Numberlist.levelup (NEXTIDX); Changelist.add (NEXTIDX);}}


After writing these, basically completed the main judgment, but there are two questions: 1 is if each slide without a lattice move (merge), then should not be randomly generated lattice; 2 each lattice can only be merged once.

To solve these two problems, I added two additional variables.

Used to save each operation, the checked list<integer> changelist = new arraylist<integer> () is used to indicate whether the sliding has a lattice move over a Boolean moved = false;


Where the changelist is emptied before each swipe, and then joined in the movement of the merged lattice, in the judgment of each merger first see whether the lattice to be merged in the list, if so, the description has been merged, then do not perform the merge operation.

There is also a moved variable, which is also set to false before each slide, if in this slide, there is a lattice move or merge, is set to ture, at the end of the sliding, through this variable to determine whether to randomly produce a new lattice.


The following is the code in the complete activity:

Package Com.example.t2048;import Java.util.arraylist;import Java.util.list;import java.util.random;import Android.app.activity;import Android.os.bundle;import Android.view.gesturedetector;import Android.view.gesturedetector.ongesturelistener;import Android.view.menu;import Android.view.MotionEvent;import Android.view.view;import Android.view.view.ontouchlistener;import Android.widget.gridlayout;import Android.widget.imageview;public class Mainactivity extends Activity {final static int left = -1;final static int right = 1 ; final static int up = -4;final static int down = 4; GridLayout GridLayout = null;//is used to save spaces list<integer> spacelist = new arraylist<integer> ();// All non-empty lattice numberlist numberlist = new NumberList ();//For saving each operation, the already upgraded lattice list<integer> changelist = new arraylist< Integer> ();//used to indicate whether the sliding has a lattice moved over a Boolean moved = FALSE; Gesturedetector GD = null;/** * Icon Array */private final int[] icons = {r.drawable.but_empty, r.drawable.but2,r.drawable.but4 , R.drawable.but8, R.DRawable.but16,r.drawable.but32, R.drawable.but64, r.drawable.but128,r.drawable.but256, R.drawable.but512, r.drawable.but1024,r.drawable.but2048, r.drawable.but4096};p rotected void OnCreate (Bundle savedinstancestate) { SYSTEM.OUT.PRINTLN ("program start"); Super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); GridLayout = (gridLayout) Findviewbyid (R.ID.GRIDLAYOUT1); init (); Mygesturedetector mg = new Mygesturedetector (); gd = new Gesturedetector (mg); Gridlayout.setontouchlistener (MG); Gridlayout.setlongclickable (TRUE);} Initialize interface public void init () {System.out.println ("initialize");//First fill in 16 various blanks with blank picture for (int i=0;i<16;i++) {View view = View.inflate (this, r.layout.item, null); ImageView image = (ImageView) View.findviewbyid (r.id.image); Image.setbackgroundresource (Icons[0]); Spacelist.add (i); Gridlayout.addview (view);} Randomly add two x 2 or 4addRandomItem () to the interface, Addrandomitem ();} Randomly get the location public int Getrandomindex () {Random random = new random () from the empty column table, and if (Spacelist.size () >0) return Random.nextint (Spacelist.size ()); else return-1;} Randomly add a number 2 or 4public void Addrandomitem () {int index = Getrandomindex () in a blank lattice, if (index!=-1) {System.out.println ("randomly generated digit position +spacelist.get (index));//get Viewview view = Gridlayout.getchildat (Spacelist.get (index)) corresponding to the corresponding coordinates; ImageView image = ( ImageView) View.findviewbyid (r.id.image);//randomly generate a number 1 or 2int i = (int) math.round (math.random () +1);// Replace the picture of the current grid with 2 or 4image.setbackgroundresource (Icons[i]),//Add the information numberlist.add the lattice in Numlist (Spacelist.get (index), i) ;//Remove the lattice Spacelist.remove (index) from the blank list;}} public class Mygesturedetector implements ongesturelistener,ontouchlistener{@Overridepublic boolean OnTouch (View V, Motionevent event) {//TODO auto-generated method Stubreturn gd.ontouchevent (event);} @Overridepublic Boolean Ondown (motionevent e) {//TODO auto-generated method Stubreturn false;}              @Overridepublic boolean onfling (motionevent E1, motionevent E2, float velocityx,float velocityy) {//Parameter explanation: E1:1th action_down motionevent//E2: Last Action_move MotionevenT///VELOCITYX:X axis movement speed, pixels/sec//Velocityy:y axis movement speed, pixels/sec//Trigger condition: The coordinate displacement of the x-axis is greater than fling_min_distance and moves at a speed greater than fling_min_velocity pixels per second if (E1.getx ()-e2.getx () >100) {System.out.println ( Move (left); return true;} ElseIf (E1.getx ()-e2.getx () <-100) {System.out.println ("right"); "Move"; return true;} ElseIf (E1.gety ()-e2.gety () >100) {System.out.println ("up"), move (UP), return true; ElseIf (E1.gety ()-e2.gety () <-00) {System.out.println ("down"), move (down); return true;} return false;} @Overridepublic void Onlongpress (Motionevent e) {//TODO auto-generated Method stub} @Overridepublic Boolean Onscroll ( Motionevent E1, Motionevent e2,float Distancex, float Distancey) {//TODO auto-generated method Stubreturn false;} @Overridepublic void Onshowpress (Motionevent e) {//TODO auto-generated Method stub} @Overridepublic Boolean Onsingletapup (motionevent e) {//TODO auto-generated method Stubreturn false;}} /** * Used to get the position of the upper and lower grid of the moving direction * @param index whenThe position of the front lattice * @param direction sliding direction * @return If at the boundary return-1 */public int getNext (int index,int direction) {int y = index/4;int x = Index%4;if (x==3 && direction==right) return-1;if (x==0 && direction==left) return-1;if (y==0 && Direction==up) return-1;if (y==3 && direction==down) Return-1;return index+direction;} /** * Used to get the position of the previous lattice in the moving direction * @param index The position of the current lattice * @param direction sliding direction * @return If at the border in return-1 */public int Getbefore (i NT Index,int direction) {int y = index/4;int x = index%4;if (x==0 && direction==right) return-1;if (x==3 && D Irection==left) return-1;if (y==3 && direction==up) return-1;if (y==0 && direction==down) return-1; return index-direction;} /** * This method is used to swap the current grid with the position of the target space * @param thisidx the coordinates of the current grid * @param nextidx The coordinates of the target blank grid */public void replace (int thisidx, int nextid X) {moved = true;//gets the view of the current lattice and place it into a blank grid view Thisview = Gridlayout.getchildat (THISIDX); ImageView image = (ImageView) Thisview.findviewbyid (r.id.image); image.setbackgRoundresource (Icons[0]);//Get the view of the blank lattice and set its background to the current grid background view NextView = Gridlayout.getchildat (NEXTIDX); ImageView NextImage = (ImageView) Nextview.findviewbyid (r.id.image); Nextimage.setbackgroundresource (icons[ Numberlist.getnumberbyindex (THISIDX)]);//In the blank column table, remove the target grid, plus the current lattice Spacelist.remove (Spacelist.indexof (NEXTIDX)); Spacelist.add (THISIDX);//In the Numeric column table, the coordinates of the current grid are replaced with the coordinates of the target grid numberlist.changeindex (THISIDX, nextidx);} /** * method is used to merge two identical lattices in the moving direction * @param thisidx coordinates of the current grid * @param nextidx The coordinates of the target lattice */public void LevelUp (int thisidx, int nextid x) {///on a move, each lattice can only be upgraded once if (!changelist.contains (NEXTIDX)) {moved = true;//get the view of the current lattice and place it into a blank grid view Thisview = Gridlayout.getchildat (THISIDX); ImageView image = (ImageView) Thisview.findviewbyid (r.id.image); Image.setbackgroundresource (Icons[0]);//Get the view of the target and set its background to the background view NextView = Gridlayout.getchildat (NEXTIDX) after the current grid upgrade ; ImageView nextimage = (ImageView) Nextview.findviewbyid (r.id.image); Nextimage.setbackgroundresource (icons[ Numberlist.getnumberbyindex (NEXTIDX) +1]);//Add the current SP to the blank grid tableAcelist.add (THISIDX);//delete the first lattice numberlist.remove (THISIDX) in the numeric column and/or upgrade the contents of the list to Numberlist.levelup (NEXTIDX); Changelist.add (NEXTIDX);}} /** * This method performs different traversal order for different sliding directions * @param direction slide direction */public void Move (int direction) {moved = False;changelist.clear (); num Berlist.printlog (); switch (direction) {case Right:for (int. y=0;y<4;y++) {for (int x=2;x>=0;x--) {int thisidx = 4*y +x ; Change (thisidx,direction);}} Break;case left:for (int y=0;y<4;y++) {for (int x=1;x<=3;x++) {int thisidx = 4*y +x; Change (thisidx,direction);}} Break;case up:for (int x=0;x<4;x++) {for (int y=1;y<=3;y++) {int thisidx = 4*y +x; Change (thisidx,direction);}} Break;case down:for (int x=0;x<4;x++) {for (int y=2;y>=0;y--) {int thisidx = 4*y +x; Change (thisidx,direction);}} break;} If this slide has a lattice move, then randomly fills the new lattice if (moved) Addrandomitem ();} /** * This method performs a change of operation for each qualifying lattice, such as permutation, upgrade, etc. * @param thisidx the coordinates of the current grid * @param direction sliding direction */public void change (int thisid X,int direction) {if (Numberlist.contains (THISIDX)) {int nextidx = GetLast (Thisidx, diRection); if (nextidx = = Thisidx) {//cannot move return;} else if (Spacelist.contains (NEXTIDX)) {//There is a blank space that can be replaced replace (THISIDX,NEXTIDX);} Else{if (Numberlist.getnumberbyindex (thisidx) = = Numberlist.getnumberbyindex (nextidx)) {//Can merge LevelUp (THISIDX, NEXTIDX);} Else{int before = Getbefore (nextidx, direction); if (before! = Thisidx) {//There are blank spaces replaceable (Thisidx,before);}}}} /** * To get the position after the last empty cell in the direction of movement * @param index The coordinates of the current grid * @param direction Move direction * @return */public int getlast (int thisid x, int direction) {int nextidx = GetNext (thisidx, direction), if (Nextidx < 0) return thisidx; else{if (Spacelist.contai NS (NEXTIDX)) return GetLast (Nextidx, direction); else return nextidx; }}public boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is PRESENT.G Etmenuinflater (). Inflate (R.menu.main, menu); return true;}}


Written here, as I studied Android, the first one to write my own program is half done. Logic to judge this part of the writing, it took a little time, because there are always some circumstances have not been considered, until now basically has been achieved. But also reflects a very important problem, that is, the data structure and algorithms are still very weak, the whole reading of their own code, in order to complete the judgment of various situations, the entire code looks very redundant, and the efficiency of the must not not to mention. Look at other people write code, feel oneself in the development aspect still has a long way to go.

The next time, I will use the spare time to constantly improve the program, and as far as possible to optimize. Let's share it!

Code written in this way, I also do not Cangzhuo, I put the code to upload, the need for friends can download, but also hope that we have a lot of corrections

http://download.csdn.net/detail/johnsonwce/7269315

Developing Android from scratch 2048 (three) logic judgment

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.