Project 1: Rectangles

Group 2: Eric Li, Ludvig Ungewitter

Introduction

The first project, Rectangles, was a game played on a grid board where each player controls n robots and tries to encircle the maximum amount of space on the board by constructing rectangles whose border consists completely of that player's color. The game ends when an agreed on number of moves has been played without any new cells have been claimed. The goal of each group is to implement algorithms that govern the behavior of the player's robots in order to be the best at winning the game.

Strategies

The dilemma with the game is that there is no general optimal strategy. Different strategies will apply to different board densities and to different players. Also, the opponents are unknown prior to the start of a match. The option of choosing a strategy that fits a certain opponent, therefore, does not exist. However, you do have access to various parameters such as board size, number of teams, number of robots, and number of free spaces. These parameters can wisely be used as guidelines for what strategy to use at what time.

Choosing the correct strategy based on parameters is no trivial task. There are many different directions that can be taken. Each robot can be constructive or destructive. A constructive robot tries to build rectangles, whereas a destructive robot tries to destroy other players' rectangles. A team can assign all its robots to be destructive or just a few. Different constructive techniques have their own tradeoffs. For example, a constructive player may attempt to enclose a large rectangle. If successful, this will net the player a large number of points relatively fast. However, the larger the rectangle the longer it takes to complete and the higher the risk of having another player interfere. If the player attempts to construct only small rectangles, there is much less risk of being disrupted but the points earned is also much less.

From analysis and discussion of the previous year's players, we were able to see the various strategies that the previous groups had come up with and their relative effectiveness against each other. Since we had access to the code, our group was able to do some extensive analysis of our own to profile the various strategies we had seen and use that to innovate our own strategy. In general, the primary strategies can be categorized into either offensive or defensive types, so we shall give an enumeration of the important ones (We leave out strategies such as walking around the border or moving randomly or being idle because we don't consider those viable strategies) and what we noted about each. The reason we go into quite a bit of detail even on strategies we didn't use in our final player is that we have actually implemented and tried our own variations of all of these strategies so they were important stepping stones for us.

Offensive Strategies

These are the primary categories of offensive strategies. There were numerous variations on each and some groups used more than one. But they could all be broken down into these.

Defensive Strategies

These are the primary defensive strategies that we knew of. There were other defensive strategies out there that we didn't talk about because we didn't explore in those directions. From these strategies, both offensive and defensive, we realized the key factors governing the effectiveness of a player and the tradeoffs involved in using them, and proceeded to innovate our own player.

Group2 Player

In actuality, no player is as simple as any one of the strategies detailed above. All players use combinations of several strategies and even switch strategies based on the game conditions. Our player is no different. Below, we explain the various strategies that we tried.

Primary Strategy

From the beginning, we decided that our primary strategy would be a chaser. Though the previous year had not produced any effective chaser players, we reasoned that the complete chaser is essentially the most effective two player strategy by analyzing its characteristics qualitatively. We successfully implemented a primitive chaser as our first deliverable, and in tests against last years players, we were able to beat all of them in all two player scenarios. Because of this, we decided to stay with the chaser as our main strategy and build on it.

First Chaser

The first incarnation of our chaser had each of our robots target each robot of the opposing player with the same index. This was essentially a random targeting. We only wanted to see how effective chasers are at first. Later, we developed much more complex targeting mechanisms. The chasing algorithm we used was simply to use the coordinates of the enemy robot and our own to calculate the x-distance and y-distance between the two, i.e. the horizontal and vertical components of the cartesian distance. By the sign of the distances, we could then tell the direction of the other robot relative to our robot and set our moving direction toward that robot. Despite its simple logic, it was effective against all of last year's players. Yet, there were obviously many improvements that could be made to this player.

Rectangular Path

One of the first inefficiencies about the chaser that we noticed was the way in which it headed toward the enemy. It tended to zigzag. One reason for this was that our robot always checked the north/south direction before the east/west direction, so that if the enemy is directly east of us and we're heading towards it, if it heads north one block, we will also head north one block and same for south. This way, instead of making a straight line towards the enemy, our robot draws a broken zigzagging line. To correct this, we made our robot always head in the same direction that it headed in the previous round as long as the distance between our robot and the enemy robot in that direction is not zero. As expected, our robots now headed in unbroken rectangular paths towards the enemy. This made the chasing paths more useful as edges of rectangles that often emerged from several chasers walking by each other.

Target Furthest

Once we find the opponent, our chasing path is no longer necessarily rectangular since it's then determined by the movements of the enemy robot. So we decided to chase the enemy robot that is furthest. That way, our robots draw out the longest stretches of rectangular lines on their way. We achieved this using a matrix of distances between our robots and the enemy's robots. Also, we placed our robots evenly spaced around the board so that when they started moving, they naturally formed grids as they headed toward the enemy robots. Our goal was to increase our ability to capture squares at the beginning of the game prior to reaching our enemies. Our improved chaser was highly efficient and extremely effective against most regular players. But against chasers, our targeting strategy actually made us weaker. See the section on targeting nearest for further explanation.

