Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cmsc436PublicF2021
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
cmsc436PublicF2021
Commits
9f17fb92
Commit
9f17fb92
authored
3 years ago
by
Peter J. Keleher
Browse files
Options
Downloads
Patches
Plain Diff
auto
parents
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
assign1/README.md
+190
-0
190 additions, 0 deletions
assign1/README.md
assign1/assign1Tests.swift
+87
-0
87 additions, 0 deletions
assign1/assign1Tests.swift
assign1/xcode.png
+0
-0
0 additions, 0 deletions
assign1/xcode.png
with
277 additions
and
0 deletions
assign1/README.md
0 → 100644
+
190
−
0
View file @
9f17fb92
# Assignment 1: Swift and Extensions
## 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.5, using XCode 12 or later as your friendly development
environment.
*
Errors resulting from development in different
environments still result in loss of points.
*
Specifically, you will create an application having a model that emulates the logic of the 2048
app
[
here
](
https://play2048.co/
)
in a SwiftUI app, though we won't actually
build a GUI at all. Your app will do nothing when run, but does
include the app's
model and unit tests with which to test your model.
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
You will submit your assignment solution through git. Clone your
repository from
`gitlab.cs.umd.edu`
as follows:
```
git clone git@gitlab.cs.umd.edu:cmsc436Fall2021/cmsc436-<dirid>
```
with your directoryID substituted for "
<dirid>
" above. This is the ssh
version of git clone, which assumes you've uploaded an ssh key for
your machine. Otherwise you can use:
```
git clone https://gitlab.cs.umd.edu/cmsc436Fall2021/cmsc436-<dirid>
```
Email me directly (w/ "436" in the subject) if your repository does
not seem to exist.
Create the new project
`assign1`
in your repository. Always close the
project first before pushing back to gitlab. The first time you create
the project, cd into the repository and then push the new project back
to gitlab.
For example, close the repository (w/ my dirid just as an example),
like the following:
```
git clone git@gitlab.cs.umd.edu:cmsc436Fall2021/cmsc436-keleher
```
Create the new
`assign1`
project inside cmsc436-keleher, create a new
`model.swift`
in the project to define your model, update the unit
tests via the link below, and perform the following for your first
commit:
```
cd cmsc436-keleher
git add assign1
git commit -a -m auto
git push origin master
```
You should add, commit, and push frequently,
so that:
1.
you do not lose work, and
2.
we can help answer your questions by looking at your code.
**Important:**
Test that your project create and push to the
repository is correct by cloning it to a separate, throwaway
location. Open this throwaway version and verify that it works the
same way as your primary copy. If it doesn't, you probably did not
*add*
all the files in your project. Do this manually and try again.
# 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 SwiftUI 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
(not fatal, but the
`Test`
command from the
`Product`
menu will
fail because it will try to test your GUI, and you don't have one.
-
select a "single-view" iOS app even though we will not have any graphical
characteristics
-
Create a new file
`model.swift`
to implement the
`Twos`
class in
your app by selecting "New / File"
from the File menu, selecting the Swift file icon in the dialog, and
then naming it
`model.swift`
.
`model.swift`
will contain the "model" known
from the model-view-controller (MVC) or model-view-viewmodel paradigms.
-
Copy and paste the code in
[
assign1Tests.swift
](
assign1Tests.swift
)
verbatim over the default version.
Your file structure should look like the following: !
[
xcode.png
](
xcode.png
)
## App Logic
Our game action will be similar to the app
`2048`
on the apple
and android app stores. Game-play should be as on the
[
website
](
https://play2048.co/
)
.
## Your Tasks
Your tasks are to implement the
*model*
of the game. Specifically, you will implement the "collapse", which
given a swipe in a direction collapses each row or column parallel
to the swipe by:
-
eliminating any blanks, and
-
performing a single pass over each row/col in the reverse of the
swipe and combining consecutive individual values into a single value
twice as large
Note that a "swipe" can also be performed in a variety of other ways,
for now we will do it using on-screen buttons.
For more specifics, see the tests described below.
## The `Twos` Class
In the file
`model.swift`
you will define a new class
`Twos`
to
implement the gameplay model and
implements the methods discussed below.
`Twos`
will need the following definitions:
```
struct Tile {
var val : Int
var lastRow = 0, lastCol = 0
init(v: Int) {
val = v
}
}
enum Direction {
case left
case right
case up
case down
}
var board: [[Tile]] // must be init'd, but contents overwritten
```
and functions:
```
// primitive functions
public func rotate2DInts(input: [[Int]]) ->[[Int]] // rotate a square 2D Int array clockwise
public func rotate2D<T>(input: [[T]]) ->[[T]] // generic version of the above
// high-level functions
func shiftLeft() // collapse to the left
func rightRotate() // define using only rotate2D
func collapse(dir: Direction) // collapse in direction "dir" using only
// shiftLeft() and rightRotate()
```
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.
A
`Tile`
is a simple structure containing a
`val`
(the value of the
tile) and additional
`Int`
fields
`lastRow`
and
`lastCol`
. You will
need to ensure that
`Tile`
conforms to the
`Equatable`
protocol.
You
**must**
define and use the generic function
`rotate2D()`
to get
any credit, do not define a
`Tile`
-specific version of rotate or use
`rotate2DInts`
at all in the
`collapse()`
function.
### testing
The provided copy of
`assign1Tests.swift`
should have been copied
**unaltered**
into your project. Test your project by
running this set of tests by clicking "Test" in the "Products" menu, or
clicking in the margin next to
`class assign1Tests: XCTestCase`
, or in
the margin next to the individual tests.
# Submit, and Grading
Submit by pushing your project to your repository.
**Check this**
by visiting your repository in a web browser at
`https://gitlab.cs.umd.edu/cmsc436-marsh/students/<dirid>/assign1`
Each of the eight tests is worth 1 point. There is no partial
credit. You will not get credit if you:
-
modify
`assign1Tests.swift`
in any way
-
do not define
`rightRotate()`
and
`collapse()`
as specified above
-
define a
`Tile`
-specific version of rotate.
# Notes
-
Remember, frequently save your work on gitlab. You can push your
work as many times as you wish. We will download
your repository from gitlab directly after the deadline.
This diff is collapsed.
Click to expand it.
assign1/assign1Tests.swift
0 → 100644
+
87
−
0
View file @
9f17fb92
//
// assign1Tests.swift
// assign1Tests
//
// Created by Pete Keleher on 2/2/20.
// Updated by Shoumit Karnik on 1/20/21.
// Copyright © 2020 PeteWorks. All rights reserved.
//
import
XCTest
@testable
import
assign1
class
assign1Tests
:
XCTestCase
{
override
func
setUpWithError
()
throws
{
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override
func
tearDownWithError
()
throws
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func
int2tile
(
iboard
:
[[
Int
]])
->
[[
Tile
]]
{
var
b
:
[[
Tile
]]
=
Array
(
repeating
:
Array
(
repeating
:
Tile
(
v
:
0
),
count
:
iboard
.
count
),
count
:
iboard
.
count
)
for
i
in
0
..<
iboard
.
count
{
for
j
in
0
..<
iboard
.
count
{
b
[
i
][
j
]
.
val
=
iboard
[
i
][
j
]
}
}
return
b
}
func
testSetup
()
{
let
game
=
Twos
()
XCTAssertTrue
((
game
.
board
.
count
==
4
)
&&
(
game
.
board
[
3
]
.
count
==
4
))
}
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
]])
}
func
testRotate2
()
{
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"
]])
}
func
testShift
()
{
let
game
=
Twos
()
game
.
board
=
int2tile
(
iboard
:
[[
0
,
2
,
2
,
2
],[
4
,
2
,
4
,
4
],[
0
,
8
,
2
,
4
],[
0
,
0
,
4
,
4
]])
game
.
shiftLeft
()
XCTAssertTrue
(
game
.
board
==
int2tile
(
iboard
:
[[
4
,
2
,
0
,
0
],[
4
,
2
,
8
,
0
],[
8
,
2
,
4
,
0
],[
8
,
0
,
0
,
0
]]))
}
func
testLeft
()
{
let
game
=
Twos
()
game
.
board
=
int2tile
(
iboard
:
[[
0
,
2
,
2
,
2
],[
4
,
2
,
4
,
4
],[
0
,
8
,
2
,
4
],[
0
,
0
,
4
,
4
]])
game
.
collapse
(
dir
:
.
left
)
XCTAssertTrue
(
game
.
board
==
int2tile
(
iboard
:
[[
4
,
2
,
0
,
0
],[
4
,
2
,
8
,
0
],[
8
,
2
,
4
,
0
],[
8
,
0
,
0
,
0
]]))
}
func
testRight
()
{
let
game
=
Twos
()
game
.
board
=
int2tile
(
iboard
:
[[
0
,
2
,
2
,
2
],[
4
,
2
,
4
,
4
],[
0
,
8
,
2
,
4
],[
0
,
0
,
4
,
4
]])
game
.
collapse
(
dir
:
.
right
)
XCTAssertTrue
(
game
.
board
==
int2tile
(
iboard
:
[[
0
,
0
,
2
,
4
],[
0
,
4
,
2
,
8
],[
0
,
8
,
2
,
4
],[
0
,
0
,
0
,
8
]]))
}
func
testDown
()
{
let
game
=
Twos
()
game
.
board
=
int2tile
(
iboard
:
[[
0
,
2
,
2
,
2
],[
4
,
2
,
4
,
4
],[
0
,
8
,
2
,
4
],[
0
,
0
,
4
,
4
]])
game
.
collapse
(
dir
:
.
down
)
XCTAssertTrue
(
game
.
board
==
int2tile
(
iboard
:
[[
0
,
0
,
2
,
0
],[
0
,
0
,
4
,
2
],[
0
,
4
,
2
,
4
],[
4
,
8
,
4
,
8
]]))
}
func
testUp
()
{
let
game
=
Twos
()
game
.
board
=
int2tile
(
iboard
:
[[
0
,
2
,
2
,
2
],[
4
,
2
,
4
,
4
],[
0
,
8
,
2
,
4
],[
0
,
0
,
4
,
4
]])
game
.
collapse
(
dir
:
.
up
)
XCTAssertTrue
(
game
.
board
==
int2tile
(
iboard
:
[[
4
,
4
,
2
,
2
],[
0
,
8
,
4
,
8
],[
0
,
0
,
2
,
4
],[
0
,
0
,
4
,
0
]]))
}
}
This diff is collapsed.
Click to expand it.
assign1/xcode.png
0 → 100644
+
0
−
0
View file @
9f17fb92
474 KiB
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