Created
July 17, 2017 08:03
-
-
Save kouya/0df62394281cb65f69f02e9f3659374d to your computer and use it in GitHub Desktop.
Snownews' christmas mini-game, stand-alone version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Santa Hunta! | |
* Snownews' christmas mini-game | |
* Stand-alone version | |
* | |
* Compile with: | |
* gcc -lncurses -lm -o santa_hunta santa_hunta.c | |
* | |
* Needs C toolchain and ncurses5 dev headers. | |
* | |
* Part of: | |
* Snownews - A lightweight console RSS newsreader | |
* $Id: about.c 1080 2005-06-05 09:50:33Z kiza $ | |
* | |
* Copyright 2003-2004 Oliver Feiler <kiza@kcore.de> | |
* http://kiza.kcore.de/software/snownews/ | |
* | |
* about.c | |
* | |
* Please read the file README.patching before changing any code in this file! | |
* | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
* published by the Free Software Foundation. | |
* | |
* 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, write to the Free Software | |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
* | |
*/ | |
#include <ncurses.h> | |
#include <time.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/time.h> | |
#include <math.h> | |
/* Santa Hunta */ | |
typedef struct shot { | |
int x; | |
int y; | |
int fired; | |
} shot; | |
typedef struct santa { | |
int x; | |
int y; | |
int height; | |
int length; | |
int speed; | |
int anim; | |
char *gfx; | |
char *gfx_line2; | |
char *altgfx; | |
char *altgfx_line2; | |
} santa; | |
typedef struct scoreDisplay { | |
int score; | |
int x; | |
int y; | |
int rounds; | |
} scoreDisplay; | |
void SHDrawGun (int gun_pos) { | |
move (LINES-3, 0); | |
clrtoeol(); | |
move (LINES-2, 0); | |
clrtoeol(); | |
attron (WA_BOLD); | |
mvaddstr (LINES-3, gun_pos-3, "___/\\___"); | |
mvaddstr (LINES-2, gun_pos-3, "|######|"); | |
attroff (WA_BOLD); | |
} | |
void SHDrawStatus (void) { | |
attron (WA_BOLD); | |
mvaddstr (LINES-1, 1, "Move: cursor; shoot: space; quit: q"); | |
move (LINES-1, COLS-1); | |
attroff (WA_BOLD); | |
} | |
void SHDrawScore (int score, int level) { | |
int i, len; | |
char scorestr[16]; | |
char levelstr[16]; | |
attron (WA_REVERSE); | |
for (i = 0; i < COLS; i++) { | |
mvaddch (0, i, ' '); | |
} | |
mvaddstr (0, 1, "Santa Hunta!"); | |
snprintf (scorestr, sizeof(scorestr), "Score: %d", score); | |
len = strlen (scorestr); | |
mvaddstr (0, COLS-1-len, scorestr); | |
snprintf (levelstr, sizeof(levelstr), "Level: %d", level); | |
len = strlen (levelstr); | |
mvaddstr (0, COLS/2-len/2, levelstr); | |
attroff (WA_REVERSE); | |
} | |
void SHClearScreen (void) { | |
int i; | |
for (i = 0; i < LINES; i++) { | |
move (i, 0); | |
clrtoeol(); | |
} | |
} | |
void SHDrawProjectile (shot shot) { | |
attron (WA_BOLD); | |
mvaddstr (shot.y, shot.x, "|"); | |
attroff (WA_BOLD); | |
} | |
void SHDrawSanta (santa santa) { | |
int len; | |
char *draw_string; | |
len = COLS - santa.x; | |
if (santa.anim == 0) { | |
if (santa.x < 0) { | |
draw_string = santa.gfx+abs(santa.x); | |
mvaddnstr (santa.y, 0, draw_string, len); | |
} else | |
mvaddnstr (santa.y, santa.x, santa.gfx, len); | |
if (santa.x < 0) { | |
draw_string = santa.gfx_line2+abs(santa.x); | |
mvaddnstr (santa.y+1, 0, draw_string, len); | |
} else | |
mvaddnstr (santa.y+1, santa.x, santa.gfx_line2, len); | |
} else { | |
if (santa.x < 0) { | |
draw_string = santa.altgfx+abs(santa.x); | |
mvaddnstr (santa.y, 0, draw_string, len); | |
} else | |
mvaddnstr (santa.y, santa.x, santa.altgfx, len); | |
if (santa.x < 0) { | |
draw_string = santa.altgfx_line2+abs(santa.x); | |
mvaddnstr (santa.y+1, 0, draw_string, len); | |
} else | |
mvaddnstr (santa.y+1, santa.x, santa.altgfx_line2, len); | |
} | |
attron (COLOR_PAIR(10)); | |
mvaddch (santa.y, santa.x + santa.length - 1, '*'); | |
attroff (COLOR_PAIR(10)); | |
} | |
void newSanta (santa * santa, int level) { | |
santa->x = -27; | |
santa->y = 1+((float)rand() / (float)RAND_MAX * (LINES-7)); | |
santa->speed = level + ((float)rand() / (float)RAND_MAX * 3); | |
santa->anim = 0; | |
santa->height = 2; | |
santa->length = 27; | |
santa->gfx = "##___ __-+---+/*__-+---+/*"; | |
santa->gfx_line2 = "_|__|_) /\\ /\\ /\\ /\\ "; /* Append 2 spaces! */ | |
santa->altgfx = "##___ __-+---+/*__-+---+/*"; | |
santa->altgfx_line2 = "_|__|_) /| |\\ /| |\\ "; /* Append 1 space! */ | |
} | |
int SHHit (shot shot, santa santa) { | |
if ((shot.x >= santa.x) && (shot.x <= santa.x + santa.length) && | |
((shot.y == santa.y) || (shot.y == santa.y+1))) | |
return 1; | |
else | |
return 0; | |
} | |
int SHAddScore (santa santa) { | |
return 100 / santa.y * santa.speed; | |
} | |
void SHDrawHitScore (scoreDisplay score) { | |
int rand_color; | |
rand_color = 10 + ((float)rand() / (float)RAND_MAX * 6); | |
attron (WA_BOLD); | |
attron (COLOR_PAIR(rand_color)); | |
mvprintw (score.y, score.x, "%d", score.score); | |
attroff (COLOR_PAIR(rand_color)); | |
attroff (WA_BOLD); | |
} | |
void printFinalScore (int score) { | |
int i, j, pos, number_count; | |
char *numbers[10][5] = { | |
{"_______","| _ |","| | | |","| |_| |","|_____|"}, /* 0 */ | |
{" ____ "," / | ","/_/| | "," | | "," |_| "}, /* 1 */ | |
{"_______","|___ |","| ____|","| |____","|_____|"}, /* 2 */ | |
{"_______","|___ |"," ___ |","___| |","|_____|"}, /* 3 */ | |
{"___ ___","| |_| |","|____ |"," | |"," |_|"}, /* 4 */ | |
{"_______","| ___|","|___ |","____| |","|_____|"}, /* 5 */ | |
{" __ "," / / "," / \\","| O /"," \\___/ "}, /* 6 */ | |
{"_______","|___ |"," | |"," | |"," |_|"}, /* 7 */ | |
{"_______","| _ |","| |_| |","| |_| |","|_____|"}, /* 8 */ | |
{" ___ "," / \\ ","| O |"," \\ / "," \\__\\ "} /* 9 */ | |
}; | |
int y; | |
int divisor; | |
int digit; | |
if (score == 0) | |
number_count = 1; | |
else | |
number_count = log10(score) + 1; | |
pos = COLS/2 - ((number_count * 8) / 2); | |
for (i = 0; i < number_count; i++) { | |
y = 12; | |
divisor = pow (10, number_count-1-i); | |
digit = score / divisor; | |
score -= digit * divisor; | |
for (j = 0; j < 5; j++) { | |
mvaddstr (y, pos + (i * 8), numbers[digit][j]); | |
y++; | |
} | |
} | |
refresh(); | |
} | |
void SHFinalScore (int score) { | |
int rand_color; | |
attron (WA_BOLD); | |
mvaddstr (9, COLS/2-6, "Final score:"); | |
refresh(); | |
sleep(1); | |
for (;;) { | |
if (getch() == 'q') | |
break; | |
rand_color = 10 + ((float)rand() / (float)RAND_MAX * 6); | |
attron (WA_BOLD); | |
attron (COLOR_PAIR(rand_color)); | |
printFinalScore(score); | |
attroff (COLOR_PAIR(rand_color)); | |
attroff (WA_BOLD); | |
move (LINES-1, COLS-1); | |
refresh(); | |
} | |
attroff (WA_BOLD); | |
} | |
void santaHunta (void) { | |
int input; | |
int score = 0; | |
int last_score; | |
int gun_pos = COLS/2; | |
int count = 0; | |
int level = 1; | |
struct timeval before; | |
struct timeval after; | |
struct timeval delay; | |
int draw_loop = 0; | |
long draw_delay = 0; | |
shot shot; | |
santa santa; | |
int targets = 0; | |
int hitcount = 0; | |
scoreDisplay scoreDisplay; | |
shot.fired = 0; | |
shot.x = 0; | |
shot.y = 0; | |
scoreDisplay.rounds = 0; | |
/* Set ncurses halfdelay mode. | |
* Max resolution is 1/10sec */ | |
halfdelay (1); | |
for (;;) { | |
gettimeofday (&before, NULL); | |
input = getch(); | |
gettimeofday (&after, NULL); | |
if (after.tv_sec > before.tv_sec) | |
after.tv_usec += 1000000; | |
delay.tv_sec = 0; | |
delay.tv_usec = abs(100000 - (after.tv_usec - before.tv_usec)); | |
if (!targets) { | |
newSanta(&santa, level); | |
targets = 1; | |
} | |
/* Pad drawing resolution to 1/10sec */ | |
draw_delay += after.tv_usec - before.tv_usec; | |
if (draw_delay > 100000) { | |
draw_delay = 0; | |
draw_loop++; | |
SHClearScreen(); | |
if (targets) | |
SHDrawSanta(santa); | |
if (santa.anim == 0) | |
santa.anim = 1; | |
else | |
santa.anim = 0; | |
if (santa.x >= COLS) | |
targets = 0; | |
if (shot.fired) | |
SHDrawProjectile(shot); | |
if (scoreDisplay.rounds > 0) | |
SHDrawHitScore(scoreDisplay); | |
if (SHHit(shot, santa)) { | |
targets = 0; | |
hitcount++; | |
last_score = SHAddScore(santa); | |
score += last_score; | |
scoreDisplay.x = shot.x; | |
scoreDisplay.y = shot.y; | |
scoreDisplay.score = last_score; | |
scoreDisplay.rounds = 20; | |
} | |
santa.x += santa.speed; | |
scoreDisplay.rounds--; | |
shot.y--; | |
if (shot.y == 0) | |
shot.fired = 0; | |
if (hitcount == 10) { | |
hitcount = 0; | |
level++; | |
} | |
} | |
count++; | |
if (input == KEY_RIGHT) { | |
if (gun_pos < COLS-5) | |
gun_pos++; | |
} else if (input == KEY_LEFT) { | |
if (gun_pos > 3) | |
gun_pos--; | |
} else if (input == ' ') { | |
if (!shot.fired) { | |
attron (WA_BOLD); | |
attron (COLOR_PAIR(12)); | |
mvaddstr (LINES-4, gun_pos-2, "\\***/"); | |
attroff (COLOR_PAIR(12)); | |
attroff (WA_BOLD); | |
shot.x = gun_pos; | |
shot.y = LINES-4; | |
shot.fired = 1; | |
} | |
} else if (input == 'q') { | |
SHFinalScore(score); | |
break; | |
} | |
SHDrawGun(gun_pos); | |
SHDrawScore(score, level); | |
SHDrawStatus(); | |
refresh(); | |
} | |
/* Leave halfdelay mode. */ | |
cbreak(); | |
} | |
void initCurses (void) { | |
initscr(); | |
keypad (stdscr, TRUE); | |
cbreak(); | |
noecho(); | |
clear(); | |
curs_set(0); | |
refresh(); | |
start_color(); | |
use_default_colors(); | |
init_pair (10, 1, -1); /* red */ | |
init_pair (11, 2, -1); /* green */ | |
init_pair (12, 3, -1); /* orange */ | |
init_pair (13, 4, -1); /* blue */ | |
init_pair (14, 5, -1); /* magenta */ | |
init_pair (15, 6, -1); /* cyan */ | |
init_pair (16, 7, -1); /* gray */ | |
/* Default terminal color color pair */ | |
init_pair (63, -1, -1); | |
} | |
int main (void) { | |
initCurses(); | |
santaHunta(); | |
endwin(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment