title: Understanding Java code for Tetris
body: <p>First off, just so we are completely clear, I took too classes on java a year ago. I have the fundamentals, but am pretty rusty. I tried to code Tetris on my own, but got stuck for a few days so I decided to look up a tutorial. I checked out the "tutorial" at <a href="http://zetcode.com/tutorials/javagamestutorial/tetris/" rel="nofollow">http://zetcode.com/tutorials/javagamestutorial/tetris/</a> but it was hardly a tutorial and more just code. So, in order to help myself better understand it, in hopes of coding my very own Tetris, I took the code, simplified it, changed one or two things, and have sense been writing comments out of what I believe each line does. </p>
  
  <p>I'm just looking for someone to confirm if the code is actually doing what I think it is doing. More specifically with the enum part, the rotate, and the random method. 
  Thank you for any of your time, I know I'm biting off more than I can chew, but I have already learned so much by looking up many tutorials and videos and reading through my java book that I don't want to stop now.</p>
  
  <p>here is the code, thank you for any help:</p>
  
  <pre><code>package tetris; //keeps things tidy
  
  import java.util.Random;  //needed for when the random shape generator is used
  import java.lang.Math;
  import java.util.Arrays;
  
  public class Shape {
  
      enum Tetrominoes { NoShape, SShape, ZShape, IShape,     //enum allows to predefine a set of constants and group them together
                         TShape, OShape, LShape, FShape };    //This is also used to positionally search the array later on using the ordinal() function
  
      private Tetrominoes TetrisShape;                        //variable stores one of our many Tetrominoes at a time, see enum^
      private int IndividualBlockCoordinates[][];             //this array is used to hold the actual coordinates of the Blocks on the board
      private int[][][] ShapeCoordinates;                     //this 3-dimensional array holds pairs of the coordinates of each Tetrominoe if they were centered at (0,0)
                                                              //centering at (0,0) instead of using that as a starting Block is really preference, but allows for bettering 
                                                              //centering of Blocks on the board later
      public Shape()                                          //this is the constructor of the class, it is automatically ran because it is a constructor,
      {                                                       //have your constructor run methods in order to run them without having to call them individually
          IndividualBlockCoordinates = new int[4][2];    //-----------------&gt; this array is used to hold the actual coordinates of the Blocks on the board                                                    
          setShape(Tetrominoes.NoShape);  //------|            each line of the array holds a pair of X and Y coordinates for each block of 
                                          //      |            the tetromino
      }                                   //      |-----------------------------&gt;This is THE purpose of the Shape object/class this calls the 
                                          //                                      setShape method, which gets the ShapeCoordinates and BlockCoordinates
  
      public void setShape(Tetrominoes shape)            //"shape" takes on one of the 8 Tetrominoes 
      {
           ShapeCoordinates = new int[][][] 
                   {
                      { { 0, 0 },  { 0, 0 },   { 0, 0 },   { 0, 0 } }, //NoShape
                      { { 0,-1 },  { 0, 0 },   {-1, 0 },   {-1, 1 } }, //SShape
                      { { 0,-1 },  { 0, 0 },   { 1, 0 },   { 1, 1 } }, //ZShape
                      { { 0,-1 },  { 0, 0 },   { 0, 1 },   { 0, 2 } }, //IShape
                      { {-1, 0 },  { 0, 0 },   { 1, 0 },   { 0, 1 } }, //TShape
                      { { 0, 0 },  { 1, 0 },   { 0, 1 },   { 1, 1 } }, //OShape
                      { {-1,-1 },  { 0,-1 },   { 0, 0 },   { 0, 1 } }, //LShape
                      { { 1,-1 },  { 0,-1 },   { 0, 0 },   { 0, 1 } }  //FShape
                   };
                                                                              //this nested for loop is the money maker right here. With each loop through, it stores 1 value
           for (int i = 0; i &lt; 4 ; i++)                                       //in the IndvidualBlockCorrdinates, therefore, every two loop throughs will provide the x and y value for a singular block
              {                                                               //with 8 total loops, it return the pair of coordinates for each of the 4 blocks in a Tetronimoe
                  for (int j = 0; j &lt; 2; ++j)
                      {
                          IndividualBlockCoordinates[i][j] = ShapeCoordinates[shape.ordinal()][i][j];
                      }
              }
           TetrisShape = shape;       //stores one of the 8 tetronimoes in TetrisShape???
      }
  
      private void setX(int index, int x) 
      { 
          IndividualBlockCoordinates[index][0] = x;    //sets the first element on row (index (0,1,2, or 3)) to x
      }
      private void setY(int index, int y) 
      {  
          IndividualBlockCoordinates[index][1] = y;    //sets the second element on row (index (0,1,2, or 3)) to y
      }
      public int x(int index) 
      { 
          return IndividualBlockCoordinates[index][0]; //returns the first element on row (index (0,1,2, or 3)) to x
      }
      public int y(int index)
      { 
          return IndividualBlockCoordinates[index][1]; //returns the second element on row (index (0,1,2, or 3)) to y
      }
      public Tetrominoes getShape()  
      { 
          return TetrisShape;                         //returns a TetrisShape(one of the 8 tetronimoes) which also holds individual block coordinates
      }
  
      public void setRandomShape()
      {
          Random randomGenerator = new Random();          //random number generator
          int randomInt = randomGenerator.nextInt(7);     //picks random numbers from 0 to 7
          Tetrominoes[] values = Tetrominoes.values();    //Tetrominoes array name values holds 8 shapes
          setShape(values[randomInt+1]);                  //setShape method is called on one of the 8 shapes represented by values+1, so 1-8 position in enum 
      }                                                   //for example, values[2] retruns enum position 2, or SShape
  
  
      public int minY()                                   //returns the lowest Y coordinate of each block
      {
        int m = IndividualBlockCoordinates[0][0];         //initialiezes m, the variable used to find the lowest coordinate to 0,0 in the array
        for (int i=0; i &lt; 3; i++) {
            m = Math.min(m, IndividualBlockCoordinates[i][1]);  //this runs through the first two sets of coordinates and stores the lower of the two
        }                                                       //as m, it only has to check twice because the lowest coordinate of each piece can be
        return m;                                               //found within the first two blocks. m is compared to each of the two, the lowest one is then stored
      }                                                         //as a new m. It will always be 0 or negative 1
  
      public Shape rotate()                           
      {
          Shape RotatedPiece = new Shape();
          RotatedPiece.TetrisShape = TetrisShape;         //Rotated Tetris Shape now because stored as Tetris Shape
       for(int i=0; i&lt;4; i++)                             
           for(int j=0; j&lt;4; j++)
           {
                  RotatedPiece.setX(i, y(i));             //Sets new X value for each piece one by one
                  RotatedPiece.setY(i, -x(i));            //Sets new Y value for each piece one by one
           }
  
       return RotatedPiece;                               //returns the rotated piece with new coordinates
      }
  }
  </code></pre>