SLC21 Week5 - Programming Games&Puzzles

in #slc21w5sergeyk18 days ago (edited)

fombae-learning-cover.png

Greetings Steemit friends

1) Edges Make the field longer, put ( в init()) on the edges, for example, of a pillar - #at a random distance of 0-2 from the edges of the map (field). The player must move between these pillars.

void init(char* field, int n, int& x) // <= C++/C => init(cha* field, int n, int* x)
{
for(int i=0; i<n; i++) field[i]='.';
field[n]='\0';
x=n/2;
}

Here we have the code, and I believe the modification will be done to the code. The parameters are okay, that is the game field, the size of the game field, and the player's position. We have the loop to fill the field with '.' to represent empty spaces running from i=0 to the point where i<n. field[n] = '\0' makes the end of the loop and x = n / 2; is used to set the player's position.

Now, to make changes to the code add pillars(#) at a random distance of 0-2 from the edges. I need to set a random number to place the pillars starting from 0. We stick to the original logic to initialize the fields with empty spaces.

We are using # to represent pillars and they will be positioned every 3 cells. So we check position by ensuring i % 3 == 0. We used a second loop to achieve this. So we will be trying to place the Pillars (#) at positions 0, 3, 6, 9, etc. At this point, I did a player position check to make sure that a player's starting position was not a pillar. I will be using a field size of 30 cells.

void init(char* field, int n, int& x) {
srand(time(0));
for (int i = 0; i < n; i++) field[i] = '.';
for (int i = 0; i < n; i++) {
if (i % 3 == 0) {
if (rand() % 2 == 0) field[i] = '#';
}
}
field[n]='\0';
x = n / 2;
if (field[x] == '#') field[x] = '.';
}

2) puddles Complete the first task, make the field even longer, randomly place puddles on the field _. The player has to pass through these puddles without obstacles, only to change his appearance to %a wet player.

Okay, for us to add the puddles (_) and make the field longer. I will make some changes to the init() function. Note this is the core of the game and the reason why most modifications will be done here. We have to loop and check to place pillars(#) at the random position alongside spaces(.) else puddles(_) and spaces(.) will be placed. We are making sure that puddles are placed without any obstacles. The rest of the code is pretty much not changed, but we are making the starting position clear.

void init(char* field, int n, int& x) {
srand(time(0));
for (int i = 0; i < n; i++) {
if (i < 3 || i >= n - 3) {
field[i] = (rand() % 3 == 0) ? '#' : '.';
} else {
field[i] = (rand() % 5 == 0) ? '_' : '.';
}
}
field[n] = '\0';
x = n / 2;
if (field[x] != '.') field[x] = '.';
}

Changes in the player's appearance will mean moving and checking when he moves into a puddle. So if the wet player gets to the position of a puddle, change appearance to %. The move function comes in now to track if the players stop on a puddle(_) (wet). We give the player the chance to move either to the left or right by inputting '4/a' to the left and '6/d' to the right.

void move(char* field, int n, int& x, char mv, bool& is_wet) {
if ((mv == '4' || mv == 'a') && x > 0 && field[x - 1] != '#') {
x--;
}
if ((mv == '6' || mv == 'd') && x < n - 1 && field[x + 1] != '#') {
x++;
}
is_wet = (field[x] == '_');
}

The display function shows the whole game field with the payer's position. If the play happens to be on a wet spot, it will show %. I define PLAYER 'P' at the beginning of the program above the init() function.

void display(char* field, int n, int x, bool is_wet) {
for (int i = 0; i < n; i++) {
if (i == x) {
std::cout << (is_wet ? '%' : PLAYER);
} else {
std::cout << field[i];
}
}
std::cout << std::endl;
}

3) Jump Add a jump (spacebar) - the player jumps one cell in the direction of his movement!!!

Add a jump to the direction of the player's movement by pressing the spacebar. Jumping is a moving ability, so let's look at updating the move() function and adding another condition. This time if (mv == ' '), the spacebar (' ') will move two cells to the current direction skipping over obstacles or a pillar.

