COMP 202 Team Project v1.3
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
COMP 202
Fall 2021
Team Project v1.3
Please read the entire PDF before starting. You must do this assignment individually.
Question 1: 100 points
100 points total
It is very important that you follow the directions as closely as possible. The directions, while perhaps tedious, are designed to make it as easy as possible for the TAs to mark the assignments by letting them run your assignment, in some cases through automated tests. While these tests will never be used to determine your entire grade, they speed up the process significantly, allowing the TAs to provide better
feedback and not waste time on administrative details. Plus, if the TA is in a good mood while grading, then that increases the chance of them giving out partial marks. :)
To get full marks, you must follow all directions below:
• Make sure that all file names and function names are spelled exactly as described in this document. Otherwise, a 50% penalty per question will be applied.
• Make sure that your code runs without errors. Code with errors will receive a very low mark.
• Write the names and student IDs of all your group members in a comment at the top of all .py files you hand in.
• Name your variables appropriately. The purpose of each variable should be obvious from the name.
• Avoid writing repetitive code, but rather call helper functions! You are welcome to add additional functions if you think this can increase the readability of your code.
• Lines of code should NOT require the TA to scroll horizontally to read the whole thing.
• Vertical spacing is also important when writing code. Separate each block of code (also within a function) with an empty line.
• Do not include function calls in the main body of any of your files.
• You are not allowed to use anything seen after Lecture 42 or not seen in class at all. You will be heavily penalized if you do so.
• Docstrings are not required for this project.
In this project, we ask you to write a piece of code that can play a game of COMP 202 WARS. You will write your code in a file called ai_player.py.
Game description
COMP 202 WARS is a multiplayer turn-based game that takes place on a grid. Various objects are scattered across the grid, and you must collect them. Moving onto a square that contains an object will automatically collect it.
There are three types of objects: the banana, the coin, and the cauldron. A random number of each will be placed at random spots on the grid. Other images on the grid correspond to the players who are picking up the objects.
A turn is comprised of all players moving to a new square (at the same time). If both players move onto an object at the same time, one of them will be chosen at random to pick up the object.
The game ends when either all objects on the grid have been picked up, or the turn limit is surpassed. When the game ends, the player who has the top number of objects in each category will be declared the winner.
For example, if the map contained three bananas, one coin and 10 cauldrons, and player 1 had collected two bananas and one coin, then they would automatically be declared the winner because they collected the most objects in two of the three categories (banana and coin). Even if player 2 had collected 10 cauldrons, they would not win as they would have only collected the most in one category (cauldron), whereas player 1 had collected the most in two categories.
If there is a tie between two players, then there is considered to be no winner. Further, if two players tie for top in one category, neither will be considered to have won that category.
Game representation
The grid of the game is represented as a two-dimensional list (matrix). Each spot in the grid will be a list. If there is nothing in the square, the list will be empty. If there is one or more bots in the square, there will be one or more Bot objects in the list. If there is an object (coin, cauldron or banana), there will be a GameObject object in the list.
The GameObject class has the following instance attributes:
• position: a tuple representing the position of the object in the grid
• obj_type: a string representing the name of the object ( 'banana', 'coin' or 'cauldron') The Bot class has the following instance attributes:
• position: a tuple representing the position of the object in the grid
• collected_objects: a tuple of three non-negative integers representing the number of objects the bot has collected for each category (banana, coin and cauldron).
• prev_collected_objects: the same as above, but representing the previous number of objects collected (before the last object was picked up)
• category_tops: a non-negative integer representing the number of categories in which this bot currently has the most objects (there are 3 categories, so this number can range from 0-3).
• i: a non-negative integer representing the ID of the current bot.
• name: the name of the bot (the same string as the one you will define below)
• group: the group who submitted the bot (the same string as the one you will define below)
These classes as well as several constants and some useful functions can all be found in the consts.py file which is provided to you with this PDF.
Let us now take a look at an example of a player for the game, located in the random_player.py file provided to you with this PDF.
import random from consts import *
class Player(GamePlayer): def __init__(self): self.name = "Random" self.group = 'n/a'
def step(self, game_map, turn, cur_pos): return random.choice(list(ACTIONS)) |
We define a class Player in this file. The constructor defines two instance attributes: name (the name of the player) and group.
There is also the method step. This is where the magic happens. The method must decide where to move next in the grid, by returning a string for the direction: either 'up', 'down', 'left' or 'right'. These strings are all contained within the ACTIONS dictionary contained in the consts.py file. You will see we are calling random.choice on the keys of this dictionary, which will return one key at random. This player thus always chooses a random direction in which to move (hence the name of the file).
Your task
Now let us take a look at ai_player.py, which you must fill in.
import random from consts import *
class Player(GamePlayer): def __init__(self): self.name = "your team name here" self.group = "your group here"
def step(self, game_map, turn, cur_pos): pass # remove this line and write your code |
To start, you and your group must first decide on a name for your player to be stored in the name attribute. (Please be mindful to choose an appropriate name.) Likewise, you must fill in the group attribute with your group number (e.g., '1A').
You must then implement the step method and return one of the four direction strings mentioned above.
How will you make this decision? By using the three inputs to the method:
• game_map: the matrix representing the current game grid, as described above.
• turn: the current turn number (an integer)
• cur_pos: a tuple representing your bot’s current position in the grid.
Player objects also have an instance attribute i defined which will equal to the attribute i of the corresponding Bot object in the game_map. That is, by comparing self.i with bot.i for every Bot in the game_map, you can find your bot.
Running the game
First, before running for the first time, you must install the pygame library in Thonny. Check the slides on Matplotlib for a reminder on how to install libraries.
Then, to start the game, you will run the play.py file. At the top of this file there are various variables which you can modify:
• NUM_GAMES: the number of games to run (integer)
• MAP_SIZE: the length of the grid (integer)
• GUI: a boolean indicating if the graphical user interface should be shown
• CHECK_TIMING: a boolean indicating if timing statistics on your step method should be calculated and printed
• PLAYER_MODULES: a list containing the name of the files corresponding to the players that will participate in the game. You will note that initially only two random players will play the game. If you would like your player to participate in the game, you can either replace one of the two strings with 'ai_player', or you could add 'ai_player' as a third element of the list (then the game would have three players: two being random, and one being yours). (In general, there could be any number of players in a game.)
Note: Do not make changes to any files other than the ai_player.py file and the variables at the top of the play.py file. You will only be able to submit the ai_player.py file to codePost. When we test your code, we will use our versions of the other files.
Note: Each game player (bot) has its own image. We provide to you four bot images with the code (Thonny, the Windows bug, the samosa and Cloudberry). If you would like to add more players, you will have to add your own images to the tiles folder, with filename tile_bX.png, where X is a number (5 or higher).
Hints
As mentioned above, in order to implement the step method and decide where to move, you will have to use the inputs to the method.
For example, you may decide to simply always move to the object which is closest to you. (We can call this the ‘greedy’ approach.)
However, the greedy approach may not be the optimal in many cases, since we do not simply want to collect as many objects as possible, but as many objects from the most categories as possible. That is, if there is only 1 coin and 1 cauldron, but 10 bananas, then it would serve you much better to collect the coin and cauldron, even if they are much further from you than the bananas.
There is also the idea of finding a path in the grid that would let you collect a large number of objects. That is, instead of thinking about only one move at a time, you could plan ahead, making perhaps sub-optimal moves in the context of a single turn, but collecting more objects over the long term. Remember that by using attributes, you can store data and then retrieve it at a later time.
Finally, another possibility would be to consider the opponent bots’ positions and try to anticipate their movements. If you see they are going for an object that may be very useful to them, and it is possible for you to collect it before them, then you may find it advantageous to do so (under certain conditions).
Note also that the success of certain strategies may not be immediately apparent on small map sizes, and may only prove to be superior once the map size is increased.
These are just a few hints. There are many strategies! You can also mix and match!
Grading
When we grade your submission, we will first check if your step method returns a correct string in all cases. That means that whatever the current state, you must return one of the four valid direction strings. If the method does not return a correct value, even if it is only once in a while, your bot will be disqualified and you will receive a very low mark on the project. Please make absolutely certain that your method returns a correct value in all possible cases. To do so you can simply trace through your code and check that whatever combination of conditionals or loops are executed, there will always be an appropriate return statement at the end.
We will then check the speed of your step method. It should not take any significant time to run. For example, if playing against one random player in a series of 100 games on a 5x5 map, no more than two (2) seconds should elapse on average during a call to your step method. Players which take longer than this amount will be disqualified and will receive a low mark on the project.
We will then test your player against the random player, which is provided with the PDF. If your player consistently wins at least 60 out of 100 games against the random player, on different map sizes, then you will receive 50 points out of 100 on the project (minus any penalties as described on page 1 of this PDF).
We will then test your player against a player that follows a ‘greedy’ approach, as described in the section above. If your player consistently wins at least 60 out of 100 games against the greedy player, on different map sizes, then you will receive 85 points out of 100 on the project (minus any penalties as described on page 1 of this PDF). Further, players who rise to this level will be entered into the class tournament, described below.
We will then test your player against a slightly more optimized greedy player. If your player consistently wins at least 60 out of 100 games against the slightly more optimized greedy player, on different map sizes,
then you will receive 99 points out of 100 on the project (minus any penalties as described on page 1 of this PDF).
We will then test your player against the player to be designed by the teaching staff. If your player consistently wins at least 60 out of 100 games against the teaching staff player, then you will receive 100 points out of 100 on the project (minus any penalties as described on page 1 of this PDF).
Tournament
Players who consistently win at least 60 out of 100 games against the greedy player, on different map sizes, will be entered into the class tournament.
The tournament will be a single-elimination format and proceed as follows. Entrants will be randomly assigned into groups of 3 or 4. A large number of games will be played amongst the players of each group. The bottom two players of each group (in terms of wins) will be eliminated, and new groups of 3 or 4 will be formed from the top 1 or 2 players of each group. The tournament will continue in this fashion until 4 players remain. We will announce these top 4 players as our winners. Prizes will be awarded to each group member of the top 4 submissions as follows:
• First place: 10,000 COMP202COINs to each contributing group member
• Second place: 5,000 COMP202COINs to each contributing group member
• First place: 2,500 COMP202COINs to each contributing group member
• First place: 1,000 COMP202COINs to each contributing group member
COMP202COINs
You may also redeem COMP202COINs for this project. The following options are available:
• 100 coins: get the number of currently passing vs. failing private tests on your latest submission for the team project.
• 500 coins: get basic information about the first failed private test on your latest submission for the team project.
You will be able to redeem coins for the project starting on Monday, November 29 at 1:00 p.m.
Teamwork
Finally, note that this is a group project. We expect everyone in your group to participate equally in this project. When you make your final submission, you must send a direct message over Slack to your group’s TA. In this direct message you will rate each of your group members’ contribution to the project on a scale from 1 to 3 (3: worked very hard, 1: did little to no work). If a group member receives a large number of 1’s from their teammates, they may be asked by the instructor to take an oral exam to determine their mark on the project and whether they can keep any COMP202COIN they have earned from the project (the latter if the group’s submission places in the top four).
Note: Though the vast majority of groups have four or five students, some groups may only have three students. If you are in a group of only three, then please discuss amongst yourselves whether you would like to remain in that group to work on this project, or whether you would prefer to split up and join with
other groups (solely for this project). If you decide on the latter, please email me no later than Wednesday, November 24.
What To Submit
You must submit all your files on codePost (https://codepost.io/). The file you should submit are listed below. As this is a group project, one member of the group should create a group submission and send the others the invite link to join the submission. All other group members must then join the submission. Deviation from these requirements will lead to penalties.
Note: codePost will only let you join onto your group’s submission if you did not previously make your own submission. Therefore, please choose one member of your group who will be responsible for submitting to codePost. No other group member should submit, otherwise, they will not be able to join onto the group submission and thus could not be given any mark.
ai_player.py
README.txt In this file, you can tell the TA about any issues you ran into doing this assignment. If you point out an error that you know occurs in your program, it may lead the TA to give you more partial credit.
This assignment is a group assignment. It must represent the effort of only your group members. You are permitted to discuss ideas with other groups, as long as no written notes are taken. If you do discuss it with anyone from another group, please make note of those people in this README.txt file. If you didn’t talk to anybody outside your group nor have anything you want to tell the TA, just say “nothing to report” in the file.
2021-12-01