aboutsummaryrefslogtreecommitdiffstats
path: root/src/yetihack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yetihack.cpp')
-rw-r--r--src/yetihack.cpp646
1 files changed, 646 insertions, 0 deletions
diff --git a/src/yetihack.cpp b/src/yetihack.cpp
new file mode 100644
index 0000000..129d759
--- /dev/null
+++ b/src/yetihack.cpp
@@ -0,0 +1,646 @@
+/*
+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 <http://www.gnu.org/licenses/>.
+*/
+#include <iostream>
+#include <curses.h>
+#include <cstdlib>
+#include <ctime>
+#include <vector>
+#include <cstring>
+#include <fstream>
+#include <sstream>
+#include <cmath>
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+ #include <windows.h>
+#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<int> turns(int);
+const char* convert(int);
+void menu(bool);
+void help();
+//void demo();
+void intro();
+
+void osleep(int miliseconds)
+{
+ #ifdef HAVE_WINDOWS_H
+ Sleep(miliseconds);
+ #endif
+ #ifdef HAVE_UNISTD_H
+ 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<yeti> 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, "Are you having fun yet?\n", immortal))
+ {
+ return;
+ }
+ if (!smessage(6, "This is the last level.\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<int> turns(int num)
+{
+ vector<int> 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<yeti> 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<int> 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<int> 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<yeti> 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;
+}
+