Individual Project 2 Due Wednesday February 21, 11:00am EST
The objective for this semester’s individual project is to extend this new GameArea
abstraction, implementing Connect Four as a new game that can be played within a GameArea
.
This implementation effort will be split across two deliverables. In this second deliverable, you will implement and the core frontend components.
Objectives of this assignment
The objectives of this assignment are to:
- Investigate and understand a large, existing codebase
- Write new TypeScript code that uses asynchronous operations
- Write test cases that utilize mocks and spies
- Write React components and hooks that make use of state
Changelog
- Feb 11: Fixed the mock initializer in
GamesArea.test.tsx
- this was causing some student submissions to fail with an error about the incorrectinteractableID
being found. The handout is updated with the test, and it can also be directly downloaded from here. - Feb 8: 🤦 If you had the pre-Feb-7 handout, note that Lines 627 and 709 should read
expect(screen.getByText('Waiting for players to press start', { exact: false })).toBeInTheDocument();
- Feb 7: Updated handout to fix typo in ConnectFourArea.test.tsx. Line 627 should read
expect(screen.getByText('Waiting for players to press start', { exact: false })).toBeInTheDocument();
- Feb 6: Fixed typo in the list of files in “General Requirements” (
ConnectFourAreaController.ts.ts
->ConnectFourAreaController.ts
)
Getting started with this assignment
Start by downloading the starter code. Extract the archive and run npm install
to fetch the dependencies.
System-level dependencies: The libraries used for React require some native binaries to be installed – code written and compiled for your computer (not JavaScript). If you run into issues with npm install
not succeeding, please try installing the following libraries using either Homebrew (if on Mac), apt-get, or your favorite other package manager: pixman
, cairo
, pkgconfig
and pango
. For example, on a Mac, after installing Homebrew, run brew install pixman cairo pkgconfig pango
. You should not continue with the installation until this succeeds. On Windows: Students have reported seeing the failure error /bin/bash: node: command not found
upon npm install
in the frontend
directory. If you encounter this error, please try to delete the node_modules
directory and re-run npm install
in the frontend
directory from a bash shell instead of a windows command prompt.
Node 16 vs 18
For this assignment (and the team project), you should use NodeJS 16 and NPM 9. You can check your version of NodeJS by running node -v
and your version of NPM by running npm -v
. We had gotten over-eager at the start of the semester, updating our tutorial on installing a development environment to NodeJS 18. Several of us got stuck in “dependency hell” with one of the transitive dependencies of the project, node-gyp
on various versions of Node 18. All who tested it reported success on Node 16. If you run into failures running npm install
, and have Node 18, please try downgrading to Node 16 (easiest accomplished using nvm and the command nvm install 16
followed optionally by nvm alias default 16
to make this the default). If you end up changing versions of Node, you will need to delete the node_modules
directory and run npm install
again.
Configuring Jest and VSCode: If you would like to use the built-in Jest test runner for VSCode (where it shows the tests and their status in the sidebar), the easiest way to accomplish this for this project is to open just the “frontend” directory or just the “townService” directory in VSCode - not the top-level “ip2-handout” directory. If you have a quick-fix to make it work with the whole project at once, please feel free to share on Piazza and we will incorportate that here.
Running the app: We strongly encourage you to interactively experiment as you develop by running the entire application in your development environment. See the instructions in README.md for how to run the app.
Grading
This submission will be scored out of 200 points, 180 of which will be automatically awarded by the grading script, with the remaining 20 manually awarded by the course staff.
Your code will automatically be evaluated for linter errors and warnings. Submissions that have any linter errors will automatically receive a grade of 0. Do not wait to run the linter until the last minute. To check for linter errors, run the command npm run lint
from the terminal. The handout contains the same eslint configuration that is used by our grading script.
Your code will be automatically evaluated for functional correctness by a test suite that expands on the core tests that are distributed in the handout. Your tests will be automatically evaluated for functional correctness by a process that will inject bugs into our reference solution: to receive full marks your tests must detect a minimum number of injected bugs. Each submission will be graded against the same set of injected bugs (repeated submissions will not receive new/different injected bugs). You will not receive detailed feedback on which injected bugs you do or do not find.
The autograding script will impose a strict rate limit of 5 submissions per 24 hours. Submissions that fail to grade will not count against the quota. This limit exists to encourage you to start early on this assignment: students generally report that assignments like this take between 3-20 hours. If you start early, you will be able to take full advantage of the resources that we provide to help you succeed: office hours, discussion on Piazza — and the ability to have a greater total number of submission attempts.
Your code will be manually evaluated for conformance to our course style guide. This manual evaluation will account for 10% of your total grade on this assignment. We will manually evaluate your code for style on the following rubric:
To receive all 20 points:
- All new names (e.g. for local variables, methods, and properties) follow the naming conventions defined in our style guide
- There are no unused local variables
- All public properties and methods (other than getters, setters, and constructors) are documented with JSDoc-style comments that describes what the property/method does, as defined in our style guide
- The code and tests that you write generally follows the design principles discussed in week one. In particular, your design does not have duplicated code that could have been refactored into a shared method.
We will review your code and note each violation of this rubric. We will deduct four points for each violation, up to a maximum of deducting all 20 style points.
Implementation Tasks
This deliverable has four parts; each part will be graded on its own rubric. You should complete the assignment one part at a time, in the order presented here.
General Requirements: Implement your code only in the files specified:
- Task 1:
frontend/src/classes/interactable/ConnectFourAreaController.ts
- Task 2:
frontend/src/components/Town/interactables/GamesArea.tsx
- Task 3:
frontend/src/components/Town/interactables/ConnectFour/ConnectFourArea.tsx
- Task 4:
frontend/src/components/Town/ConnectFour/ConnectFourBoard.tsx
- Task 5:
frontend/src/components/SocialSidebar/InteractableAreaList.tsx
andfrontend/src/classes/interactable/InteractableAreaController.ts
You should not install any additional dependencies. The autograder will ignore any other files that you modify, and will not install any dependencies that you add to the project.
Task 1: Implement the ConnectFourAreaController (60 points)
The ConnectFourAreaController
is a class that is responsible for managing the state of a single ConnectFour game. It is responsible for communicating with the TownService backend. Frontend components will interact with the ConnectFourAreaController
to get the current state of the game, and to send commands to the backend to update the game state. The ConnectFourAreaController
also will emit events when the state of the game changes, so that frontend components can update their state accordingly.
ConnectFourAreaController
extends the base GameAreaController
class.
The base class tracks the game model (this._model
), the set of players in the game (this.players
), and the set of observers in the game (this.observers
). It also provides methods for joining and leaving the game, as well as a base implementation of _updateFrom
, which is responsible for updating the game state when the backend notifies the frontend of a change.
Your first task is to implement each of the properties and methods of the ConnectFourAreaController
class (frontend/src/classes/interactable/ConnectFourAreaController.ts
). The specification for these properties and methods appears below:
GitHub Co-pilot: If you haven’t yet used GitHub Copilot, this might be a good time to set it up. It can be very helpful for writing boilerplate code, and especially for proposing implementations of very simple methods. You likely will find it very useful for many of these implementation tasks. To get it for free: 1. Sign up for GitHub’s Student Pack and wait for your student status to be verified, then 2. Install the GitHub Copilot extension for VSCode.
View the specification for these methods
Testing: Avery has provided you with tests for everything in ConnectFourAreaController
. You can run the tests by running the command npx jest ConnectFourAreaController
in the frontend
directory (for convenience, you may want to use npx jest --watch
…).
The grading script will assign full marks for each implementation task if all of the tests for that task pass. There is no partial credit.
Grading for implementation tasks:
- All properties and methods besides
_updateFrom
,startGame
andmakeMove
: 10 points _updateFrom
: 10 pointsstartGame
: 10 pointsmakeMove
: 20 points
Task 2: GamesArea Component (20 points total)
In last semester’s individual project, students implemented the TicTacToeArea component. This component was responsible for rendering information about the area, including the list of players observing the game, a leaderboard, and the game itself. Avery decided that rather than copy-pasting this component, it would be better to refactor it into a more general GamesArea
component, which could be used to render any game area. This component is located in the file frontend/src/components/Town/interactables/GamesArea.tsx
.
As you work on this component, you might find it helpful to view the code of the old TicTacToeArea component, which included the functionality for rendering the leaderboard and list of observers.
View the specification for this component
Grading:
- Correctly register the listeners: 10 points
- Displaying the leaderboard component: 2 points
- List of observers watching game: 2 points
- Render the game area component: 2 points
- Render the chat channel: 2 points
Task 3: Connect Four Area (50 points total)
The next task is to implement the React component that will render the Connect Four game area. This component will show information about the game area, and the current state of the game. It displays the ConnectFourBoard
` (which you’ll implement in the next task).
This component is located in the file frontend/src/components/Town/interactables/ConnectFour/ConnectFourArea.tsx
- you should implement component class in this file.
View the specification for this component
You can begin to implement these tasks in whatever order you see fit, but we would suggest completing them in the order shown in the specification.
There is significant ambiguity in the specification when it comes to exactly how this looks. We will not evaluate your submission on the basis of how closely it looks like our referencence implementation: it need only be functionally correct (as defined by the included test cases).
Grading for implementation tasks:
- Correctly registering the listeners: 10 points
- Join game button: 15 points
- Start game button: 15 points
- List of players in game: 5 points
- Display the game status: 5 points
All of the tests are provided in the handout. Run the tests for this task by running the command npx jest ConnectFourArea.test
in the frontend
directory (for convenience, you may want to use npx jest --watch
…). You will also likely find it convenient to run the app in your browser while you work on this task for interactive debugging.
The grading script will assign full marks for each implementation task if all of the tests for that task pass. There is no partial credit.
Task 4: Implement the ConnectFourBoard (20 points total)
This task is to implement the ConnectFourBoard
component, which will render the actual (interactive) board. It is located in the file frontend/src/components/Town/interactables/ConnectFour/ConnectFourBoard.tsx
.
View the specification for this component
Again, there is significant ambiguity in the specification when it comes to exactly how this looks. We will not evaluate your submission on the basis of how closely it looks like our referencence implementation: it need only be functionally correct (as defined by the included test cases).
Grading for implementation tasks:
- Drawing the board for observers: 10 points
- Drawing the interactive board for players: 10 points
All of the tests are provided in the handout. Run the tests for this task by running the command npx jest ConnectFourBoard
in the frontend
directory (for convenience, you may want to use npx jest --watch
…). You will also likely find it convenient to run the app in your browser while you work on this task for interactive debugging.
The grading script will assign full marks for each implementation task if all of the tests for that task pass. There is no partial credit.
Task 5: Extend the SocialSidebar (30 points total)
On the right hand side of the Covey.Town interface, there is a sidebar that displays information about the current town, listing the players in the town and the active ConversationAreas. This sidebar is implemented in the SocialSidebar
component, located in the file frontend/src/components/SocialSidebar/SocialSidebar.tsx
.
Given the growth of the Covey.Town codebase, Avery has decided that instead of just listing the active Conversation Areas, it would be better to list all of the active interactables in the town. This will allow the sidebar to list the active Conversation Areas, as well as any active games, viewing areas, or future interactable areas not yet conceived.
Your specific task is to implement the InteractableAreaList
component, which will display a list of all active interactable areas in the town. This component is located in the file frontend/src/components/SocialSidebar/InteractableAreaList.tsx
. This component should make use of two React hooks defined in InteractableAreaController.ts
- useInteractableAreaOccupants
and useInteractableAreaFriendlyName
. These hooks are responsible for fetching the list of occupants of an interactable area, and the friendly name of the interactable area, respectively. You will need to implement the useInteractableAreaFriendlyName
hook, but will find the other is already completed.
You might find it useful to view the code of the old ConversationAreasList component.
View the specification for this component and these hooks
Grading for implementation tasks:
- Implement the useInteractableAreaFriendlyName hook: 10 points
- Implement the InteractableAreaList component: 20 points
All of the tests are provided in the handout. Run the tests for this task by running the command npx jest InteractableAreasList hooks
in the frontend
directory (for convenience, you may want to use npx jest --watch
…). You will also likely find it convenient to run the app in your browser while you work on this task for interactive debugging.
The grading script will assign full marks for each implementation task if all of the tests for that task pass. There is no partial credit.
Submission Instructions
Submit your assignment in GradeScope. The easiest way to get into GradeScope the first time is to first sign into Canvas and then click the link on our course for “GradeScope.” You should then also have the option to create an account on GradeScope (if you don’t already have one) so that you can log in to GradeScope directly. Please contact the instructors immediately if you have difficulty accessing the course on GradeScope.
To submit your assignment: run the command npm run zip
in the top-level directory of the handout. This will produce a file called covey-town.zip
. Submit that zip file on GradeScope.
GradeScope will provide you with feedback on your submission, but note that it will not include any marks that will be assigned after we manually grade your submission for code style (it will show 0 for this until it is graded). It may take several minutes for the grading script to complete.
GradeScope is configured to only provide feedback on at most 5 submissions per-24-hours per-student (submissions that fail to run or receive a grade of 0 are not counted in that limit). We strongly encourage you to lint and test your submission on your local development machine, and not rely on GradeScope for providing grading feedback - relying on GradeScope is a very slow feedback loop. To check for linter errors, run the command npm run lint from the terminal. The handout contains the same eslint configuration that is used by our grading script.