]> git.bzium.org - embe/choinka.git/blob - choinka.c
b117972281f325bb341ccf914f85202cf741fbce
[embe/choinka.git] / choinka.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <term.h>
4 #include <time.h>
5
6 #define A_POGRUBIONY (1 << 0)
7
8 #define KOLOR_BRAK -1
9 #define KOLOR_CZARNY 0
10 #define KOLOR_CZERWONY 1
11 #define KOLOR_ZIELONY 2
12 #define KOLOR_BRAZOWY 3
13 #define KOLOR_NIEBIESKI 4
14 #define KOLOR_MAGENTA 5
15 #define KOLOR_CYJAN 6
16 #define KOLOR_BIALY 7
17
18 typedef struct {
19   int attr;
20   int kolor;
21 } atrybut;
22
23 static atrybut const bombki[] = {
24   {A_POGRUBIONY, KOLOR_CZERWONY},
25   {A_POGRUBIONY, KOLOR_NIEBIESKI},
26   {A_POGRUBIONY, KOLOR_BRAZOWY},
27   {A_POGRUBIONY, KOLOR_MAGENTA},
28   {A_POGRUBIONY, KOLOR_CYJAN},
29   {A_POGRUBIONY, KOLOR_BIALY},
30 };
31 static int const ile_b = sizeof bombki / sizeof *bombki;
32
33 static atrybut const spacja = {0, KOLOR_BRAK};
34 static atrybut const choinka = {0, KOLOR_ZIELONY};
35 static atrybut const podstawa = {0, KOLOR_BRAZOWY};
36 static atrybut const podpis = {A_POGRUBIONY, KOLOR_CZERWONY};
37 static atrybut const gwiazdka = {A_POGRUBIONY, KOLOR_BRAZOWY};
38
39 static void inicjuj_rng()
40 {
41   unsigned ziarno = 0;
42   FILE* f = fopen("/dev/urandom", "rb");
43   if (f != NULL) {
44     unsigned nowe_ziarno;
45     if (fread(&nowe_ziarno, sizeof nowe_ziarno, 1, f) == 1) {
46       ziarno = nowe_ziarno;
47     }
48     fclose(f);
49   }
50   if (ziarno == 0) {
51     ziarno = time(NULL);
52   }
53   srand(ziarno);
54 }
55
56 static char const rysunek[] =
57 "           *\n"
58 "          /.\\\n"
59 "         /..'\\\n"
60 "         /'.'\\\n"
61 "        /.''.'\\\n"
62 "        /.'.'.\\\n"
63 "       /'.''.'.\\\n"
64 "  jgs  ^^^[_]^^^\n"
65 ;
66
67 static void ustaw(atrybut const* attr)
68 {
69   static atrybut ostatni = {-1, -1};
70   if (ostatni.attr == attr->attr && ostatni.kolor == attr->kolor) return;
71   ostatni = *attr;
72   putp(exit_attribute_mode);
73   if ((attr->attr & A_POGRUBIONY) != 0) {
74     putp(enter_bold_mode);
75   }
76   if (attr->kolor != KOLOR_BRAK) {
77     putp(tparm(set_a_foreground, attr->kolor));
78   }
79 }
80
81 int main()
82 {
83   inicjuj_rng();
84   setupterm(NULL, 1, NULL);
85   atrybut const* kolor = &choinka;
86   for (int i = 0; rysunek[i] != '\0'; i++) {
87     char c = rysunek[i];
88     if (c == '[') kolor = &podstawa;
89     atrybut const* akt = kolor;
90     if (c >= 'a' && c <= 'z') akt = &podpis;
91     if (c == '.') akt = &bombki[rand() % ile_b];
92     if (c == '*') akt = &gwiazdka;
93     if (c == ' ' || c == '\n') akt = &spacja;
94     if (c == ']') kolor = &choinka;
95     ustaw(akt);
96     putchar(c);
97   }
98   putp(exit_attribute_mode);
99   return 0;
100 }