
// LevyC.java
// Stefania Bergljot Stefansdottir, 2015
// Slightly reformatted by Andrew Davison, Nov. 2022

/* Draws a Levy C curve 
   (http://en.wikipedia.org/wiki/L%C3%A9vy_C_curve)

   Usage:
     > compile LevyC.java
     > run LevyC n
   e.g.
     > run LevyC 13
*/


import java.util.*;


public class LevyC
{

  public static void main(String[] args)
  {
    if (args.length != 1) {
      System.out.println("Usage: run LevyC <no. of levels>");
      return;
    }
    int n = Integer.parseInt(args[0]);     // number of levels

    ArrayList<Integer> sequence = new ArrayList<Integer>();
    sequence.add(2);

    int lvlCount = 1;
    double scale = 1;
    for (int i = 0; i < n; i++) {
      lvlCount++;
      sequence = nextCurve(sequence);
      if (lvlCount%2 != 0)
        scale = (2 * scale+1);
    }
    draw(sequence, lvlCount, scale);
  }  // end of main()



  private static ArrayList<Integer> nextCurve(
                              ArrayList<Integer> prevSeq)  
  // generates the next sequence
  {
    ArrayList<Integer> seq = new ArrayList<Integer>();
    for (int i : prevSeq) {
      seq.add((i+1) % 8);
      seq.add((i+7) % 8);
    }
    return seq;
  } /* nextCurve */


  private static void draw(ArrayList<Integer> sequence, 
                           int lvlCount, double scale)
  {
    double d = 0.75 / (scale);
    if (lvlCount % 2 == 0) 
      d /= 2;
    double xc = 0.25, yc = 0.6;
    StdDraw.setCanvasSize(650, 650);

    for (int i : sequence)
      switch (i) {
      case 0:  StdDraw.line(xc, yc, xc, yc+d);
        yc += d;
        break;
      case 1:  StdDraw.line(xc, yc, xc+d, yc+d);
        yc += d; xc += d;
        break;
      case 2:  StdDraw.line(xc, yc, xc+d, yc);
        xc += d;
        break;
      case 3:  StdDraw.line(xc, yc, xc+d, yc-d);
        yc -= d; xc += d;
        break;
      case 4:  StdDraw.line(xc, yc, xc, yc-d);
        yc -= d;
        break;
      case 5:  StdDraw.line(xc, yc, xc-d, yc-d);
        yc -= d; xc -= d;
        break;
      case 6:  StdDraw.line(xc, yc, xc-d, yc);
        xc -= d;
        break;
      case 7:  StdDraw.line(xc, yc, xc-d, yc+d);
        yc += d; xc -= d;
        break;
      } /* switch */
  } /* draw */


}  // end of LevyC class