This is an example of our player using rectangular paths and target furthest together with the perimeter initial placement to achieve grid formation as each of our robots head towards the enemy's robots. Notice how the grids are emerging in the second screenshot. In the third screenshot, we see the devastating efficiency of our initial grid strategy.

Proximity Chasing

After the release of our player, various teams optimized against the chaser strategy. One strategy that existed even in last year's players was stopping when an opponent's robots are near. This is damaging to the chaser as the chaser relies on the enemy's movements to capture further area. Thus, to counter this, we added proximity chasing. Bascially, we keep a variable called proximity that determines how close we want to get to the enemy before we consider ourselves to have reached him. In our previous chasers, we always assumed a proximity of zero, i.e. we aimed to be exactly where the enemy was. With a proximity of two, our robot stops when we're within two squares of the enemy robot. Given the appropriate proximity, the enemy would not be able to know that it is being chased. Therefore, we effectively combat the situation where the enemy slows down or stops. This proved to be quite effective against most players. However, having a proximity also means the enemy actually has a few squares belonging to him at any given time that he is being chased. In some situations, though rare, this allowed him to complete rectangles.

Back Off

A problem with proximity chasing is that we don't know within what proximity the other players consider themselves to be chased. In order to accommodate all players, we could hardcode a large proximity, but this would greatly weaken the effectiveness of our chaser. So instead, we implemented automatic proximity tuning which we call back off. Basically, proximity starts at zero when we first chase. When we get to the enemy, if he stops moving for a certain number of rounds, we know that he has detected our chasing, so we increase the proximity variable by one and then retrace our steps and back away from the enemy by one square. If the enemy continues to stay still, we repeatedly increase our proximity and distance until the enemy starts moving again. At that time, we continue with our chasing making sure to stay at that distance so that he doesn't stop again. To guard against having too high of a proximity that we're no longer effective chasers, we set a maximum that the proximity can be. To avoid situations where the enemy stops for some other reason instead of being chased, we decrement the proximity variable every eight rounds because the closer we chase the more effective we are. When we tested back off, it had mixed results. Against some players, it did exactly what it was meant to. Against other players, it didn't have much of an effect in preventing freezes. We conjecture that that has to do with the way our enemies detected chasing, since back off assumes they do it by distance.

This is an example of our player using proximity chasing and back off. We intentionally used only 4 robots so the chaos of robot movements doesn't obscure the chasing trail. Notice how in the last picture, our robots have adjusted themselves to chase at the optimal distance so that the enemy doesn't notice our activity.

Anti-Freeze

In some cases, some players stop all their robots once they detect chasing. This creates absolute stagnance in the game and the winner is the player with the higher score at the time. If it's not us, then our chaser is in trouble. In the case that proximity and back off fail, we fall back on a simple anti-freeze strategy where if we detect that all enemy robots have stopped, we reacquire targets of chasing for all of our robots by finding the furthest enemy robot to chase. This way, our robots will start moving again even if the enemy's don't. The idea is that as we're moving, we'll create more rectangles along the way so while the enemy stays still, we can still get points.

Target Nearest

A problem we had with target furthest is that against other chasers, this strategy made us quite ineffective. In fact, our target furthest chaser consistently lost to our most primitive chaser. The reason for this is that a chaser becomes effective the moment it gets close enough to the enemy to nullify it while gaining territory for itself. In targeting furthest, while we're going after the enemy robots furthest away, there are already enemy robots chasing us and nullifying our paths. So the grid work that we lay out as we get to the enemy is consumed by the enemy and helps him make rectangles instead of us. Because of this, we decided to switch to a target nearest strategy. It proved much more effective against chasers. We often ended up in draws instead of losing. However, against group 7's player, we were still losing more often than we were winning even with target nearest. This is because there's a targeting strategy that gets to the enemy even faster than target nearest. And that is what we call touch chasing.

Touch Chasing

Touch chasing is the idea of chasing the first enemy robot that touches our robot. This idea can be generalized to chasing the first enemy robot that comes within some certain distance of our robot. This makes targeting immediate and decreases the amount of work needed to find the enemy robot since we let it come to us instead of going to it. One other advantage of touch chasing is that it lets our robots do something constructive before beginning to chase the opponents robots. If we use this time correctly, we can gain a large point advantage before nullifying the other player. The weakness of touch chasing also lies in this same idea of a constructive beginning. As long as the enemy doesn't approach us, we're essentially behaving like a regular offensive player. If this is prolonged, our player no longer leverages the strengths of being a chaser and the contest then becomes just a matter of who captures squares quicker between two offensive players. And since we're a touch chaser, we can't be too elaborate or ambitious with our initial offensive strategy since our robots will abandon their tasks as soon as someone is near making it quite a task to find the right starting strategy.

Score Checking + Absolute Chasing

One simple improvement to a chaser is to check the score before chasing. If we're winning, then we can do absolute zero distance chasing. No matter what the opponent does, the game will then end with us winning.

Army Start

One strategy we tried in conjunction with touch chasing is to start using the army strategy. The army strategy captures squares relatively fast without delay, and we wanted to use that to our advantage. This seemed like a good idea, and against some players it was. However, most good players optimized around having a quick start strategy, and the longer that player is allowed to roam free, the more damage it could do to us. Thus, the army strategy proved ineffective against the optimized players.

