ref: 796572b18e177f129778b68460a2618de881a624
dir: /rand.c/
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <local/colors.h>
#include <signal.h>
#include <sys/ioctl.h>
#define DINASOUR_HEIGHT 15
#define DINASOUR_WIDTH 15
#define SUN_HEIGHT 5
#define SUN_WIDTH 5
#define DELAY 10000
void die(const char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
char *colors[] = {
//black_fg,
red_fg,
//green_fg ,
yellow_fg ,
//blue_fg ,
//magenta_fg,
//cyan_fg ,
//white_fg ,
};
char *fbuffer = NULL; // should be point_t* buffer
uint64_t fbuffer_size = 0;
static volatile int cursor = 0;
int max_y;
int max_x;
static volatile bool resize = false;
typedef struct {
bool *matrix;
int height;
int width;
int x;
int y;
} shape_t;
// a hash tables suits better no?
// keys will be memory address of shapes.
// and vals will be the number of times they collided
// and um, we also need to store coordinates of collisions?
// maybe we can use an observer pattern here!\
// each shape subscribes to collisions,...
typedef struct collision_t {
shape_t *shape;
struct collision_t *next;
} collision_t;
typedef struct {
char *escapes;
char charachter;
// collision_t collisions; // it's actually better to have a global collisions
// (hash table or linked list and update it every tflush()).
int x;
int y;
bool written;
} point_t;
void alloc_fbuf();
void gotoxy(int x, int y) {
if (x >= max_x || y >= max_y)
return;
int new_cursor = (max_x * y) + x;
cursor = (max_x * y) + x;
}
void _gotoxy(int x, int y) { printf("%c[%d;%df", 0x1B, y, x); }
void max_xy(int signo) {
(void)signo;
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
max_x = w.ws_col;
max_y = w.ws_row;
resize = true;
//alloc_fbuf();
}
void tprint(const char c) {
if (cursor >= fbuffer_size || cursor < 0)
return;
fbuffer[cursor++] = c;
}
void draw_line(point_t a, point_t b) {
//int slope = (a.y - b.y) / (a.x - b.x);
int dy = b.y - a.y;
int dx = b.x - a.x;
while (true) {
int newx = a.x + dx;
int newy = a.y + dy;
if (newx == b.x && newy == b.y)
break;
gotoxy(a.x + dx, a.y + dy);
tprint('*');
}
}
void draw_shape(shape_t *shape, const char *color) {
bool print_newline = false;
// gotoxy(shape->x, shape->y);
for (int i = 0; i < shape->height; i++) {
gotoxy(shape->x, shape->y + i);
for (int j = 0; j < shape->width; j++) {
if (shape->matrix[i * shape->height + j]) {
print_newline = true;
// printf("%s%s%s", inverse_off , color, " " reset );
tprint('*');
} else {
// printf(" ");
tprint(' ');
}
}
if (print_newline)
printf("\r");
// fbuffer[cursor] = '\n'
tprint('\n');
}
}
shape_t *init_shape(int width, int height) {
shape_t *ret = calloc(width * height, sizeof(bool));
return ret;
}
void free_shape(shape_t *shape) { free(shape); }
void tflush() {
for (uint64_t row = 0; row < max_y; ++row) {
printf("\n");
for (uint64_t col = 0; col < max_x; ++col) {
if (fbuffer[row * max_x + col] == '*') {
_gotoxy(col, row);
printf("%s%s %s",inverse, colors[rand() % sizeof(colors)/sizeof(*colors)], reset);
//printf("%s%c%s", reset inverse, /*fbuffer[row * max_x + col]*/ ' ', reset);
}
else
printf(reset " " reset);
}
}
//write(STDOUT_FILENO, fbuffer, max_x * max_y); // drawing will be very smooth this way.
}
void alloc_fbuf() {
if (max_x * max_y > fbuffer_size) {
fbuffer_size = max_y * max_x; //* sizeof(char);
fbuffer = realloc(fbuffer, fbuffer_size);
assert(fbuffer);
}
}
bool dinasour_frame1[DINASOUR_WIDTH][DINASOUR_HEIGHT] = {
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0},
{1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},
{1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0},
{1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0},
{1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0},
};
bool dinasour_frame2[DINASOUR_WIDTH][DINASOUR_HEIGHT] = {
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0},
{1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},
{1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0},
{1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0},
{1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
};
bool dinasour_frame3[DINASOUR_WIDTH][DINASOUR_HEIGHT] = {
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0},
{1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},
{1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0},
{1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0},
{1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
};
void clear_screen() {
memset(fbuffer, 0, fbuffer_size);
printf("\033c");
}
int main(int argc, char *argv[]) {
max_xy(0);
alloc_fbuf();
shape_t dinasour_f1 = {.matrix = &dinasour_frame1[0][0],
.width = DINASOUR_WIDTH,
.height = DINASOUR_HEIGHT,
.x = 10,
.y = 10};
shape_t dinasour_f2 = {.matrix = &dinasour_frame2[0][0],
.height = DINASOUR_HEIGHT,
.width = DINASOUR_WIDTH,
.x = 10,
.y = 10};
shape_t dinasour_f3 = {
.matrix = &dinasour_frame3[0][0],
.height = DINASOUR_HEIGHT,
.width = DINASOUR_WIDTH,
.x = 10,
.y = 10,
};
shape_t dinasour2_f1 = {.matrix = &dinasour_frame1[0][0],
.width = DINASOUR_WIDTH,
.height = DINASOUR_HEIGHT,
.x = 10,
.y = 10 };
shape_t dinasour2_f2 = {.matrix = &dinasour_frame2[0][0],
.height = DINASOUR_HEIGHT,
.width = DINASOUR_WIDTH,
.x = 10,
.y = 10};
shape_t dinasour2_f3 = {
.matrix = &dinasour_frame3[0][0],
.height = DINASOUR_HEIGHT,
.width = DINASOUR_WIDTH,
.x = 10,
.y = 10 + DINASOUR_HEIGHT + 2,
};
bool sun_matrix[SUN_HEIGHT][SUN_WIDTH] = {
{0, 0, 1, 0, 0}, {0, 1, 0, 1, 0}, {1, 0, 0, 0, 1},
{0, 1, 0, 1, 0}, {0, 0, 1, 0, 0},
};
shape_t sun = {.matrix = &sun_matrix[0][0],
.height = SUN_HEIGHT,
.width = SUN_WIDTH,
.x = (float)max_x / 2,
.y = 10};
struct sigaction sa;
sa.sa_handler = max_xy;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGWINCH, &sa, NULL);
int randx =0 ;
int randy =0 ;
clear_screen();
shape_t *arr[3] = {&dinasour_f1, &dinasour_f2, &dinasour_f3};
shape_t *arr2[3] = {&dinasour2_f1, &dinasour2_f2, &dinasour2_f3};
unsigned int index = 0;
srand(time(NULL));
unsigned int t = 1;
while (true) {
shape_t *ptr = arr[index % 3];
shape_t *ptr2 = arr2[index % 3];
draw_shape(ptr, white_bg);
//printf("\nptr->x = %d, ptr->y = %d\n", ptr->x, ptr->y);
//printf("max_x = %d, max_y = %d\n", max_x, max_y);
//printf("fbuffer = %#X, fbuffer_size=%PRlu64\n", (unsigned int)fbuffer, fbuffer_size);
//printf("fbuffer = %#X, fbuffer_size=%llu, cursor = %d\n", fbuffer, fbuffer_size, cursor);
//draw_shape(&sun, yellow_bg);
draw_shape(ptr2, yellow_bg);
tflush();
//usleep(DELAY);
for (int i = 0; i < 3; ++i) {
arr[i]->x = (arr[i]->x + 3) % max_x;
//arr[i]->y = (arr[i]->x - 1) % (max_y - DINASOUR_HEIGHT);
arr[i]->y = rand() % (max_y - DINASOUR_HEIGHT);
//arr2[i]->x = (arr[i]->x - 10) % max_x;
//arr2[i]->y = (arr[i]->y - 10) % max_y;
}
index++;
if (sun.y + sun.height >= max_y)
sun.y = 0;
sun.y += 1;
// collisions();
if (resize) {
alloc_fbuf();
resize = false;
}
//if (arr[index]->x >= max_x)
// clear_screen();
}
free(fbuffer);
return 0;
}