Skip to content

Instantly share code, notes, and snippets.

@kdrnic
Last active June 22, 2017 00:26
Show Gist options
  • Save kdrnic/e36fa5fad04de197104ea1baafa1d5cd to your computer and use it in GitHub Desktop.
Save kdrnic/e36fa5fad04de197104ea1baafa1d5cd to your computer and use it in GitHub Desktop.
//MIT License
//
//Copyright (c) [2016] kdrnic ( website: kdrnic.xyz )
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
// Compile with:
// gcc stacker.c -o stacker.exe -lncurses
#include <ncurses.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#define G_COLS 7
#define G_ROWS 15
#define G_CLR ((80/2)-G_COLS)
#define H_POS 36
#define V_POS 4
#define P_SIZE 3
#define TRIANGLE(a,b) abs(((a) % (2 * (b))) - (b))
#define DRAW_GAREA(R) for(c = 0; c < G_COLS; c++){ \
for(r = R; r < G_ROWS; r++){ \
if(gArea[c + r * G_COLS]) attron(A_REVERSE); \
mvaddch(r + V_POS, H_POS + c, ' '); \
attroff(A_REVERSE); \
} \
}
char gArea[G_COLS * G_ROWS];
void Enbox(){
attron(COLOR_PAIR(2));
for(int r = -1; r < G_ROWS + 1; r++){
switch(r){
case -1:
case G_ROWS:
move(r + V_POS, H_POS - G_CLR);
for(int c = 0; c < G_COLS + G_CLR * 2; c++) addch(' ');
break;
default:
move(r + V_POS, H_POS - G_CLR);
for(int c = 0; c < G_CLR; c++) addch(' ');
move(r + V_POS, H_POS + G_COLS);
for(int c = 0; c < G_CLR; c++) addch(' ');
}
}
attroff(COLOR_PAIR(2));
}
int main(void){
srand(time(0));
initscr();
cbreak();
keypad(stdscr, TRUE);
start_color();
init_pair(2, COLOR_RED, COLOR_RED);
noecho();
int counter = 0;
int c,r;
int ch;
int pRow, pSize;
modeAttract:
timeout(40);
while(TRUE){
counter++;
erase();
mvaddstr(V_POS + 0, TRIANGLE(counter, 4 + G_COLS - 1) - 4 + H_POS, "PRESS");
mvaddstr(V_POS + 1, TRIANGLE(counter, G_COLS - 1) + H_POS, "P");
mvaddstr(V_POS + 2, TRIANGLE(counter, 1 + G_COLS - 1) - 1 + H_POS, "TO");
mvaddstr(V_POS + 3, TRIANGLE(counter, 3 + G_COLS - 1) - 3 + H_POS, "PLAY");
for(c = 0; c < G_COLS; c += 2){
int height = floor((sin((float)(counter + c) * 0.3) + 1.0) * 0.5 * (float)(G_ROWS - 3));
for(r = G_ROWS - height; r < G_ROWS; r++){
mvaddch(r + V_POS, H_POS + c, ' ' | A_REVERSE);
}
}
Enbox();
ch = tolower(getch());
if(ch == 'q') goto modeNo;
if(ch == 'p'){
memset(gArea, 0, sizeof(gArea));
pRow = G_ROWS - 1;
pSize = P_SIZE;
goto modePlace;
}
refresh();
}
modePlace:
timeout(60);
do{
counter = rand() % 999;
c = TRIANGLE(counter, pSize + G_COLS - 1) - pSize;
}
while((c < 0 - pSize) || (c > G_COLS - 1));
while(TRUE){
erase();
int pCol = TRIANGLE(counter, pSize + G_COLS - 1) - pSize;
move(V_POS + pRow, H_POS + pCol);
attron(A_REVERSE);
for(c = 0; c < pSize; c++) addch(' ');
attroff(A_REVERSE);
DRAW_GAREA(pRow + 1);
counter++;
Enbox();
ch = tolower(getch());
if(ch == 'q') goto modeGameOver;
if(ch == 'z'){
int newSize = 0;
for(c = pCol; c < pCol + pSize; c++){
if(c < 0) continue;
if(c >= G_COLS) continue;
gArea[c + pRow * G_COLS] = TRUE;
if(pRow < G_ROWS - 1){
if(gArea[c + (pRow + 1) * G_COLS]) newSize++;
}
else newSize++;
}
pSize = newSize;
if(pSize > 0){
pRow--;
if(pRow < 0) goto modeVictory;
goto modeFalling;
}
else goto modeGameOver;
}
refresh();
}
modeFalling:
timeout(0);
while(getch() != ERR) continue;
timeout(500);
for(int _r = 0; _r < G_ROWS - 1; _r++){
erase();
DRAW_GAREA(0);
Enbox();
int doGetch = 0;
for(c = 0; c < G_COLS; c++){
if(gArea[c + _r * G_COLS]){
if(!gArea[c + (_r + 1) * G_COLS]){
gArea[c + _r * G_COLS] = 0;
gArea[c + (_r + 1) * G_COLS] = TRUE;
doGetch = 1;
}
}
}
if(doGetch) getch();
}
goto modePlace;
modeVictory:
timeout(40);
counter = 0;
while(TRUE){
counter++;
erase();
DRAW_GAREA(0);
if((counter / 30) % 2){
mvaddstr(V_POS + G_ROWS - 2, TRIANGLE(counter, 2 + G_COLS - 1) - 2 + H_POS, "YOU");
mvaddstr(V_POS + G_ROWS - 1, TRIANGLE(counter + 3, 2 + G_COLS - 1) - 2 + H_POS, "WIN");
}
else{
mvaddstr(V_POS + G_ROWS - 2, TRIANGLE(counter, 4 + G_COLS - 1) - 4 + H_POS, "PRESS");
mvaddstr(V_POS + G_ROWS - 1, TRIANGLE(counter, G_COLS - 1) + H_POS, "R");
}
Enbox();
ch = tolower(getch());
if(ch == 'q') goto modeNo;
if(ch == 'r') goto modeAttract;
refresh();
}
modeGameOver:
timeout(40);
counter = 0;
while(TRUE){
counter++;
erase();
DRAW_GAREA(4);
mvaddstr(V_POS + 0, TRIANGLE(counter, 3 + G_COLS - 1) - 3 + H_POS, "GAME");
mvaddstr(V_POS + 1, TRIANGLE(counter + 3, 3 + G_COLS - 1) - 3 + H_POS, "OVER");
mvaddstr(V_POS + 2, TRIANGLE(counter, 4 + G_COLS - 1) - 4 + H_POS, "PRESS");
mvaddstr(V_POS + 3, TRIANGLE(counter, G_COLS - 1) + H_POS, "R");
if(counter > 60){
gArea[(rand() % G_COLS) + (rand() % G_ROWS) * G_COLS] = TRUE;
gArea[(rand() % G_COLS) + (rand() % G_ROWS) * G_COLS] = 0;
}
Enbox();
ch = tolower(getch());
if(ch == 'q') goto modeNo;
if(ch == 'r') goto modeAttract;
refresh();
}
modeNo:
endwin();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment