Computer Science · Projects

A* Demo in Processing

Pathfinding has been with us for a very long time. From Marco Polo to Christopher Columbus, the adventures and misadventures of getting from one place to another have been turning points in history. As it turns out, being able to navigate from one point to another is a really useful thing to be able to do – and so, computer programmers have figured out a way (in fact, many ways) to do it using computers. You probably use these algorithms all the time. Every time you get directions from Waze or Google Maps, you’re using a pathfinding algorithm that probably works very similarly to this simple example.

Consider a grid, like a chessboard. Imagine yourself put on one of these squares, and told to find a path to some destination square. You know what direction it’s in, so you start walking towards it. If you hit an obstacle, you try to walk around it, and eventually you reach your goal. Computer scientists call what you just did a Greedy Best-first search – at every step of your process, you tried to get as close to your goal as you could, based on some guess of which steps would take you closer. This got you to the destination eventually, but you probably spent a lot of time finding your way around obstacles.

Let’s try this example again, but this time, you want to avoid knocking into any walls. Instead of immediately finding your goal and moving towards it, you instead start searching the tiles around you. Because you want to walk as little as possible, you explore the squares closest to your starting point, and explore outwards in this fashion until you find your destination. This gets you a shortest path (for there may be many equally short paths) towards your goal. We in the computer business call what you just did Dijkstra’s Algorithm (no, I can’t help you pronounce that, but Wikipedia can). It got you the best path, but you spent a lot of time exploring.

On your third attempt at this maze, you decide to combine the approaches of your first two attempts. You want to explore tiles before traversing them to avoid obstacles, but you also don’t want to waste time looking at tiles that aren’t going to help you get closer to your destination. This time, you consider both how far you are from your destination and from your goal when you decide on your final path. This is the secret to the algorithm known as A* (pronounced “A Star”). By looking at both your starting point and destination, you can be both fast and find an optimal path.

A* works using what computer scientists call a Heuristic. This algorithm’s heuristic is the same one that you were using in the first example – how far do I think I am from my destination. For every tile you looked at in example one, you estimated how far it would be to your destination. For every tile you looked at in example two, you could easily see how far it was from your starting point. In example 3, you can say that you added the two numbers together. For every tile you looked at, you combine how far you are from your starting point with how far you think you are from your goal. You can see then that if that number is small, you’ve found a short path (i.e. if you are close to both the start and end). The beauty of A* is that it lets you customize the parameters of your search. If you always take the distance to the destination to be 0, then you’re only looking at the distance to the start (this is Dijkstra’s Algorithm). If you take the distance to the origin to always be 0, then you’re only looking at the distance to the goal (Greedy Best-first). The smaller you estimate the distance to the destination to be, the more time you spend searching but the better your final path. The larger your estimate of the distance to the destination is, the less time you spend searching, but your search takes less time. This ability to customize the algorithm makes its utility clear.

My implementation of A* was done on a 2D grid, on which we generated a maze using Recursive Backtracking and then knocking out some random walls. The maze itself was a class, which stored the maze as a 2D array of GridCell objects, which each had a location on the grid, a randomly generated inherent cost, amd an array storing booleans representing walls on each side. After generating, the Maze object would then make a new instance of the AStar class, which ran on the Maze. The implementation used Java’s built-in Priority Queue, which organized gridCells yet to be looked at by their heuristic cost.

The process of conversion was, to put it mildly, quite a challenge. This was my first time working in JavaScript, and dealing with the differences between it and Java were quite difficult. JavaScript, unlike Java, is an interpreted functional language with weak typing. What does that mean? Java is a compiled language. Whenever I want to run it, I have to translate (compile) it into a form that can run on my JVM. JavaScript, however, is interpreted – browsers load the source code, then look at it and execute it line by line. Java is what we call an object-oriented language. Everything in Java is an object, which we can assign properties to and make instances of. For an example, if you were to describe your house in Java, you might have a “chair” class, and every chair in your house would be an instance of that class. JavaScript is functional – everything in it is a function under the hood. This makes it difficult to use the same ideas as real life – where things are “objects” that share certain properties, it makes many other tasks much easier, and lets you modify your program when it runs in ways that you can’t with Java. Another difference between Java and JavaScript is that JavaScript has many fewer built in functions and data types. This meant that I needed to implement the Priority Queue and the Stack data types myself, but fortunately that wasn’t too hard, as JavaScript has a lot of useful functions of its own that can be run on an array.

