Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
iosStudentsSpring2020
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Peter Keleher
iosStudentsSpring2020
Commits
505cf86f
Commit
505cf86f
authored
5 years ago
by
keleher
Browse files
Options
Downloads
Patches
Plain Diff
auto
parent
32a000dd
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
assign2.md
+189
-0
189 additions, 0 deletions
assign2.md
with
189 additions
and
0 deletions
assign2.md
0 → 100644
+
189
−
0
View file @
505cf86f
# Assignment 2: Triples
**Due: March 8, 2020, 11:59:59 pm, v1.0**
## Goals
Use the routines you implemented for assign1 in building the
*Triples*
game.
## Creating the Project
**Note:**
create your new project
**assign2**
directly in your repository, so the resulting directory
structure should look like this:
```
repository
/ \
assign1 assign2
/ \ / \
assign2 assign2.xcodeproj/
/ \
model.swift ...
```
Also:
-
Do not select either unit tests or automated tests, we will not use them.
-
Do
**not**
select "Create git repository".
## Game Rules
1.
The board consists of a 4x4 grid of rectangles.
1.
Move the board contents Up, Down, Left, and Right, combining compatible numbers into their sums.
1.
The game's "goal" is to achieve the highest score, and the game continues as long
as the player is able to keep moving.
## Board Details
First, set your simulated phone to an
**iPhone 11**
. This will give us a
common platform.
The elements of your view should be the following:
-
16 rectangular "tiles", implemented by buttons.
-
A button labeled 'New Game'
-
Buttons labeled 'Left', 'Right', 'Up', and 'Down'.
-
A segmented control, consisting of panes "Random"
(random), and "Determ" (deterministic). Check for deterministic running as
`segmentedOutlet.selectedSegmentIndex == 1`
, where
`segmentedOutlet`
is an outlet you
ctrl-dragged from your new segmented
button.
-
A label where you will show the current score.
The actions should be as follows:
-
Activating the
`New Game`
button should cause the game to be restarted, calling
`newgame()`
with the
`rand`
initializer
argument (see below) defined by the current state of the switch, followed by
*four*
`spawn()`
s.
-
Activating directional arrows should cause a
*collapse*
towards the indicated direction, followed
by a spawn
*if the collapse modified the board*
.
-
Changing Random/Determ does not affect the current game, it only changes subsequent games.
-
A running score should be shown in the label.
## Model Details
Define your model by augmenting the
`Triples`
model from
**assign1**
to
ensure the following properties are externally visible:
-
`var board: [[Int]]`
-
`var score: Int`
Property
`score`
shows the current game score, calculated by incrementing your total with
the value of each new number that appears in the game. For example, spawns of a '1' and a
'2' will add 1 and 2 points, respectively. Combining a '2' and a '1' into a '3' adds 3
points. Combining two '3's into a '6' adds six points, etc. Look at the running point
count in the video if this is unclear.
Your model should also have the following externally-visible methods:
-
`newgame(rand: Bool)`
- reinitializes all model state. The value of
`rand`
should be derived from the Random/Deterministic segmented button. Note that this method
should
*not*
call
`spawn()`
(calling
`newgame`
just initializes an empty game). Instead,
the "action" for the newgame button should call
`newgame()`
, followed by four
`spawn()`
s.
-
`collapse(dir: Direction) -> Bool`
, collapse the model's board in the indicated
direction, in place. Return
`true`
if movement occurred. You should
define Direction to be an enum consisting of "Left", "Right", "Up", and
"Down". Coincidentally, these are also the labels of the directional buttons.
-
`spawn()`
: which randomly chooses to create a new '1' or a '2', and puts it in an open
tile, if there is one. See
`Randomized Spawn`
below.
-
`isDone()`
: returns true if there are no more possible moves.
Your model may have other externally visible controls and state, only the above is required.
All of this state should be kept in the
`Triples`
class defined in a file called
`model.swift`
.
## Game Play
-
Pressing
`New Game`
should produce a brand new game on the display, w/ four
newly-spawned tiles, each either a "1" or a "2".
-
Pressing
`Left`
,
`Right`
,
`Up`
, or
`Down`
should cause the underlying model to react as
in
`assign1`
. The visible buttons should correspond to that model, and the score should
be updated.
-
A new tile is spawned afterwards if at least one tile has moved or combined with
another.
-
When your app determines that there are no more possible moves in any direction it
displays an alert showing the current score, with an action that allows the alert to
be dismissed.
-
Pressing either
`Random`
or
`Determ`
(deterministic) controls the random seed used by
future new games. See below.
### Randomized and Deterministic Spawning
Swift 4.2+ has a beautiful new way of creating random values (e.g.
`Int.random(in:
1...10)`
). We aren't going to use that.
The reason is that we want to allow the game
to be made repeatable for debugging and testing (including our
testing). Define the following in your model:
```
func prng(max: Int) -> Int {
let ret = Int(floor(drand48() * (Double(max))))
return (ret < max) ? ret : (ret-1)
}
```
The
`drand48()`
method is a
pseudo random number generator (PRNG) deterministically generates a random-ish
sequence of values from an initial seed.
Use
`prng`
in all cases to get random integers for this project. Seed
`prng`
in
`newgame()`
, using
`srand48(42)`
when running deterministically, or
`srand48(Int.random(in:1...1000))`
when in random mode. This latter
approach is seeded from operating system sources and is easily random enough for your
needs.
Your app has only two randomized decisions: whether to spawn a '1' or a '2', and where to
put the newly spawned value:
-
'1's and '2's have equal probability.
-
Choose the open tile to filled by the following:
-
number the open tiles by traversing the grid by row, and left-to-right within each
row. The first open tile has index
`0`
.
For example, with:
```
| 0 1 0 2 |
| 0 0 3 6 |
| 1 2 1 1 |
| 3 3 0 3 |
```
Conceptually number these open spots as follows:
```
| 0 1 |
| 2 3 |
| |
| 4 |
```
Choose among them by randomly selecting in indice from 0 to 4.
Use
`prng`
to make both random choices. We want your deterministic mode to
exactly match ours, so use the following ordering:
-
First check to see if there's an open spot for a new tile. Do not call
`prng`
otherwise.
-
Use
`prng`
to decide the value of the new tile.
-
Use
`prng`
to decide where to place the new tile.
This ordering is important; otherwise your random decisions may not match
ours.
**Your gameplay must match the below video**
for full credit.

