In a game of Minesweeper, the board consists of multiple cells arranged in a grid. We will refer to the (at most 8) cells to the left/right, above/below or diagonal as adjacent cells. If we are considering only above/below and left/right but not diagonal cells (so at most 4), these will be called directly adjacent cells. Each cell is either empty, is a mine or has a number (1-8) on it. As well as this, each cell is either hidden or revealed. At the start of the game, every cell is hidden. The aim is to reveal all non-mine cells. The player can click on a cell to reveal it – if the player reveals a mine, the game ends and the player has lost. If instead, the player has clicked and revealed all non-mine cells, the game ends and the player has won.
The numbered cells aid the player – they describe the number of adjacent cells that are mines – if there are no adjacent mines, the cell is empty. Any hidden cells can be “flagged” by the player, this places a flag on the cell which prevents the player from accidentally revealing said cell. The cell can only be revealed if it is first “unflagged” by the player. Typically, flags are used to represent known or potential locations for mines. If the player reveals an empty cell, a process known as a “floodfill” takes place, which is where all non-mine directly adjacent cells are also revealed. If the directly adjacent cell is empty, the “floodfill” is applied recursively from that cell. Otherwise, if the directly adjacent cell is numbered, the “floodfill” is not recursively applied. This ends up expanding a large cluster of empty cells until a boundary consisting of only numbered cells are reached and revealed.
In a game of Picross (formally known as a nonogram), there are a grid of cells. The aim of the game is to colour in certain cells in the grid, according to some rules. To the left of each row (and above each column) is a list of numbers. When these are read left to right (or top to bottom), the list of numbers signifies the sizes of each block of shaded cells in that row (column).
So, a list of 3 5 1 in a row signifies some number of blank cells, followed by 3 shaded cells, followed by at least 1 blank cell, then 5 more shaded cells, followed again by at least 1 blank cell, then 1 shaded cell, followed by some number of blank cells. The sizes of the gaps between the shaded blocks (i.e. the sizes of the blank blocks) is unknown, but may be deduced by the player e.g. by examining the size of the entire row (column) or by looking at intersecting columns (rows). So, as the row is read from left to right, the (non-empty) blocks of cells alternate in being shaded or blank (and the shaded block sizes are given by the ordered list of numbers).
The player can mark each square as shaded, or as blank (which acts as a flag for a non-shaded square). At the end of the game, the player can click a button to check if their solution is correct, at which point, the game checks that each shaded cell has indeed been shaded by the player (whether blank cells have been blanked by the player is not checked). Note that the player is not corrected if a mistake is made during play, only when the player checks to confirm their solution, does the game output if the shading is correct or not. Note that some newer editions do check for mistakes during gameplay, but this is not common.
In this variant of Minesweeper that we will be implementing, the game will run exactly the same as the original Minesweeper, except for a few changes. Firstly, there will be a ? cell, which will signify a numbered cell, where the number is unknown. These cells will also start off as hidden.
Once the hidden mines have been generated in the grid, a random selection of rows and columns will be chosen. These rows and columns will have a list of numbers written to their left/above them, signifying the sizes of blocks of non-mine squares (non-mine, since we can expect these blocks to be bigger, so it is more useful). Within these rows/columns, all numbered cells will be marked as ?. For the remaining cells in the grid, they will be correctly marked as mines, empty or a number. Also, as in the original game, all cells will start off being hidden, with the same win/lose conditions.
The only difference is that some of the information that the player uses to aid them (some of the numbered cells) have been exchanged with row/column information (in a Picross-esque fashion). Do take note that the only part of this variant that is from Picross is the usage of rows/columns for information. The idea of shading in cells, or marking some as blank will not be used in the implementation of our game. Clicking on a mine still results in an instant loss.
Creating a game in Unity consists of setting up Game Objects which are used to visually represent the game, and then adding components to these objects to manipulate them. The left window in Unity is the hierarchy, a diagram showing the different Game Objects. On the right is the Inspector, which allows you to examine a particular Game Object and adjust its components. Some of these components can also be scripts. Scripts in Unity are written in C# (quite similar to Java in style).
Most of you will be working on the scripts, some on the Game Objects. Scripts can reference the Game Objects that they are components of; this can be used to manipulate said Game Objects. When writing scripts, consider carefully whether to make methods/members public or private. Make sure to comment your code so that anyone reading it can understand it – this may happen quite often given that many parts of the project rely on other parts. Also, ensure that any drafts of your work have been uploaded e.g. to GitHub so that others know what syntax is being used etc. Make sure to label your final draft as final. Each person is responsible for ensuring their code is error-free.
If you are in a team, you can split the work between you however you like. Just try to ensure that each of you at least gets to write some scripts. As you are writing scripts, do remember that the program is supposed to be able to run on Android, iOS and PC. You may find it easier to focus on writing scripts with a desktop platform in mind; then modifying and extending this code for compatibility – if your script is taking user input, it may be better to avoid using keys on the keyboard to trigger events (except if the user has to type their details) to keep the program compatible with multiple platforms.
I have tried to split the workload (below) so that everyone has enough details to write about in their individual contributions. I have also tried to cater to peoples’ strengths however with limited knowledge of said strengths. If you feel that the workload is too much/little, let me know. Also, feel free to swap your teams in between yourselves. Most likely, the difficulty of the work will arise as you will find that either: there is a lot of pre-thought required to form good ideas but once the ideas are formed, the actual work is not too much; or that there is not too much pre-thought required but there is more script-writing involved.
You will have to implement abstract representations of the different data structures in the game, along with sending signals to render the state of the game. This will be dependent on the design choices made by the graphics and UI team. Most likely, there will have to be a representation of a Square or Cell, which would have to be identifiable as hidden or revealed, along with if it is numbered or flagged etc. The game’s Grid would also have to be implemented as a collection of Squares/Cells. This would have to communicate directly to the Tilemap to render the state of the game whilst also producing methods for the main game to use. Representations of the lists of numbers on the rows/columns would also have to be implemented. These will have to be general representations, which are then given specific values by the main game. You will have to ensure that there is ample scope to the abstract representations i.e. that all possible details and methods that may be needed by the main game team are represented and implemented effectively.
This is to set up the main game; it involves the actual gameplay by the user. Some of the algorithms will involve instantiating and manipulating data structures which will be constructed from the abstract representation of the game – these will be abstractly designed by the game state team. You would have to initialise a new game setting, once given some user input to start the game from the UI. Also, the player’s names and email addresses should be stored once passed in from the UI. The game will have a 16x16 grid, filled with exactly 50 mines. Firstly, the mines should be generated. Then, the random selection of rows and columns (try to make these at least 2 or 3 but at most, say, 6 or 7?) should be initialised. Finally, the rest of the cells in the grid should be initialised correctly, and then some of these should be set to ? (the numbered cells that are in the randomly selected rows or columns). After the initial setup, conditioning on the type of input from the player, you would have to determine whether to flag/unflag a square, to reveal a square etc. You can feel free to choose what kinds of inputs to use for flagging etc. but keep in mind that the program will also have to be compatible with other platforms (smartphones) – you might find it easier to focus on a single desktop platform to start with. Signals should be sent to the Grid to render the new changes to the state of the game, including upon initialisation of a new game. Win/loss conditions should also be checked upon revealing a square. Upon game ending, no more user input should be accepted to the game itself (except for the UI – not handled here). A flagged square must not be revealable. A “floodfill” method should also be implemented – fortunately, this can be done by simple recursion (only on above/below and left/right cells, not diagonal) – no need for a complicated iterative searching algorithm. The end of the game should trigger the corresponding popup menu in the UI. You should also pass the player’s names and email as well as if they have won/lost (and how many moves they have made) to the data storage code. This data should be passed before notifying the user if they have won/lost (i.e. displaying the corresponding menu in the UI) so that it is ensured that the data is stored before the user closes the game.
This is to set up the visual representation of the game. You would have to construct the shapes used for all of the visual parts of the game – these include 12 types of cells: cells numbered 1-8, mine cell, empty cell, ? cell and hidden cell. You should also find (perhaps different font style) cells to represent the numbers written next to the rows and columns (which will vary from 1 to 16 – the width of the grid). Fortunately, there are many free-to-use assets available online so you don’t have to personally construct most of them (if any at all). Just ensure that you check the copyrights of any assets used. You also have to set up the Game Object to represent the game. I would recommend using a Game Object known as a Tilemap to represent the board of the game (which includes the grid and the lists of numbers next to rows and columns). This is essentially a structure consisting of many Tiles (which will represent individual cells in the grid, and some tiles will be used for each number in the list of numbers). The visuals used for the Tiles will be the assets you have collected above. None of the above ought to involve writing a script. You will also have to add an info button to the game (using a Button Game Object), which when clicked, opens a popup menu giving a condensed how-to-play description. The button must be linked to the menu via a short script. A popup menu asking the player to submit their first name, last name and email address must be enforced before the game starts (i.e. displayed immediately) and a popup menu at the end must be set up to tell the player if they have won or lost. I would recommend using a UI Canvas Game Object to set up the popup menus. These end menus will not be displayed via buttons, they will be activated by a separate piece of code elsewhere and activating their display is not handled here. A short script should be used to execute the main game code as well as sending the player’s names and email to the main game code, once the player has submitted their details. At the end, ensure that the camera is calibrated so that the player will be able to see the menus and the game board during gameplay. Most of this will be collecting online resources and visually setting them up correctly – only a few short and simple scripts need to be written. Note that there may be a more “cleaner” way to obtain the names and email addresses of the player in Unity (instead of in a custom popup menu), perhaps research and find a simple but good way to do this. Also, the usage of UI canvases is a recommendation but if you find a better way to implement the menus, feel free to do so. Once you have decided on the design choices for the board, communicate this to the game state team.
This is to test the final program. Given all of the scripts and the visual Game Objects, you will have to attach the scripts to the Game Objects in the correct locations – consider at which point each script should run and also what Game Objects each script requires local access to. Then, build the program and test manually. You will also have to use a testing framework to write some test scripts. Communicate with the main game team to find out the inputs that the player will use e.g. to flag, to reveal etc. I recommend using Unity’s in-built Unity Testing Framework to write the scripts. For example, there would be a test script which purposely flags a cell and checks if the given cell has indeed been flagged etc. Other tests include win/loss, invalid clicks/inputs, reveal, UI menus and buttons etc. Also, you should ensure that the tests are performed on both smartphone and desktop platforms. Any bugs should be communicated back to the responsible team for them to fix.
This is to handle the data from the player and to display it in an accessible format for the client to use. Using a database service, once given the state of the final game from the main game team, you should generate a “score”; a way to measure the performance of the player. Some basic rules should hold regarding the value of the score e.g. a win should always be better than a loss, whilst a loss after more moves should be better than a loss after few moves. If you wish to use a different metric instead of the number of moves, feel free to do so, but make sure to communicate this to the main game team at the earliest opportunity. This score should be stored alongside the user’s names and email securely on a database. The client should be able to securely access said database, using special credentials. Then, there should be an option for the client to view a “leaderboard” of, say, the top 8 players with the highest scores. An option for the client to look up an email address and be able to find the corresponding names and score should also be implemented. Also, lookup via names – if multiple people share the same names, then provide a list of emails and scores of all such people. The data should be stored separately from the program i.e. so that the database is kept updated across multiple instances of the program running and so that the client can properly access the database – if database access can be done without having to run the game, that is more preferable.
The game will open with a menu for the player to input their first name, last name and email address. Then, the main game will begin. The player’s moves will be watched and the grid of cells will be visually updated accordingly. At any stage of the game, the player can access a popup menu to see how to play. Once the game has finished, a score linked to the final state of the game as well as the player’s details are stored on a database. Then, the player is informed of whether they have won or lost.
P.S. If anyone thinks of a good name for the game, I would appreciate it if you would let the group know.