For the sake of time and my sanity, my conversion was fairly simple. Rather than completely rewrite the algorithm from scratch, I instead altered my syntax and changed some structures until it ran without throwing errors. Though unoptimized, it let me get the job done in a timely manner.

Thanks for reading, and fly safe!

You can try out my A* implementation in glorious fullscreen by going to https://theocoulson.com/stuff/code/AStarJS/ and pressing Space to start. Use the arrow keys to change the dimensions of the maze. Enjoy!

Computer Science · Projects

Silly Collecting Game (Lonk Gets Rupees)

I’d bet that nobody expected a random project made to get the hang of a visual library to end up here. I mean, nobody expects the Spanish Inquisition, but really. Surely no sane person would spend ages rewriting, refactoring, and debugging JavaScript purely for the purpose of posting to a website dedicated to actual accomplishments! Oh ye of little faith! Lonk must his rupees have, and you shall aid him in his quest! Yes, I am using this website as a front for Lonk’s rupee collection racket. And no, there are no problems with this. Go forth!

[Please note that this thing uses keyboard input. Sorry not sorry to mobile users]

3D Modelling · Art · Computer Science · Dungeons and Dragons · Everything Else

Minis for the DnD Artificer!

As a huge fan of Dungeons and Dragons, I love to have miniature figures for my character. I also love playing tinker and inventor characters, and so when I saw the latest version of the artificer class on Unearthed Arcana (the pdf is on Unearthed Arcana, linked here) I was… excited.
Now, for some context, I’m part of a massive high-school spanning Dungeons and Dragons (DnD) game with my friends, and my character has bounced around a little bit in terms of his class. I was looking for a fun and interesting set of game mechanics, and boy does the artificer have those in spades. So, I took the artificer, choosing the artillerist subclass as the logical choice for someone just coming off of a gunslinger. The big selling point of the artillerist was the ability to build specialized turrets, which participate in combat (These mechanics have been changed in the official release).
A while ago, I bought a miniature figure of my character from the site HeroForge, which I use to mark the location of my character on the battlefield whenever our party engages in combat. Amidst the general excitement about the awesomeness of the new class and the anticipation of our first session in more than a month, an idea came to me – use Tinkercad to make custom miniatures of the turrets I would be placing which I could use alongside my character’s miniature in combat. And so the adventure began.

The first step was to design the miniatures in Tinkercad. To this end, I enlisted the aid of my friend Jawon Lee to come up with interesting concepts for a few of the turrets. The artificer artillerist subclass specifies three types of turrets: Flamethrowers, Force Ballistas, and Defense Turrets. We set to work on concepts, and eventually finished the models you see here. (You can see and download them here)(Jawon completely modeled the turrets on the left and right of the back row, the rest were mine; the little scopes visible on most of the turrets were his idea as well). After a few days of work, we were ready to print.

Now, you may have noticed that the model pictured above has an awful lot of overhangs and hollow areas, normally anathema to most consumer 3d Printers. Fortunately, my school recently acquired a new model of printer which can print both solid, normal plastic and special dissoluble plastic that it uses for supports. Simply placing the model in water (as pictured above) dissolves away the supports, leaving just the original model. Since the materials don’t mix or bond during printing, the resulting edges and overhangs are perfectly smooth. Fun fact – the supports absorb water as they dissolve, so they hang out as a sort of goop for a while before completely washing away; if you’ve ever handled a hagfish, imagine that stuff sorta clinging to the model. Its super cool (and no, I’m not a weirdo, goop is fun and all of you who think this sounds gross need to go and find a hagfish).

After about twelve hours of soaking, the minis came out just about perfectly! because of the small scale, the fine details like the sloped top of the ballista and the tip of the flamethrower barrel came out a bit rough, but in all other ways it was about as cool as can be imagined!

Cheers, and may the dice roll ever in your favor.