void move(char* field, int n, int& x, char mv, bool& is_wet) {
if ((mv == '4' || mv == 'a') && x > 0 && field[x - 1] != '#') {
x--;
}
if ((mv == '6' || mv == 'd') && x < n - 1 && field[x + 1] != '#') {
x++;
}
// Jump logic(spacebar)
if (mv == ' ') {
if (x > 1 && field[x - 2] != '#' && field[x - 1] != '#') {
x -= 2;
}
if (x < n - 2 && field[x + 2] != '#' && field[x + 1] != '#') {
x += 2;
}
}
is_wet = (field[x] == '_');
}

So, when the player presses the spacebar (' '), we have to jump two cells and if in case jump into a puddle(_). The spot still becomes a wet spot, and pillars still maintain position to block jump.

4) The puddle disappears If the player jumps (through the space) into a single puddle - it dries up, when the player simply runs through the puddle - it does not dry up.

Note that previously the wet spot was maintained when a player jumped into using the spacebar. This time the task required us to dry up when they jumped when using the spacebar (' '). Our jump login is in the move() function, and we make some changes with the if (mv == ' ') condition.

void move(char* field, int n, int& x, char mv, bool& is_wet) {
if ((mv == '4' || mv == 'a') && x > 0 && field[x - 1] != '#') {
x--;
}
if ((mv == '6' || mv == 'd') && x < n - 1 && field[x + 1] != '#') {
x++;
}
// Jump logic(spacebar)
if (mv == ' ') {
if (x > 1 && field[x - 2] != '#' && mv == 'a') {
if (field[x - 2] == '') field[x - 2] = '.';
x -= 2;
}
if (x < n - 2 && field[x + 2] != '#' && mv == 'd') {
if (field[x + 2] == '
') field[x + 2] = '.';
x += 2;
}
}
is_wet = (field[x] == '_');
}

Walking into a puddle is by using the direction (4/a and 6/d) wet spots, nothing will change. But when the player jumps (spacebar) into the puddles, it will dry up (_ to . ). At this point the player state changes and becomes wet (%).

5) Complete the first task, make the field even longer, and randomly place stones on the field (a). The player cannot cross these stones, but must cross these stones

Adding stones to the field where players cannot walk passed stones but jump past them. To place the stones in the field means making some changes to the game field init() function. Randon's positioning will make it less predictable.

void init(char* field, int n, int& x) {
srand(time(0));
for (int i = 0; i < n; i++) {
if (i < 3 || i >= n - 3) {
field[i] = (rand() % 3 == 0) ? '#' : '.';
} else {
int rand_value = rand() % 10;
if (rand_value == 0) {
field[i] = '_';
} else if (rand_value == 1) {
field[i] = 'a';
} else {
field[i] = '.';
}
}
}
}

The next function to look at is the move() function which handles the movement and jump operation for the game. Here, movement (4/a and 6/d) will be blocked by stones(a) but can be jumped over.

void move(char* field, int n, int& x, char mv, bool& is_wet) {
if ((mv == '4' || mv == 'a') && x > 0 && field[x - 1] != '#' && field[x - 1] != 'a')
x--;
if ((mv == '6' || mv == 'd') && x < n - 1 && field[x + 1] != '#' && field[x + 1] != 'a')
x++;
if (mv == ' ') {
if (x > 1 && field[x - 2] != '#' && mv == 'a') {
if (field[x - 1] == 'a') x -= 2;
}
if (x < n - 2 && field[x + 2] != '#' && mv == 'd') {
if (field[x + 1] == 'a') x += 2;
}
}
is_wet = (field[x] == '_');
}

So at this point of the game, pillars(#) and stones block all movement except for jumping(spacebar).

6) Statistics Add statistics: - number of moves, jumps, puddles, stones.

To have the statistics for the number of moves, jumps, puddles, and stones. We have to find a means to count each iteration done in the move() function.

Each condition passes, be it moves, jumps, puddles_crosses, stones_jump. A count is valid with an increase as the player moves through the field. I added a variable to store the count values using the ++ operator to increment the value of a variable by the number of loops.
For us to have the probable statistics, I have to make sure the game is over.


