This repository has been archived by the owner on Mar 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
216 lines (194 loc) · 7.53 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/******************************************************
** Program: main.cpp
** Author: Nils Streedain
** Date: 11/21/2021
** Description: Main driver file for hunt the wumpus.
** Input: Command Line Arguments to specify size & debug mode
** Output: The game will be output to the command line interface.
******************************************************/
#include <iostream>
#include <stdlib.h>
#include <stdexcept>
#include <ncurses.h>
#include <string.h>
#include "cave.h"
/*********************************************************************
** Function: verifySizeArgument()
** Description: Function to make sure the command line argument for size is correct & then return it as an int.
** Parameters: char *size
** Pre-Conditions: size must be provided
** Post-Conditions: the size will be returned as an int if valid
*********************************************************************/
int verifySizeArgument(char *size) {
// If size argument is left empty, an exception is thrown.
if (size == NULL)
throw std::invalid_argument("No size provided.");
// If the size is not a valid int or larger than 3, an exception is thrown.
if (!(std::atoi(size) > 3))
throw std::invalid_argument("Size must be larger than 3");
return atoi(size);
}
/*********************************************************************
** Function: verifyDebugArgument()
** Description: Function to make sure the debug is correct & then return it as a bool.
** Parameters: char *debugMode
** Pre-Conditions: debugMode must be provided
** Post-Conditions: the debugMode will be returned as a bool iif valid
*********************************************************************/
bool verifyDebugArgument(char *debugMode) {
// If debug argument is left empty, an exception is thrown.
if (debugMode == NULL)
throw std::invalid_argument("No debug mode provided.");
// If debug argument is true, true is returned. If false, false is returned.
if (!strcmp(debugMode, "true"))
return true;
else if (!strcmp(debugMode, "false"))
return false;
// If debug argument is anything else, an exception is thrown.
throw std::invalid_argument("Invalid debug mode argument.");
}
/*********************************************************************
** Function: getUserInput()
** Description: Fuction for getting a singly character input from the user without enter needing to be pressed.
** Parameters: std::string inputMessage
** Pre-Conditions: inputMessage may be provided
** Post-Conditions: the user input character will be returned
*********************************************************************/
char getUserInput(std::string inputMessage) {
std::cout << inputMessage << std::endl;
// Sets command line input to retrieve a single char without enter being pressed
system("stty raw");
char input = getchar();
system("stty cooked");
std::cout << "\x1B[2J\x1B[H";
std::cout << std::endl;
return input;
}
/*********************************************************************
** Function: fireArrow()
** Description: Fuction to allow the user to select which direction to fire an arrow towards
** Parameters: Cave *cave
** Pre-Conditions: cave must be provided
** Post-Conditions: an arrow will be fired in the direction specified
*********************************************************************/
void fireArrow(Cave *cave, bool debugMode) {
cave->print(debugMode);
switch (getUserInput("\nPress a key to fire an arrow: (W) North, (A) West, (S) South, (D) East")) {
case 'w':
cave->arrowUp();
break;
case 'a':
cave->arrowLeft();
break;
case 's':
cave->arrowDown();
break;
case 'd':
cave->arrowRight();
break;
default:
fireArrow(cave, debugMode);
break;
}
}
/*********************************************************************
** Function: chooseMove()
** Description: Fuction to allow the user to select which move to make for the turn
** Parameters: Cave *cave, int numArrows
** Pre-Conditions: cave & numArrows must be provided
** Post-Conditions: the move will be made and if applicable, the number of arrows will be reduced and returned.
*********************************************************************/
int chooseMove(Cave *cave, int numArrows, bool debugMode) {
switch (getUserInput("Press a key to move: (W) Up, (A) Left, (S) Down, (D) Right, ( ) Fire Arrow")) {
case 'w':
cave->moveUp();
break;
case 'a':
cave->moveLeft();
break;
case 's':
cave->moveDown();
break;
case 'd':
cave->moveRight();
break;
case ' ':
if (numArrows > 0) {
numArrows--;
fireArrow(cave, debugMode);
}
break;
default:
break;
}
return numArrows;
}
/*********************************************************************
** Function: printGameStatus()
** Description: Fuction to print the status of the wumpus, number of arrows left & the gold collection state
** Parameters: Cave *cave, int numArrows
** Pre-Conditions: cave & numArrows must be provided
** Post-Conditions: the function will print the state of the wumpus, number of arrows left & the gold collection state
*********************************************************************/
void printGameStatus(Cave *cave, int numArrows) {
std::cout << "You have ";
if (!cave->isWumpusAlive())
std::cout << "killed the Wumpus and have ";
else if (numArrows > 0)
std::cout << numArrows << " arrows left and have ";
if (cave->isGoldCollected())
std::cout << "collected the gold!" << std::endl;
else
std::cout << "not collected the gold." << std::endl;
}
/*********************************************************************
** Function: newGame()
** Description: Fuction start and manage a new game
** Parameters: Cave *cave, bool debugMode
** Pre-Conditions: cave & debugMode must be provided
** Post-Conditions: the function will start the game based on the cave & debug mode and return when the game hass ended
*********************************************************************/
void newGame(int size, int seed, bool debugMode) {
int numArrows = 3;
Cave cave(size, seed);
// While the game is not over, the game state will be printed and the user will be asked to make a move
while (!cave.isGameOver()) {
// Print out user interface & have user choose move.
cave.print(debugMode);
cave.percepts();
printGameStatus(&cave, numArrows);
numArrows = chooseMove(&cave, numArrows, debugMode);
// Run encounter
cave.encounter();
}
}
/*********************************************************************
** Function: main()
** Description: Main driver function for hunt the wumpus
** Parameters: command line arguments for size and debugMode
** Pre-Conditions: size & debugMode must be provided
** Post-Conditions: The function will create a cave and start a game, then ask the user what to do when the game has ended.
*********************************************************************/
int main(int argc, const char * argv[]) {
int size = verifySizeArgument((char*)argv[1]);
bool debugMode = verifyDebugArgument((char*)argv[2]);
srand(static_cast<unsigned int>(time(0)));
int seed = rand();
// Creates a cave for the game to use
// Starts a game based on that cave
std::cout << "\x1B[2J\x1B[H";
newGame(size, seed, debugMode);
char input;
do {
// Gets user input on what to do when the game has ended.
input = getUserInput("Select Game: (1) Same Cave, (2) New Cave, (3) End Game");
// Determines what to do based on the input
if (input == '1') {
newGame(size, seed, debugMode);
} else if (input == '2') {
seed = rand();
newGame(size, seed, debugMode);
}
} while (input == '1' || input == '2');
return 0;
}