ACSSE CSC01B1 2024 P1 Solution
ACSSE CSC01B1 2024 P1 Solution
h"
2
3 #include <cstdlib>
4 #include <ctime>
5 #include <iostream>
6
7 using namespace std;
8 using namespace CrawlerSpace;
9
10 int main(int argc, char** argv)
11 {
12 srand(time(nullptr));
13 if(argc != 6){
14 cerr << "Incorrect number of arguments." << endl;
15 exit(ERROR_ARG_COUNT);
16 }
17 int intRows = convToInt(argv[1]);
18 int intCols = convToInt(argv[2]);
19 int intNumMonsters = convToInt(argv[3]);
20 int intNumItems = convToInt(argv[4]);
21 int intNumObstacles = convToInt(argv[5]);
22
23 GameWorld* recWorld = initWorld(intRows, intCols, intNumMonsters, intNumItems,
intNumObstacles);
24
25 bool blnContinue = true;
26 char chOption = '\0';
27 do{
28 system("cls");
29 recWorld->displayWorld(recWorld);
30 cin >> chOption;
31 switch(tolower(chOption)){
32 case 'y':
33 {
34 blnContinue = false;
35 break;
36 }
37 case 'w':
38 {
39 recWorld->performAction(recWorld, UP);
40 break;
41 }
42 case 's':
43 {
44 recWorld->performAction(recWorld, DOWN);
45 break;
46 }
47 case 'a':
48 {
49 recWorld->performAction(recWorld, LEFT);
50 break;
51 }
52 case 'd':
53 {
54 recWorld->performAction(recWorld, RIGHT);
55 break;
56 }
57 case 'q':
58 {
59 recWorld->performAction(recWorld, UP_LEFT);
60 break;
61 }
62 case 'e':
63 {
64 recWorld->performAction(recWorld, UP_RIGHT);
65 break;
66 }
67 case 'z':
68 {
69 recWorld->performAction(recWorld, DOWN_LEFT);
70 break;
71 }
72 case 'x':
73 {
74 recWorld->performAction(recWorld, DOWN_RIGHT);
75 break;
76 }
77 case 'c':
78 {
79 recWorld->performAction(recWorld, ATTACK_MONSTER);
80 break;
81 }
82 default:
83 {
84 cerr << "Invalid input." << endl;
85 system("pause");
86 }
87 }
88 }while(blnContinue && recWorld->eState == ONGOING);
89
90 if(!blnContinue){
91 cout << "Goodbye!" << endl;
92 }else if(recWorld->eState == WON){
93 cout << "YOU WIN!" << endl;
94 }else if(recWorld->eState == LOST){
95 cout << "YOU LOSE!" << endl;
96 }
97 return SUCCESS;
98 }
1 #ifndef LIBCRAWLER_H
2 #define LIBCRAWLER_H
3
4 #include <string>
5
6 namespace CrawlerSpace{
7 enum GameState{
8 ONGOING,
9 WON,
10 LOST
11 };
12
13 enum StatusCode{
14 ERROR_RANGE = -3,
15 ERROR_CONV,
16 ERROR_ARG_COUNT,
17 SUCCESS
18 };
19
20 enum Action{
21 UP,
22 DOWN,
23 LEFT,
24 RIGHT,
25 UP_RIGHT,
26 UP_LEFT,
27 DOWN_RIGHT,
28 DOWN_LEFT,
29 ATTACK_MONSTER
30 };
31
32 enum Entity{
33 EMPTY_SPACE,
34 ENERGY_FIELD,
35 WALL,
36 EXIT,
37 PLAYER,
38 MONSTER
39 };
40
41 const char ARR_ENTITIES[9] = {' ', 'T', '#', 'E', 'P', 'M', 'M', 'M', 'M'};
42
43 typedef int* OneDimArray;
44 typedef OneDimArray* TwoDimArray;
45
46 struct GameWorld{
47 TwoDimArray arrWorld;
48 GameState eState;
49 int intRows;
50 int intCols;
51 int intPRow;
52 int intPCol;
53 int intNumItemsWithPlayer;
54 int intNumMonstersInWorld;
55
56 /*
57 * Behaviour/functionality
58 */
59 void (*displayWorld)(GameWorld* recWorld);
60 void (*performAction)(GameWorld* recWorld, Action eAction);
61 };
62
63 GameWorld* initWorld(int intRows, int intCols, int intNumMonsters, int
intNumItems, int intNumObstacles);
64 void destroyWorld(GameWorld& recWorld);
65
66 // Utility Functions
67 int convToInt(std::string strArg);
68 int rangedRandom(int intLB, int intUB);
69 //void updateWorld(GameWorld recWorld);
70 }
71
72 #endif // LIBCRAWLER_H
1 #include "LibCrawler.h"
2
3 #include <iostream>
4 #include <sstream>
5
6 using namespace std;
7
8 namespace CrawlerSpace{
9 TwoDimArray alloc(int intRows, int intCols){
10 TwoDimArray arrWorld = new OneDimArray[intRows];
11 for(int r = 0; r < intRows; r++){
12 arrWorld[r] = new int[intCols];
13 for(int c = 0; c < intCols; c++){
14 arrWorld[r][c] = EMPTY_SPACE;
15 }
16 }
17 return arrWorld;
18 }
19
20 void placeEntity(GameWorld* recWorld, Entity eEntity, int intCount){
21 if(eEntity == EXIT){
22 int intCol = recWorld->intCols - 1;
23 int intRow = rangedRandom(0, recWorld->intRows - 1);
24 while(recWorld->arrWorld[intRow][intCol] != EMPTY_SPACE){
25 intRow = rangedRandom(0, recWorld->intRows - 1);
26 }
27 recWorld->arrWorld[intRow][intCol] = eEntity;
28 }else if(eEntity == PLAYER){
29 int intCol = 0;
30 int intRow = rangedRandom(0, recWorld->intRows - 1);
31 while(recWorld->arrWorld[intRow][intCol] != EMPTY_SPACE){
32 intRow = rangedRandom(0, recWorld->intRows - 1);
33 }
34 recWorld->arrWorld[intRow][intCol] = eEntity;
35 recWorld->intPRow = intRow;
36 recWorld->intPCol = intCol;
37 }else{
38 for(int i = 0; i < intCount; i++){
39 int intRow = rangedRandom(0, recWorld->intRows - 1);
40 int intCol = rangedRandom(0, recWorld->intCols - 1);
41 while(recWorld->arrWorld[intRow][intCol] != EMPTY_SPACE){
42 intRow = rangedRandom(0, recWorld->intRows - 1);
43 intCol = rangedRandom(0, recWorld->intCols - 1);
44 }
45 recWorld->arrWorld[intRow][intCol] = eEntity;
46 }
47 }
48 }
49
50 void displayWorldImpl(GameWorld* recWorld){
51 for(int r = 0; r < recWorld->intRows; r++){
52 for(int c = 0; c < recWorld->intCols; c++){
53 cout << ARR_ENTITIES[recWorld->arrWorld[r][c]] << ' ';
54 }
55 cout << endl;
56 }
57 cout << "Energy Field Units: " << recWorld->intNumItemsWithPlayer * 5 <<
endl
58 << "Monsters Remaining: " << recWorld->intNumMonstersInWorld << endl
59 << "Movement: W, S, A, D, Q, E, Z, X" << endl
60 << "Attack Monsters: C" << endl;
61 }
62
63 void attackMonsters(GameWorld* recWorld){
64 for(int r = recWorld->intPRow - 1; r <= recWorld->intPRow + 1; r++){
65 for(int c = recWorld->intPCol - 1; c <= recWorld->intPCol + 1; c++){
66 if(recWorld->arrWorld[r][c] == MONSTER){
67 recWorld->arrWorld[r][c] = EMPTY_SPACE;
68 recWorld->intNumMonstersInWorld--;
69 }
70 }
71 }
72 }
73
74 bool isInWorld(GameWorld* recWorld, int intRow, int intCol){
75 if(intRow < 0)
76 return false;
77 if(intRow >= recWorld->intRows)
78 return false;
79 if(intCol < 0)
80 return false;
81 if(intCol >= recWorld->intCols)
82 return false;
83 return true;
84 }
85
86 void performActionImpl(GameWorld* recWorld, Action eAction){
87 int intDRow = recWorld->intPRow;
88 int intDCol = recWorld->intPCol;
89 bool blnMoved = true;
90 switch(eAction){
91 case UP:
92 {
93 intDRow--;
94 break;
95 }
96 case DOWN:
97 {
98 intDRow++;
99 break;
100 }
101 case LEFT:
102 {
103 intDCol--;
104 break;
105 }
106 case RIGHT:
107 {
108 intDCol++;
109 break;
110 }
111 case UP_LEFT:
112 {
113 intDRow--;
114 intDCol--;
115 break;
116 }
117 case UP_RIGHT:
118 {
119 intDRow--;
120 intDCol++;
121 break;
122 }
123 case DOWN_LEFT:
124 {
125 intDRow++;
126 intDCol--;
127 break;
128 }
129 case DOWN_RIGHT:
130 {
131 intDRow++;
132 intDCol++;
133 break;
134 }
135 case ATTACK_MONSTER:
136 {
137 blnMoved = false;
138 if(recWorld->intNumItemsWithPlayer > 0){
139 recWorld->intNumItemsWithPlayer--;
140 attackMonsters(recWorld);
141 if(recWorld->intNumMonstersInWorld == 0){
142 if(recWorld->intNumMonstersInWorld > 0){
143 recWorld->eState = LOST;
144 }else{
145 placeEntity(recWorld, EXIT, 1);
146 }
147 }
148 }
149 break;
150 }
151 }
152 if(blnMoved
153 && isInWorld(recWorld, intDRow, intDCol)
154 && recWorld->arrWorld[intDRow][intDCol] != WALL){
155 if(recWorld->arrWorld[intDRow][intDCol] == ENERGY_FIELD){
156 recWorld->intNumItemsWithPlayer++;
157 }else if(recWorld->arrWorld[intDRow][intDCol] == MONSTER){
158 recWorld->eState = LOST;
159 }else if (recWorld->arrWorld[intDRow][intDCol] == EXIT){
160 recWorld->eState = WON;
161 }
162 recWorld->arrWorld[intDRow][intDCol] = PLAYER;
163 recWorld->arrWorld[recWorld->intPRow][recWorld->intPCol] = EMPTY_SPACE;
164 recWorld->intPRow = intDRow;
165 recWorld->intPCol = intDCol;
166 }
167
168 }
169
170 GameWorld* initWorld(int intRows, int intCols, int intNumMonsters, int
intNumItems, int intNumObstacles){
171 GameWorld* recWorld = new GameWorld;;
172 recWorld->arrWorld = alloc(intRows, intCols);
173 recWorld->intRows = intRows;
174 recWorld->intCols = intCols;
175 recWorld->eState = ONGOING;
176 recWorld->intNumItemsWithPlayer = 0;
177 recWorld->intNumMonstersInWorld = intNumMonsters;
178 placeEntity(recWorld, ENERGY_FIELD, intNumItems);
179 placeEntity(recWorld, WALL, intNumObstacles);
180 placeEntity(recWorld, MONSTER, intNumMonsters);
181 placeEntity(recWorld, PLAYER, 1);
182 // Function Pointer
183 recWorld->displayWorld = &displayWorldImpl;
184 recWorld->performAction = &performActionImpl;
185 return recWorld;
186 }
187
188 void destroyWorld(GameWorld& recWorld){
189 for(int r = 0; r < recWorld.intRows; r++)
190 delete [] recWorld.arrWorld[r];
191 delete [] recWorld.arrWorld;
192 recWorld.arrWorld = nullptr;
193 }
194
195 int convToInt(string strArg){
196 stringstream ssConv(strArg);
197 int intResult = 0;
198 ssConv >> intResult;
199 if(ssConv.fail()){
200 cerr << "Could not convert " << intResult << "." << endl;
201 exit(ERROR_CONV);
202 }
203 return intResult;
204 }
205
206
207 int rangedRandom(int intLB, int intUB){
208 return rand() % (intUB - intLB + 1) + intLB;
209 }
210
211 }