<commit_before>---
layout: post
title:  "Game of the Amazons"
subtitle: "Fire burn!"
date: "2019-06-15"
categories: amazons js react
---

Game of the Amazons is a lot like chess except all pieces cannot be killed, move like queens,
and shoot fire arrows that also move like queens.

Ok, maybe it's not like chess at all.

In short, Game of the Amazons pits two players on a grid with an equal number of pieces or "Amazons."
Each player takes turns moving their Amazon and firing an arrow from it,
both actions functioning like the queen's
movement in vanilla chess. When an arrow is fired onto a square, the square "catches fire" and becomes
a barrier, blocking future movement and arrow firings. The game goes until one of the players cannot
move anymore of their Amazons.

![Game of the Amazons](/images/amazons/amazons_01.gif)

I started getting interested in the game after watching a
[Numberphile video](https://www.youtube.com/watch?v=kjSOSeRZVNg)
on it a while back. Mathematically, it seems to be a very interesting and
difficult game to solve. I wanted to experiment around with something more than the
toy example given in the video and started scouring the internet for a playable version.
I must've been really shot in the head that day because I could not find anything other
than Michael Keller's version of the game for Windows 3. Getting that
to run was an adventure all on its own (see Appendix A).

Disappointed at the relative lack of Amazons online, I did the only reasonble thing
a bored college student would do: Write my own!

## Design

My goal was to build something similar to Keller's implementation. I wanted to make
it easily accessible and experiment with learning React as well so making it in the browser was the natural choice.

I also knew I wanted to separate out my UI code and my game logic from the start. The Amazons game
was going to be abstracted out into a set of possible actions that the UI code would interface
the game with.

## Starting React

Before this, my experience with React was next to none, so most of this was an uphill fight.
I also wanted to make this solely a browser project which meant avoiding Node as much as possible.
I ended up getting React as a CDN and started testing out some sample JSX... But hold up! The browser
doesn't understand JSX! A quick search taught me about the Babel compiler which among many things
can apparently transform JSX into browser-compatible Javascript.

I did the Babel transformation in the browser which popped up a warning telling me to transform before
serving in production. I ignored it at first but later in the project, I did some digging and found out
I could compile and bundle JS using Webpack first and simply include a single, bundled script file.
Of course this meant going back near Node since I was using npm again. However, it seemed that Webpack
just transformed and bundled the scripts without involving anything server-side. I think my fears
were mostly in wrongly associating Node with being exclusively linked to doing server work.

Anyways, with JSX working, I could finally go my merry way and get started.

## Amazons Game Logic

Game logic was contained within a single class that would keep track of the state of the game and provide
a set of interfacable actions for the game.

I split the functionality of the game into 3 different actions: choosing a piece, moving a piece, and firing
an arrow. Each action would accomodate for the state of the game and alter the board accordingly,
usually setting for the next action to take place. This scheme worked very well for player vs player
games as it made every action easy to link to some event that happened on the UI side. However,
as I started adding rudimentary AI later, I found it to be quite troublesome, needing to save the
state of the Amazons instance as actions would directly alter the board.

I also needed a way of highlighting where the pieces could move and fire. Since they follow the movement
rules of queens, I had thought to originally just highlight the 4 lines going through the piece. However,
this presented a problem: I was unable to detect when a barrier was blocking movement. In the end,
I switched over to doing a very watered-down raycast. Normally, raycast is something seen in graphics where,
a vector is incrementally traveled along until it ends up within or on some mesh. Here, however, I simply
needed to travel along the eight directions on the grid, stopping when I hit a barrier or the edge of the grid.

![Game of the Amazons](/images/amazons/amazons_02.png)

## Wrapping Up

The rest of the project was mainly linking up the UI with the game logic, making sure users couldn't pull off
illegal moves and break the game. I also added some extra features like a board reset, a dialog that displayed
the state of the game, and a log of player moves.

I also wanted to try adding AI but realized that it was its own can of worms. Moreover, the possible moves
in Amazons is very large in the opening making the AI very slow as I tried to add in a heuristic. Perhaps
with the advent of web assembly and more time, I could properly sit down and try to write something that
would work and run reasonably fast but that's for another time. For now, the AI option simply has the agent move randomly
until the number of possible moves it can make thins down. At that point it switches over to
greedily using the relative territory heuristic that tries to maximize square ownership.

## Conclusion

In retrospect, doing this write-up and retracing my steps and thoughts, I feel like this was a project
where a few things were done right but many could have been done better. For one, I severely underestimated
the number of implementations of Amazons floating out there. I think a decent number of people got the same idea
as me after watching the Numberphile video and set out to make their own versions. Additionally, instead of taking the
path of least resistance, I ended up installing Windows 3 to play Amazons to begin with and then
re-invented the wheel to make my own JS version. The journey itself was fun and I frankly learned a lot
from simply finishing this project, but it's also something that shows I should be more aware of
my own naivities and perhaps do better reconnaissance before starting things.

On the other hand, this project was my gateway into a larger browser JS project along with learning more of
the language and its accompanying resources. Amazons itself often served as a small reprieve from school. I
would often boot-up my VM and play Keller's implementation with the AI or friends.

Currently, the project is live [here](/demos/amazons) to play around with.

## Appendix A: Fun with Windows

For some reason I was really intent on getting <NAME>'s Game of the Amazons implementation up
and running. The oldest Windows system I had ever used was XP so anything older was truly a mystery.
Internet searches convinced me Keller's game was supposed to run on Windows 3 (although it may have been
fine on Windows 95).

