/* 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 #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_WINDOWS_H #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 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 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 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; }