SLC21 Week5 - Programming Games&Puzzles
Hello everyone! I hope you will be good. Today I am here to participate in Steemit Learning Challenge of @sergeyk about the Programming Games&Puzzles. It is really an interesting and knowledgeable contest. There is a lot to explore. If you want to join then:
Making a Long Field and Adding Pillars
The code implements a simple console based game where the player (@
) moves left or right within a field filled with empty spaces (.
) and pillars (#
). The game ends when the player collides with a pillar or chooses to quit.
Initialization (init
function)
- The game field is set up with a fixed size which is 25 and it is longer than 20 and is initialized with empty spaces (
.
). - Two pillars are randomly placed. One is placed near the left end and the other is placed near the right end of the field.
- The player is positioned in the center of the field to start as I have used used
x = n / 2;
.
Displaying the Field (display
function)
- The game field is displayed on the console.
- The player (
@
) is shown at their current position by replacing the default field character at that index. - All other positions display either empty spaces or pillars.
Player Movement (move
function)
- The player's movement is processed based on the user input:
'4'
or'a'
: Move left.'6'
or'd'
: Move right.'q'
: Quit the game.
- The next position is calculated based on the input.
- Movement rules:
- If the next position is outside the field boundaries then the player cannot move.
- If the next position contains a pillar then the game ends.
- If the next position is valid then the player's position is updated.
Game Loop (main
function)
- The game starts by initializing the field and placing the player.
- A loop continues to:
- Clear the screen for a clean display.
- Show the current state of the field.
- Prompt the player for input and process the movement.
- The loop exits when the player collides with a pillar or chooses to quit.
Game Over Condition
- Currently the game ends under two conditions:
- Collision: The player moves into a position occupied by a pillar. And if the player tries to cross the pillar then the game ends.
- Quit: When the player wants to exit or end the game by himself then he can enter
'q'
as input. It will terminate the game by displaying an appropriate message.
In the game these are the best features:
- Randomized Pillar Placement: Makes each game unique.
- Interactive Display: Updates the console with each move for a dynamic experience.
- Simplified Logic: Concise handling of movement and collision detection.
- Custom End Messages: Tailored messages provide clear feedback based on how the game ends.
Making Field More Longer and Adding Puddles and Changing the Appearance
Now in order to meet the requirements of the next task where we need to make the field more longer and we have to add the puddles on the field randomly. And we have to change the appearance of the player when it comes on the puddle from @
to %
. I have made the following changes and additions in the game.
1. Puddle Placement (init
function):
- Random puddles (
_
) are placed on the field, avoiding overlap with pillars (#
). This is done by generating random positions and checking if the spot is empty.
2. Wet Appearance (display
function):
- The player’s appearance changes to
%
(wet) if they step on a puddle, controlled by theisWet
flag.
3. Movement and Wet Check (move
function):
- If the player moves onto a puddle, the
isWet
flag is set totrue
(changing the player’s appearance).
Moreover in the last code the end game messages were very long so I have make them more consize and short.
Add a jump (spacebar) - the player jumps one cell in the direction of his movement!!!
At this task I consumed a lot of time and I have to change the way in which I was writing the previous code but not all I added only a one new function which resolved my problem. I was facing the issue in the jump. When I was using spacebar
button on the keyboard it was just giving the space and while entering it was unable to perform the jump functionality in the game. I tried different ways but at the end I modified the way of getting the user input by using the new function. Here is the explanation how I did it:
Capturing Single Keypress (myget
function)
In order to capture a single keypress without the need to press Enter I used the myget
function which relies on modifying terminal settings.
Here is how the function works:
tcgetattr
: Fetches the current terminal settings.newt.c_lflag &= ~(ICANON | ECHO)
: Disables canonical mode and echoing by allowing the program to read individual keys without needing to press Enter and without showing what is typed.getchar()
: Reads a single character from the keyboard input.tcsetattr
: Restores the terminal to its original settings after capturing the keypress.
This allows the game to respond immediately to keypresses, enabling smoother interaction.
I had this only way to perform the jumping. I do not know any other way and maybe I can get assistance from the professor if is there any other way without using this way.
Implementing Jump Functionality
The jump functionality was added by modifying the position of the player. When the spacebar (' '
) is pressed then jump is performed. The key points are:
- The spacebar (
' '
) is mapped to either a left jump or a right jump depending on the current position of the player (nextX
). - We check that the next position of the player is valid such that there is not a pillar.
- Right Jump: When the spacebar is pressed then the program checks if the player can move one step to the right (
nextX + 1
) and whether the position is not occupied by a pillar. - Left Jump: Similarly if the player is not at the start then the player can move one step to the left (
nextX - 1
) while ensuring there is no pillar in the way.
The conditions ensure that the player can only jump in the direction that is not blocked by a pillar. In the video I have shown practically how the player moves in the left and right direction when we press the buttons and similarly the player jumps in the direction of movement.
According to my understanding I have moved the player by just 1 move of the cell. And I am not sure if I need to move the player two times but by understanding 1 cell I have tried to move the player with each jump only once and I have performed it accordingly. Moreover If there is the requirement to move to the player two times then we can simply update the increment counter to count the movement for two times. If there is the requirement then I will do it as well because I am confuse while understanding this question completely. Seeing the 1 cell I have just moved the player once.
Controlling the Appearance of the Puddles
It is going to make the game more interesting where when the player will pass through the puddle simply by walking then it will not dry up but on the other hand if the player jump through the puddle it dries up and the puddle is converted to the empty field and replaced by .
.
- We need to check if the player landed on a puddle after jumping.
- If the player lands on a puddle then the puddle should be replaced with an empty field ('.').
- We need to ensure that running through the puddle does not modify the puddle.
For this purpose we need to modify the code in the move()
function because it is handling the movement of the player. We need to add a check for whether the player's current move is a jump and if they land on a puddle.
Check if the Move is a Jump (mv == ' '):
- This ensures puddles only disappear when the player jumps into them.
Dry up the Puddle:
- When the player jumps into a puddle (
field[nextX] == PUDDLE && mv == ' '
) then the code replace the puddle ('_'
) with an empty field ('.'
).
Normal Movement Through Puddle:
- If the player runs through a puddle then the puddle remains intact and the
isWet
flag is updated to true without modifying the field.
Adding Stones to the Game
The game is going more interesting now we have to add the stones on the way of the player and the player cannot cross the stones. So in order to add the stones on the way of the player I have performed following additions to the code.
Define Stone Symbol
I have defined a new symbol for stones:
In the STONE
variable I have stored the alphabet a
to represent the stones on the field.
Place Stones on the Field
In order to place the stones on the field I have modified the init
function. It will randomly place stones on the field:
- Stones are placed on random positions in the field where no other obstacles like pillars or puddles exist.
- Count: The number of stones is determined by
n / 6
making it proportional to the field size.
Block Movement Across Stones
To block the movement I have updated the move
function to handle stones. If the player tries to move onto or jump onto a stone:
- If the player tries to move onto a stone the position (
nextX
) is reset to the current position (x
). - A message is displayed: "You cannot cross the stone."
- The game pauses briefly (
usleep(1000000)
) to let the player see the message before the screen clears.
Display Stones on the Field
The display
function remains unchanged but now shows stones (a
) as part of the field:
Moreover I have extended the field size in the main
function to accommodate more stones.
These modifications in the game code ensures the addition of the stones on the field and the stones block the movement of the player and show an appropriate message on the screen when tries to cross the stones.
Addition of the Statistics
In order to track the statistics of the I have implemented different modifications such as:
Variables for Statistics
- The statistics being tracked are:
steps
: The number of times the player moves left or right.jumps
: The number of jumps the player makes (either left or right).collisions
: The number of times the player collides with a pillar or stone.puddles
: The number of times the player steps into a puddle.
These variables are updated in the move()
function and then displayed during each cycle in the display()
function.
Updating Statistics
- Steps: Each time the player moves left (
a
or4
) or right (d
or6
) thesteps
counter is incremented by 1 in themove()
function. - Jumps: If the player jumps (by pressing the spacebar) to the left or right the
jumps
counter is incremented by 1. - Collisions: If the player moves into a pillar or stone (
field[nextX] == PILLAR
orfield[nextX] == STONE
) thecollisions
counter is incremented by 1. - Puddles: If the player steps into a puddle (
field[nextX] == PUDDLE
) thepuddles
counter is incremented by 1 and the puddle is dried up.
3. Displaying Statistics
- The
display()
function prints the statistics at the top of the screen before showing the game field.
This ensures that after each move the player can see their current stats.
Game Loop and Statistics
- The game loop continues running until the player either collides with an obstacle or chooses to quit.
- Every time the loop runs the
display()
function is called to refresh the screen and show the current statistics.
5. Game Over Conditions
- When the game ends (either by quitting or colliding with a pillar), the game prints a game over message based on the condition that triggered the end. The statistics are maintained throughout the game and are part of the final display.
Statistics Functionality:
- The variables
steps
,jumps
,collisions
, andpuddles
are used to track game statistics. - These variables are updated in the
move()
function based on the player’s actions. - The
display()
function shows these statistics at the top of the game screen. - The game continues until a game over condition occurs (either by quitting or colliding) at which point the game over message is displayed.
This ensures that the player can monitor their performance throughout the game and see how many steps, jumps, collisions and puddles they encountered.
A player can push one stone
To implement the functionality where the player can push one stone but no more, we need to add the logic for detecting the stone in front of the player and moving it, ensuring that the player can only push it once. Here is how we can implement it:
- Check for Stone in Front of the Player: When the player moves we need to check if there is a stone directly in front of them depending on whether they are moving left or right.
- Move the Stone: If there is a stone we need to move it to the next space in the direction the player is moving.
- Prevent Pushing More Than One Stone: After the player pushes a stone no more stones should be pushed so we will track whether a stone has been pushed or not yet.
Here are the modifications in the code:
New Variable to Track Stone Pushing:
We add the stonePushed
variable to ensure that only one stone can be pushed by the player. This is a bool
type variable.
bool stonePushed = false;
This tracks if the player has already pushed a stone
Modification in the move
Function:
Within the move
function, we check whether there is a stone in front of the player, and allow them to push it only once.
Stone Interaction Check:
If the player tries to move into a stone and has already pushed a stone, they will be prevented from moving further. This check is made when the player attempts to move:
Working:
stonePushed
: Added a flag to ensure the player can push only one stone.- Stone Moving Logic: In the
move
function, we check if there is a stone in front of the player, and if the player hasn't already pushed a stone (!stonePushed
), they are allowed to move it. - Prevent Further Pushing: Once a stone is pushed, the
stonePushed
flag is set totrue
, and the player can no longer push additional stones.
These changes ensure that the player can only push one stone during the game.
Now in order to make the game more interesting and to add a use case I have added the coins on the way of the player. As the player will move on the track it will get coins and can collect the coins and these coins will also be tracked. It has made the game more interesting.
- Coins Placement: Coins ($) are randomly placed in the game field, just like pillars, puddles, and stones. Their placement avoids overlap with existing objects.
- Coin Collection: The player can collect coins by moving over them. Every time a coin is collected, the coin counter is incremented, and the coin is removed from the field.
- Display Stats: The player’s total coins are displayed at the top of the screen during gameplay.
Note: I have used Onlinegdb Compiler to compile the code in C++ language.
Thank you for participating, at first glance everything looks correct - I will give a detailed assessment of your work later.
Ahan Thank you take your time.