#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define _LED_ROWS 5
#define _LED_COLS 5
static const unsigned int _LED_TABLE[_LED_ROWS][_LED_COLS] =
{
{4, 5, 14, 15, 24},
{3, 6, 13, 16, 23},
{2, 7, 12, 17, 22},
{1, 8, 11, 18, 21},
{0, 9, 10, 19, 20},
};
static int _LED_DISPLAY[_LED_ROWS][_LED_COLS] =
{
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
};
static int SAND_CLOCK[_LED_ROWS][_LED_COLS] =
{
{1, 2, 3, 2, 1},
{0, 1, 2, 1, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
};
int idx(const int i, const int j, const int rows)
{
return i * rows + j;
}
void remove_idx_from_points_arr(int *array, int index, size_t *el_cnt)
{
int i, u;
for (i = index; i < *el_cnt; i++)
{
array[i] = array[i + 1];
}
(*el_cnt)--;
printf("After deletion, the array = ");
for (u = 0; u < 10; u++)
{
printf("%*d", 10, array[u]);
}
printf("\n");
}
int pick_random_layer_point(int *array, size_t *el_cnt, const int lower_limit, const int upper_limit)
{
int index = 0, value = 0;
srand(time(NULL));
do
{
index = (rand() % (upper_limit - lower_limit + 1)) + lower_limit;
} while (array[index] < 0);
value = array[index];
remove_idx_from_points_arr(array, index, el_cnt);
return value;
}
void sand_clock(void)
{
static int state = 0;
static int target_layer_value = 0;
static int step = 1;
size_t elements_count;
int random_point;
int layer_points[10];
int *layer_points_ptr;
int x;
int y;
switch (state)
{
case 0: // setup / reload
memset(&layer_points[0], -1, sizeof(layer_points));
layer_points_ptr = &layer_points[0];
elements_count = 0;
target_layer_value++;
state = 1;
break;
case 1: // find points of selected layer
for(int i = 0; i < _LED_ROWS; i++)
{
for(int j = 0; j < _LED_COLS; j++)
{
//printf("Point: %d\n", idx(i, j, _LED_ROWS));
if (SAND_CLOCK[i][j] == target_layer_value)
{
*layer_points_ptr++ = idx(i, j, _LED_ROWS);
elements_count++;
//printf("\ni: %d\tj: %d\n", i, j);
}
}
}
printf("\n");
printf("Layer points array = ");
for (int u = 0; u < 10; u++)
{
printf("%*d", 10, layer_points[u]);
}
printf("\n");
/*for (int o = 0; o < _LED_ROWS * _LED_COLS; o++)
{
printf("%d\t%d\t%d\n", SAND_CLOCK[*layer_points_ptr + o / _LED_COLS][*layer_points_ptr + o % _LED_COLS],
*layer_points_ptr + o / _LED_COLS,
*layer_points_ptr + o % _LED_COLS
);
}
printf("\n");*/
state = 2;
break;
case 2: // select random point from layer
random_point = pick_random_layer_point(layer_points, &elements_count, 0, 10);
printf("Choosed random layer point: %d\n", random_point);
x = random_point / _LED_COLS;
y = random_point % _LED_COLS;
printf("X: %d\tY: %d\telem cnt = %ld\n", x, y, elements_count);
state = 3;
break;
case 3: // move selected point to the bottom border OR until closest layer will be reached
if (x + step <= _LED_COLS - 1)
{
SAND_CLOCK[x + step - 1][y] = 0;
SAND_CLOCK[x + step][y] = target_layer_value;
step++;
printf("\n_LED_DISPLAY = \n\n");
for (size_t i = 0; i < _LED_ROWS; i++)
{
printf("{ ");
for (size_t j = 0; j < _LED_COLS; j++)
{
if (SAND_CLOCK[i][j])
{
_LED_DISPLAY[i][j] = 1;
}
else
{
_LED_DISPLAY[i][j] = 0;
}
printf("%u ", SAND_CLOCK[i][j]);
}
printf("}\n");
}
printf("\n");
}
else
{
if (!elements_count)
{
state = 0;
step = 1;
break;
}
state = 2;
step = 1;
}
break;
default:
break;
}
}
int main()
{
printf("\nDefault pattern = \n\n");
for (size_t i = 0; i < _LED_ROWS; i++)
{
printf("{ ");
for (size_t j = 0; j < _LED_COLS; j++)
{
printf("%u ", SAND_CLOCK[i][j]);
}
printf("}\n");
}
printf("\n");
int f = 56;
while (f)
{
sand_clock();
f--;
}
/*printf("\n_LED_DISPLAY = \n\n");
for (size_t i = 0; i < _LED_ROWS; i++)
{
printf("{ ");
for (size_t j = 0; j < _LED_COLS; j++)
{
if (SAND_CLOCK[i][j])
{
_LED_DISPLAY[i][j] = 1;
}
else
{
_LED_DISPLAY[i][j] = 0;
}
printf("%u ", SAND_CLOCK[i][j]);
}
printf("}\n");
}
printf("\n");*/
return 0;
}