Project 3: 2048
Version 3.1. Last Updated: 2024-10-10.
We highly recommend reading through this spec in its entirety before you begin.
We also recommend you complete all labs up to and including Lab 8: Boards
To begin, load this starter project
Any important updates or clarifications will be made here:
Due Date Extended to Tuesday, 10/22
Project 3 Party: Thursday, 10/10 from 5 - 7PM in Soda 326
Project 3 Party: Monday, 10/7 from 5 - 7PM in Moffit 145
Guide to help with Testing Blocks
Content
I. Introduction
II. Helper Blocks
III. Suggestions
IV. Part 1: Populating the Board
V. Part 2: Rotating the Board
VI. Part 3: Merging
VII. Part 4: Ending the Game
VIII. Part 5: Tests
IX. Feedback Form
X. Grading
Submission Guidelines
Please submit on Gradescope using these submission instructions, and make sure to add your partner!
Introduction
In this project, youâll be working off some skeleton code to build 2048! If youâre unfamiliar, 2048 is a sliding puzzle game where the goal is to combine same-valued tiles to reach the value 2048. You can play the game at this link for free to get used to how it works. You wonât be building the game from scratch, just filling out five blocks. All of those blocks will be reporters, and should not update the board display â thatâs handled for you in the skeleton code. So make sure not to mutate the original board. Once youâve completed those five block definitions, you wonât need to change anything else about the code; it should work!
In a nutshell, the game works like this:
- The starting board contains two tiles with values of 2 or 4.
- When the player hits an arrow key, all tiles on the board âmergeâ in that direction.
- After each merge, a random tile of value 2 or 4 is added to the screen.
- The game ends when there are no merges left. You âwinâ if a tile reads â2048â or more!
The board representation in this version of 2048 is abstracted away (we call that an âabstract data typeâ), but you can picture it as a table that looks like the picture on the right, containing only 0 and powers of 2 greater than or equal to 2 (e.g., 2, 4, 8, 16, etc). Do not assume that boards are always 4x4 â all the code we give you as well as the code you write should be able to work with any size square board!
Note: Make sure to run your game in Turbo Mode for best response time results. To turn on Turbo Mode, check the âTurbo Modeâ box in the gear icon menu. The green starting flag will change to a lightning bolt (as shown).
This project must be completed with a partner. If youâre having trouble finding one, head to the Partner-Finding thread on Ed! Do remember that while you may discuss general ideas with students you arenât partners with, sharing code would be academically dishonest. If youâre having trouble, please contact the course staff for assistance âEd, Office hours, labs, and the project party are all here to help you feel good about the work youâre doing! If you canât make the times, tell us, and weâll figure out how you can still get support. But we wonât know when or how to help unless you let us know!
Note: You can import blocks from libraries
Helper Blocks
You will not need to know how we represent a board in this game â we have provided the following nine helper blocks for you to use to interface with our board implementation. The Power of Abstraction! With this in mind, please make sure not to modify the input board in any of the blocks you write! In addition, please use these blocks, rather than coming up with your own. Also keep in mind that you generally want to abstract as much as possible, meaning you should not use global variables within blocks. We created all custom blocks (including the five you will fill out) so that any information youâll need will be passed into the block as input.
Block | Input | Output | Description |
---|---|---|---|
new board size | side length (number) - desired length of one side of the board | an empty side length x side length square board | Use this block rather than the ânew 4x4 board with values ___âŠâ block from the testing lab. That block should be used only for testing, per the name of the lab |
size of board | board - a 2048 game board at some point in the game | the length of one side of the input board | â |
item of | row (number), column (number), board (a 2048 game board) | the value (number) at row, column on the board | â |
set item of | row (number), column (number), board (a 2048 game board), value (number) - a value to be inserted into board at row, column | none, this is a command block | Use this block to set a particular square on the board to a particular value |
copy of | board - a 2048 game board at some point in the game | a separate board with all the same values as the input board | Use this block to build boards that need to have/start with the same values/game state as another board. Updating the copy will not update the input board |
empty positions of | board - a 2048 game board at some point in the game | a list of lists where each sublist contains the row and column of an empty position | â |
rotated row for, for size | row (number), column (number), size (number) - the side length of the board youâd like to rotate within | the row number of the resulting location of this item | This block does not actually rotate any part of the board. It only returns the row that the input coordinates (row, column) would end up in if the board was rotated 90 degrees clockwise. Here is a visual example |
rotated col for, for size | row (number), column (number), size (number) - the side length of the board youâd like to rotate within | the column number of the resulting location of this item | This block does not actually rotate any part of the board. It only returns the column that the input coordinates (row, column) would end up in if the board was rotated 90 degrees clockwise. Here is a visual example |
update display for | board - a 2048 game board at some point in the game | none, this is a command block | This block updates the stage to display the input board, and sets (game board). This will help you mainly in testing, but should not be used in your game code |
We encourage you to play around with these blocks (input different values and see what the output is) to better understand what they do and how they work â you can also go into each block and look at the code. This will help you when using these blocks in the rest of the project. Just be sure not to change what is inside each of them.
Suggestions
Parts 3 and 4 will take a significant amount of your time spent on the project. We recommend managing your time to accommodate for the influx of difficulty on the latter half of project 3. A good mental checkpoint is to have part 2 done by Friday. These are merely suggestions based on the experience of students from previous semesters.
Part 1: Populating the Board
In this section of the project, you should fill out the âadd 2 or 4 to _â block. The value 2 should have a 75% chance of being added, and the value 4 should have a 25% chance. These values should be added to a randomly-selected empty space on the board.
Input: board - a 2048 game board with at least one empty space
Output: a copy of board with an added value at a random location
Make sure you arenât modifying the original board when working on this. Your output should be a new copy of the board, and should not update the existing board. Updating the existing board is done for you in the provided game code.
Hint: Stuck? Check out some of the existing blocks in Snap! How will you find where to insert the value in the board? Are there any blocks we provide that could help?
Part 2: Rotating the Board
In this part, you should fill out the ârotate _ clockwiseâ block, which takes in a board and returns a copy of the board that is the result of rotating the input board 90 degrees clockwise. (You will lose points if you rotate anti-clockwise.)
Input: board - a 2048 game board with at least one empty space
Output: a copy of board that has been rotated 90 degrees clockwise
Make sure you arenât modifying the original board when working on this. Your output should be a new copy of the board, and should not update the existing board. Updating the existing board is done for you in the provided game code.
Hint: Take a look at the ârotated rowâ, ârotated columnâ, âsize of boardâ, and âcopy ofâ blocks if youâre not sure how to do something! In particular, the âcopy ofâ block will let you duplicate the contents of a board and then update it separately from the original.
Part 3: Merging
In this section of the project, youâll be filling out two blocks: âmerge column _ of _ upâ and âmerge up _â. It is highly recommended that you make helper blocks as part of your implementation of âmerge column _ of _ upâ. Note that you can create helper blocks by right clicking in the scripting area and selecting âmake a blockâŠâ
This article breaks down the components of merging a single column, which you should mimic with your implementation. Also, make sure that youâre maintaining the abstraction provided by âmerge column __ of __ upâ when you build âmerge up __â which is to say try to use âmerge column __ of __ upâ while coding up âmerge up __â.
âmerge column __ of __ upâ Input: col (number, 1 is the leftmost column), board - a 2048 game board Output: a copy of the board in which column col has been completely merged up
âmerge upâ Input: board - a 2048 game board at some point in the game Output: a copy of board in which all columns have been merged up
Make sure you arenât modifying the original board when working on this. Your output should be a new version of the board, and should not update the existing board. Updating the existing board is done for you in the provided game code. Note that we only need one block that merges upward (rather than four blocks that each merge left, right, up, down) because we have the ârotate clockwiseâ block. If we want to merge left, for example, we can first rotate the board clockwise 90 degrees, merge up, and then rotate the board clockwise 270 degrees. The provided skeleton code implements this for you, though!
Hint: Stuck? Check out some of the existing blocks in Snap! How will you find where to insert the value in the board? Are there any blocks we provide that could help?
Part 4: Ending the Game
In this part of the project, youâll be filling in the âno moves left for _?â block, which should report False when there are still merges available on the board, and True when the board cannot be merged further. Keep in mind that the board can be full and there can still be moves available.
Input: board - a 2048 game board
Output: whether or not the board can be merged further (Boolean)
Make sure you arenât modifying the original board when working on this. Your output should be a Boolean, ie, True/False value signifying whether the game is over or not. Hint: We found the âcascadeâ block helpfulâŠ
Part 5: Testing
An important part of learning to program is being able to test your code effectively. Weâve taken the training wheels off; in earlier projects we gave you all the tests, here we ask you to create the tests yourself. In the TESTER sprite, you will see four blocks:
You need to create at least two separate test cases for these four blocks, with their respective expected output. Please note, that the reporter test function requires the board to be wrapped in an additional list block. Once you are done with all your tests, to get credit from the autograder, you have to drag these four blocks into the four holes of the append block and then click that block to assign GRADED TESTS, which the Autograder will use to give you credit.
Please note that your test cases should output True, not False. This is because the goal of testing is to check that your blocks work in normal cases as well as edge cases, not to check that it fails when expected. If your block outputs False, we assume this means your block does not pass the case and is therefore faulty. When writing test cases, each test should include input and output (follow the format in the Testing lab), and you should think about a genuine input for the block that would help you test if it accomplishes the task it should do, or catches some edgecase. For example, does the merge column up block work on a column with the values [0, 0, 2, 2]? If the merge column with this input correctly outputs [4, 0, 0, 0] in that column, the test block should output True. Check out these workbook pages which go deeper into the Test block and testing. Feel free to test your concepts in the 2048 lab section. Tests only present in your lab sprite will not be counted for project credit. The tests must be present in the âTESTERâ section.
Here is guide and some examples of the testing block:
Feedback Form
Congratulations on finishing your third project in CS10đ„łPlease spend some time completing this feedback form. This will be worth 1 point of your project grade. Each member of your group should submit to the form. Thank you!
Grading
You have five blocks to write, and they will be scored according to the table below; a perfect score would earn 35 points. Note that for a particular block, the test cases may have different weights. The autograder needs a score between 0 and 1, so we divide the total score by 35 to send to the autograder. You should continue to work on your code until all test cases pass
Remember that your final score on this project is the score youâll see on Gradescope, which will be out of 35 points. If at any point youâd like to see a more detailed about how we calculate that out-of-35 score, you can run the block we provide, which reports a nicely-formatted table (with headers) showing every test case, the expected value, and the actual value. Note: correct, working code should handle those test cases, but not have the test cases hardcoded into your solution; they should be able to handle any inputs according to the specifications. See grading breakdown below:
Block | Type of Block | Points per Block |
---|---|---|
add 2 or 4 to _ | Reporter | 4.67 |
rotate _ clockwise | Reporter | 4.67 |
merge up column _ of _ | Reporter | 11.67 |
merge up _ | Reporter | 4.67 |
no moves left for _ ? | Predicate | 4.67 |
Testing | Variable | 3.65 |
Feedback Form | N/A | 1 |