#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); } }