Intro to the ENCMP 100 Programming Contest

This whole project started in my second semester of my first year of engineering. One of the courses that we are required to take in the first year is called "ENCMP 100", or "Programming for Engineers". I was pretty excited about taking this course since I had a background in programming and thoroughly enjoyed the subject. However, since the course was geared towards absolute newbies to programming, I found it very difficult to be engaged with the material. The course moved at a painfully slow pace (to the degree that we spent an entire week on VARIABLES). It was really hard to sit through these lectures on basic programming concepts I had literally years of experience with already.

Additionally, the main focus of the course was the "MATLAB" programming language. For those of you who know what MATLAB is, you probably already know where I'm going with this. For those of you who don't, MATLAB is a programming language designed for mathematical, scientific and engineering applications. It is not a general-purpose programming language like C++, Java, or Python. It has many strange constructs that are intended to make it "more intuitive" to engineers and scientists who don't have a strong programming background. However, some of these constructs go against what you learn in programming, and so it feels like a sort of "blasphemy" to write code in MATLAB (like seriously, why do array indices start at "1" and not "0" in this language?)

Naturally, I decided to get ahead in the course to try and speed things up and keep things interesting, but that only helped for so long. By week 3 of the semester I was already wrapping up material for week 10, and was on track to have the entire course done in a month. This might sound like a good thing as a first-year engineer, as on paper it gave me more time to devote to my other classes. In practice however, this was a burden: since the course still released assignments and classwork on their schedule (and not mine), I could only get ahead in the lecture material, not the assignments. I was still burdened with the time-consuming works of semi-regular assignments from that course. Needless to say, it was a painful experience. But, everything changed one day in January when my professor made an announcement.

My professor announced that later in the course there would be an optional programming contest that was tied to the course. It wasn't for marks, just purely for fun. Given that I found all of the assignments pretty easy, I was intrigued because I wanted a challenge. In early February, all of the details of the contest were released, and we were given about a week to sign up for it. I decided to go for it because it was going to be a new and interesting experience for me. Although I had spent a lot of time programming for personal projects, I had never really shared anything I did because I wasn't confident enough in my abilities to program and not get scrutinized for a lack of programming skill in the eyes of others. With that considered, jumping all the way to a programming competition was quite a stretch, and so I made sure to give it everything I had in order to have a chance at winning. I felt like the competition would give myself the opportunity to prove to others, but even more importantly myself, that I could make something good if I really applied myself.