Cavalry Start

As an alternative to the army start, we used the cavalry start, which has a higher efficiency. Cavalry start faired much better. It was able to defeat most players, even some optimized ones. However, the cavalry start suffered from the weaknesses of the cavalry, i.e. it would move through squares regardless if they were black or not and that was a waste of moves. Also, cavalry depends more heavily on the formation of the players and their adherence to their paths, so when robots went off to chase other robots, the cavalry became ineffective.

Here, we have an example of our player using cavalry start and touch chasing. Notice how the cavalry formation is broken because some of our robots have detected enemy robots and went off to chase them.

Multiplayer Target Switch

In multiplayer games, the chaser was completely ineffective. To remedy this, we came up with the idea of having the chaser target the robots of whichever player is winning. This can be determined dynamically, so every x number of rounds, we check to see who is winning and go after that player. Theoretically, this strategy has the ability to pick out the best player among the rest and win by shadowing that player. In practice, due to the fact that almost all the good players have anti-chasing strategies, whenever our player targets any player, ourselves and that player nullify each other and are essentially taken out of the game.

Multiplayer Strategy Switch

In the end, due to time constraints, we couldn't explore all the strategies we had thought of so we ended up partitioning game conditions into several possibilities and then selecting one strategy we thought was effective in that scenario. For our two player games, we used the version of our chaser that did best overall against all the players. Then for medium robot density multiplayer games, we used group 5's cavalry. For games with a large number of robots on the screen, we used a search and fill strategy from group 8.

Initial Placement

One important component of our strategies was initial placement of robots. We focused on optimizing initial placement to best support our chaser strategy. For that, we tried placing robots evenly spaced around the perimeter of the board. This has the advantage of creating the most extensive grid when used in conjunction with target furthest. But since we switched to touch chasing, our initial placement then became a grid formation of four lines cutting through the board like a tic tac toe game board. The distance from each line to the edge of the board is exactly one fourth the length of one side of the board. This is to minimize the distance between any one of our robots and any enemy robot so that it is at most within a few squares of the quarter length of a side of the board. Used in conjunction with target nearest or touch chasing, this placement proved quite effective.

This is an example of the perimeter placement. The advantage of this placement lies in being able to create grids as our robots head towards the enemy's robots. An example of this tactic is shown in the pictures several paragraphs above.

This is an example of the grid placement. In this picture, the distance from each line to the board edges is actually 1/5 the length of a side of the board. In our final player, we stuck with 1/4.

Another initial placement we tested was to put all our robots around the perimeter of a square. Once the game starts, the first thing we do is to complete that square using the minimum number of moves before we head off to chase other players. If the square is large enough, we will gain a sizable advantage in points much sooner than the opponent, and once we initiate chasing, we would be the guaranteed victors. However, this placement turned out to not work so well because we can't know in advance where the opponents robots will be. Often times, the enemy robots appeared right next to or even on the border of our square making completion very difficult, especially if the opponent is also a chaser, in which case completion is impossible since they would never leave the border. In the end, we abandoned this placement, though it's very possible to develop this into an effective starting strategy by adding more logic to the way we complete our initial square.

This is an example of the square boundry placement. Notice the enemy robots right near the square's edges. The random appearance of those are what caused this placement to be ineffective.

Tournament Results Analysis

Our player, Group2PlayerF, consistently ranked second in the 2 player games with 10 robots. In the other 2 player games, with either more or less robots, our rankings fluctuated. The weaker performance in games with few robots can be attributed to the fact that the other players tried to quickly capture squares in the beginning. With a low robot to board size ratio, it took a while for our robots to get to the enemy robots, thus, giving them sufficient time to score some points. Once we caught up with them, they most likely stalled until the game ended. With a higher than average robot density on the board, the same phenomenon can occur if the enemy robots can leverage their closeness to quickly score some points before switching to an anti-chasing mode. Our games versus last year's players came out as expected. We won the majority of our games since we spent much of our time optimizing using the old players.

In multiplayer games, we performed as expected in the lower density games where our robots could take advantage of the cavalry strategy by occupying the abundance of white space quickly. In higher density games, the constant disruptions caused by all the chaos of the other players moving around made our player ineffective.

One factor we feel hindered our ability to perform better was not knowing the anti-chasing strategy used by our opponents. We tried to accommodate for most of them but were successful only to a degree. Nevertheless, our tournament results seem quite satisfactory.

Conclusion

Rectangles was a very interesting and entertaining first project to work on. One of the areas that would be interesting to delve further into would be to come up with a strategy that can consistently and effectively beat an optimized chaser in two player games without using chasing of its own, or prove that no such strategy exists for the given game conditions. One other area we wanted to develop further but couldn't due to time constraints was building a highly intelligent cooperative search and fill player. It was actually one of our initial ideas to use a statistical model to model the board and a hidden markov model for the states of our robots. But discovering that the chaser had such effectiveness without the onerous burden of complexity, we chose to go down that path instead for this project, as often times in software engineering, simplicity and project completion is more valuable than complexity and unfulfilled potential.