void move(char* field, int n, int& x, char mv, bool& is_wet, int& moves, int& jumps, int& puddles_crossed, int& stones_jumped) {
if (mv == '4' || mv == 'a') {
if (x > 0 && field[x - 1] != '#' && field[x - 1] != 'a') {
x--;
moves++; // Increment operation
if (field[x] == '') {
puddles_crossed++; // Increment operation
is_wet = true;
}
}
} else if (mv == '6' || mv == 'd') {
if (x < n - 1 && field[x + 1] != '#' && field[x + 1] != 'a') {
x++;
moves++; // Increment operation
if (field[x] == '
') {
puddles_crossed++; // Increment operation
is_wet = true;
}
}
} else if (mv == ' ') {
if (x > 1 && field[x - 2] != '#' && field[x - 1] == '.') {
x -= 2;
jumps++; // Increment operation
stones_jumped++; // Increment operation
if (field[x] == '') {
puddles_crossed++; // Increment operation
is_wet = true;
} else {
is_wet = false;
}
}
if (x < n - 2 && field[x + 2] != '#' && field[x + 1] == '.') {
x += 2;
jumps++; // Increment operation
stones_jumped++; // Increment operation
if (field[x] == '
') {
puddles_crossed++; // Increment operation
is_wet = true;
} else {
is_wet = false;
}
}
}
}

So let's bring in the game_over() function. We need to find a means to end the game, when if (field[x] == '#'), that if the player hits a pillar. While we can have the statistics for each round of play, I was thinking of ending the game. It was challenging because hitting the pillar was not that easy.

bool game_over(char* field, int n, int x) {
if (field[x] == '#') return true;
}

7) push A player can push one stone, no more.

Now, we will make some changes to our current operation. At first, the player could only jump over a stone, but this task required the player to push the stone. I think it will be preferable if a stone is pushed into a space and not through a pillar or into a puddle. That will make our game more challenging and interesting.

void move(char* field, int n, int& x, char mv, bool& is_wet, int& moves, int& jumps, int& puddles_crossed, int& stones_jumped, bool& pushed) {
if (mv == '4' || mv == 'a') {
if (x > 0) {
if (field[x - 1] == 'a' && !pushed && x - 2 >= 0 && field[x - 2] == '.') {
field[x - 1] = '.';
field[x - 2] = 'a';
x--;
moves++; // Increment operation
pushed = true;
} else if (field[x - 1] == '.') {
x--;
moves++; // Increment operation
if (field[x] == '') {
puddles_crossed++; // Increment operation
is_wet = true;
} else {
is_wet = false;
}
}
}
} else if (mv == '6' || mv == 'd') {
if (x < n - 1) {
if (field[x + 1] == 'a' && !pushed && x + 2 < n && field[x + 2] == '.') {
field[x + 1] = '.';
field[x + 2] = 'a';
x++;
moves++; // Increment operation
pushed = true;
} else if (field[x + 1] == '.') {
x++;
moves++; // Increment operation
if (field[x] == '
') {
puddles_crossed++; // Increment operation
is_wet = true;
} else {
is_wet = false;
}
}
}
} else if (mv == ' ') {
if (x > 1 && field[x - 1] == 'a' && field[x - 2] == '.') {
x -= 2;
jumps++; // Increment operation
stones_jumped++; // Increment operation
} else if (x < n - 2 && field[x + 1] == 'a' && field[x + 2] == '.') {
x += 2;
jumps++; // Increment operation
stones_jumped++; // Increment operation
}
}
}

Pushing is a moving ability, so we look at modifying the move function. Note, that just one push is permitted lol.
We check if the player is moving into a stone, and check if it can be moved. That is the next position is a space(.).
The screenshot shows a move, where the player (P) pushes the stone(a) into a space(.).

Screenshot 2024-12-01 081117.jpg



Cheers
Thanks for dropping by
@fombae

Sort:  
Loading...