Individual Project 2 Due Wednesday October 18, 11:00am EDT
The objective for this semester’s individual project is to implement this new GameArea
abstraction, with one concrete implementation: TicTacToeArea
.
The TicTacToeArea
will implement the gameplay for the classic game, Tic-Tac-Toe.
This implementation effort will be split across two deliverables. In this second deliverable, you will implement and (partially) test the core frontend components.
Change log
- 10/13 Updated handout
TicTacToeAreaController.test.ts
to create the mock implementation ofmockTownController.getPlayer
method beforeTicTacToeAreaController
’s constructor is called. To update your code without downloading the zip file, move the following piece of code from line 87 to line 36.mockTownController.getPlayer.mockImplementation(playerID => { const p = mockTownController.players.find(player => player.id === playerID); assert(p); return p; });
- 10/11 Updated handout
TicTacToeArea.test.tsx
to correctly updategameAreaController.mockIsOurTurn
in each relevant test. To update your code without downloading the entire zip file, simply add the line below to the ‘Updates whose turn it is when the game is updated’ and ‘Displays a message “Game in progress, {numMoves} moves in” and indicates whose turn it is when it is the other player's turn’ tests inTicTacToeArea.test.tsx
.gameAreaController.mockIsOurTurn = false;
- 10/3: Updated handout
TicTacToeArea.test.tsx
to add the linegameAreaController.mockIsOurTurn = true;
, which may be required to be set for your implementation ofTicTacToeArea
- 9/30: Updated handout
TicTacToeBoard.test.tsx
to add missingawait
calls on lines 234 and 243 (if missing, could cause the test runner to crash if the assertions failed) - 9/30: UpdatedUpdated handout
TicTacToeAreaController.test.ts
, adding a mock implementation ofmockTownController.getPlayer
, which you might or might not choose to use in your implementation (and without which the tests would fail). If you run into this issue and would like to directly update your code, that mock implementation is added to the bottom ofticTacToeAreaControllerWithProp
, and is:mockTownController.getPlayer.mockImplementation(playerID => { const p = mockTownController.players.find(player => player.id === playerID); assert(p); return p; });
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
Getting started with this assignment
Start by downloading the starter code. Extract the archive and run npm install
to fetch the dependencies.
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.
NPM install failures: 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, run brew install pixman cairo pkgconfig pango
. If you are on a newer Mac with an M1 or M2 chip, you may need to use arch -arm64 brew install pixman cairo pango
. 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.
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/TicTacToeAreaController.ts
- Task 1:
frontend/src/classes/interactable/TicTacToeAreaController.test.ts
- Task 2:
frontend/src/components/Town/interactables/TicTacToe/TicTacToeArea.tsx
- Task 3:
frontend/src/components/Town/interactables/TicTacToe/TicTacToeBoard.tsx
- Task 4:
frontend/src/components/Town/interactables/Leaderboard.tsx
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: The TicTacToeAreaController (30 points)
The TicTacToeAreaController
is a class that is responsible for managing the state of a single TicTacToe game. It is responsible for communicating with the TownService backend. Frontend components will interact with the TicTacToeAreaController
to get the current state of the game, and to send commands to the backend to update the game state. The TicTacToeAreaController
also will emit events when the state of the game changes, so that frontend components can update their state accordingly.
TicTacToeAreaController
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 TicTacToeAreaController
class (frontend/src/classes/interactable/TicTacToeAreaController.ts
). The specification for these properties and methods appears below:
View the specification for these methods
Testing: Avery has provided you with tests for everything in TicTacToeController
except for makeMove
and _updateFrom
. Please implement these additional tests in the file frontend/src/classes/interactable/TicTacToeAreaController.test.ts
. You can run the tests by running the command npx jest TicTacToeAreaController
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. The grading script will assign full marks for each testing task if all of the faults in that task are detected by your tests. There is no partial credit.
Grading for implementation tasks:
- All properties and methods besides
_updateFrom
: 10 points _updateFrom
: 10 points
Grading for the testing tasks:
- Tests for
_updateFrom
: 5 points - Tests for
makeMove
: 5 points
Task 2: Tic-Tac-Toe Area (95 points total)
The next task is to implement the React component that will render the Tic-Tac-Toe game area. This component will show information about the game area, and the current state of the game. It displays the TicTacToeBoard
(which you'll implement in the next task), and also the
Leaderboard` component (which you’ll implement in the task after that).
This component is located in the file frontend/src/components/Town/interactables/TicTacToe/TicTacToeArea.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: 20 points
- Display the leaderboard component: 10 points
- Join game button: 30 points
- List of observers watching game: 15 points
- List of players in game: 10 points
- Display the game status: 10 points
All of the tests are provided in the handout. Run the tests for this task by running the command npx jest TicTacToeArea.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 3: Implement the Tic-Tac-Toe Board (40 points total)
This task is to implement the TicTacToeBoard
component, which will render the actual (interactive) board. It is located in the file frontend/src/components/Town/interactables/TicTacToe/TicTacToeBoard.tsx
.
View the specification for this component
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: 15 points
- Drawing the interactive board for players: 25 points
All of the tests are provided in the handout. Run the tests for this task by running the command npx jest TicTacToeBoard
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 Leaderboard (15 points total)
This task is to implement the Leaderboard
component, which will render a list of GameResult
s as a leaderboard. It is located in the file frontend/src/components/Town/interactables/Leaderboard.tsx
.
View the specification for this component
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:
- Implementing the leaderboard: 15 points
All of the tests are provided in the handout. Run the tests for this task by running the command npx jest Leaderboard
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 to the instance of Autograder.io running at neu.autograder.io. Navigate to neu.autograder.io in your web browser, click the “Sign in” button, and log in with your Northeastern account. You should then see the course listed on the neu.autograder.io home page. Please contact the instructors immediately if you have difficulty accessing the course on Autograder.io. If you haven’t been added to the course roster yet, you can access the assignment page at this direct link.
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 Autograder.io.
Autograder.io 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 (these marks will remain hidden until it is graded). It may take several minutes for the grading script to complete.
Autograder.io 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 Autograder.io for providing grading feedback - relying on Autograder.io 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.
Submission limit resets at 11am EST.