guli-tools 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- guli_tools-0.1.0/PKG-INFO +5 -0
- guli_tools-0.1.0/guli_tools.egg-info/PKG-INFO +5 -0
- guli_tools-0.1.0/guli_tools.egg-info/SOURCES.txt +11 -0
- guli_tools-0.1.0/guli_tools.egg-info/dependency_links.txt +1 -0
- guli_tools-0.1.0/guli_tools.egg-info/top_level.txt +1 -0
- guli_tools-0.1.0/modules/ANSI.py +257 -0
- guli_tools-0.1.0/modules/G_anicurves.py +67 -0
- guli_tools-0.1.0/modules/G_perlin.py +3 -0
- guli_tools-0.1.0/modules/Goosefull.py +251 -0
- guli_tools-0.1.0/modules/guli_progress_bar.py +83 -0
- guli_tools-0.1.0/modules/render.py +53 -0
- guli_tools-0.1.0/pyproject.toml +9 -0
- guli_tools-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
guli_tools.egg-info/PKG-INFO
|
|
3
|
+
guli_tools.egg-info/SOURCES.txt
|
|
4
|
+
guli_tools.egg-info/dependency_links.txt
|
|
5
|
+
guli_tools.egg-info/top_level.txt
|
|
6
|
+
modules/ANSI.py
|
|
7
|
+
modules/G_anicurves.py
|
|
8
|
+
modules/G_perlin.py
|
|
9
|
+
modules/Goosefull.py
|
|
10
|
+
modules/guli_progress_bar.py
|
|
11
|
+
modules/render.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
modules
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# usefull for projects that use the terminal allat
|
|
2
|
+
filename = __file__.split("\\")[-1]
|
|
3
|
+
print(f"(Loading module: {filename}..")
|
|
4
|
+
|
|
5
|
+
class F:
|
|
6
|
+
BOLD = "\033[1m"
|
|
7
|
+
FAINT = "\033[2m"
|
|
8
|
+
DIM = "\033[22m"
|
|
9
|
+
ITALIC = "\033[3m"
|
|
10
|
+
UNDERLINE= "\033[4m"
|
|
11
|
+
NEGATIVE = "\033[7m"
|
|
12
|
+
CROSSED = "\033[9m"
|
|
13
|
+
END = "\033[0m"
|
|
14
|
+
|
|
15
|
+
def UP(lines):
|
|
16
|
+
return f"\033[{lines}A"
|
|
17
|
+
|
|
18
|
+
def DOWN(lines):
|
|
19
|
+
return f"\033[{lines}B"
|
|
20
|
+
|
|
21
|
+
def RIGHT(amount):
|
|
22
|
+
return f"\033[{amount}C"
|
|
23
|
+
|
|
24
|
+
def LEFT(amount):
|
|
25
|
+
return f"\033[{amount}D"
|
|
26
|
+
|
|
27
|
+
def COLUMN(column):
|
|
28
|
+
return f"\033[{column}G"
|
|
29
|
+
|
|
30
|
+
def SET_POS(line, column):
|
|
31
|
+
return f"\033[{line};{column}H"
|
|
32
|
+
|
|
33
|
+
def CLEAR_TERMINAL():
|
|
34
|
+
return f"\033[2J"
|
|
35
|
+
|
|
36
|
+
def CLEAR_LINE():
|
|
37
|
+
return f"\r\033[2K"
|
|
38
|
+
|
|
39
|
+
def grad(text="\nU DIDN'T ADD TEXT DUMBASS\n", color_list=[[200,200,200],[200,200,200]], size=0):
|
|
40
|
+
if size > 0:
|
|
41
|
+
color_list = list(color_list) + [color_list[0]]
|
|
42
|
+
steps = len(text)
|
|
43
|
+
num_segments = len(color_list) - 1
|
|
44
|
+
steps_per_segment = (size if size > 0 else steps) / num_segments
|
|
45
|
+
result = []
|
|
46
|
+
|
|
47
|
+
for i, char in enumerate(text):
|
|
48
|
+
cycle_i = i % (size if size > 0 else steps)
|
|
49
|
+
if steps > 1:
|
|
50
|
+
segment = min(int(cycle_i / steps_per_segment), num_segments - 1)
|
|
51
|
+
seg_start = segment * steps_per_segment
|
|
52
|
+
seg_end = (segment + 1) * steps_per_segment
|
|
53
|
+
factor = (cycle_i - seg_start) / (seg_end - seg_start)
|
|
54
|
+
else:
|
|
55
|
+
segment, factor = 0, 0.0
|
|
56
|
+
|
|
57
|
+
c1 = color_list[segment]
|
|
58
|
+
c2 = color_list[segment + 1]
|
|
59
|
+
|
|
60
|
+
r = int(c1[0] + (c2[0] - c1[0]) * factor)
|
|
61
|
+
g = int(c1[1] + (c2[1] - c1[1]) * factor)
|
|
62
|
+
b = int(c1[2] + (c2[2] - c1[2]) * factor)
|
|
63
|
+
|
|
64
|
+
result.append(f"\x1b[38;2;{r};{g};{b}m{char}")
|
|
65
|
+
|
|
66
|
+
return "".join(result) + "\x1b[0m"
|
|
67
|
+
|
|
68
|
+
def RGB_end():
|
|
69
|
+
return "\x1b[0m"
|
|
70
|
+
|
|
71
|
+
class C:
|
|
72
|
+
# --- THE CLASSICS ---
|
|
73
|
+
RAINBOW = [(255, 0, 0), (255, 127, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255), (0, 0, 255), (139, 0, 255)]
|
|
74
|
+
SUNSET = [(255, 94, 87), (255, 159, 67), (255, 205, 86), (253, 121, 168), (108, 92, 231)]
|
|
75
|
+
TWILIGHT = [(15, 32, 67), (84, 90, 182), (179, 107, 202), (249, 133, 133), (255, 211, 153)]
|
|
76
|
+
|
|
77
|
+
# --- CYBER & SCI-FI ---
|
|
78
|
+
VAPORWAVE = [(255, 113, 206), (1, 205, 254), (5, 255, 161), (185, 103, 255), (255, 251, 150)]
|
|
79
|
+
AURORA = [(5, 230, 140), (0, 180, 216), (123, 44, 191), (224, 170, 255)]
|
|
80
|
+
MATRIX_DRIFT = [(0, 15, 0), (0, 75, 15), (0, 150, 30), (50, 255, 70), (200, 255, 210)]
|
|
81
|
+
|
|
82
|
+
# --- NATURE & MOODS ---
|
|
83
|
+
DEEP_OCEAN = [(0, 7, 45), (0, 28, 85), (0, 53, 102), (0, 119, 182), (72, 202, 228)]
|
|
84
|
+
FOREST_FIRE = [(34, 76, 56), (143, 184, 112), (247, 147, 30), (218, 44, 56), (106, 4, 15)]
|
|
85
|
+
GLACIER = [(224, 251, 252), (152, 193, 217), (61, 90, 128), (41, 50, 65)]
|
|
86
|
+
|
|
87
|
+
# Standard
|
|
88
|
+
red_light = (255, 100, 100)
|
|
89
|
+
red = (255, 0, 0 )
|
|
90
|
+
red_dark = (180, 0, 0 )
|
|
91
|
+
green_light = (100, 255, 100)
|
|
92
|
+
green = (0, 200, 0 )
|
|
93
|
+
green_dark = (0, 120, 0 )
|
|
94
|
+
blue_light = (70, 130, 255)
|
|
95
|
+
blue = (10, 20, 255)
|
|
96
|
+
blue_dark = (10, 10, 180)
|
|
97
|
+
cyan_light = (100, 255, 255)
|
|
98
|
+
cyan = (0, 255, 255)
|
|
99
|
+
cyan_dark = (0, 180, 180)
|
|
100
|
+
yellow_light = (255, 255, 100)
|
|
101
|
+
yellow = (255, 255, 0 )
|
|
102
|
+
yellow_dark = (180, 180, 0 )
|
|
103
|
+
magenta_light= (255, 100, 255)
|
|
104
|
+
magenta = (255, 0, 255)
|
|
105
|
+
magenta_dark = (180, 0, 180)
|
|
106
|
+
orange_light = (255, 180, 80 )
|
|
107
|
+
orange = (255, 140, 0 )
|
|
108
|
+
orange_dark = (180, 90, 0 )
|
|
109
|
+
white = (255, 255, 255)
|
|
110
|
+
gray_light = (200, 200, 200)
|
|
111
|
+
gray = (128, 128, 128)
|
|
112
|
+
gray_dark = (60, 60, 60 )
|
|
113
|
+
black = (0, 0, 0 )
|
|
114
|
+
|
|
115
|
+
# Neon & Cyberpunk Colors
|
|
116
|
+
neon_pink = (255, 0, 128)
|
|
117
|
+
neon_purple = (187, 0, 255)
|
|
118
|
+
electric_cyan= (0, 225, 255)
|
|
119
|
+
toxic_green = (57, 255, 20)
|
|
120
|
+
|
|
121
|
+
# Soft Pastels
|
|
122
|
+
pastel_pink = (255, 179, 186)
|
|
123
|
+
pastel_peach = (255, 223, 186)
|
|
124
|
+
pastel_yellow= (255, 255, 186)
|
|
125
|
+
pastel_green = (186, 255, 201)
|
|
126
|
+
pastel_blue = (186, 225, 255)
|
|
127
|
+
|
|
128
|
+
# Earthy & Rich Tones
|
|
129
|
+
crimson = (220, 20, 60)
|
|
130
|
+
gold = (255, 215, 0)
|
|
131
|
+
lime = (50, 205, 50)
|
|
132
|
+
teal = (0, 128, 128)
|
|
133
|
+
indigo = (75, 0, 130)
|
|
134
|
+
|
|
135
|
+
# Monochromes
|
|
136
|
+
white = (255, 255, 255)
|
|
137
|
+
gray = (128, 128, 128)
|
|
138
|
+
black = (0, 0, 0)
|
|
139
|
+
|
|
140
|
+
def grad_x(x, color_list, length=100):
|
|
141
|
+
x = max(0.0, min(1.0, x / length))
|
|
142
|
+
num_segments = len(color_list) - 1
|
|
143
|
+
segment = min(int(x * num_segments), num_segments - 1)
|
|
144
|
+
factor = (x * num_segments) - segment
|
|
145
|
+
|
|
146
|
+
c1 = color_list[segment]
|
|
147
|
+
c2 = color_list[segment + 1]
|
|
148
|
+
|
|
149
|
+
r = int(c1[0] + (c2[0] - c1[0]) * factor)
|
|
150
|
+
g = int(c1[1] + (c2[1] - c1[1]) * factor)
|
|
151
|
+
b = int(c1[2] + (c2[2] - c1[2]) * factor)
|
|
152
|
+
|
|
153
|
+
result = f"\x1b[38;2;{r};{g};{b}m"
|
|
154
|
+
return result
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def rgb(r=200, g=200, b=200):
|
|
158
|
+
if isinstance(r, tuple):
|
|
159
|
+
r, g, b = r
|
|
160
|
+
return f"\x1b[38;2;{r};{g};{b}m"
|
|
161
|
+
|
|
162
|
+
def progress_bar(percent, color_list, length=20):
|
|
163
|
+
filled = int((percent / 100) * length)
|
|
164
|
+
bar = "".join(
|
|
165
|
+
grad_x(i, color_list, length) + '█' if i < filled else rgb(C.gray_dark) + '░'
|
|
166
|
+
for i in range(length)
|
|
167
|
+
)
|
|
168
|
+
return f"[{bar}{F.END}] {grad(f'{percent}%', color_list)} {rgb(C.gray_dark)}| {rgb(C.red_light)}{100 - percent}% remaining{F.END}"
|
|
169
|
+
|
|
170
|
+
def info_colors(show=["colors", "example", "use", "alternate", "class"]):
|
|
171
|
+
entries = [name for name, value in vars(C).items() if not name.startswith('_') and isinstance(value, list)]
|
|
172
|
+
|
|
173
|
+
if "colors" in show:
|
|
174
|
+
print()
|
|
175
|
+
for name in entries:
|
|
176
|
+
colors = colors = getattr(C, name)
|
|
177
|
+
print(grad(name, colors), end=" "*(15-len(name)))
|
|
178
|
+
print(grad("█"*40, colors), grad("█"*40, colors, 20))
|
|
179
|
+
print()
|
|
180
|
+
for name, value in vars(C).items():
|
|
181
|
+
if not name.startswith('_') and isinstance(value, tuple):
|
|
182
|
+
print(rgb(*value) + name, "▇"*(30-len(name)), F.END)
|
|
183
|
+
if "dark" in name or name == "black" or name in ("toxic_green", "pastel_blue", "lime", "white"):
|
|
184
|
+
print()
|
|
185
|
+
|
|
186
|
+
if "example" in show:
|
|
187
|
+
print(
|
|
188
|
+
f"\n {F.BOLD}grad{F.END}(text, color_list, size=0)\n"
|
|
189
|
+
f" {rgb(C.gray_dark)}basic {F.END}{grad('grad(\"hello\", [(255,0,0),(0,0,255)])', [(255,0,0),(0,0,255)])}\n"
|
|
190
|
+
f" {rgb(C.gray_dark)}G class {F.END}{grad('grad(\"hello\", C.RAINBOW)', C.RAINBOW)}\n"
|
|
191
|
+
f" {rgb(C.gray_dark)}tiling {F.END}{grad('grad(\"hello\", C.AURORA, 10) ← cycle size, empty for no cycle', C.AURORA, 10)}\n"
|
|
192
|
+
f"\n {F.BOLD}rgb{F.END}(r, g, b)\n"
|
|
193
|
+
f" {rgb(C.gray_dark)}usage {F.END}{rgb(255,100,50)}rgb(255,100,50) + your text{F.END}\n"
|
|
194
|
+
f" {rgb(C.gray_dark)}C class {F.END}{rgb(C.neon_pink)}rgb(C.neon_pink) + your text{F.END}\n"
|
|
195
|
+
f"\n {F.BOLD}grad_x{F.END}(x, color_list, length=100)\n"
|
|
196
|
+
f" {rgb(C.gray_dark)}usage {F.END}{grad_x(0, C.SUNSET, 3)}x=0 {grad_x(1, C.SUNSET, 3)}x=1 {grad_x(2, C.SUNSET, 3)}x=2{F.END} ← x is position along length\n"
|
|
197
|
+
f" {rgb(C.gray_dark)}tip {F.END}{rgb(C.gray_dark)}use in loops: grad_x(i, C.SUNSET, total){F.END}\n"
|
|
198
|
+
f"\n {F.BOLD}alternate{F.END}(text, colors)\n"
|
|
199
|
+
f" {rgb(C.gray_dark)}basic {F.END}{alternate('alternate(\"hello\", [C.cyan_light, C.blue_dark])', [C.cyan_light, C.blue_dark])}\n"
|
|
200
|
+
f" {rgb(C.gray_dark)}multi {F.END}{alternate('alternate(\"hello\", [C.pastel_blue, C.pastel_green, C.pastel_yellow, C.pastel_pink])', [C.pastel_blue, C.pastel_green, C.pastel_yellow, C.pastel_pink])}\n"
|
|
201
|
+
f" {rgb(C.gray_dark)}tip {F.END}{rgb(C.gray_dark)}cycles through colors per character{F.END}\n"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
if "use" in show:
|
|
205
|
+
print(
|
|
206
|
+
f"\n"
|
|
207
|
+
f" {grad(' ANSI use 101 ', C.SUNSET)}\n"
|
|
208
|
+
f"\n"
|
|
209
|
+
f" {rgb(C.gray_dark)}Solid color with rgb():{F.END}\n"
|
|
210
|
+
f" {rgb(C.red_dark)}✦ error:{F.END} file not found\n"
|
|
211
|
+
f" {rgb(C.toxic_green)}✦ success:{F.END} connected\n"
|
|
212
|
+
f" {rgb(C.yellow)}✦ warning:{F.END} retrying in 3s\n"
|
|
213
|
+
f"\n"
|
|
214
|
+
f" {rgb(C.gray_dark)}Gradient label with grad():{F.END}\n"
|
|
215
|
+
f" {grad(' LOADING ', C.AURORA)} ← status badge\n"
|
|
216
|
+
f" {grad(' WARNING ', C.SUNSET)} ← swap palette for tone\n"
|
|
217
|
+
f" {grad(' SUCCESS ', C.MATRIX_DRIFT)} ← any color_list works\n"
|
|
218
|
+
f"\n"
|
|
219
|
+
f" {rgb(C.gray_dark)}Progress_bar() made with grad_x():{F.END}\n"
|
|
220
|
+
f" {(progress_bar(75, C.DEEP_OCEAN))}\n"
|
|
221
|
+
f" {(progress_bar(40, C.SUNSET))}\n"
|
|
222
|
+
f"\n"
|
|
223
|
+
f" {rgb(C.gray_dark)}Combine them:{F.END}\n"
|
|
224
|
+
f" {grad(' ★ TOP SCORE ', C.VAPORWAVE)} {rgb(C.gold)}{F.BOLD}9,420pts{F.END}\n"
|
|
225
|
+
f" {rgb(C.gray_dark)}user:{F.END} {grad('guli', C.AURORA)} {rgb(C.gray_dark)}status:{F.END} {grad('online', [(0,220,100),(0,180,80)])}\n"
|
|
226
|
+
)
|
|
227
|
+
if "class" in show:
|
|
228
|
+
print(
|
|
229
|
+
f"\n"
|
|
230
|
+
f" {F.BOLD}Class Overview{F.END}\n"
|
|
231
|
+
f" {rgb(C.gray_dark)}C {F.END}= Colors {rgb(C.gray_dark)}→{F.END} tuples like {rgb(C.cyan)}(r, g, b){F.END} used with {F.BOLD}rgb(){F.END} or {F.BOLD}grad(){F.END}\n"
|
|
232
|
+
f" {rgb(C.gray_dark)}F {F.END}= Formats {rgb(C.gray_dark)}→{F.END} ANSI escape codes for {F.BOLD}bold{F.END}, {F.ITALIC}italic{F.END}, {F.UNDERLINE}underline{F.END}, etc.\n"
|
|
233
|
+
f" {rgb(C.gray_dark)}tip {F.END}combine them: {rgb(C.neon_pink)+F.BOLD}rgb(C.neon_pink) + F.BOLD{F.END}\n"
|
|
234
|
+
f"\n"
|
|
235
|
+
)
|
|
236
|
+
def alternate(text, colors):
|
|
237
|
+
result = []
|
|
238
|
+
color_len = len(colors)
|
|
239
|
+
for i in range(len(text)):
|
|
240
|
+
r = colors[i%color_len][0]
|
|
241
|
+
g = colors[i%color_len][1]
|
|
242
|
+
b = colors[i%color_len][2]
|
|
243
|
+
|
|
244
|
+
result.append(f"\x1b[38;2;{r};{g};{b}m{text[i]}")
|
|
245
|
+
|
|
246
|
+
return "".join(result) + "\x1b[0m"
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def credit():
|
|
251
|
+
print(
|
|
252
|
+
f"{UP(1)+CLEAR_LINE()+rgb(C.green_dark)}Loaded Module:{F.END} Guli's {F.BOLD+alternate("ANSI", [C.cyan_light, C.blue_light, C.red_light, C.yellow_light])} decoder."
|
|
253
|
+
)
|
|
254
|
+
credit()
|
|
255
|
+
|
|
256
|
+
if __name__ == "__main__":
|
|
257
|
+
info_colors()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import ANSI
|
|
3
|
+
import Goosefull as goose
|
|
4
|
+
|
|
5
|
+
filename = __file__.split("\\")[-1]
|
|
6
|
+
print(f"(Loading module: {filename}..")
|
|
7
|
+
|
|
8
|
+
# Definieer de tekst en RGB-kleuren
|
|
9
|
+
blue = (0, 0, 255)
|
|
10
|
+
green = (0, 255, 0)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _bounce_out(t):
|
|
14
|
+
n, d = 7.5625, 2.75
|
|
15
|
+
if t < 1/d: return n * t * t
|
|
16
|
+
elif t < 2/d: t -= 1.5/d; return n*t*t + 0.75
|
|
17
|
+
elif t < 2.5/d: t -= 2.25/d; return n*t*t + 0.9375
|
|
18
|
+
else: t -= 2.625/d; return n*t*t + 0.984375
|
|
19
|
+
|
|
20
|
+
def _ease_out(f, t): return 1 - f(1 - t)
|
|
21
|
+
def _ease_in_out(f, t): return f(2*t) / 2 if t < 0.5 else 1 - f(2 - 2*t) / 2
|
|
22
|
+
|
|
23
|
+
_in = {
|
|
24
|
+
"Sine": lambda t: 1 - math.cos((t * math.pi) / 2),
|
|
25
|
+
"Quad": lambda t: t ** 2,
|
|
26
|
+
"Cubic": lambda t: t ** 3,
|
|
27
|
+
"Quart": lambda t: t ** 4,
|
|
28
|
+
"Quint": lambda t: t ** 5,
|
|
29
|
+
"Expo": lambda t: 0 if t == 0 else 2 ** (10*t - 10),
|
|
30
|
+
"Circ": lambda t: 1 - math.sqrt(1 - t**2),
|
|
31
|
+
"Back": lambda t: 2.70158*t**3 - 1.70158*t**2,
|
|
32
|
+
"Elastic": lambda t: 0 if t==0 else 1 if t==1 else -(2**(10*t-10)) * math.sin((t*10-10.75)*(2*math.pi)/3),
|
|
33
|
+
"Bounce": lambda t: 1 - _bounce_out(1 - t),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
_easings = {}
|
|
37
|
+
for name, f in _in.items():
|
|
38
|
+
_easings[f"easeIn{name}"] = f
|
|
39
|
+
_easings[f"easeOut{name}"] = lambda t, f=f: _ease_out(f, t)
|
|
40
|
+
_easings[f"easeInOut{name}"] = lambda t, f=f: _ease_in_out(f, t)
|
|
41
|
+
|
|
42
|
+
copya = _easings.copy()
|
|
43
|
+
for k,v in copya.items():
|
|
44
|
+
_easings[k.lower()] = v
|
|
45
|
+
|
|
46
|
+
def curve(x, ease="easeInSine", start=0, end=1, strength=1):
|
|
47
|
+
ease = ease.lower()
|
|
48
|
+
x = (x - start) / (end - start)
|
|
49
|
+
x = max(0.0, min(1.0, x))
|
|
50
|
+
t = _easings[ease](x)
|
|
51
|
+
t = t ** (1 / strength) if t >= 0 else -((-t) ** (1 / strength))
|
|
52
|
+
return start + (end - start) * t
|
|
53
|
+
|
|
54
|
+
def lerp(progress, start, end):
|
|
55
|
+
return (end - start) * progress
|
|
56
|
+
|
|
57
|
+
def curve_info():
|
|
58
|
+
goose.print_set(_in, True)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def credit():
|
|
62
|
+
print(
|
|
63
|
+
f"{ANSI.UP(1)+ANSI.CLEAR_LINE()+ANSI.C.GREEN}Loaded Module:{ANSI.C.END} Guli's {ANSI.C.END}", end=""
|
|
64
|
+
)
|
|
65
|
+
print(ANSI.grad("AnimationCurves", [blue, green])+ANSI.C.END+".")
|
|
66
|
+
credit()
|
|
67
|
+
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import math
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from . import ANSI
|
|
5
|
+
import numpy as np
|
|
6
|
+
import random
|
|
7
|
+
from scipy.signal import fftconvolve
|
|
8
|
+
from scipy import ndimage
|
|
9
|
+
|
|
10
|
+
print("Loading module: Goosefull..")
|
|
11
|
+
|
|
12
|
+
# this is basicly Juliano's trash bin of usefull stuff
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# =========================
|
|
16
|
+
# -------GRID STUFF-------
|
|
17
|
+
# =========================
|
|
18
|
+
|
|
19
|
+
opposite_dir = {0: 2, 1: 3, 2: 0, 3: 1} # N<->S, E<->W
|
|
20
|
+
|
|
21
|
+
def give_neighbours(grid, x, y, mode='+'):
|
|
22
|
+
result = []
|
|
23
|
+
if mode == '3x3':
|
|
24
|
+
offsets = [(dx, dy) for dx in [-1,0,1] for dy in [-1,0,1] if not (dx==0 and dy==0)]
|
|
25
|
+
elif mode == '+':
|
|
26
|
+
offsets = [(0,-1),(1,0),(0,1),(-1,0)]
|
|
27
|
+
|
|
28
|
+
for i, (dx, dy) in enumerate(offsets): # N E S W
|
|
29
|
+
nx, ny = x + dx, y + dy
|
|
30
|
+
if 0 <= nx < len(grid) and 0 <= ny < len(grid[0]):
|
|
31
|
+
val = grid[nx][ny]
|
|
32
|
+
if val != -1:
|
|
33
|
+
result.append((val, i))
|
|
34
|
+
return result
|
|
35
|
+
|
|
36
|
+
def count_neighbours(grid, x, y, mode='3x3'):
|
|
37
|
+
counts = {}
|
|
38
|
+
if mode == '3x3':
|
|
39
|
+
offsets = [(dx, dy) for dx in [-1,0,1] for dy in [-1,0,1] if not (dx==0 and dy==0)]
|
|
40
|
+
elif mode == '+':
|
|
41
|
+
offsets = [(0,-1),(1,0),(0,1),(-1,0)]
|
|
42
|
+
elif mode == "5x5":
|
|
43
|
+
offsets = [(dx, dy) for dx in [-2,-1,0,1,2] for dy in [-2-1,0,1,2] if not (dx==0 and dy==0)]
|
|
44
|
+
|
|
45
|
+
for dx, dy in offsets:
|
|
46
|
+
nx, ny = x + dx, y + dy
|
|
47
|
+
if 0 <= nx < len(grid) and 0 <= ny < len(grid[0]):
|
|
48
|
+
val = grid[nx][ny]
|
|
49
|
+
counts[val] = counts.get(val, 0) + 1
|
|
50
|
+
return counts
|
|
51
|
+
|
|
52
|
+
def count_neighbours_np(grid_np, mode='3x3', max_val=None, kernel_cache={}):
|
|
53
|
+
if mode not in kernel_cache:
|
|
54
|
+
if mode[0] == 'c':
|
|
55
|
+
r = int(mode[1:])
|
|
56
|
+
size = 2*r + 1
|
|
57
|
+
center = r
|
|
58
|
+
kernel = np.zeros((size, size))
|
|
59
|
+
for dx in range(-r, r+1):
|
|
60
|
+
for dy in range(-r, r+1):
|
|
61
|
+
if 0 < dx**2 + dy**2 <= r**2:
|
|
62
|
+
kernel[dx+center, dy+center] = 1
|
|
63
|
+
elif mode == '3x3':
|
|
64
|
+
kernel = np.ones((3, 3)); kernel[1,1] = 0
|
|
65
|
+
elif mode == '+':
|
|
66
|
+
kernel = np.array([[0,1,0],[1,0,1],[0,1,0]])
|
|
67
|
+
elif mode == '5x5':
|
|
68
|
+
kernel = np.ones((5, 5)); kernel[2,2] = 0
|
|
69
|
+
kernel_cache[mode] = kernel
|
|
70
|
+
else:
|
|
71
|
+
kernel = kernel_cache[mode]
|
|
72
|
+
|
|
73
|
+
max_val = max(int(grid_np.max()), max_val) if max_val is not None else int(grid_np.max())
|
|
74
|
+
h, w = grid_np.shape
|
|
75
|
+
pad_h, pad_w = kernel.shape[0]//2, kernel.shape[1]//2
|
|
76
|
+
|
|
77
|
+
# tile-pad for toroidal wrap, then valid-convolve, avoids per-color loop overhead from mode='wrap' in ndimage
|
|
78
|
+
padded_grid = np.pad(grid_np, ((pad_h,pad_h),(pad_w,pad_w)), mode='wrap')
|
|
79
|
+
|
|
80
|
+
counts = np.zeros((max_val + 1, h, w), dtype=np.int32)
|
|
81
|
+
for v in range(max_val + 1):
|
|
82
|
+
mask = (padded_grid == v).astype(np.float32)
|
|
83
|
+
conv = fftconvolve(mask, kernel, mode='valid')
|
|
84
|
+
counts[v] = np.round(conv)
|
|
85
|
+
|
|
86
|
+
return counts
|
|
87
|
+
|
|
88
|
+
def superposition_entropy(neighbours, all_superpos, biasses):
|
|
89
|
+
'''
|
|
90
|
+
neighbours acces: neighbours[direction] = [neighbours]
|
|
91
|
+
all_superpos acces: all_superpos = [ter, ter, ter, ter, ter, ter]
|
|
92
|
+
biasses acces: biasses[terrain][direction] = [terrain, bias]
|
|
93
|
+
'''
|
|
94
|
+
allowed = set(all_superpos)
|
|
95
|
+
if not neighbours:
|
|
96
|
+
return allowed, len(allowed)
|
|
97
|
+
|
|
98
|
+
for direction, neighbour_list in neighbours.items():
|
|
99
|
+
allowed_from_dir = set()
|
|
100
|
+
for neighbour_terrain in neighbour_list:
|
|
101
|
+
for terrain, bias in biasses[neighbour_terrain][opposite_dir[direction]]:
|
|
102
|
+
if bias > 0:
|
|
103
|
+
allowed_from_dir.add(terrain)
|
|
104
|
+
allowed &= allowed_from_dir # intersect: must be valid from ALL directions
|
|
105
|
+
|
|
106
|
+
entropy = len(allowed)
|
|
107
|
+
return allowed, entropy
|
|
108
|
+
|
|
109
|
+
def List_is_list_2D(list1, list2):
|
|
110
|
+
for x in range(len(list1)):
|
|
111
|
+
for y in range(len(list1[x])):
|
|
112
|
+
if list1[x][y] != list2[x][y]:
|
|
113
|
+
return False
|
|
114
|
+
return True
|
|
115
|
+
|
|
116
|
+
def list_in_history(list, history):
|
|
117
|
+
for past in history:
|
|
118
|
+
if List_is_list_2D(list, past):
|
|
119
|
+
return True
|
|
120
|
+
return False
|
|
121
|
+
|
|
122
|
+
def leftover_2D(grid, search):
|
|
123
|
+
count = 0
|
|
124
|
+
for row in grid:
|
|
125
|
+
for item in row:
|
|
126
|
+
if item == search:
|
|
127
|
+
count += 1
|
|
128
|
+
return count
|
|
129
|
+
|
|
130
|
+
def print_grid(grid, align=4):
|
|
131
|
+
height = len(grid)
|
|
132
|
+
width = len(grid[0])
|
|
133
|
+
print()
|
|
134
|
+
print("╋━"+"━"*(align*width)+"━━╋")
|
|
135
|
+
print("┃"," "*(align*width)," ┃")
|
|
136
|
+
for row in range(height):
|
|
137
|
+
print("┃ ", end="")
|
|
138
|
+
for column in range(width):
|
|
139
|
+
item = str(grid[row][column])
|
|
140
|
+
print(item.rjust(align), end="")
|
|
141
|
+
print(" ┃")
|
|
142
|
+
print("┃"," "*(align*width)," ┃")
|
|
143
|
+
print("╋━"+"━"*(align*width)+"━━╋", )
|
|
144
|
+
|
|
145
|
+
def make_grid(length, width=None, values=(-1,), map_type=0, density=1.0, points=2):
|
|
146
|
+
if not width:
|
|
147
|
+
width = length
|
|
148
|
+
|
|
149
|
+
if map_type == 0:
|
|
150
|
+
return np.random.choice(values, size=(length, width))
|
|
151
|
+
|
|
152
|
+
if map_type == 1:
|
|
153
|
+
unique = [v for v in dict.fromkeys(values) if v != 0]
|
|
154
|
+
|
|
155
|
+
if isinstance(density, float):
|
|
156
|
+
density = [density for _ in range(len(unique))]
|
|
157
|
+
|
|
158
|
+
seeds_yx = []
|
|
159
|
+
seeds_val = []
|
|
160
|
+
for v in unique:
|
|
161
|
+
for _ in range(points):
|
|
162
|
+
seeds_yx.append((random.randint(0, length - 1), random.randint(0, width - 1)))
|
|
163
|
+
seeds_val.append(v)
|
|
164
|
+
|
|
165
|
+
if not seeds_yx:
|
|
166
|
+
return np.zeros((length, width), dtype=int), np.zeros((length, width), dtype=int)
|
|
167
|
+
|
|
168
|
+
seeds_yx = np.array(seeds_yx) # (N, 2)
|
|
169
|
+
seeds_val = np.array(seeds_val) # (N,)
|
|
170
|
+
|
|
171
|
+
yy, xx = np.indices((length, width)) # (length, width) each
|
|
172
|
+
|
|
173
|
+
# toroidal distance per seed
|
|
174
|
+
dy = np.abs(yy[..., None] - seeds_yx[:, 0]) # (length, width, N)
|
|
175
|
+
dy = np.minimum(dy, length - dy)
|
|
176
|
+
dx = np.abs(xx[..., None] - seeds_yx[:, 1])
|
|
177
|
+
dx = np.minimum(dx, width - dx)
|
|
178
|
+
dist2 = dy**2 + dx**2
|
|
179
|
+
|
|
180
|
+
closest_idx = np.argmin(dist2, axis=-1) # (length, width)
|
|
181
|
+
voronoi_map = seeds_val[closest_idx]
|
|
182
|
+
|
|
183
|
+
seed_to_value_idx = np.array([unique.index(v) for v in seeds_val]) # (N,)
|
|
184
|
+
density = np.array(density)
|
|
185
|
+
cell_density = density[seed_to_value_idx[closest_idx]]
|
|
186
|
+
mask = np.random.random((length, width)) < cell_density
|
|
187
|
+
grid = np.where(mask, voronoi_map, 0)
|
|
188
|
+
|
|
189
|
+
return grid, voronoi_map
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# =========================
|
|
194
|
+
# -------INFO STUFF-------
|
|
195
|
+
# =========================
|
|
196
|
+
|
|
197
|
+
def info_time(asc_start, time1, asc_end, time2, message="Total time is: {difference}"):
|
|
198
|
+
print("\nStarted at:",asc_start)
|
|
199
|
+
print("Finished at:", asc_end)
|
|
200
|
+
|
|
201
|
+
dt1 = datetime.fromtimestamp(time1)
|
|
202
|
+
dt2 = datetime.fromtimestamp(time2)
|
|
203
|
+
|
|
204
|
+
difference = dt2 - dt1
|
|
205
|
+
print(message.format(difference = difference))
|
|
206
|
+
|
|
207
|
+
def print_set(a_set, name_only):
|
|
208
|
+
if not name_only:
|
|
209
|
+
for item in a_set:
|
|
210
|
+
print(f"{item}: {a_set[item]}")
|
|
211
|
+
else:
|
|
212
|
+
for item in a_set:
|
|
213
|
+
print(item)
|
|
214
|
+
# =========================
|
|
215
|
+
# -------MATH STUFF-------
|
|
216
|
+
# =========================
|
|
217
|
+
|
|
218
|
+
def lerp(x, start, end):
|
|
219
|
+
return round((end-start)*x*0.01, 2)
|
|
220
|
+
|
|
221
|
+
def smoothstep(x, start, end):
|
|
222
|
+
t = (x - start) / (end - start)
|
|
223
|
+
t = min(1, max(0, t))
|
|
224
|
+
return t * t * (3 - 2 * t)
|
|
225
|
+
|
|
226
|
+
def ease_in_out_spring(x, start, end):
|
|
227
|
+
if start == end:
|
|
228
|
+
return 0.0
|
|
229
|
+
|
|
230
|
+
t = (x - start) / (end - start)
|
|
231
|
+
t = max(0.0, min(1.0, t))
|
|
232
|
+
|
|
233
|
+
# damped oscillator centered at 0.5
|
|
234
|
+
damping = 10
|
|
235
|
+
frequency = 8 * math.pi
|
|
236
|
+
|
|
237
|
+
if t == 0 or t == 1:
|
|
238
|
+
return t
|
|
239
|
+
|
|
240
|
+
return (
|
|
241
|
+
1
|
|
242
|
+
- math.exp(-damping * t)
|
|
243
|
+
* math.cos(frequency * t)
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def credit():
|
|
248
|
+
print(
|
|
249
|
+
f"{ANSI.UP(1)+ANSI.CLEAR_LINE()+ANSI.rgb(ANSI.C.green_dark)}Loaded Module:{ANSI.F.END} Guli's {ANSI.rgb(ANSI.C.neon_purple)}goose{ANSI.rgb(ANSI.C.blue)}full{ANSI.F.END} stuff."
|
|
250
|
+
)
|
|
251
|
+
credit()
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import ANSI
|
|
2
|
+
filename = __file__.split("\\")[-1]
|
|
3
|
+
print(f"(Loading module: {filename}..")
|
|
4
|
+
|
|
5
|
+
# this is just cool
|
|
6
|
+
|
|
7
|
+
def progress_bar(progress, max_progress, on="█", off="|", color_on=ANSI.C.GREEN, color_off=ANSI.C.RED, bar_width=5, bar_length=100, form=1, stick_out=0, name=""):
|
|
8
|
+
bar_width = max(3, bar_width)
|
|
9
|
+
print(ANSI.UP(bar_width + 2 + (1 if len(name) else 0)), end="")
|
|
10
|
+
padding = (bar_length + stick_out - len(name)) // 2
|
|
11
|
+
if len(name):
|
|
12
|
+
print(color_on +"=" * (padding+(len(name)%2==0)) + name + "=" * padding + ANSI.C.END)
|
|
13
|
+
|
|
14
|
+
on = on[0]
|
|
15
|
+
off = off[0]
|
|
16
|
+
if form==1:
|
|
17
|
+
bar_length += stick_out
|
|
18
|
+
percent = -(-progress*bar_length // max_progress)
|
|
19
|
+
print(color_on +"╔" + "═"*(bar_length-stick_out-1) + "╗")
|
|
20
|
+
print(color_on +"║"+on*min(percent, bar_length-stick_out-1) + color_off + off*(bar_length-percent-stick_out-1)+color_on+f"╚{"═"*stick_out}╗")
|
|
21
|
+
|
|
22
|
+
for i in range(bar_width-2):
|
|
23
|
+
print(color_on+"║" + on*percent +color_off + off*(bar_length-percent)+color_on+"║")
|
|
24
|
+
|
|
25
|
+
print(color_on +"║"+on*min(percent, bar_length-stick_out-1) + color_off + off*(bar_length-percent-stick_out-1) + color_on + f"╔{"═"*stick_out}╝")
|
|
26
|
+
print(color_on +"╚" + "═"*(bar_length-stick_out-1) + f"╝ {progress}/{max_progress}"+ANSI.C.END)
|
|
27
|
+
if form==0:
|
|
28
|
+
percent = -(-progress*bar_length // max_progress)
|
|
29
|
+
if percent == bar_length:
|
|
30
|
+
color_off = color_on
|
|
31
|
+
off = on # wouw
|
|
32
|
+
print(color_on+"╔" + "═"*bar_length + "╗")
|
|
33
|
+
for i in range(bar_width):
|
|
34
|
+
print(color_on+"║"+on*percent + color_off + off*(bar_length-percent)+ color_on +"║")
|
|
35
|
+
print(color_on+"╚" + "═"*bar_length + f"╝ {progress}/{max_progress}", color_off)
|
|
36
|
+
|
|
37
|
+
def INFO():
|
|
38
|
+
print(
|
|
39
|
+
f"{ANSI.C.FAINT}{'='*80}{ANSI.C.END}\n"
|
|
40
|
+
f"{ANSI.C.BOLD}Welcome to {ANSI.C.GREEN}PROGRESS{ANSI.C.RED}BAR{ANSI.C.END}\n\n"
|
|
41
|
+
f"{ANSI.C.BOLD}Usage:{ANSI.C.END}\n"
|
|
42
|
+
f" {ANSI.C.BLUE}progress_bar(progress, max_progress, [optional stuff]){ANSI.C.END}\n\n"
|
|
43
|
+
f"{ANSI.C.BOLD}Optional stuff:{ANSI.C.END}\n"
|
|
44
|
+
f" on Character for filled portion (default: '█')\n"
|
|
45
|
+
f" off Character for empty portion (default: '|')\n"
|
|
46
|
+
f" color_on Color for filled portion (default: GREEN)\n"
|
|
47
|
+
f" color_off Color for empty portion (default: RED)\n"
|
|
48
|
+
f" bar_width Height of the bar (default: 5, min: 3)\n"
|
|
49
|
+
f" bar_length Width of the bar (default: 100)\n"
|
|
50
|
+
f" form Shape: 0=flat, 1=battery (default: 1)\n"
|
|
51
|
+
f" stick_out Battery end size (default: 0)\n"
|
|
52
|
+
f" name Label shown above the bar (default: '')\n\n"
|
|
53
|
+
f"{ANSI.C.RED}NOTE: Print empty lines before calling progress_bar() - at least (bar_width + 2).{ANSI.C.END}\n\n"
|
|
54
|
+
f"Made by {ANSI.C.BOLD}{ANSI.C.UNDERLINE}GULI GULI{ANSI.C.END}\n"
|
|
55
|
+
f"{ANSI.C.FAINT}{'='*80}{ANSI.C.END}\n"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def main():
|
|
62
|
+
bigness = int(input("bigness: "))
|
|
63
|
+
width = 6 # AT LEAST 3
|
|
64
|
+
print("\n"*(width+2))
|
|
65
|
+
for i in range(bigness+1):
|
|
66
|
+
progress_bar(i, bigness, "█", "|", bar_width=width, bar_length=50, stick_out=1)
|
|
67
|
+
#time.sleep(0.1)
|
|
68
|
+
print("\n")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def credit():
|
|
73
|
+
print(
|
|
74
|
+
f"{ANSI.UP(1)+ANSI.CLEAR_LINE()+ANSI.C.GREEN}Loaded Module:{ANSI.C.END} Guli's {ANSI.C.BOLD+ANSI.C.GREEN}PROGRESS{ANSI.C.RED}BAR{ANSI.C.END}."
|
|
75
|
+
)
|
|
76
|
+
credit()
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
main()
|
|
80
|
+
INFO()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import pygame as pyg
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def init_window():
|
|
6
|
+
global window
|
|
7
|
+
window = pyg.display.set_mode((1920, 1080), pyg.RESIZABLE)
|
|
8
|
+
|
|
9
|
+
background = window
|
|
10
|
+
|
|
11
|
+
def resize_grid(grid, scale):
|
|
12
|
+
grid_scale = len(grid)
|
|
13
|
+
delta = scale - grid_scale
|
|
14
|
+
|
|
15
|
+
if delta > 0:
|
|
16
|
+
grid = [
|
|
17
|
+
row + [0] * delta
|
|
18
|
+
for row in grid
|
|
19
|
+
]
|
|
20
|
+
grid.extend([[0] * scale for _ in range(delta)])
|
|
21
|
+
|
|
22
|
+
elif delta < 0:
|
|
23
|
+
grid = [
|
|
24
|
+
row[:scale]
|
|
25
|
+
for r, row in enumerate(grid)
|
|
26
|
+
if r < scale
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
return grid # fix: was missing
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def grid_to_surface(grid, colors, surface, grid_px, transparent_alive=0, transparent_dead=0, ghost=False):
|
|
33
|
+
alive_alpha = 255 - transparent_alive
|
|
34
|
+
dead_alpha = 255 - transparent_dead
|
|
35
|
+
|
|
36
|
+
arr = np.array(grid)
|
|
37
|
+
all_colors = np.array(colors, dtype=np.uint8)
|
|
38
|
+
|
|
39
|
+
if ghost:
|
|
40
|
+
all_colors = (all_colors // 3).astype(np.uint8)
|
|
41
|
+
|
|
42
|
+
mapped = np.where(arr == 0, len(colors) - 1, arr - 1)
|
|
43
|
+
mapped = np.where(arr > len(colors) - 1, arr - 1, mapped)
|
|
44
|
+
|
|
45
|
+
rgb_array = all_colors[mapped]
|
|
46
|
+
surf = pyg.surfarray.make_surface(rgb_array.transpose(1, 0, 2))
|
|
47
|
+
|
|
48
|
+
surf = surf.convert_alpha()
|
|
49
|
+
alpha = np.where(arr.T == 0, dead_alpha, alive_alpha).astype(np.uint8)
|
|
50
|
+
pyg.surfarray.pixels_alpha(surf)[:] = alpha
|
|
51
|
+
|
|
52
|
+
scaled = pyg.transform.scale(surf, (grid_px, surface.get_height()))
|
|
53
|
+
surface.blit(scaled, (0, 0))
|