### Grading / Testing
Our grading will once again be automated grading. We will soon release two scripts
that you can run to test your interfaces and gameplay. We will use those scripts
and two others for our automated testing.
We will award points as follows:
-
(5 pts) Display is layed out with correct controls.
-
(5 pts) Gameplay is correct, numbers move as expected, combine as expected.
-
(5 pts) Scores are correct. This can be checked even with out determinism, but in
deterministic mode:
-
click "New Game". Should have a score of 7.
-
new game / down / down / down / down / right should give a score of 26
-
(5 pts) Click new game (in random mode) multiple times and see different initial
conditions, all with 4 buttons displayed, each either a '1' or a '2'
-
(10 pts) Determinism works:
-
in deterministic mode a new game reproduces the sequences shown above, i.e.:
-
new game / right / right / right gives the "C" shape, and
-
new game / down (9 times) results in
the two rows (plus 1 extra tile) shown in the movie above
-
(10 pts) Overall look and feel. It's an app! Your app should be well layed
out, clear, and attractive. We are not grading how closely it looks to the one shown
above, though the three classes of colors (ones, twos, others) should be distinct.
Your app should be attractively layed out.
Notes:
-
Your game should look relatively close to the above video in coloration and layout.
-
You do not need to worry about orientation changes.
-
We are not looking at your code other than to look for plagiarism.
-
We do not care if you implement the "tiles" by changing the appearance of 16 static
buttons (easiest), or if you use fewer buttons and move them about.
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment