#include #include #include #include #include #include "Cave.h" #include "CaveMaze.h" #include "Die.h" using namespace std; CaveMaze::CaveMaze(string filename) // Constructor: creates a cave maze -- caves are added for each entry in the // specified file, the number of wumpi and grades is selected, and the // wumpi, pit, and bats are randomly placed in the maze. { ifstream myin(filename.c_str()); assert(myin); int numCaves; myin >> numCaves; caves.resize(numCaves); string name; int num, left, straight, right; while (myin >> num >> left >> straight >> right && getline(myin, name)) { Cave c(num, name, left, straight, right); caves[num] = c; } currentLoc = 0; caves[currentLoc].MarkAsVisited(); Die d(caves.size()/4); numWumpi = d.Roll(); numGrenades = 4*numWumpi; caves[currentLoc].SetContents(WUMPUS); for (int i = 0; i < numWumpi; i++) { caves[FindEmpty()].SetContents(WUMPUS); } caves[FindEmpty()].SetContents(BATS); caves[FindEmpty()].SetContents(PIT); caves[currentLoc].SetContents(EMPTY); } void CaveMaze::Move(int tunnel) // Results: moves to the cave connected by the specified tunnel // if new cave contains WUMPUS or PIT, then killed // if new cave contains BATS, then moved at random { currentLoc = caves[currentLoc].GetAdjacent(tunnel); caves[currentLoc].MarkAsVisited(); CaveContents room = caves[currentLoc].GetContents(); if (room == WUMPUS) { cout << "You have entered the Wumpus' lair... CHOMP CHOMP CHOMP" << endl; alive = false; } else if (room == PIT) { cout << "Look out for the bottomless pit... AAAAAiiiiiiyyyeeeeeeee" << endl; alive = false; } else if (room == BATS) { cout << "A swarm of giant bats picks you up and flies away." << endl; currentLoc = FindEmpty(); caves[currentLoc].MarkAsVisited(); } } void CaveMaze::Toss(int tunnel) // Results: tosses a grenade into the cave connected by the specified tunnel // if a WUMPUS is in that cave, it is killed // any adjacent wumpi pick a random tunnel and move (if empty) { if (numGrenades == 0) { cout << "You have no grenades to throw!" << endl; } else { numGrenades--; int target = caves[currentLoc].GetAdjacent(tunnel); if (caves[target].GetContents() == WUMPUS) { cout << "Got that sucker!" << endl; numWumpi--; caves[target].SetContents(EMPTY); if (numWumpi == 0) { cout << "And that was the last one." << endl; } } else { cout << "Missed, dagnabit!" << endl; } if (numWumpi > 0) { MoveAdjacentWumpi(); } } } void CaveMaze::ShowLocation() const // Results: shows the current location in the maze (current cave and adjacent caves, // if previously visited), with possible warnings based on feel/smell/sound { cout << endl << "You are currently in " << caves[currentLoc].GetCaveName() << endl; for (int i = 1; i <= 3; i++) { cout << " (" << i << ") " << caves[caves[currentLoc].GetAdjacent(i)].GetCaveName() << endl; } if (AdjacentTo(PIT)) { cout << "You feel a draft coming from one of the tunnels." << endl; } if (AdjacentTo(WUMPUS)) { cout << "You smell an awful stench coming from somewhere nearby." << endl; } if (AdjacentTo(BATS)) { cout << "You hear the flapping of wings close by." << endl; } } bool CaveMaze::StillAlive() const //Returns: whether still alive { return alive; } bool CaveMaze::StillWumpi() const // Returns: whether any wumpi remain { return (numWumpi > 0); } int CaveMaze::FindEmpty() const // Returns: the location of a random, empty cave { Die d(caves.size()); int loc = d.Roll()-1; while (caves[loc].GetContents() != EMPTY) { loc = d.Roll()-1; } return loc; } void CaveMaze::MoveAdjacentWumpi() // Results: any wumpi adjacent to the current cave pick a random tunnel and move there if empty, // possibly killing the player { cout << "DANGER: any nearby wumpi are on the move." << endl; Die d3(3); for (int i = 1; i <= 3; i++) { int adjLoc = caves[currentLoc].GetAdjacent(i); if (caves[adjLoc].GetContents() == WUMPUS) { int moveLoc = caves[adjLoc].GetAdjacent(d3.Roll()); if (caves[moveLoc].GetContents() == EMPTY) { caves[adjLoc].SetContents(EMPTY); caves[moveLoc].SetContents(WUMPUS); } } } if (caves[currentLoc].GetContents() == WUMPUS) { cout << "A wumpus is coming toward you with big, gnarly teeth..." << " CHOMP CHOMP CHOMP" << endl; alive = false; } } bool CaveMaze::AdjacentTo(CaveContents room) const // Returns: whether an adjacent cave contains room { return (caves[caves[currentLoc].GetAdjacent(1)].GetContents() == room || caves[caves[currentLoc].GetAdjacent(2)].GetContents() == room || caves[caves[currentLoc].GetAdjacent(3)].GetContents() == room); }