Windows 3 runs on top of MS-DOS.
At first, I got DOSBox but couldn't figure how to install anything on top of it. The only other way
I could think of to get Windows 3 was through a virtual machine. I created a new MS-DOS VM in VMware,
but when I went to find images of MS-DOS and Windows 3, I found myself greeted with about 3 to 7 floppy
disk images. Vintage. Turns out I can choose to add a floppy drive to my VM as well, so pretending to be from a
bygone era, I loaded the images into my virtual floppy drive, switching them out when prompted to
to obtain my version of MS-DOS. Then doing the same procedure, I installed Windows 3 on top of it.

How was I going to transfer my copy of Amazons to my VM though? I figured well since the floppy drive
worked so well, why not just burn it on an floppy disk image like everything else and load it in? Sure enough it worked.
Missing a DLL? Do the same thing and copy it to where it needed to go. 

As someone who thought VHS tapes were ancient when I was young, seeing this kind of old tech was a little
exciting. Floppy disks are only around half a century old at the time of this writing, so it really makes
you think about how fast technology advances. We take a lot for granted these days too. First booting up
Windows 3 after installation, I was asked if I wanted to know how a mouse worked. A mouse. Of course everyone
knows how a mouse works! But not those who grew up on a terminal right? Windows 3 also had some
different widgets on their windows. We're mostly used to the standard minimize, expand, and exit widgets today
but on Windows 3, I was trying to make heads and tails of these minus signs and up and down arrows!

![Windows 3 mouse tutorial](/images/amazons/win3_mouse.png)

I'm sure older developers are rolling their eyes as they read this, but that's how I really felt. We treat
a lot of technology as "duh" and "it's always been this way" but the truth is that there were many prototypes
and versions that came before our obvious standards today. It's quite fascinating and also makes me slightly
afraid that in the future, I will be one those people complaining how, "Yer new-fangled 3D desktop don't
make no sense! In my day, we had 2D windows" or something like that.<commit_msg>Fix link to amazons demo<commit_after>---
layout: post
title:  "Game of the Amazons"
subtitle: "Fire burn!"
date: "2019-06-15"
categories: amazons js react
---

Game of the Amazons is a lot like chess except all pieces cannot be killed, move like queens,
and shoot fire arrows that also move like queens.

Ok, maybe it's not like chess at all.

In short, Game of the Amazons pits two players on a grid with an equal number of pieces or "Amazons."
Each player takes turns moving their Amazon and firing an arrow from it,
both actions functioning like the queen's
movement in vanilla chess. When an arrow is fired onto a square, the square "catches fire" and becomes
a barrier, blocking future movement and arrow firings. The game goes until one of the players cannot
move anymore of their Amazons.

![Game of the Amazons](/images/amazons/amazons_01.gif)

