public class SymmetricRandomMosaicWalk {

   /*
      This program shows a window full of randomly colored
      squares.  A "disturbance" moves randomly around
      in the window, randomly changing the color of
      each square that it visits.  The program runs
      in an infinite loop, and so will never end on its
      own.
      
      The colored squares in this program form a pattern that
      is horizontally and vertically symmetric.
      
      This is a modification of a program that did the
      same thing, without the symmetry.  The ONLY change
      from the original was to change the line:
      
           static MosaicFrame mosaic  = new MosaicFrame(ROWS,COLUMNS);
      to
           static MosaicFrame mosaic  = new SymmetricMosaicFrame(ROWS,COLUMNS);
           
      SymmetricMosaicFrame is a subclass of MosaicFrame in which the
      setColor() method has been overriden to implement the symmetry.
      (The new version of setColor always colors the horizontal and
      vertical reflections of the squares it colors.)
   */

   final static int ROWS = 10;    // number of rows of squares
       // (The rows of squares are numbered from 0 to ROWS-1)
   final static int COLUMNS = 20; // number of columns of squares
       // (The columns of squares are numbered from 0 to COLUMNS-1)
       
   static MosaicFrame mosaic  = new SymmetricMosaicFrame(ROWS,COLUMNS); // the window
   static int currentRow; // row currently containing the disturbance
   static int currentColumn; // column currently containing disturbance
           
   public static void main(String[] args) {
          // Main program creates the window, fills it with
          // random colors, then moves the disturbance in
          // a random walk around the window.
       fillWithRandomColors();
       currentRow = ROWS / 2;   // start at center of window
       currentColumn = COLUMNS / 2;
       while (mosaic.stillOpen()) {
           changeToRandomColor(currentRow, currentColumn);
           randomMove();
           mosaic.delay(10);
       }
   }  // end of main()
   
   static void fillWithRandomColors() {
           // fill every square, in each row and column,
           // with a random color
        for (int row=0; row < ROWS; row++) {
           for (int column=0; column < COLUMNS; column++) {
               changeToRandomColor(row, column);  
           }
        }
   }  // end of fillWithRandomColors()
   
   static void changeToRandomColor(int rowNum, int colNum) {
           // change the square in row number rowNum and
           // column number colNum to a random color.
        int red = (int)(256*Math.random());    // choose random levels in range
        int green = (int)(256*Math.random());  //     0 to 255 for red, green, 
        int blue = (int)(256*Math.random());   //     and blue color components
        mosaic.setColor(rowNum,colNum,red,green,blue);  
    }  // end of changeToRandomColor()
    
    static void randomMove() {
           // randomly move the disturbance in one of
           // four possible directions: up, down, left, or right;
           // if this moves the disturbance outside the window,
           // then move it to the opposite edge of the window.
        int directionNum = (int)(4*Math.random());
             // directionNum is randomly set to 0, 1, 2, or 3
        switch (directionNum) {
           case 0:  // move up 
              currentRow--;
              if (currentRow < 0)
                 currentRow = ROWS - 1;
              break;
           case 1:  // move right
              currentColumn++;
              if (currentColumn >= COLUMNS)
                 currentColumn = 0;
              break; 
           case 2:  // move down
              currentRow ++;
              if (currentRow >= ROWS)
                 currentRow = 0;
              break;
           case 3:  
              currentColumn--;
              if (currentColumn < 0)
                 currentColumn = COLUMNS - 1;
              break; 
        }
    }  // end of randomMove()
   
} // end of class RandomMosaicWalk
