#include <stdio.h>
#include <stdlib.h>

//
// probably should have used something like:
//
//    https://bitesofcode.wordpress.com/2016/12/23/landscape-generation-using-midpoint-displacement/
//
// but tried my own hack first to see what it would look like.  At least mine only uses context of
// immediate neighbour, so very suitable for left & right scrolling on Vectrex (for a Lunar Lander
// game, or a Defender clone or maybe Scramble...)
//
// Note: surface wraps so can be infinite.
//
// Needs a good random with an easily-set seed.
//

#define WRAP 1023
#define BASE 2    /* minimum height */

int surface(int i) {
  int flat=0, prev_flat=0, height=0, block=0, prev_major=0, major=0, next_major=0, minor;
  int global_seed = 1234;
  
  // everything is in 8-unit blocks
  block = ((i-8)&WRAP) & ~7;
  srandom((block<<3+global_seed)^block);
  prev_major = (random()&15) * 4;
  prev_flat = random()&15; // 1 in 15 is a flat zone, where we override the point to the right, and set it the
                           // same height as this point, providing a flat area to land on, or house fuel depots, etc.
      
  block = ((i+8)&WRAP) & ~7;
  srandom((block<<3+global_seed)^block);
  next_major = (random()&15) * 4;

  block = i & ~7;
  srandom((block<<3+global_seed)^block);
  major = (random()&15) * 4;
  flat = random()&15; // 1 in 15 is a flat zone
      
  // every flat segment is a landing zone - probability = 1 in 16      
  if (prev_flat == 0) {
    minor = 0;
    major = prev_major;
  } else if (flat == 0) {
    minor = 0;
    next_major = major;
  } else {
    srandom(((i<<3)+global_seed)^i);
    minor = (random()&3);
  }
  height = major + ((next_major - major) * (i&7) / 8); // on the vectrex could skip minor, and draw one line between 8 points.
  return height+minor;
}

void stars(int i) {
  while (i --> 0) fputc('*', stdout);
  fputc('\n', stdout);
}

int main(int argc, char **argv) {
  int y, x;
  for (x = 0; x <= WRAP; x++) {
    y = surface(x);
    //fprintf(stdout, "y %d\n", y);
    stars(BASE+y);
  }
}