/*
Copyright 2011, 2012 Ray Hogenson
This file is part of YetiHack.
YetiHack 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.
YetiHack 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 YetiHack. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef LINUX
#include
#endif
#ifdef WINDOWS
#include
#endif
#include "yeti.h"
using namespace std;
void osleep(int);
void endCurses();
void startCurses();
int start(bool, bool, double);
void story(bool);
bool smessage(int, string, bool);
vector turns(int);
const char* convert(int);
void menu(bool);
void help();
//void demo();
void intro();
void osleep(int miliseconds)
{
#ifdef WINDOWS
Sleep(miliseconds);
#endif
#ifdef LINUX
usleep(miliseconds * 1000);
#endif
}
void endCurses()
{
if (!isendwin())
endwin();
}
void startCurses()
{
initscr();
cbreak();
noecho();
intrflush(stdscr, false);
keypad(stdscr, true);
}
int start(bool immortal, bool story, double escapeturns)
{
int escapeturnsold = (int)escapeturns;
if (story)
{
escapeturns = turns((int)escapeturns)[1];
}
int rate;
if (story)
{
rate = turns(escapeturnsold)[0];
}
else
{
rate = escapeturns;
escapeturns = 0;
}
int x, y;
int sizex, sizey;
getmaxyx(stdscr,y,x);
sizey = y - 3;
sizex = x;
int input;
int yetinum = 1;
x = 1;
y = 1;
vector yetis;
yeti yeti1(sizex / 2, sizey / 2, sizex, sizey);
yetis.push_back(yeti1);
for (int i = 0; i < sizey; ++i)
{
for (int j = 0; j < sizex; ++j)
{
addch('.');
}
}
move(y - 1, x - 1);
addch('@');
for (int i = 0; i < yetinum; ++i)
{
move(yetis[i].ypos() - 1, yetis[i].xpos() - 1);
addch('y');
}
move(sizey, 0);
refresh();
int count = 0;
move(sizey + 1, 0);
addstr("count: 0");
while (!story || count < escapeturns)
{
input = getch();
move(y - 1, x - 1);
addch('.');
for (int i = 0; i < yetinum; ++i)
{
move(yetis[i].ypos() - 1, yetis[i].xpos() - 1);
addch('.');
}
if (input == '4' || input == KEY_LEFT)
{
--x;
}
else if (input == '7')
{
--x;
--y;
}
else if (input == '8' || input == KEY_UP)
{
--y;
}
else if (input == '9')
{
++x;
--y;
}
else if (input == '6' || input == KEY_RIGHT)
{
++x;
}
else if (input == '3')
{
++x;
++y;
}
else if (input == '2' || input == KEY_DOWN)
{
++y;
}
else if (input == '1')
{
++y;
--x;
}
++count;
// did you go off the side?
if (x < 1)
{
x = sizex;
}
if (x > sizex)
{
x = 1;
}
if (y < 1)
{
y = sizey;
}
if (y > sizey)
{
y = 1;
}
// begin yeti Ai
for(int i = 0; i < yetinum; ++i)
{
yetis[i].movetowards(x, y, yetis, i);
}
// End Yeti AI
for (int i = 0; i < yetinum; ++i)
{
if (x == yetis[i].xpos() && y == yetis[i].ypos() && !immortal)
{
if (story)
{
return 1;
}
for (int i = 0; i < yetinum; ++i)
{
move(yetis[i].ypos() - 1, yetis[i].xpos() - 1);
addch('y');
}
move(sizey, 0);
addstr("You Died!\n");
char buf[100];
for (int j = 0; j < 100; ++j)
{
buf[j] = ' ';
}
sprintf(buf, "You survived %d turns\n", count);
for(int j = 0; buf[j] != '\n'; ++j)
{
addch(buf[j]);
}
addstr("\nDo you want to play again?[y/n] ");
refresh();
char playagain = getch();
while (playagain != 'y' && playagain != 'n')
{
playagain = getch();
}
erase();
if (playagain == 'y')
{
#ifdef WINDOWS
system("cls");
#endif
return 1;
}
else
{
endCurses();
#ifdef WINDOWS
system("cls");
#endif
cout << "You survived " << count << " turns" << endl;
}
return 0;
}
}
for (int i = 0; i < yetinum; ++i)
{
move(yetis[i].ypos() - 1, yetis[i].xpos() - 1);
addch('y');
}
move(y - 1, x - 1);
addch('@');
move(sizey + 1, 7);
addstr(" ");
move(sizey + 1, 7);
addstr(convert(count));
move(sizey, 0);
addstr(" ");
move(sizey, 0);
refresh();
if (count % rate == 0)
{
move((sizey / 2) - 1,(sizex / 2) - 1);
addch('y');
move(sizey, 0);
addstr("A New Yeti Has Appeared!");
refresh();
++yetinum;
yetis.push_back(yeti1);
}
}
addstr("\nYou Escaped! Press enter to continue.");
do
{
input = getch();
} while (input != '\n');
return 0;
}
void story(bool immortal)
{
if (!smessage(1, "One day, you are ambushed by yetis!\n", immortal))
{
return;
}
if (!smessage(2, "You escaped, unfortunately, they attack again.\n", immortal))
{
return;
}
if (!smessage(3, "Now, you are attacked a third time!\n", immortal))
{
return;
}
if (!smessage(4, "There sure are a lot of yetis, because you are attacked again!\n", immortal))
{
return;
}
if (!smessage(5, "One last fight.\n", immortal))
{
return;
}
addstr("You won!!!!");
getch();
}
bool smessage(int num, string message, bool immortal)
{
char input;
int x, y;
getmaxyx(stdscr,y,x);
const char* printm = message.c_str();
addstr(printm);
addstr("You have to survive ");
addstr(convert(turns(num)[1]));
addstr(" turns\n");
addstr("Press any key to fight them...\n");
refresh();
getch();
erase();
if (start(immortal, true, num) == 1)
{
erase();
addstr("You died!");
do
{
input = getch();
} while (input != '\n');
return false;
}
erase();
return true;
}
vector turns(int num)
{
vector numbers;
int x, y;
getmaxyx(stdscr,y,x);
double turn = 100 * sqrt(num*num*num);
double rate = 10 / num;
turn = turn / 7810. * x * y;
numbers.push_back((int)rate);
numbers.push_back((int)turn);
return numbers;
}
const char* convert(int a)
{
stringstream convert;
string out;
convert << a;
convert >> out;
const char* caout = out.c_str();
return caout;
}
void menu(bool immortal)
{
int a = 100;
erase();
char input;
addstr("Welcome to yetihack!\n");
addstr("\t1. Arcade mode (classic)\n");
addstr("\t2. Story mode\n");
addstr("\t3. Help\n");
addstr("\t4. Exit\n");
addstr("Select an option to proceed: ");
refresh();
echo();
input = getch();
noecho();
int rate = 0;
switch(input)
{
case '1':
addstr("\nEnter the yeti spawn rate: ");
refresh();
echo();
input = '0';
do
{
a = a + 1;
if (input == 7)
{
int x, y;
getyx(stdscr, y, x);
move(y, 0);
addstr(" ");
move(y, 0);
addstr("Enter the yeti spawn rate: ");
rate /= 10;
if (rate != 0)
{
addstr(convert(rate));
}
refresh();
input = getch();
}
else
{
rate *= 10;
rate += input - '0';
input = getch();
}
} while (input != '\n');
noecho();
erase();
while(start(immortal, false, rate));
break;
case '2':
erase();
story(immortal);
break;
case '3':
erase();
help();
break;
case '4':
endCurses();
exit(0);
break;
}
addstr(convert(a));
}
void help()
{
addstr("To begin, choose story mode.\n");
addstr("Then, enjoy the first story prompt.\n");
addstr("You are the @.\n");
addstr("Move the @ with the number pad.\n");
addstr("Note that num lock must be on to move the @\n");
addstr("Avoid the y characters, they are yetis.\n");
addstr("New yetis will spawn every once in a while.\n");
addstr("At the beginning of each round, a message will tell you how many turns you need to survive.\n");
addstr("After that, press enter to go to the next round.\n");
addstr("Good luck.\n");
addstr("Press enter to return to the menu.\n");
refresh();
char input;
do
{
input = getch();
} while (input != '\n');
}
// stupidest thing ever. Kept to make the file bigger.
/*void demo()
{
erase();
int x, y;
getmaxyx(stdscr, y, x);
for (int xcoord = 0; xcoord < x; ++xcoord)
{
for (int ycoord = 0; ycoord < y; ++ycoord)
{
move(ycoord, xcoord);
addstr(".");
}
}
move(y / 2 - 1, 0);
addstr("@");
move(y - 1,x - 1);
refresh();
osleep(100);
for (int i = 1; i < x / 2; ++i)
{
move(y / 2 - 1, i - 1);
addstr(".");
move(y / 2 - 1, i);
addstr("@");
move(y - 1, x - 1);
refresh();
#ifdef LINUX
usleep(100000);
#endif
#ifdef WINDOWS
Sleep(100);
#endif
}
move(y / 2 - 2, x / 2 - 1);
addstr("!");
move(y - 1,x - 1);
refresh();
osleep(200);
move(y / 2 - 1, x - 1);
addstr("y");
move(y - 1, x - 1);
refresh();
osleep(100);
move(y / 2 - 2, x / 2 - 1);
addstr(".");
for (int i = x - 1; i >= 0; --i)
{
if (i - (x / 2) + 1 >= 0)
{
move(y / 2 - 1, i - (x / 2) + 1);
}
else
{
move(y / 2 - 1, x + (i - (x / 2) + 1));
}
addstr(".");
if (i - (x /2) >= 0)
{
move(y / 2 - 1, i - (x / 2));
}
else
{
move(y / 2 - 1, x + (i - (x / 2)));
}
addstr("@");
move(y / 2 - 1, i + 1);
addstr(".");
move(y / 2 - 1, i);
addstr("y");
move(y - 1, x - 1);
refresh();
osleep(100);
}
}*/
void intro()
{
int x, y;
getmaxyx(stdscr, y, x);
vector dummy;
int xtemp[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 6, 6, 6, 6, // y
9, 9, 9, 9, 9, 10,10,10,11,11,11, // e
14,15,15,15,15,15,16, // t
19,19,20,20,20,20,20,21,21, // i
24,24,24,24,24,25,26,26,26,26,26, // h
29,29,29,29,30,30,31,31,32,32,32,32, // a
35,35,35,35,35,36,36,37,37, // c
40,40,40,40,40,41,42,42,43,43}; // k
int ytemp[] = { 0, 1, 2, 3, 0, 1, 2, 3, 2, 3, 4, 5, 6,
7, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 0,
1, 2, 3, 0, 1, 2, 3, // y
3, 4, 5, 6, 7, 3, 5, 7, 3, 3, 7, // e
3, 3, 4, 5, 6, 7, 3, // t
3, 7, 3, 4, 5, 6, 7, 3, 7, // i
3, 4, 5, 6, 7, 5, 3, 4, 5, 6, 7, // h
4, 5, 6, 7, 3, 5, 3, 5, 4, 5, 6, 7, // a
3, 4, 5, 6, 7, 3, 7, 3, 7, // c
3, 4, 5, 6, 7, 5, 4, 6, 3, 7}; // k
int numyetis = 102;
vector xs;
for (int i = 0; i < numyetis; ++i)
{
xs.push_back(xtemp[i]);
}
for (int i = 0; i < numyetis; ++i)
{
xs[i] += x / 2 - 21;
}
vector ys;
for (int i = 0; i < numyetis; ++i)
{
ys.push_back(ytemp[i]);
}
for (int i = 0; i < numyetis; ++i)
{
ys[i] += y / 2 - 3;
}
vector yetis;
int version = rand() % 2;
for (int i = 0; i < numyetis; ++i)
{
yeti yeti1(rand() % x + 1, rand() % y + 1, x, y);
if (version == 0)
{
yeti1.setx(x / 2 + 1);
yeti1.sety(y / 2 + 1);
}
yetis.push_back(yeti1);
}
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
addch('.');
}
}
refresh();
timeout(0);
bool done = false;
bool reallydone = false;
for (int movenum = 0; !done && !reallydone; ++movenum)
{
for (int numyeti = 0; numyeti < numyetis; ++numyeti)
{
move(yetis[numyeti].ypos() - 1,yetis[numyeti].xpos() - 1);
addch('.');
yetis[numyeti].movetowards(xs[numyeti] + 1,ys[numyeti] + 1,dummy,0);
move(yetis[numyeti].ypos() - 1,yetis[numyeti].xpos() - 1);
addch('y');
}
osleep(70);
refresh();
done = true;
for (int numyeti = 0; numyeti < numyetis && done; ++numyeti)
{
if (yetis[numyeti].xpos() - 1 != xs[numyeti])
done = false;
if (yetis[numyeti].ypos() - 1 != ys[numyeti])
done = false;
}
char input = getch();
if (input != ERR)
{
reallydone = true;
}
}
timeout(-1);
if (!reallydone)
osleep(2000);
}
int main(int argc, char* argv[])
{
/*startCurses();
while (true)
{
char input = getch();
int a = input;
addstr(convert(a));
}*/
srand(time(0));
startCurses();
intro();
bool immortal = false;
if (argc > 1 && strcmp(argv[1],"-c") == 0)
{
immortal = true;
}
while(true)
{
menu(immortal);
}
return 0;
}