java - Tetris Rotation Algorithm not working -


i'm working tetris rotation algorithm. used algorithm in winforms app while ago , worked fine. want write tetris game in android write algorithm in java again.

however, time doesn't work. wrote algorithm quite while ago when beginner programmer code kind of bad. here algorithm in java:

public static final int clockwise = 1; public static final int anticlockwise = -1;  public static point rotateclockwise (int x, int y) {     int temp;     temp = y;     y = x;     x = -temp;     return new point (x, y); }  public static point rotateanticlockwise (int x, int y) {     int temp;     temp = x;     x = y;     y = -temp;     return new point (x, y); }  public static boolean tryrotatetetrimino (tetrimino tetrimino,         int rotationpointblockindex, int direction) {      //local variable declarations     boolean a, b, c, d;     tetrisblock rotationblock = tetrimino.blocks[rotationpointblockindex];     int x1, y1, x2, y2, x3, y3, x4, y4;      //assign coordinates relative centre of rotation.     x1 = tetrimino.blocks[0].getx () - rotationblock.getx ();     y1 = tetrimino.blocks[0].gety () - rotationblock.gety ();     x2 = tetrimino.blocks[1].getx () - rotationblock.getx ();     y2 = tetrimino.blocks[1].gety () - rotationblock.gety ();     x3 = tetrimino.blocks[2].getx () - rotationblock.getx ();     y3 = tetrimino.blocks[2].gety () - rotationblock.gety ();     x4 = tetrimino.blocks[3].getx () - rotationblock.getx ();     y4 = tetrimino.blocks[3].gety () - rotationblock.gety ();      //rotate coordinates.     if (direction == clockwise) {         x1 = rotateclockwise (x1, y1).x;         y1 = rotateclockwise (x1, y1).y;         x2 = rotateclockwise (x2, y2).x;         y2 = rotateclockwise (x2, y2).y;         x3 = rotateclockwise (x3, y3).x;         y3 = rotateclockwise (x3, y3).y;         x4 = rotateclockwise (x4, y4).x;         y4 = rotateclockwise (x4, y4).y;     } else {         x1 = rotateanticlockwise (x1, y1).x;         y1 = rotateanticlockwise (x1, y1).y;         x2 = rotateanticlockwise (x2, y2).x;         y2 = rotateanticlockwise (x2, y2).y;         x3 = rotateanticlockwise (x3, y3).x;         y3 = rotateanticlockwise (x3, y3).y;         x4 = rotateanticlockwise (x4, y4).x;         y4 = rotateanticlockwise (x4, y4).y;     }      //declares 2 arrays of absolute x , y coordinates.     int[] xarray = new int[] { rotationblock.getx() + x1,             rotationblock.getx() + x2,             rotationblock.getx() + x3,             rotationblock.getx() + x4 };     int[] yarray = new int[] { rotationblock.gety() + y1,             rotationblock.gety() + y2,             rotationblock.gety() + y3,             rotationblock.gety() + y4 };      //check if coordinates valid     = tetrimino.checkpositionvalid (xarray[0], yarray[0]);     b = tetrimino.checkpositionvalid (xarray[1], yarray[1]);     c = tetrimino.checkpositionvalid (xarray[2], yarray[2]);     d = tetrimino.checkpositionvalid (xarray[3], yarray[3]);      //if coordinates valid, assign them each of blocks.     if (a && b && c && d) {         (int = 0 ; < 4 ; i++) {             tetrimino.blocks[i].setx (xarray[i]);             tetrimino.blocks[i].sety (yarray[i]);         }         return true;     }     return false;  } 

i think code hard understand except me. used write worst code in world. method returns true when terimino can rotate , rotated. parameter rotationpointblockindex indicates center of rotation. therefore, can try rotate tetrimino every tetris block, this:

if (tetrisutility.tryrotatetetrimino (this, 0, tetrisutility.clockwise))         tetrisutility.addrotationindex (this);     else if (tetrisutility.tryrotatetetrimino (this, 1, tetrisutility.clockwise))         tetrisutility.addrotationindex (this);     else if (tetrisutility.tryrotatetetrimino (this, 2, tetrisutility.clockwise))         tetrisutility.addrotationindex (this);     else if (tetrisutility.tryrotatetetrimino (this, 3, tetrisutility.clockwise))         tetrisutility.addrotationindex (this); 

please note setx , sety methods change physical position of tetris block.

i same thing before doesn't work. example:

o o o o 

rotate, , turns into

o   o     o 

it seems 2 of tetris blocks have overlapped.

if think algorithm wrong , want suggest one, can explain in terms of tetrimino class , tetrisblock class?

tetrimino.java

public abstract class tetrimino { public tetrisblock[] blocks;  protected int interval = 1000; protected boolean paused = false; protected handler handler; protected tetrisblock[][] tetrisblockmatrix; protected arraylist<itetriseventlistener> landedeventlisteners; protected runnable task = new timertask () {     @override     public void run() {         if (!paused) {             movedown ();             if (handler != null)                 handler.postdelayed (task, interval);         }     } };  public static final int left = -1; public static final int right = 1;  protected abstract tetrisblock[] gettouchingsides();  protected void landed () {     (int = 0 ; < landedeventlisteners.size () ; i++) {         landedeventlisteners.get (i).onlanded (this);     } }  public void registerlandedlisteners (itetriseventlistener listener) {     landedeventlisteners.add (listener); }  public void movedown () {     if (!checklanded ()) {         (tetrisblock block:blocks) {             block.movedown ();         }     } else {         handler = null;         landed ();     } }  protected boolean checklanded () {     tetrisblock[] touchingsides = gettouchingsides ();     (tetrisblock block:touchingsides) {         if (block.gety () >= 21) {             return true;         }          if (tetrisblockmatrix[block.getx ()][block.gety () + 1] != null) {             return true;         }     }     return false; }  public boolean checkpositionvalid (int x, int y) {     if (x < 0 || y < 0 ||             x > 15 || y > 21)         return false;     if (tetrisblockmatrix[x][y] == null)         return true;     return false; }  public void move (int side) {     if (side == 1 || side == -1) {         (tetrisblock block:blocks) {             block.setx (block.getx () + side);         }          (tetrisblock block:blocks) {             if (!checkpositionvalid (block.getx (), block.gety ())) {                 if (side == left)                     move (right);                 else                     move (left);             }         }     } else {         throw new illegalargumentexception ();     } }  public void addtetrisblockstomatrix (tetrisblock[][] matrix) {     (tetrisblock block:blocks) {         if (matrix[block.getx ()][block.gety ()] == null) {             matrix[block.getx ()][block.gety ()] = block;         } else {             throw new illegalargumentexception ();         }     } }  public void settimerenabled (boolean value) {     if (value && paused) {         handler.post (task);     } else {         paused = true;     } }  public void settimerinterval (int milliseconds) {     interval = milliseconds; }  protected tetrimino (tetrisblock[][] matrix, tetrisactivity activity) {     this.tetrisblockmatrix = matrix;     handler = new handler ();     handler.post (task);     landedeventlisteners = new arraylist<> ();     blocks = new tetrisblock[4]; } 

}

tetrisblock.java

public class tetrisblock { private static final int length_in_dp = 20; private tetrisactivity activity; private imageview picture; private int color; private int x; private int y;  private absolutelayout.layoutparams getlayoutparams () {     return (absolutelayout.layoutparams) picture.getlayoutparams (); }  public tetrisactivity getactivity() {     return activity; }  public imageview getpicture() {     return picture; }  public int gety() {     absolutelayout.layoutparams params = getlayoutparams ();     return params.y / getlengthinpixels (); }  public void sety(int y) {     this.y = y;     absolutelayout.layoutparams params = getlayoutparams ();     params.y = y * getlengthinpixels ();     picture.setlayoutparams (params); }  public int getx() {     absolutelayout.layoutparams params = getlayoutparams ();     return params.x / getlengthinpixels (); }  public void setx(int x) {     this.x = x;     absolutelayout.layoutparams params = getlayoutparams ();     params.x = x * getlengthinpixels ();     picture.setlayoutparams (params); }  public int getcolor() {     return color; }  public void setcolor(int color) {     this.color = color;     picture.setbackgroundcolor (color); }  public tetrisblock (int color, int x, int y, tetrisactivity activity) {     this.activity = activity;     picture = new imageview (activity);     setcolor (color);     picture.setimageresource (r.drawable.tetrisblock);      int w, h;     w = getlengthinpixels ();     h = getlengthinpixels ();     absolutelayout.layoutparams params = new absolutelayout.layoutparams (w,             h, x * getlengthinpixels (), y * getlengthinpixels ());      picture.setlayoutparams (params);     picture.setscaletype (imageview.scaletype.fit_center);      ((absolutelayout)activity.findviewbyid (r.id.main_frame)).addview (picture); }  public void movedown () {     sety (gety () + 1); }  public int getlengthinpixels () {     return (int)(length_in_dp * activity.getscale () + 0.5f); } } 

the problem when rotate, setting x co-ordinate new value , overwriting old one, when still need second call rotation function. example rotated value of x1 passed second call of rotateclockwise here, when should passing original value:

x1 = rotateclockwise (x1, y1).x; y1 = rotateclockwise (x1, y1).y; 

just call once , assign x , y values variables:

point point1 = rotateclockwise (x1, y1); x1 = point1.x; y1 = point1.y; 

Comments