Assigned: 2020-09-22
Due Date: 2020-09-29 by 11:59PM U.S. Central Time
You will need to submit your GitHub repository to Gradescope after completing this assignment.
For this assignment, you will be creating at least one intelligent player strategy for a strategy game based on exhilarating concepts like mining and economics. This game is called Mine-opoly. Unlike previous assignments, we are giving you a significant amount of code. We have taken care of everything needed to run the game. This includes a game engine, graphics, and of course an interface for your strategy implementation. You are not allowed to modify this MinePlayerStrategy interface. You are however free to modify any other files including the game engine and graphics, but you do so at your own risk, and we will be using the original copy that we gave you to run the competition.
Get your copy of the assignment here: https://classroom.github.com/a/MU3MLl9F
Why the 3.0? This is a new and improved version of previous semesters’ games.
The game is a turn based mining competition played on an NxN square set of tiles which is considered the Game Board. There are 4 types of tiles on the board:
There are two players per game, one with a red robot and one with a blue robot. Both players start in the center of
the board on their lower market tile. Each turn both players will receive information about the
board state. This information contains where all the resources are, where your opponent is,
prices for each resource, and other such information. Each turn both players will be required to
return a TurnAction
. This TurnAction is an enum value which indicates what your
strategy wants your player to do for the current turn. TurnActions are one of the following:
MOVE_UP
, MOVE_DOWN
, MOVE_LEFT
, or MOVE_RIGHT
all indicate that your player would like to move in that
direction on this turn. Movement is relative to the bottom left tile, so MOVE_UP
will move your player
towards the top of your screen and MOVE_RIGHT
will move your player towards the right of your screen.
If your robot is out of charge (indicated by the battery icon in the GUI), then your robot will be in low-power mode.
When in low-power mode, your robot only has a 25% chance to successfully move to another tile in a single turn.
MINE
indicates that you would like to mine your player's current tile.
How many turns it takes to finish mining a resource depends on the resource type. Diamond takes 3
turns to mine, emerald takes 2 turns to mine, and ruby only takes 1 turn to mine. When you have mined
a resource enough, it will drop a gem on the tile your player is standing on.
PICK_UP_RESOURCE
indicates you would like to add a resource to your inventory. If your player is standing on a tile that has a mined gem, it will add the gem to your inventory. The maximum inventory size for your player will always be 5. Attempting to pick up an item when your inventory is full will leave the item on the ground.
PICK_UP_AUTOMINER
indicates you would like to add an autominer to your inventory. If your player is standing on a tile that has an autominer, it will add the autominer to your inventory. The maximum inventory size for your player will always be 5. Attempting to pick up an item when your inventory is full will leave the item on the ground.
PLACE_AUTOMINER
indicates you want to place an autominer. The autominer will be placed on the tile that you are currently standing on. An autominer can not be placed on top of another autominer. However, when placed adajcently, their effects can stack.
null
indicates that you would like to do nothing on your turn. You will need to return
null for multiple turns in a row to become fully charged while standing on a recharge tile.
As previously mentioned, market tiles are where you can sell your gathered gems for points. Stepping on one of these tiles will immediately sell every gem in your inventory at the current price for each type of gem. The price for each gem will then decrease depending on the amount of each type sold. Prices for gems will steadily increase over time again until reaching the max value for the gem type.
Finally, since players execute turns "at the same time", potential conflicts such as moving into the same tile will be handled by the concept of red turns and blue turns. On a red turn, the red player will have priority for these types of moves. On a blue turn, the blue player will have priority. Red turns and blue turns will alternate throughout the game. The first turn will be a red turn. So if two players are trying to move into the same tile, and it is currently a red turn, the red player has priority and will successfully move into that tile. The blue player will be blocked from moving and therefore do nothing.
We have given you an interface that your player strategy should implement. You need to implement this
interface without modifications, otherwise your strategy will not run in the provided game engine or
the competition. This interface is called MinePlayerStrategy
. It has the following
methods:
initialize()
- This function will be called at the start of every round, passing
in the size of the board, the maximum items that a player can carry in their inventory, the maximum charge
that your robot will start with the score to reach to win a single round, an initial view of the GameBoard,
the starting tile location for the player, whether the player is a red player, and finally a Random
object for the player to use for generating random numbers if their strategy needs that.
getTurnAction()
- This function is the primary purpose of your strategy. It is
called every turn to get the action your player should execute. The parameters are a PlayerBoardView
object which represents the state of the board, an Economy
object with resource price information, the
current charge your robot has, and a boolean to say if the current turn is a red priority turn or not.
This function returns a TurnAction
for the action the player wants to execute.
Returning null
from this function will cause the player to do nothing.
onReceiveItem()
- This function is called whenever the player successfully
executed a PICK_UP
TurnAction on their last turn. The only parameter for this
function is a reference to the InventoryItem picked up. This function is not called when the player
inventory is full because the item is not picked up in that case.
onSoldInventory()
- This function is called whenever the player steps on a market
tile of their color with at least one gem in their inventory. The only parameter for this function is
an int for the total number of points received by selling everything in the inventory.
getName()
- This function is super simple, just return the name that you want to
give your player on the GUI and in the competition. Can be as simple as a string constant like
"ExampleName". Note that if you somehow manage to throw an exception in this function, your player's
name will be the exception that you threw. That's super embarrassing for everyone involved.
endRound()
- This function is called at the end of every round. This passes in
the number of points that your player scored and the number of points that the opposing player
scored. You should also use this method to reset the state of your strategy class.
Every semester we get complaints from people that their strategy acts buggy in the competition, and
it turns out their strategy is still using variables set in the previous round.
To fully complete this assignment, you must write at least one MinePlayerStrategy
in the mineopoly_three.strategy
package that meets the following requirements:
30 * (boardSize * boardSize)
99% of the time for at least board sizes of 14, 20, 26, and 32.The provided implementation of RandomStrategy cannot pick up gems, so it cannot score any points. It will therefore only make things easier for you to score more points.
In addition to those requirements on the strategy:
getStrategyWinPercent()
method
in MineopolyMain.java.You are entirely allowed to write more than one strategy. In fact it probably makes sense to have a strategy that maximizes your points against a RandomStrategy for the assignment, and then another strategy that does more complicated actions against a smarter human-programmed opponent for the competition. If you write a separate strategy for the competition, it will not be graded as part of this assignment.
Part of this assignment is becoming familiar with an unfamiliar codebase. IntelliJ has built-in tools to allow you to more easily explore code
By all means feel free to ask questions on Campuswire or in office hours if you get stuck, but you have all the code running the game in front of you. If you look around enough, you can probably find the answer to any question you may have, and develop a useful skill in the process.
Consider exploring around before you ever attempt to write a strategy. Are there some parts that seem
more important than others (like the main method in MineopolyMain
, or runGameLoop()
in GameEngine
)?
Are there some parts that seem irrelevant to your needs (like anything dealing with the graphics or
the paint()
methods)?
When you do feel like you are ready to write a strategy, are there certain helper methods it would make sense to have? If you do decide to write a more complex strategy for the competition, are there some design choices you could make to implement complicated conditional behavior more easily? Can an interface or abstract base class you write help you swap strategy behaviors on the fly?
Other things we will take into consideration:
Test suites for this assignment are expected to be a bit slim, since of course you are only writing a strategy, and all of the game engine functionality has been done for you. That being said, if you write helper methods that you reuse (which is a good idea in general), you should be testing them.
This assignment is a test of your problem-solving skills: if you don't know how to do something (for example, writing an abstract class,) you should try your favorite search engine. (Make sure you follow our policy on citing online code.) If you're still stuck, consider Campuswire and office hours.
This feature is not necessary to complete the assignment. The autominer exists to aid those who seek ultimate glory by winning the competition. There are two autominers per map, spawning in the same corners each time. Anybody can pick up either autominer, but it does fill an inventory space. When placed, the autominer mines the surrounding tiles and the tile that it is placed on. Note that this mining rate is slower than the player's. Mined resources still have to be picked up. Additionally, if a autominer and resource are both on the same tile, it will take two turns to pick them up, as each item must be picked up individually. We encourage you to explore the starter code to maximize the effectiveness of the autominer's usage.
Participation in the competition is completely optional. However, we make no guarantees about the impact of these things on your sense of self-worth. The top 8 strategies will be immortalized in a Hall of Fame on the website. The losing strategies... will not be. Particpation is worth 2.5 points of EC, you will earn an additional bonus based on your ranking: (ranking/total * 7.5).
Push code to your master branch. This is the branch we will pull from when we run the competition.
In order for us to run your player strategy in the tournament, you must put a single class that
implements the MinePlayerStrategy
in the competition package. You may also put any
other classes you need in that package. This package is package mineopoly_three.competition;
Do not include any subpackages in the competition package. These will not get compiled or run. Do not reference any classes that you personally created which are outside the competition package.
MinePlayerStrategy
or TurnAction
are perfectly finePut only one player strategy in the competition package, otherwise we will not know which strategy
to run. There should only be one class in the competition package that implements
MinePlayerStrategy
System.exit()
in your player
strategy will not work and will result in a 0 for this assignment.We will be auto-running the competition starting this Tuesday, September 29th. Indeed, this is on the due date, but we won't be closing the competition until the following Tuesday, October 6. Note that you will still have an assignment due that week, and it will be our first C++ assignment. However, the workload should be smaller, so you can spend some time tweaking your strategy if you'd like.
Note that this rubric is not a comprehensive checklist; it’d be impossible to list out every single thing that you should be considering while writing your code. The rubric is slightly different from what you're used to, as a small part of your grade is dependent on having a strategy that meets the winning requirements for each board size.
Your grades for each section of the rubric will be weighted as follows: