Every game has a source code that is the core function of how the game operates, video game devs put DRM protections on their property to prevent people from learning the source code, cracking a game means overriding the security measures so you can access the sources code, once you have the source code you can replicate and modify the game to your hearts content. Okey (Turkish pronunciation: ) is a tile-based game, very popular in Turkey. It is almost always played by four players, although, in principle, it can be played by two or three players. It is very similar to the game Rummikub, as it is played with the.
In previousposts, we saw how to code a small interactive text-based Tic-Tac-Toe game, especially within time limit of a technical interview, and with unit tests. In this next part of the series, we are going to give a similar demonstration of coding up an interactive Minesweeper game! Read on…
Rules of the Interview
Like we said before, live coding interview questions are fundamentally different from whiteboarding. Here are a few ground rules for doing well in these interviews:
- Your code better work! Use compiler/interpreter/error messaging from your programming language as a friend and write an error-free program!
- A good design is EXTREMELY important. Never write a single function (like you’d usually do on a whiteboard).
- Big-Oh computation complexity is less important. It’s okey to use additional storage/iterate over array multiple times or even to code an O(n2) algorithm instead of O(nlogn).
With these rules in mind, let’s take a quick look at what we are supposed to code.
Rules of the Game
Recall how Minesweeper works:
- A user starts with empty NXN board. A few unknown cells on the board have “mines” behind them. Other cells are benign.
- At each turn, the user clicks on a cell of the board. If the chosen cell contains a mine, the user loses immediately.
- Otherwise, the game reveals the cells using a recursive algorithm:
- If a cell has non-zero neighbors with mines, it simply shows the number of neighbors with mines on that cell.
- Otherwise, it opens up all the neighboring cell, and recursively calls reveal on the neighbors.
In this case, a cell has 8 neighbors, left, right, top, bottom and four diagonals. Here is a gameplay demo:
Problem 1:
Design a class to create an empty NxN Minesweeper board, where the dimension N is provided by the user.
Solution:
Well begun, half done, etc.. Well, in this case, coming up with the correct data structures is indeed half of the work. What kind of internal state/data structures do we need for this problem?
The problem statement gives us a good hint. At the very least,
- We need an NxN vector of bools to store whether a cell contains a mine. We can use a sparse representation like a list or hash table, but I like keeping and indexing a vector of vectors. It’s clean!
- We need an NxN vector of integers to keep track of the number of neighboring mines for a cell. This vector never changes during the game.
- Finally, we also need an NxN vector of bools to keep track of whether a cell has been revealed so far. This helps displaying the board, and is also going to help us later to perform graph-based iteration during the reveal algorithm.
Again, it’s important to initialize and update these three data structures correctly and efficiently.
Let’s start with the class structure and a simple constructor that initializes these internal data structured. Let’s also assume that 10% of random cells contain mines.
minesweeper.h
minesweeper.cc
Problem 2:
Write a function to display the board on the screen
Solution:
We want to display a board like the following on the screen at any given point in the game:
Let’s use the following convention
- A non-revealed cell is displayed as empty string.
- A revealed cell with zero neighboring mines is displayed using “#”.
- A mine (if revealed) is displayed using “*”.
We shall also add cell borders to make the board look neat! Here is the code:
minesweeper.h
minesweeper.cc
Now is a good time to write a simple main method that accepts N, the dimension of the board, and displays the board. We will extend it to include the main game play.
main.cc
Demo Time!
Let’s compile and run the code, shall we?
Problem 3:
Write a method to accept the cell location (i, j) from the user and reveal the board. Terminate the game if the user loses (steps on a mine), or wins (all cells revealed).
Solution:
Now we come to the business end of the problem! Our single public method should
- Modify all the internal data structures by implementing the reveal algorithm
- And also return an appropriate value when all available cells are revealed.
Let’s define an enum to denote the return value of the function.
Let’s also write a helper method to find whether the user has won by exploring all possible cells.
With these two pieces, we are ready to write our final method to explore the board given user’s input (i, j).
- Perform some sanity check on (i, j). Is it a valid input (non-negative, and within the bounds). Is the cell (i, j) already revealed. In all of these cases, return ILLEGAL, and ask the user to play again.
- The simplest case to check is whether the user has stepped on a mine! In that case, return MINE immediately and terminate the game.
- Slightly more complicated is a case where the call has more than one neighboring mine. In that case, simply reveal the neighboring-mine number, and ask the user to play again.
- Finally, when the cell has zero neighboring mines, we are going to use Breadth First Search (BFS) to reveal all reachable cells with zero neighbors.
And oh, don’t forget to call our handy UserWinStatus to check whether the user has won and return an appropriate Reply message.
Here is the code.
minesweeper.h
minesweeper.cc
Let’s finish off with a final piece of code to main.cc.
Time for a final demo:
We are pretty much ready with a working version of the game with these three simple steps. Let’s fire up the compiler and test it on the console! The following screencast video shows the game play for our program:
Parting Thoughts:
Writing a good build system is essential for many compiled languages like Java/C++. In these blog posts, we have chosen GNU make as our default build system. You are welcome to pick your own.
Let’s write a simple MakeFile to compile and run the code:
Okey Game Source Code In C++
Last but not the least… We have left out unit tests from this little longish blog post. Let’s leave them as an exercise for the reader, shall we? 🙂
The source code accompanying this blog post is available here.
Okey is a top-rated game in the rummy family—commonly played in Turkish coffee houses. The objective is to collect sets of same-numbered tiles and runs of consecutive tiles of the same color, or pairs of identical tiles. In a winning hand, all 14 tiles consist of sets and runs, or seven pairs. Discard your final tile to the stack in the middle to claim your victory. Finish by discarding a joker to open the safe. Play with 2, 3 or 4 players. Create a table and invite friends to challenge them. Come and Play Now!