I started getting interested in the game after watching a
[Numberphile video](https://www.youtube.com/watch?v=kjSOSeRZVNg)
on it a while back. Mathematically, it seems to be a very interesting and
difficult game to solve. I wanted to experiment around with something more than the
toy example given in the video and started scouring the internet for a playable version.
I must've been really shot in the head that day because I could not find anything other
than <NAME>'s version of the game for Windows 3. Getting that
to run was an adventure all on its own (see Appendix A).

Disappointed at the relative lack of Amazons online, I did the only reasonble thing
a bored college student would do: Write my own!

## Design

My goal was to build something similar to Keller's implementation. I wanted to make
it easily accessible and experiment with learning React as well so making it in the browser was the natural choice.

I also knew I wanted to separate out my UI code and my game logic from the start. The Amazons game
was going to be abstracted out into a set of possible actions that the UI code would interface
the game with.

## Starting React

Before this, my experience with React was next to none, so most of this was an uphill fight.
I also wanted to make this solely a browser project which meant avoiding Node as much as possible.
I ended up getting React as a CDN and started testing out some sample JSX... But hold up! The browser
doesn't understand JSX! A quick search taught me about the Babel compiler which among many things
can apparently transform JSX into browser-compatible Javascript.

I did the Babel transformation in the browser which popped up a warning telling me to transform before
serving in production. I ignored it at first but later in the project, I did some digging and found out
I could compile and bundle JS using Webpack first and simply include a single, bundled script file.
Of course this meant going back near Node since I was using npm again. However, it seemed that Webpack
just transformed and bundled the scripts without involving anything server-side. I think my fears
were mostly in wrongly associating Node with being exclusively linked to doing server work.

Anyways, with JSX working, I could finally go my merry way and get started.

## Amazons Game Logic

Game logic was contained within a single class that would keep track of the state of the game and provide
a set of interfacable actions for the game.

I split the functionality of the game into 3 different actions: choosing a piece, moving a piece, and firing
an arrow. Each action would accomodate for the state of the game and alter the board accordingly,
usually setting for the next action to take place. This scheme worked very well for player vs player
games as it made every action easy to link to some event that happened on the UI side. However,
as I started adding rudimentary AI later, I found it to be quite troublesome, needing to save the
state of the Amazons instance as actions would directly alter the board.

I also needed a way of highlighting where the pieces could move and fire. Since they follow the movement
rules of queens, I had thought to originally just highlight the 4 lines going through the piece. However,
this presented a problem: I was unable to detect when a barrier was blocking movement. In the end,
I switched over to doing a very watered-down raycast. Normally, raycast is something seen in graphics where,
a vector is incrementally traveled along until it ends up within or on some mesh. Here, however, I simply
needed to travel along the eight directions on the grid, stopping when I hit a barrier or the edge of the grid.

![Game of the Amazons](/images/amazons/amazons_02.png)

## Wrapping Up

The rest of the project was mainly linking up the UI with the game logic, making sure users couldn't pull off
illegal moves and break the game. I also added some extra features like a board reset, a dialog that displayed
the state of the game, and a log of player moves.

I also wanted to try adding AI but realized that it was its own can of worms. Moreover, the possible moves
in Amazons is very large in the opening making the AI very slow as I tried to add in a heuristic. Perhaps
with the advent of web assembly and more time, I could properly sit down and try to write something that
would work and run reasonably fast but that's for another time. For now, the AI option simply has the agent move randomly
until the number of possible moves it can make thins down. At that point it switches over to
greedily using the relative territory heuristic that tries to maximize square ownership.

## Conclusion

In retrospect, doing this write-up and retracing my steps and thoughts, I feel like this was a project
where a few things were done right but many could have been done better. For one, I severely underestimated
the number of implementations of Amazons floating out there. I think a decent number of people got the same idea
as me after watching the Numberphile video and set out to make their own versions. Additionally, instead of taking the
path of least resistance, I ended up installing Windows 3 to play Amazons to begin with and then
re-invented the wheel to make my own JS version. The journey itself was fun and I frankly learned a lot
from simply finishing this project, but it's also something that shows I should be more aware of
my own naivities and perhaps do better reconnaissance before starting things.

On the other hand, this project was my gateway into a larger browser JS project along with learning more of
the language and its accompanying resources. Amazons itself often served as a small reprieve from school. I
would often boot-up my VM and play Keller's implementation with the AI or friends.

Currently, the project is live [here](/amazons-js) to play around with.

## Appendix A: Fun with Windows

For some reason I was really intent on getting Michael Keller's Game of the Amazons implementation up
and running. The oldest Windows system I had ever used was XP so anything older was truly a mystery.
Internet searches convinced me Keller's game was supposed to run on Windows 3 (although it may have been
fine on Windows 95).

Windows 3 runs on top of MS-DOS.
At first, I got DOSBox but couldn't figure how to install anything on top of it. The only other way
I could think of to get Windows 3 was through a virtual machine. I created a new MS-DOS VM in VMware,
but when I went to find images of MS-DOS and Windows 3, I found myself greeted with about 3 to 7 floppy
disk images. Vintage. Turns out I can choose to add a floppy drive to my VM as well, so pretending to be from a
bygone era, I loaded the images into my virtual floppy drive, switching them out when prompted to
to obtain my version of MS-DOS. Then doing the same procedure, I installed Windows 3 on top of it.

How was I going to transfer my copy of Amazons to my VM though? I figured well since the floppy drive
worked so well, why not just burn it on an floppy disk image like everything else and load it in? Sure enough it worked.
Missing a DLL? Do the same thing and copy it to where it needed to go. 

As someone who thought VHS tapes were ancient when I was young, seeing this kind of old tech was a little
exciting. Floppy disks are only around half a century old at the time of this writing, so it really makes
you think about how fast technology advances. We take a lot for granted these days too. First booting up
Windows 3 after installation, I was asked if I wanted to know how a mouse worked. A mouse. Of course everyone
knows how a mouse works! But not those who grew up on a terminal right? Windows 3 also had some
different widgets on their windows. We're mostly used to the standard minimize, expand, and exit widgets today
but on Windows 3, I was trying to make heads and tails of these minus signs and up and down arrows!

![Windows 3 mouse tutorial](/images/amazons/win3_mouse.png)

I'm sure older developers are rolling their eyes as they read this, but that's how I really felt. We treat
a lot of technology as "duh" and "it's always been this way" but the truth is that there were many prototypes
and versions that came before our obvious standards today. It's quite fascinating and also makes me slightly
afraid that in the future, I will be one those people complaining how, "Yer new-fangled 3D desktop don't
make no sense! In my day, we had 2D windows" or something like that.

**UPDATE 11/15/20**: Update with new link to demo
{'fraction_non_alphanumeric': 0.030065919931400398, 'fraction_numerical': 0.003751540811404684, 'mean_word_length': 4.183333333333334, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '213235', 'n_tokens_mistral': 4648, 'n_tokens_neox': 4443, 'n_words': 3293}