another attempt at solving the riddle

This commit is contained in:
Lilith 2023-06-05 20:21:49 +02:00
parent 2d7b714c20
commit 1bd2e27746
Signed by: konomo
GPG Key ID: 3DD7B85531A23133
2 changed files with 243 additions and 0 deletions

203
crystal-ng.c Normal file
View File

@ -0,0 +1,203 @@
/**
* crystal-ng.c
*
* 2023 konomo
* EUPL-1.2
**/
#include<stdio.h> /* printf; fprintf */
#include<stdlib.h> /* atoi; rand; srand */
#include<time.h> /* time */
#include<math.h> /* lround */
#include "crystal-ng.h"
#include "bmp.h"
/* how many colours, max at 256 */
int colors = 256;
/* generate_bitmap() from bmp.c */
/* extern void line(int x0, int y0, int x1, int y1, unsigned char clr); /\* bres.c *\/ */
char new_sprout(int id);
void process(int x, int y);
int check_pixel(int x, int y);
int paint_pixel(int x, int y, unsigned char clr);
unsigned char image[HEIGHT][WIDTH][BPP];
int main(void)
{
if(colors<3) colors = 3;
if(colors>256) colors = 256;
char *file_name = (char*) "output.bmp";
srand(time(NULL));
for(int i=0; i<SPROUTS; ++i)
{
char err = new_sprout(i);
if(err==1) fprintf(stderr, "sprouting failed for id %d\n", i);
}
/* iterate through image grid. if on colored spot, check for empty spots and
expand as far as possible by velocity */
for(int x=0; x<WIDTH; ++x)
{
printf("%d\n", x);
for(int y=0; y<HEIGHT; ++y)
{
process(x, y);
}
}
generate_bitmap((unsigned char*)image, HEIGHT, WIDTH, file_name);
printf("image generation done.\n");
return 0;
}
/* color limiting code */
unsigned char generate_color()
{
unsigned char clr = rand() % colors /* + colors */;
clr*=(unsigned char)lround( (256/colors) );
return clr;
}
char new_sprout(int id)
{
if(id >= SPROUTS) return 1;
int x = rand() % WIDTH + 1;
int y = rand() % HEIGHT + 1;
unsigned char clr = generate_color();
printf("sprout %d at (%d|%d)\n", id, x, y);
paint_pixel(x, y, clr);
return 0;
}
int order_check(int var, int c, int order)
{
if(order==-1)
return check_pixel(c, var);
return check_pixel(var, c);
}
/* this function will first check the variables plus the total calculated
velocity (velocity in this function simply means a value that is added to (var).
if this does not work, (v) is reduced until it is 0, attempting to find the
closest uncoloured/empty pixel. once it is found (or is 0), a line is drawn.
this is how a crystal grows.
var is a variable value, c is constant value, v is velocity, order is the
order in which these values are to be checked ( [order_check] ). clr is
the color. */
void id_and_proceed(int var, int c, int v, int order, unsigned char clr)
{
if(var + v < 0)
return;
/* guard */
/* if(order==-1) /\* y-axis *\/ */
/* { */
/* if(var + v < 0) */
/* return; */
/* } */
/* else /\* x-axis *\/ */
/* { */
/* } */
int r = 2;
r = order_check(var+v, c, order);
/* if(order==-1) */
/* r = check_pixel(c, var); */
/* else */
/* r = check_pixel(var, c); */
/* if(r==2) return; */
/* find most far away empty pixel */
while(r!=0 && v > 0)
{
--v;
v-=1;
if(v<0) v=0; /* just in case */
r=order_check(var+v, c, order);
/* r=check_pixel(x, y); */
}
do
{
if(order==-1)
paint_pixel(c, var+v, clr);
else
paint_pixel(var+v, c, clr);
--v;
}
while(v>=0);
}
void process(int x, int y)
{
unsigned char clr = 0;
switch(check_pixel(x, y))
{
case 0: /* empty/black/background pixel */
case 2: /* invalid coordinates */
return;
case 1: /* colored pixel */
clr = image[y][x][0];
break;
default:
fprintf(stderr, "process(): this case should never be met.\n");
return;
}
id_and_proceed(y, x, velocity[0] * (-1), -1, clr); /* north */
id_and_proceed(x, y, velocity[1], 1, clr); /* east */
id_and_proceed(y, x, velocity[2], -1, clr); /* south */
id_and_proceed(x, y, velocity[3] * (-1), 1, clr); /* west */
/* int y_north = y - velocity[0]; */
/* int x_east = x + velocity[1]; */
/* int y_south = y + velocity[2]; */
/* int x_west = x - velocity[3]; */
return;
}
/* returns 0 if the given pixel is black (0)
returns 1 if it is coloured
returns 2 if the coordinates are invalid */
int check_pixel(int x, int y)
{
/* printf("Checking (%u|%u)\n", x, y); */
if(x>=WIDTH || y>=HEIGHT)
{
fprintf(stderr, "coords (%d|%d) exceed image size %d×%d.\n", x, y, WIDTH, HEIGHT);
return 2;
}
/* as the image will be grayscaled, it works to check only one layer */
/* this implies the background colour is 0 */
if(image[y][x][0]!=0)
{
return 1;
}
return 0;
}
int paint_pixel(int x, int y, unsigned char clr)
{
/* printf("paint_pixel called\n"); */
if(check_pixel(x, y)) return 1;
image[y][x][0]=clr;
image[y][x][1]=clr;
image[y][x][2]=clr;
return 0;
}

40
crystal-ng.h Normal file
View File

@ -0,0 +1,40 @@
/**
* crystal .h
* 2023 konomo
* EUPL-1.2
**/
#ifndef __CRYSTAL_NG_H__
#define __CRYSTAL_NG_H__
/* for 4k */
/* #define WIDTH 3840 */
/* #define HEIGHT 2160 */
/* for fullhd */
/* #define WIDTH 1920 */
/* #define HEIGHT 1080 */
/* for 360p*/
#define WIDTH 480
#define HEIGHT 360
/* #define SPROUTS 50000 */
/* #define SPROUTS 5000 */
#define SPROUTS 500
/* #define SPROUTS 50 */
/* #define SPROUTS 20 */
/* #define SPROUTS 1 */
/* length of simulation */
/* #define SIMLENGTH 10000 */
/* #define SIMLENGTH 500 */
/* #define SIMLENGTH 1 */
/* #define SIMLENGTH 5 */
/* #define SIMLENGTH 20 */
/* default velocity */
const int velocity[] = {1, 1, 1, 1};
/* const int velocity[] = {20, 20, 20, 20}; */
#endif