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.


See below for a screenshot of the game.


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.