-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshuffle.c
187 lines (156 loc) · 4.9 KB
/
shuffle.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include "shuffle.h"
int width, height;
struct timespec req;
// Swap a and b very fast (inline Assembly test: not necessary, C is really fast enough)
static void swap(int *a, int *b)
{
__asm__(
"movl (%0), %%eax;\n"
"movl (%1), %%ebx;\n"
"movl %%ebx, (%0);\n"
"movl %%eax, (%1);"
:
: "r"(a), "r"(b)
: "%eax", "%ebx");
}
// The Fischer - Yates shuffle algorithm
static void shuffle(int *array, int n)
{
srand((unsigned int)time(NULL));
for (int i = n - 1; i > 0; i--)
{
int j = rand() % (i + 1);
swap(&array[i], &array[j]);
}
}
int show_shuffled(char *ansi_pic, int speed, char *rgb, int is_help)
{
// The wait time between each printed char is: speed * 10000 nanoseconds
req.tv_nsec = speed * NSECONDS;
req.tv_sec = 0;
int shuffle_index, shuffled_row, shuffled_col, row, col, total_pixels, max_length = 0, c;
int flag = 0;
row = col = 0;
// Pointer to the loaded string
char *textfile;
textfile = ansi_pic;
// Get 2D dimension of the text file (x = max_length, y = rows)
for (c = *textfile; c != '\0'; max_length = col > max_length ? col : max_length)
{
c == '\n' ? col = 0, col++, row++ : col++;
c = *textfile++;
}
// Reset pointer
textfile = ansi_pic;
// Create 2D text array
char pic_array[row + 1][max_length];
width = max_length - 1;
height = row;
total_pixels = height * width;
row = col = 0;
/*Fill shorter rows with blank spaces and replace tabs with blank space.
*Store everything in 2D array */
while ((c = *textfile++) != '\0')
{
pic_array[row][col] = (char)c;
if (c == '\n')
{
if (col < max_length - 1)
{
for (c = ' '; col <= max_length; pic_array[row][col++] = (char)c)
;
}
col = -1;
row++;
}
else if (c == '\t')
{
pic_array[row][col] = ' ';
}
col++;
}
// go to position 34, 1 (under the picture)
printf("\033[34;1H");
int shuffle_array[total_pixels];
// Fill the shuffle array with ascending numbers.
for (int i = 0; i < total_pixels; i++)
{
shuffle_array[i] = i;
}
// Shuffle all the numbers in the array
shuffle(shuffle_array, total_pixels);
int r, g, b;
if (!strcmp(rgb, "random")) // Print with random RGB color
{
srand(time(NULL));
r = rand() % 255;
g = rand() % 255;
b = rand() % 255;
}
else if (!strcmp(rgb, "red"))
r = 255, g = 0, b = 0;
else if (!strcmp(rgb, "green"))
r = 0, g = 255, b = 0;
else if (!strcmp(rgb, "yellow"))
r = 255, g = 255, b = 0;
else if (!strcmp(rgb, "blue"))
r = 0, g = 0, b = 255;
else if (!strcmp(rgb, "magenta"))
r = 255, g = 0, b = 255;
else if (!strcmp(rgb, "cyan"))
r = 0, g = 255, b = 255;
else if (!strcmp(rgb, "white"))
r = 255, g = 255, b = 255;
else if (!strcmp(rgb, "black"))
r = 0, g = 0, b = 0;
else if (!strcmp(rgb, "orange"))
r = 255, g = 165, b = 0;
else if (!strcmp(rgb, "grey"))
r = 127, g = 127, b = 127;
else
{
printf("\033[38;2;%sm", rgb); // Print with given RGB values
goto jump;
}
printf("\033[38;2;%d;%d;%dm", r, g, b); // Print with one of the 'standard' colors
jump:
// Hide the cursor
printf(INVISIBLE);
// Show and delete the ASCII picture with amazing shuffle effect
for (int p = 0; p < (is_help ? 1 : 2); p++)
{
for (int i = 0; i < total_pixels; i++)
{
shuffle_index = shuffle_array[i];
shuffled_row = shuffle_index / width;
shuffled_col = shuffle_index % width;
// Move Cursor to shuffled position
printf("\033[%d;%dH", (shuffled_row + 1) + 34, shuffled_col + 1);
// Print char at shuffled position
printf("%c", pic_array[shuffled_row][shuffled_col]);
// Wait some nanoseconds after every char
nanosleep(&req, NULL);
fflush(stdout);
}
// Show the ASCII art for 2 seconds at first glance (with bit flag)
((!(flag & IS_END_FLAG)) && !is_help) ? sleep(2), flag |= IS_END_FLAG : 0;
if (!is_help)
{
// Shuffle the array again for deletion effect
shuffle(shuffle_array, total_pixels);
// Delete the 2D array (Fill with blank spaces)
for (int r = 0; r < height; r++)
{
for (int q = 0; q < width; pic_array[r][q++] = ' ')
;
}
}
}
// Reset text mode
printf(RST);
// Delete screen and go to position 1, 1 (only if not showing help)
!is_help ? printf(CLRJ) : printf("\033[18;1H");
// Show the cursor again
printf(VISIBLE);
return EXIT_SUCCESS;
}