For a bit of background, the competition worked like this. You would register before the end of the first week of February, and then you would have until March 27th to code the program. You had to document your process because one of the criteria for judging competition entries was the process (ex. if you left the whole project to the end of March, you wouldn't score well). They wanted students to spread out the workload fairly evenly. You were also allowed to have 1 partner, but no groups larger than 2. You also had to produce a video showing off your project, the timeline for it, and other details relating to it. This was also a very important criterion.

I decided early on that I wanted to find a partner for this competition because I felt like with how busy I got with school, I needed an additional person to keep me responsible for completing it. It would also be good to have an extra set of hands working on it as it would speed up some of the optimization processes and would also help me overcome particularly troublesome hurdles in the code. I knew a guy who lived on the same floor as myself in my residence building who liked to program as well, and so he was ultimately the one I entered the competition with. I remember that he wasn't really confident that he could contribute to the competition because he didn't have as much experience as I did, but I had a feeling that we would both be carrying our own weight for this project.

A picture of the window that pops up at the end of the program's run time. It displays four different plots which all contain information pertaining to the environment. The user can extrapolate correlations between the user-specified inputs and these outputs by comparison.

We also had to decide what we wanted to do for our project. Our first ideas involved working with neural networks, as I had finished the MATLAB neural network project shortly before the competition details were released. Despite being really interested in neural networks, I didn't really want this to be our project for a few reasons. Firstly, I knew that the project would either be way too easy or way too hard, and would not be within a reasonable range of difficulty. We would either end up using MATLAB's Deep Learning Toolbox, which would make a neural network project just a little bit too simple and not complicated enough for the scope of the competition. Or, we could program the framework of the neural network from the ground up similar to what I did in my project, but this would be too difficult to implement in a meaningful way that has a result we could actually show off that isn't just abstract numbers and other gibberish. On top of that, we didn't really know what we wanted to apply a neural network to. It would have to be something interesting and easy to show off so that the graders would be interested in it, but we didn't have any ideas.

I came up with the idea that eventually became the project from a combination of two things. First of all, I saw a similar idea in a video on YouTube about someone creating a project that simulates natural selection. I thought that the idea was pretty interesting, and I ended up mentioning it in a conversation later with both my partner and a computer science student who also lived on my floor. We were hanging out in the floor lounge talking about programming stuff, and I brought up the project I saw on YouTube. The computer science student said that he was thinking of making something similar, and my contest partner thought it was interesting. We talked about different twists you could take on the project, and an interesting idea that came up was an evolution simulator. This was ultimately what my partner and I chose, as it felt both complex enough to score well in the competition but not too difficult to achieve within the span of about two months. We also felt that it would be an adequate use for the MATLAB language, as MATLAB exceeds in data visualization and scientific applications and it was fitting to have a highly data-oriented project to go with it.

Project Planning and Theory

The very first thing we had to decide when we began the project is what we actually wanted to achieve with it. This was pretty straightforward, and all we had to do was organize these ideas. The primary ideas that we set as targets for the project were:

The goal on the above list that we started with was actually the visualization aspect of the project. At the time we were both still very new to MATLAB, and we weren't familiar with the extent of MATLAB's data visualization features. We began by exploring these features to see how we were going to visualize any number of moving entities in real time. We quickly discovered the image function, which took a matrix as an input and created a figure that displayed it. This function was useful because there were a few interesting things that we could do with it. First of all, we could resize the window to our liking using MATLAB's set function, despite the fact that the set function itself didn't appear to have that as a built-in feature. As the figure produced was a bit small, we figured that this would be mandatory for a satisfactory user experience. Secondly, if we were to change a value in the matrix and then call the image function again, it would keep the current figure window open and just update the matrix. This was really useful because it allowed us to animate the matrix, which meant that we could use it as a sort of screen for all the action inside of the simulation. It also updated surprisingly fast, which made it viable for real-time simulation as well. Finally, one last nice feature MATLAB has for data visualization is the ability to create custom colour maps for the data in the matrix. This would allow us to fine-tune what every number in the matrix corresponded to on the map and would give us full visual control over the elements of the simulation, at least in terms of colour. As an added bonus, we could also use the set function to change the title of the plot as well as the title of the window. This did end up being our method of visualization, and it worked well throughout the production of the program.

After we solved the environment visualization problem, the next goal we tackled was the genetics system. We didn't necessarily implement it in a practical way right off the start since we didn't even have the bases for the animals in yet, but we were approaching it from a more abstract, mathematical approach. We wanted to find a way to express the dominance of genes and their overlapping behaviour during reproduction as mathematical equations that MATLAB would be able to understand. We also wanted to tailor the equations specifically for the simulator so that we would observe the perfect amount of genetic variation in the simulator as the generations went on.

Project Timeline and Challenges

One of the big challenges we faced all throughout the span of the project was the optimization of the code. Our project idea was already an uphill battle because of how complex it was, but on top of that, we had to do it in MATLAB, which is a very slow programming language. This made good optimization of the system absolutely essential.

Something that my partner and I spent quite a bit of time on was the analysis of how MATLAB handled different data types, and how using certain types would affect processing speed. Fortunately, one really nice feature of MATLAB is the `tic` and `toc` functions, which start and end a timer respectively. This allowed us to benchmark the effects of working with certain data types in mass down to the millisecond, which helped with determining the fastest way to compute the simulation. MATLAB has a number of integer and double variants that each consume a different amount of memory and also have a different level of accuracy. We found that the difference between lower and higher memory decimal values was almost negligible, and that we actually lost more performance converting different data types than we gained from using singles as opposed to doubles in our computation. A workaround was to initialize certain values as singles and others as doubles, and this did actually work as long as there were no interactions between the two categories, which we minimized for the simulation.

Conclusion and Results

One of the key takeaways from this whole project, at least for me, was the importance of good program structure in bigger projects. This was one of the first big coding projects that I had completed, and so a lot of features that I normally would not have to implement (ie. several different OOP classes and structures). We originally began the project without too much structure, with the only classes in the project being that of the animals and the predators. However, once we began to implement some of the more complex features such as resources and reproduction, we quickly realized that we were going to need to restructure the program to make some of the calculations work. By adding a controller class to handle a lot of the repetitive computations, it made the whole process a lot smoother. We likely would not have finished the project if we hadn't included that class.

After all this, we got an email back from the competition coordinator about 2 weeks after we sent it our submission. He responded to us to tell us that we actually won 1st place in the contest with our submission, which was a really exciting moment for the both of us. I had never entered a programming competition before and I had always been too self-conscious about my programming skills to enter anything serious in the case that it was way over my level of programming knowledge and that I wouldn't be able to do anything useful. I think that this competition greatly improved my confidence in my programming abilities and made me way less scared of sharing my ideas with others.

Download and Usage

To run this program, open main.m in MATLAB (version 2019b or later) and run that script. Make sure the rest of the files are in the same folder so the script can access them.

A picture of the first screen that shows up when you launch the main.m file.

When you run the program, you'll be met with an interface that looks like this. There's a number of parameters that users can change in order to play aruond with the outcome of the simulation.

  1. Environment Size - This parameter controls the size of the area that the animals can move around in.
  2. Number of Animals - The initial count of prey in the environment.
  3. Number of Predators - The initial count of predators in the environment.
  4. Number of Steps - The duration of the simulation. The program uses a step-based system that updates up to 200 times a second (although it never actually reaches that maximum due to how slow the MATLAB language is).
  5. Food Multiplier - A multiplying factor that controls the amount of food introduced into the environment per iteration.
  6. Food Frequency Multiplier - A multiplying factor that scales how frequently food is introduced into the environment.

A screenshot of the help page. The text above is a recap of the contents of this page.

I also created a help page for users to have an in-application explanation of all of the factors. This wasn't a feature that we planned to add but after we started adding the different parameters that could affect the simulation, we realized that the program was a little unintuitive for other users.

After you've set your parameters, click the "Start" button on the main page. What you'll be met with is a window that looks like this:

The image above is an active display of everything that is occurring in the environment. It is a matrix whose size is determined by the size parameter set in the first menu. You can also see the duration of the simulation (controlled by the step number parameter) in the top of the window. Each coloured pixel represents something in the environment according to the guide below:

Colour of Square on Grid What it Represents
Black Nothing present in that area of the environment
White An animal (prey). Eats natural food only.
Red An animal (predator). Eats prey only.
Blue Food (for the prey to eat).
Pink An animal (prey) that is mature and seeking a partner to have offspring with.
Dark Red An animal (predator) that is mature and seeking a partner to have offspring with.

The display is programmed to update up to 200 times per second, which may sound like a lot until you realize that it will never come even close to that number in pratice. The speed of MATLAB is one of the main reasons for that, as discussed in the "Challenges" section.

After the simulation is complete, you will be met with a screen like the one above. This allows you to extrapolate the general behavior of the simulation given the configuration.