ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Yes, tried to keep the code as small as possible. You can add stuff to that forever. Put christmas trees on the ground, individualize the reindeer, at some point you just stop and say that's good enough.
I thought about giving each reindeer a distro name, and have the reindeer snort awk and sed. I did one like that, but the code gets so big. And I wanted that in one file with no headers.
Structurally, I'd suggest moving the screen drawing code into its own function, and in the main loop testing for c=='q' or KEY_RESIZE before calling the drawing function. That always seems to work best for me.
Also, if I may suggest, const * const distro[] = { "Slackware", ... } would be cleaner than that distro[25][25] you're using.
Anyway, loved it.
P.S. just giving Rudolph a red nose is an easy fix: pass i to draw_reindeer() and if it's zero, it's rudolph.
For fun, I had a little play with your code over the last couple of evenings. I've attached what I came up with.
Keys 1-9 set the number of Reindeer in the team.
's' toggles the snowfall
'g' toggles the ground (with very basic collision detection for the gifts — they won't stack).
I reworked draw_string() to be a little more efficient than drawing one char at a time in a loop, and reworked much of the snow and gift drop routines. I split the drawing/presentation from the movement logic. Been a while since I've done anything with ncurses, was a useful refresher.
Here. play with this if you want. I found several different code trees on the net over time for ncurses/curses, altered them, put them together. One c file again.
Penguin express, Or, whatever you wish.
ctrain3.c
Code:
/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
**/
#include <ctype.h>
#include <curses.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
//Make the engine and coal car
#define EngHEIGHT 10
#define EngFUNNEL 7
#define EngPATTERNS 6
#define EngSTR1 " ==== ________ ___________ "
#define EngSTR2 " _D _| |_______/ \\__I_I_____===__|__Mint___| "
#define EngSTR3 " |(_)...... S\\________/ | | . =|___ ___| "
#define EngSTR4 " / | . u | | | | . ||_| |_|| "
#define EngSTR5 " | .....|..... s |__......Slackware..... | [___] | "
#define EngSTR6 " | ________.___e_____|_______________.____| Arch | "
#define EngSTR7 " |/ | |---------I_____I--[][][]----D |=======| "
#define EngWHL11 " _/ =| o |=/~~\\ /~~\\ /~~\\ /~~\\ ____Y____________|__ "
#define EngWHL12 "/|/~\\|___|= || || || |_____/~\\___/ "
#define EngWHL13 " \\_/ \\0=====0=====0=====0_/ \\_/ "
#define EngWHL21 " _/ =| o |=/~~\\ /~~\\ /~~\\ /~~\\ ____Y____________|__ "
#define EngWHL22 "/|/~\\|___|=O=====O=====O=====O |_____/~\\___/ "
#define EngWHL23 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
#define EngWHL31 " _/ =| o |=/O=====O=====O=====O \\ ____Y____________|__ "
#define EngWHL32 "/|/~\\|___|= || || || |_____/~\\___/ "
#define EngWHL33 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
#define EngWHL41 " _/ =| o |=/~O=====O=====O=====O\\ ____Y____________|__ "
#define EngWHL42 "/|/~\\|___|= || || || |_____/~\\___/ "
#define EngWHL43 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
#define EngWHL51 " _/ =| o |=/~~\\ /~~\\ /~~\\ /~~\\ ____Y____________|__ "
#define EngWHL52 "/|/~\\|___|= O=====O=====O=====O|_____/~\\___/ "
#define EngWHL53 " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
#define EngWHL61 " _/ =| o |=/~~\\ /~~\\ /~~\\ /~~\\ ____Y____________|__ "
#define EngWHL62 "/|/~\\|___|= || || || |_____/~\\___/ "
#define EngWHL63 " \\_/ \\_O=====O=====O=====O/ \\_/ "
#define EngDEL " "
#define COAL01 " "
#define COAL02 " "
#define COAL03 " ______Redhat_____ "
#define COAL04 " _| \\Bodhi_ "
#define COAL05 " | Penguin express. | "
#define COAL06 " | ...................... | "
#define COAL07 " |________________________|_ "
#define COAL08 "o_|__________________________| "
#define COAL09 " \\__Fedora__| |__Ubuntu_/ "
#define COAL10 " \\_/ \\_/ \\_/ \\_/ "
#define COALDEL " "
#define LOGOFUNNEL 4
void add_smoke(int y, int x);
int add_Eng(int x);
int add_sl(int x);
int my_mvaddstr(int y, int x, char *str);
int NUMBER = -1;
int SIGNAL = 1;
int LOGO = 0;
int my_mvaddstr(int y, int x, char *str) {
for ( ; x < 0; ++x, ++str)
if (*str == '\0') return ERR;
for ( ; *str != '\0'; ++str, ++x)
if (mvaddch(y, x, *str) == ERR) return ERR;
return OK;
}
int add_sl(int x) {
if (NUMBER < 0)
NUMBER = 2;
int y;
y = LINES / 2 - 3;
add_smoke(y - 1, x + LOGOFUNNEL);
return OK;
}
int add_Eng(int x) {
static char *Eng[EngPATTERNS][EngHEIGHT + 1]
= {{EngSTR1, EngSTR2, EngSTR3, EngSTR4, EngSTR5, EngSTR6, EngSTR7,
EngWHL11, EngWHL12, EngWHL13, EngDEL},
{EngSTR1, EngSTR2, EngSTR3, EngSTR4, EngSTR5, EngSTR6, EngSTR7,
EngWHL21, EngWHL22, EngWHL23, EngDEL},
{EngSTR1, EngSTR2, EngSTR3, EngSTR4, EngSTR5, EngSTR6, EngSTR7,
EngWHL31, EngWHL32, EngWHL33, EngDEL},
{EngSTR1, EngSTR2, EngSTR3, EngSTR4, EngSTR5, EngSTR6, EngSTR7,
EngWHL41, EngWHL42, EngWHL43, EngDEL},
{EngSTR1, EngSTR2, EngSTR3, EngSTR4, EngSTR5, EngSTR6, EngSTR7,
EngWHL51, EngWHL52, EngWHL53, EngDEL},
{EngSTR1, EngSTR2, EngSTR3, EngSTR4, EngSTR5, EngSTR6, EngSTR7,
EngWHL61, EngWHL62, EngWHL63, EngDEL}};
static char *coal[EngHEIGHT + 1]
= {COAL01, COAL02, COAL03, COAL04, COAL05,
COAL06, COAL07, COAL08, COAL09, COAL10, COALDEL};
if (NUMBER < 0)
NUMBER = 1;
int y, i, j, dy = 0;
int EngLENGTH = 54 + 29*NUMBER;
if (x < - EngLENGTH) return ERR;
y = LINES / 2 - 5;
for (i = 0; i <= EngHEIGHT; ++i) {
my_mvaddstr(y + i, x, Eng[(EngLENGTH + x) % EngPATTERNS][i]);
for (j = 1; j <= NUMBER; ++j)
my_mvaddstr(y + i + dy*j, x + 24 + 29*j, coal[i]);
}
add_smoke(y - 1, x + EngFUNNEL);
return OK;
}
void add_smoke(int y, int x)
#define SMOKEPTNS 16
{
static struct smokes {
int y, x;
int ptrn, kind;
} S[1000];
static int sum = 0;
//Smoke puffs
static char *Smoke[2][SMOKEPTNS]
= {{"()", "( )", "( )", "( )", "( )",
"( )" , "( )" , "( )" , "()" , "()" ,
"O" , "O" , "0" , "o" , "o" ,
" " },
{"@@", "@@@", "Debian", "Gentoo", "@@@@",
"@@@" , "@@@" , "@@" , "@@" , "@@" ,
"@" , "@" , "@" , "@" , "@" ,
" " }};
static char *Eraser[SMOKEPTNS]
= {" ", " ", " ", " ", " ",
" " , " " , " " , " " , " " ,
" " , " " , " " , " " , " " ,
" " };
static int dy[SMOKEPTNS] = { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 };
static int dx[SMOKEPTNS] = {-2, -1, 0, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 3, 3, 3 };
int i;
//Smoke frequency
if (x % 3 == 0) {
for (i = 0; i < sum; ++i) {
my_mvaddstr(S[i].y, S[i].x, Eraser[S[i].ptrn]);
S[i].y -= dy[S[i].ptrn];
S[i].x += dx[S[i].ptrn];
S[i].ptrn += (S[i].ptrn < SMOKEPTNS - 2) ? 1 : 0;
my_mvaddstr(S[i].y, S[i].x, Smoke[S[i].kind][S[i].ptrn]);
}
my_mvaddstr(y, x, Smoke[sum % 2][0]);
S[sum].y = y; S[sum].x = x;
S[sum].ptrn = 0; S[sum].kind = sum % 2;
sum ++;
}
}
int main(int argc, char *argv[])
{
int x;
int base_usleep = 100000; //Animation speed
initscr();
if (SIGNAL) signal(SIGINT, SIG_IGN);
noecho();
curs_set(0);
nodelay(stdscr, TRUE);
leaveok(stdscr, TRUE);
scrollok(stdscr, FALSE);
for (x = COLS - 1; ; --x) {
if (LOGO == 1) {
if (add_sl(x) == ERR) break;
} else {
if (add_Eng(x) == ERR) break;
}
getch();
refresh();
usleep(base_usleep);
}
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
return (EXIT_SUCCESS);
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.