In: Computer Science
In this lab, you will practice the use of array by building an simple maze game, where your task is to control the prince to defeat the monster and save Snow White. You have to work based on the given skeleton code.
Game Description
The Snow White is detained in the maze by the monster, who needs the prince's help to rescure her out from the exit.
The pre-set maze is shown below, with width 11 and height 8. The maze is saved in 1D array in main().
### ###### #P ###### ### # # # # # # W # # # # # ## M # ## ###S #E#
The symbol '#' represents a wall, 'P' is the prince player, 'S' is Snow White, 'M' is the monster, 'W' is the weapon, and 'E' is the exit. Locations of the prince and monster ares stored in an array {x, y}, where x defines column number, y defines row number in main(). Prince 'P' and monster 'M' can only move one step for each move.
The top left of the maze is with coordinates (0,0). The x-coordinate goes positive to the right and y-coordinate goes positive to the bottom. For example, initially the prince 'P' is at coordinate (1,1), the monster 'M' is at coordinate (3,6), and exit 'E' is at coordinate (9, 7). The ascii maze allows the user to input movement (e.g. 'a' left, 'w' up, 'd' right, and 's' down) to control prince 'P'. The monster 'M' is repetitively walking back and forth along the next-to-last line.
When the monster 'M' and prince 'P' can see each other, which means they are in the same line or column, and there is no blocking wall '#' in that straight line/column connecting them, prince 'P' will fight with the monster 'M'. If the weapon 'W' has been fetched by the prince, the monster will be killed and 'M' will disappear from the maze. If not, the prince will be caught and game over.
How to fetch the weapon 'W': The weapon 'W' can be fetched only when the prince 'P' reaches its location. Then, 'W' will disappear from the maze.
How to save Snow White 'S': The Snow White 'S' can be saved only when the prince 'P' reaches its location ('S' will also disappear from the maze after 'P' reaches its location) and take it out from the exit 'E'.
Rules: If the player's movement hits the wall, goes beyond the maze boundary, doesn't fall to the four movement directions or caught by the monster, the prince will be killed and game over. Only when the prince reaches to the exit 'E' after saving Snow White 'S', he wins and game ends.
Hint:
1. We store the status of the monster, weapon, Snow White, ect., in
a bool array status_list in the main function and you should update
it accordingly, such as whether the weapon has been fetched or
not.
2. The position (x, y) can be represented as x + width * y in 1D
array.
3. Please read the main function first to have a general
understanding of the control logic of this game. The code comments
are also important hints.
Tasks
Task 1: Write the function find_pos to store the position of a given symbol in related position array.
Task 2: Write the function is_valid_move to check return if the move is valid or not,including whether the prince's movement hits the wall, goes beyond the maze boundary or doesn't fall to the four movement directions.
Task 3: Write the function update_pos to update the position info.
Task 4: Write the function check_visible to check whether the prince & monster will see each other based on the positions of prince & monster.
Task 5: Fill the function update_maze, which is to update update the position informations, status of prince, monster, weapon & snow white and update the symbols of the maze. There are three missing parts for this incomplete function.
Sample Output
Sample Output for Winning:
*************************************************************** *** Welcome to the maze! Let's start saving our snow white! *** *************************************************************** The prince (P) is in {1, 1} The monster (M) is in {3, 6} The exit (E) is in {9, 7} ### ###### #P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (1, 1) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (2, 1) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# . . . . . . Your (the prince) current position is at: (1, 4) Please enter your move: (up:w, down:s, left:a, right:d) a ### ###### # ###### ### # # # # P # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (0, 4) Please enter your move: (up:w, down:s, left:a, right:d) s ### ###### # ###### ### # # # # # # P # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (0, 5) Please enter your move: (up:w, down:s, left:a, right:d) w ### ###### # ###### ### # # # # P # # # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (0, 4) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # ###### ### # # # # P # # # # # # # ## M # ## ###S #E# . . . . . . Your (the prince) current position is at: (3, 4) Please enter your move: (up:w, down:s, left:a, right:d) s ### ###### # ###### ### # # # # # # #P# # # # ## M# ## ###S #E# Your (the prince) current position is at: (3, 5) Please enter your move: (up:w, down:s, left:a, right:d) s ### ###### # ###### ### # # # # # # # # # # # ## P # ## ###S #E# . . . . . . Your (the prince) current position is at: (5, 6) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # ###### ### # # # # # # # # # # # ## P # ## ###S #E# Your (the prince) current position is at: (6, 6) Please enter your move: (up:w, down:s, left:a, right:d) s ### ###### # ###### ### # # # # # # # # # # # ## # ## ###P #E# Your (the prince) current position is at: (6, 7) Please enter your move: (up:w, down:s, left:a, right:d) w ### ###### # ###### ### # # # # # # # # # # # ## P # ## ### #E# . . . . . . Your (the prince) current position is at: (8, 6) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # ###### ### # # # # # # # # # # # ## P# ## ### #E# Your (the prince) current position is at: (9, 6) Please enter your move: (up:w, down:s, left:a, right:d) s Amazing! You have completed the maze!
Sample Output for Losing
case1: run into the wall.
*************************************************************** *** Welcome to the maze! Let's start saving our snow white! *** *************************************************************** The prince (P) is in {1, 1} The monster (M) is in {3, 6} The exit (E) is in {9, 7} ### ###### #P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (1, 1) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (2, 1) Please enter your move: (up:w, down:s, left:a, right:d) w Game Over! Failed.
case2: run out of the amaze boundary.
*************************************************************** *** Welcome to the maze! Let's start saving our snow white! *** *************************************************************** The prince (P) is in {1, 1} The monster (M) is in {3, 6} The exit (E) is in {9, 7} ### ###### #P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (1, 1) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (2, 1) Please enter your move: (up:w, down:s, left:a, right:d) d ### ###### # P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (3, 1) Please enter your move: (up:w, down:s, left:a, right:d) w ###P ###### # ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (3, 0) Please enter your move: (up:w, down:s, left:a, right:d) w Game Over! Failed.
case3: illegal input character.(not the four movement directions)
*************************************************************** *** Welcome to the maze! Let's start saving our snow white! *** *************************************************************** The prince (P) is in {1, 1} The monster (M) is in {3, 6} The exit (E) is in {9, 7} ### ###### #P ###### ### # # # # # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (1, 1) Please enter your move: (up:w, down:s, left:a, right:d) f Game Over! Failed.
case4: caught by the monster (before fetching the weapon).
. . . . . . . ### ###### # ###### ### # # # # P # # W # # # # # ## M # ## ###S #E# Your (the prince) current position is at: (3, 4) Please enter your move: (up:w, down:s, left:a, right:d) s Game Over! Failed
PLEASE GIVE IT A THUMBS UP, I SERIOUSLY NEED ONE, IF YOU
NEED ANY MODIFICATION THEN LET ME KNOW, I WILL DO IT FOR
YOU
#include <iostream>
#include <algorithm>
using namespace std;
// width and height of the maze
const int WIDTH = 11;
const int HEIGHT = 8;
// Given
void print_maze(const char maze[])
{
for (int i = 0; i < WIDTH * HEIGHT; i++)
{
cout << maze[i];
if ((i + 1) % WIDTH == 0)
cout << endl;
}
}
// Task 1: find the position of a symbol
void find_pos(const char maze[], char symbol, int pos[])
{
for (int i = 0; i <= WIDTH * HEIGHT; i++)
{
if (maze[i] == symbol)
{
pos[0] = i % 11;
pos[1] = i / 11;
break;
}
}
}
bool is_valid_move(const char maze[], int pos[], char move)
{
switch (move)
{
case 'w':
if (pos[1] > 0 && maze[(pos[0] + pos[1] * WIDTH) - 11] != '#')
{
return true;
}
break;
case 'a':
if (pos[0] > 0 && maze[(pos[0] + pos[1] * WIDTH) - 1] != '#')
{
return true;
}
break;
case 's':
if (pos[1] < 7 && maze[(pos[0] + pos[1] * WIDTH) + 11] != '#')
{
return true;
}
break;
case 'd':
if (pos[0] < 10 && maze[(pos[0] + pos[1] * WIDTH) + 1] != '#')
{
return true;
}
break;
default:
break;
}
return false;
}
// Task 3: update the position info
void update_pos(int pos[], char move)
{
switch (move)
{
case 'w':
pos[1] -= 1;
break;
case 'a':
pos[0] -= 1;
break;
case 's':
pos[1] += 1;
break;
case 'd':
pos[0] += 1;
break;
default:
break;
}
}
// Task 4: check whether the prince & monster will see each other based on the positions of prince & monster
bool check_visible(const char maze[], const int prince_pos[], const int monster_pos[])
{
if (prince_pos[0] != monster_pos[0] && prince_pos[1] != monster_pos[1])
{
return false;
}
if (prince_pos[0] == monster_pos[0] - 1 || prince_pos[0] == monster_pos[0] + 1)
{
return true;
}
if (prince_pos[1] == monster_pos[1] - 1 || prince_pos[1] == monster_pos[1] + 1)
{
return true;
}
if (prince_pos[0] == monster_pos[0] && prince_pos[1] == monster_pos[1])
{
return true;
}
if (prince_pos[0] == monster_pos[0])
{
if (monster_pos[0] >= prince_pos[0])
{
for (int i = (prince_pos[0] + WIDTH * prince_pos[1]); i <= (monster_pos[0] + WIDTH * monster_pos[1]); i += 11)
{
if (maze[i] == '#')
{
return false;
}
}
}
else
{
for (int i = (prince_pos[0] + WIDTH * prince_pos[1]); i >= (monster_pos[0] + WIDTH * monster_pos[1]); i -= 11)
{
if (maze[i] == '#')
{
return false;
}
}
}
}
if (prince_pos[1] == monster_pos[1])
{
if (monster_pos[1] >= prince_pos[1])
{
for (int i = (prince_pos[0] + WIDTH * prince_pos[1]); i <= (monster_pos[0] + WIDTH * monster_pos[1]); i++)
{
if (maze[i] == '#')
{
return false;
}
}
}
else
{
for (int i = (prince_pos[0] + WIDTH * prince_pos[1]); i >= (monster_pos[0] + WIDTH * monster_pos[1]); i--)
{
if (maze[i] == '#')
{
return false;
}
}
}
}
return true;
}
void update_maze(char maze[], int prince_pos[], char prince_move, int monster_pos[], char &monster_move, bool status_list[])
{
// remove 'P' from the old position
maze[prince_pos[1] * WIDTH + prince_pos[0]] = ' ';
// update the position info of the prince
update_pos(prince_pos, prince_move);
// update the status of the weapean
if (maze[prince_pos[1] * WIDTH + prince_pos[0]] == 'W')
{
status_list[1] = true;
}
// update the status of snow white
if (maze[prince_pos[1] * WIDTH + prince_pos[0]] == 'S')
{
status_list[2] = true;
}
// move prince to the new position
maze[prince_pos[1] * WIDTH + prince_pos[0]] = 'P'; // assign 'P' to new position
if (status_list[0])
{ // if the monster is alive
maze[monster_pos[1] * WIDTH + monster_pos[0]] = ' '; // remove 'M'
if (is_valid_move(maze, monster_pos, monster_move))
update_pos(monster_pos, monster_move);
else
{
monster_move = (monster_move == 'a') ? 'd' : 'a';
update_pos(monster_pos, monster_move);
}
maze[monster_pos[1] * WIDTH + monster_pos[0]] = 'M'; // assign 'M' to new position
bool vis = check_visible(maze, prince_pos, monster_pos);
if (vis && (!status_list[1]))
{
status_list[3] = false;
}
else if (vis && status_list[1])
{
status_list[0] = false;
maze[monster_pos[1] * WIDTH + monster_pos[0]] = ' '; // remove 'M'
}
}
}
int main()
{
// initial maze definition
char maze[HEIGHT * WIDTH] = {'#', '#', '#', ' ', ' ', '#', '#', '#', '#', '#', '#',
'#', 'P', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
'#', '#', '#', '#', '#', '#', ' ', '#', '#', '#', ' ',
'#', ' ', '#', ' ', ' ', ' ', ' ', ' ', '#', ' ', '#',
' ', ' ', ' ', ' ', ' ', '#', ' ', ' ', '#', ' ', ' ',
'W', ' ', '#', ' ', '#', ' ', '#', ' ', '#', ' ', '#',
'#', '#', ' ', 'M', ' ', ' ', ' ', ' ', ' ', ' ', '#',
'#', '#', ' ', '#', '#', '#', 'S', ' ', '#', 'E', '#'};
char cheat[] = {'d', 'd', 'd', 'd', 'd', 's', 's', 'a', 'a', 's', 'a', 'a',
'a', 'a', 's', 'w', 'd', 'd', 'd', 's', 's', 'd', 'd', 'd', 's', 'w', 'd', 'd', 'd', 's'};
int cheat_step = 0;
int prince_pos[2], monster_pos[2], exit_pos[2];
// positions of the prince, monster & exit
// {x, y}, x defines column number , y defines row number
// e.g. prince_pos[0] stores the column number, while prince_pos[1] stores the row number
// find the initial position of the prince, monster & exit
find_pos(maze, 'P', prince_pos);
find_pos(maze, 'M', monster_pos);
find_pos(maze, 'E', exit_pos);
cout << "***************************************************************" << endl;
cout << "*** Welcome to the maze! Let's start saving our snow white! ***" << endl;
cout << "***************************************************************" << endl;
cout << "The prince (P) is in {" << prince_pos[0] << ", " << prince_pos[1] << "}" << endl;
cout << "The monster (M) is in {" << monster_pos[0] << ", " << monster_pos[1] << "}" << endl;
cout << "The exit (E) is in {" << exit_pos[0] << ", " << exit_pos[1] << "}" << endl;
char prince_move;
char monster_move = 'd';
bool status_list[] = {true, false, false, true}; // see comments above
do
{
print_maze(maze);
cout << endl;
cout << "Your (the prince) current position is at: (" << prince_pos[0] << ", " << prince_pos[1] << ")" << endl;
cout << "Please enter your move: (up:w, down:s, left:a, right:d) ";
cin >> prince_move;
if (prince_move == 'c')
{
prince_move = cheat[cheat_step];
}
if (is_valid_move(maze, prince_pos, prince_move))
{
update_maze(maze, prince_pos, prince_move, monster_pos, monster_move, status_list);
if (!status_list[3])
{ // prince is alive or not
cout << "Game Over! Failed." << endl;
return 0;
}
if (!status_list[2] && !(prince_pos[0] == exit_pos[0] && prince_pos[1] == exit_pos[1]))
maze[exit_pos[1] * WIDTH + exit_pos[0]] = 'E';
}
else
{
cout << "Game Over! Failed." << endl;
return 0;
}
cheat_step++;
} while (!(prince_pos[0] == exit_pos[0] && prince_pos[1] == exit_pos[1]) || !status_list[2]);
cout << "Amazing! You have completed the maze!" << endl;
return 0;
}