Skip to content
Snippets Groups Projects
Commit 541a5b0a authored by keleher's avatar keleher
Browse files

auto

parent 73986889
No related branches found
No related tags found
No related merge requests found
# Assignment 1: Swift and Extensions
**Due: Feb 16, 2020, 11:59:59 pm, v0.3**
## Goals
The primary goal of this project is to to familiarize yourself with the environment and
the language. All in this class will be written in Swift 5.1, using XCode 11 as your
friendly development environment. *Errors resulting from development in different
environments still result in loss of points.* More importantly, `SwiftUI` will not work
on anything before Mojave.
Specifically, you will do the following:
1. create a standard single-view app, "*assign1*" that does nothing (other than
compile and show a blank screen), but does include a model of our app: "Triples".
In the process you will obviously learn quite a bit about the `XCode` environment, about
unit tests in the context of Swift applications, and about defining type extensions.
## Using git
We will use [*git*](https://git-scm.com/doc) ([cheat sheet](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=2ahUKEwi_uaemsqXgAhVmzlkKHc-HCUkQFjABegQIAhAC&url=https%3A%2F%2Feducation.github.com%2Fgit-cheat-sheet-education.pdf&usg=AOvVaw2D3W2R0fwoOBi8YrhZYLFJ)) both to distribute starting files, for those projects that
have them (not `assign1`), and to submit the work that you create. Each of you will have had a single
gitlab repository create, e.g. `ios436spring2020/cmsc436-<dirid>` (but use your
directoryid, which is NOT a number). Clone this repository as follows:
1. log into gitlab and verify that you have the above repository
1. create and upload a public key as described below in "Upload Public Key". This will allow you to
access gitlab via `ssh`, which is much less kludgy/buggy than https.
1. In your terminal window, clone via `git clone git@gitlab.cs.umd.edu:ios436spring2020/cmsc436-<dirid>` (again, use *your*
dirid). **cd** into this directory.
- **Note** that if your repository is not found, or you don't have
permissions, it's because our script could not finish setting the
repository up until you had logged into gitlab.cs.umd.edu at least
once. Please do this at once, and then try again the next day. If it
still fail, email me directly w/ subject "436 repository".
2. Establish a new *upstream remote*: `git remote add upstream
git@gitlab.cs.umd.edu:keleher/cmsc436spring2020-starter.git` This remote
will be where you *pull* startup files from when each new project, or iteration of a
project, is made available (`git pull upstream master'). **You will not
need the upstream remote for this project, but set it up anyway.**
3. Verify your setup by executing `git remote -v`. You should see something
like:
```
origin git@gitlab.cs.umd.edu:ios436spring2020/cmsc436-<dirid>.git (fetch)
origin git@gitlab.cs.umd.edu:ios436spring2020/cmsc436-<dirid>.git (push)
upstream git@gitlab.cs.umd.edu:keleher/cmsc436spring2020-starter.git (fetch)
upstream git@gitlab.cs.umd.edu:keleher/cmsc436spring2020-starter.git (push)
```
Uploading your completed work is a two-step process: `git commit -m "a
label"`, followed by `git push origin master`. Verify by logging into the
gitlab website and making sure your new changes are there.
It's a good idea to
commit intermediate versions of your code many times during the development process.
### Upload Public Key
If you don't already have an RSA public key-pair, do the following:
```
> cd
> ssh-keygen -t rsa
(hit return in response to all prompts)
```
Upload the contents of `~/.ssh/id_rsa.pub` to gitlab by logging in,
selecting 'Settings' from the menu in the upper right, and then selecting 'ssh
keys' from the left of the page. Add your key by pasting into the textbox,
giving your machine's name as a title, and clicking 'Add Key'.
# Building An App
We are going to build an apple called `Triples` in two or three stages. In the first
stage, we are just going to design and implement the model, and unit-test it.
As we did in class, you will create a new single-view iOS app:
- Create a new project in XCode and save to your `cmsc436-<dirid>` directory.
- When creating the project:
- also call it `assign1`
- **check "unit tests"**, uncheck `git`, uncheck UI tests
- select a "single-view" iOS app even though we will not have any graphical characteristics
- Note that new files must be explicitly added to git via `git add <file>...`.
Create a new file `model.swift` in the app by selecting "New File" from the, and then
selecting the Swift file icon in the dialog, and name it `model.swift`.
`model.swift` will contain the "model" known from the model-view-controller (MVC) paradigm.
## App Logic
Our game action will be similar to the app `Threes` app on the apple and android app
stores. A portion of the game play is shown here:
![Similar gameplay](https://sedna.cs.umd.edu/clips/assign1DemoThrees.mp4)
## Your Tasks
Your tasks are to implement the *model* behind the gameplay shown in the clip. Specifically, you will
implement the "collapse", which given a swipe in a direction collapses each row or column
parallel to the swipe by eliminating a blank, combining a 1 and a 2, or combining two
consecutive tiles w/ the same value, 3 or higher. For more specifics, see the tests
described below.
## The `Triples` Class
In the file `model.swift` you need to define a new class `Triples`,
which implements the methods discussed below. Most importantly,
`Triples` will need the following definitions:
```
var board: [[Int]]
func newgame() {} // re-inits 'board', and any other state you define
func rotate() {} // rotate a square 2D Int array clockwise
func shift() {} // collapse to the left
func collapse(dir: Direction)) // collapse in specified direction using shift() and rotate()
```
Note that methods merely modify the `board` property. We are not taking any
actions based on the board, or doing any GUI work at all.
`Direction` is an `enum` that you will define for the four directions referenced below.
Outside `Triples`, you will need to build two other functions, one of which
should be called in your `rotate()` method (ideally the generic, but the
explicit `Int` version is fine if you don't get the generic working).
The first is:
```
// class-less function that will return of any square 2D Int array rotated clockwise
public func rotate2Dints(input: [[Int]]) -> [[Int]] {}
```
You should also build `rotate2D`, which is a *generic* version of the above.
### Unit Tests
Copy the following unit tests verbatim into your file
`assign1Ttests.swift`. Do no change anything, as we will use the exact tests
below to test your definitions in `model.swift`.
```
func testSetup() {
let game = Triples()
game.newgame()
XCTAssertTrue((game.board.count == 4) && (game.board[3].count == 4))
}
```
Tests to ensure your app defines a 4x4 2D array of `Int`s.
### Rotate
Build a func `rotate2DInts` that will take any 2D Int array and rotate it once
clockwise. Your func may assume that the array is square.
```
func testRotate1() {
var board = [[0,3,3,3],[1,2,3,3],[0,2,1,3],[3,3,6,6]]
board = rotate2DInts(input: board)
XCTAssertTrue(board == [[3,0,1,0],[3,2,2,3],[6,1,3,3],[6,3,3,3]])
}
```
### Generic Rotate
Same test using a generic func you must write called `rotate2D`, and which will work on
any type of array.
```
func testRotate1() {
var board = [[0,3,3,3],[1,2,3,3],[0,2,1,3],[3,3,6,6]]
board = rotate2D(input: board)
XCTAssertTrue(board == [[3,0,1,0],[3,2,2,3],[6,1,3,3],[6,3,3,3]])
}
```
Try again with strings.
```
func testRotate3() {
var board = [["0","3","3","3"],["1","2","3","3"],["0","2","1","3"],["3","3","6","6"]]
board = rotate2D(input: board)
XCTAssertTrue(board == [["3","0","1","0"],["3","2","2","3"],["6","1","3","3"],["6","3","3","3"]])
}
```
### Collapsing
Write a `shift()` method that collapses each row to the left (as if w/ a left swipe in the
clip).
```
func testShift() {
let game = Triples()
game.board = [[0,3,3,3],[1,2,3,3],[0,2,1,3],[3,3,6,6]]
game.shift()
XCTAssertTrue(game.board == [[3,3,3,0],[3,3,3,0],[2,1,3,0],[6,6,6,0]])
}
```
Write and test a `collapse()` method will take a `Direction` enumeration collapse in the
direction specified. Internally, you should build `collapse` using `shift()` and `rotate()`.
```
func testLeft() {
let game = Triples()
game.board = [[0,3,3,3],[1,2,3,3],[0,2,1,3],[3,3,6,6]]
game.collapse(dir: .left)
XCTAssertTrue(game.board == [[3,3,3,0],[3,3,3,0],[2,1,3,0],[6,6,6,0]])
}
func testRight() {
let game = Triples()
game.board = [[0,3,3,3],[1,2,3,3],[0,2,1,3],[3,3,6,6]]
game.collapse(dir: .right)
XCTAssertTrue(game.board == [[0,0,3,6],[0,1,2,6],[0,0,3,3],[0,3,3,12]])
}
func testDown() {
let game = Triples()
game.board = [[0,3,3,3],[1,2,3,3],[0,2,1,3],[3,3,6,6]]
game.collapse(dir: .down)
XCTAssertTrue(game.board == [[0,3,0,0],[0,2,6,3],[1,2,1,6],[3,3,6,6]])
}
func testUp() {
let game = Triples()
game.board = [[0,3,3,3],[1,2,3,3],[0,2,1,3],[3,3,6,6]]
game.collapse(dir: .up)
XCTAssertTrue(game.board == [[1,3,6,6],[0,2,1,3],[3,2,6,6],[0,3,0,0]])
}
```
# Submit, and Grading
Submit by pushing your project to your 436 repository. **Check this** by visiting your
repository in a web browser at `https://gitlab.cs.umd.edu/ios436spring2020/cmsc436-<dirid>`
Each of the nine tests is worth 1 point. There is no partial credit.
# Notes
- Remember, frequently save your work on gitlab through the folloing. This is exactly the same sequence you will use with the final submit. We will download
your repository from gitlab directly.
```
git add assign1
git commit -m "a message"
git push origin master
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment