Programming Language Concepts was a class that taught me a lot in college. Not only because of the content, but also because it was the only class I had to retake. There were two great lessons in this. One, there is no point in building or deploying if you don’t understand the problem. Two, solving the same problem multiple ways is an invaluable exercise.
The course was great because it focused on the same problem all semester, with each week or two changing the programing language used to solve it. It was an incredible lesson in critical thinking. When I switch from C# to JavaScript to PowerApps, the code is similar enough that I can translate pretty quickly. But when switching languages with major differences, it can be completely new (I’ll share at least one example later).
Luckily for me, I did not fail the course, but I was not able to maintain the grade required for my degree program. While the languages were all foreign to me, learning them was not the reason I could not make the grade. It was pride (okay, maybe there are more than two lessons here). I did not understand the problem, and I was afraid to admit it. The problem we had to solve was around Roman Numerals. This was something I never learned and did not understand (and still struggle with today). I thought I could figure it out along the way, but my programs continued to give wrong answers each week. Since I was not asking for help, the professor assumed I did not know how to code correctly. It did not seem that major then, but now that I have been working on software implementation projects for a couple decades, I have seen the same issues on a much larger scale.
So many times we think we understand the problem, then rush off to solve it without asking enough questions. Weeks go by before we present our solution, only to find out it does not meet the needs. This is one of the reasons we have adopted an Agile approach to building and show prototypes as often as we can. As the saying goes, fail faster. This is also why I try to be faster in admitting when I do not understand something.
The second lesson comes from my repeated journey through the course. In a small miracle, the problem to solve changes each semester, so in the second round, we had to convert money denominations based on efficiency. I had a better understanding of the issue and therefore could focus on learning the languages. This method of applying something you know to something new has stuck with me since then (the pride thing has as well; it turns out my professor was an amazing person that would spend hours one-on-one if you asked for help).
Learning PowerApps
This brings me to PowerApps. PowerApps is not too difficult to learn, unless you are more of a “High Code” type of person that has not been developing daily for a while. While looking through materials and samples, I realized this was another great opportunity to apply this method.
Now for a little context, the first time I tried this in my career was when I was first programming and did not have a lot of ideas to use for reference. I had a great mentor with loads of sample projects, but I needed deeper understanding of VB6 (which I do not miss). I went through a mental list of things I understood that I thought might be simple. And when I needed a break, I played Minesweeper (back in the day when free games came without ads!).
It was something my older cousin and I used to play in the Windows 3.1 days (I want to say it was a 386 machine?). It’s a simple concept based on a grid of mines with numbers that you solve by not clicking on mines. Play it long enough, you will start to recognize patterns and learn short cuts. I had set my personal records for each level, beat each level without using flags, etc.
This is when I realized that this simple game could be fun to re-create. It is also a great example of using recursion (another great programming class). Unfortunately, VB6 was not the greatest for recursion, nor did randomizing work as expected, but it reinforced the lesson that trying something new led to different solutions to the same problem. It took a while, but I did end up with a (mostly) working example that still (mostly) works today.
While I was no VB6 expert, any more than I have become an expert in any language, the exercise taught me more about it and built my confidence. A few years later, when I needed to learn Dynamics Dexterity, I went through the same exercise and built a rudimentary example that ran inside of Dynamics GP. And again, when learning C#, I was able to learn quickly and given the robustness of the .NET framework, I was able to build the best example of all my attempts.
So, since old dogs can’t learn new tricks, I’m going to use this old trick to learn something new.
Minesweeper in PowerApps
So, as I was reminiscing about learning new languages, I wanted to build a game with PowerApps. If there is anything I’ve learned from my experience, a good ol’ fashioned web search is the place to start. As luck would have it, I only found one other person that attempted this, and they were kind enough to share it. This helped tremendously, as the form and collections were already laid out, which left me to implement the logic to make it perform like the original game. I really can’t take credit, as the layout and recursion were done so well, I did not change much. I did, however, learn a great deal about collections and the code needed to make this work with Power Automate.
So how to build this, knowing there are several ways to do it and it’s rare for two people to do it exactly the same. I really liked the original structure of using dynamic collections to generate the grid, but adding a Dataverse table to run the level selection seemed like a great way to make it even more dynamic. As Dataverse is the backend data storage for Power Platform, creating a table to hold this information turned out to be simple. And by this method any future updates to the options would be a simple table update and not code.
In order to follow the original design, I changed the board layout table to hold three options (removing the custom option for simplicity):
Level 1 (Beginner): 8 by 8 with 10 mines
Level 2 (Intermediate): 16 by 16 with 40 mines
Level 3 (Expert): 30 by 15 with 99 mines
The next item to tackle was the random mine logic. In previous versions, using a randomized list of the total number of mines across the number of cells worked, so I started there. The problem was it required more code than seemed necessary and the loop to update the collection was not efficient. That’s when I found a video about shuffling (did I mention how great the Power Platform community is?). In this video about building a bingo game, I not only learned an incredibly efficient way to get a random list, but I also learned I was not the only one use a game to demonstrate how powerful these apps can be.
The Power of PowerApps for Learning
What stood out most to me during this learning is how powerful and easy to use the collections are. So many functions ended up being one line of code that performed complex operations. For instance, to get the shuffled number of mines, count the number of mines around a cell, and clear the board all were simple statements. I was amazed how easy the filtering was, and how short my code file ended up being. The great thing with this method is all of the work can be handled by the collection. The original build—setting the mines and calculating the surrounding mines—all happens in the collection.
As the collection is updated with interactions by the user, the events on those objects trigger changes in the collection, that in turn updates the visuals of the objects in the collection. I think this is another great example of why the Power Platform is so valuable—you can quickly and easily create robust applications and allow the platform to do the heavy lifting.
Finishing Touches
With the main logic done, it was time to put on some finishing touches.
Another thing I wanted to include, which deviates from the original design, is the board layout should be static. In all other examples, the first click cannot be a mine. This means that if you click a mine, that mine is moved and the board changes. To me, the board should be static and if you click a mine, you have start over (call me a purist or perhaps just harsh).
Some of the additional items I included to mimic the original design was a timer to track the length of the game, and a mine counter to show how many mines were flagged. Both of which were easy based on the Power Platform objects available and did not require a lot of time. Finally, I did some clean up on my code to ensure reusability and general ease of use, to include putting code into buttons so it can be called from other methods, removing duplicate calls, and some overall commenting.
Other items I have to credit the original author with are setting the number values, determining the win, and the genius method of using the status change to trigger the recursion that opens cells automatically when one clicked cell is empty. I can’t thank them enough for sharing their work so I could learn so much during this exercise. The original project, and the one with my changes can be found in the original link.
It’s not a complete solution as I used it more of a learning exercise, but I feel like it highlights the power of the platform and that it can be fun. Below is a list of open items as well. I hope this can be helpful to others looking to learn more, and I welcome any comments and feedback.
Issues/Improvements
- As noted in the original post, performance is not great. I was able to improve it some by moving the board/collection creation to the level selection, and with streamlining the number calculations, but randomly determining the mine locations still takes time, and anything with the larger boards are slow.
- Right clicking doesn’t work, so the method the author used was a nifty work around of the first click sets the status to a flag, and a second click set the status to open.
- The mine count can get off in certain game loss scenarios.
- Mines can be increased if the new button is pushed while loading a game.
- Even after trying several methods, I was unable to run anything at application load, like starting a new game. So the game starts with having to select the level.
- There is a recursion status check that should not be needed, which means something is causing an event that should not.
- There is potential to make the grid objects more efficient.
- The board should be disabled on game over and show the triggered mine.
- Cell text should not have the ability to be selected.
- Flagging vs clearing options are not as smooth as the original game due to the right click functionality limitation.