Bomberman


Context

Following a class focused on data structures and algorithms, students were handed an assignment called ‘Bomberman’. In this assignment, students had to make the code for the bomb explosions. These explosions had to shoot in four directions, where they stopped expanding when a wall type is hit. For the assignment, students had to experiment with using a Depth First and Breadth First approach, and were introduced to the concept of recursion.

Explosions should work like this: when the bomb is placed, it explodes after two seconds. The explosion center should look at it’s neighbor tiles in directions up, down, left and right. The program should determine if there can be an explosion placed on these tiles based on their type (empty, fragile or wall). Then, the next neighbor(s) should be evaluated to determine if an explosion can be placed on those tiles.


Project showcase

I’d like to showcase the implementations of the BreadthFirst and DepthFirst approaches. For this, I made two seperate methods that are being called when placing a bomb (only one of them is called at a time, but they are both functional). Frst, let’s look at the BreadthFirstExplosion method:


Breadth First approach

This function takes an origin tile to evaluate. From this tile, where the bomb was placed, the neighbor tiles get stored in a list. Then, a loop is used to iterate through every neighbor tile. The stepSize variable is used to expand the neighbor check on from the origin tile (1 stepSize means 1 tile away from origin etc). Because the explosion in one of the directions should stop when it hits a wall, we check if the tile between the current neighbor and the origin is not a wall. If it would be a wall, we can skip to the next neighbor tile to evaluate to stop expanding in the current direction. If the current tile is not a wall, we can create an explosion on it and change it’s tile type to empty (plain grass).

After iterating through the neighbor tiles, the function waits a few milliseconds before calling itself again. This call has an increased stepsize, so the neighbor checks are one tile further away from the origin tile. A coroutine is used to better display the output and iterations of the function, waiting a few milliseconds before the recursive call. Here’s what the output of this function more or less looks like:



Depth First approach

The first part of the function is mostly setup. A local list is created to store tiles that need to get an explosion. Tiles will be added to this list later in the function. Next, a local variable is created: ‘currentTile’. This variable will be used to iterate through when searching for neighbor tiles. In a for loop, we iterate through the four directions using a switch statement. We create another local variable called ’tile’. Using the directions, we get the neighbor of the ‘currentTile’ for each direction: ’tile’. Because DepthFirst will go into one direction untill a stopping condition is met before going to other directions, we have to update the ‘currentTile’ to the ’tile’ variable after handling it. How the tiles get handled, can be seen in the rest of the function:

First, we check if we have a neighbor tile. Next, we check if the type is wall. If the neighbor of the current tile is a wall, we need to call ‘break’. This will make the program go into the next direction. If it is not a wall, we check if it’s of type ‘fragile’. If it is, we add it to the list to explode and change it’s type to empty. Because we’d like to make the explosion stop at fragiles, we call ‘break’ again to switch to the next direction. If the tile is neither of those types, it’s empty and can be added to the list to explode. If this point is reached, the currentTile variable gets updated to the ’tile’ variable. This will make the program get the next neighbor tile and evaluate it. After this operation, all tiles that can be exploded are added to the earlier created list. To create an explosion on these tiles, a foreach loop is used to iterate through all the tiles in the list. A ‘yield return’ statement is used to make the process of the iterations visible for the eye. Although hard to capture, this is more or less what the function does:


First, the bomb gets placed:


Then, into the left direction:


Followed by the right direction:


Then upwards from the origin:


Finally, the down direction:


Conclusion

This project proved to be a big challenge with a lot of complexity. Therefore, I have learned various things from it. The main things I have learned are:

1) BreadthFirst and DepthFirst approaches, primarily what they do and how they can be implemented in various ways.

2) Recursion with it’s uses and implementation. Primarily, why this concept might work better than iterative approaches (‘while’ loops for example), and how to write recursive functions used for making games.


I really enjoyed working on this project and figuring out how to implement my own code. It has been really fun to make a game that I’ve played endlessly when I was younger, now knowing more about the complexity and underlying aspects of this widely known and popular game. Thanks for reading!