// // Privyet.swift // Privyet // // Created by Amy Bowersox on 5/24/20. // Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. // import Foundation let NumColumns = 10 let NumRows = 20 let StartingColumn = 4 let StartingRow = 0 let PreviewColumn = 12 let PreviewRow = 1 let PointsPerLine = 10 let LevelThreshold = 500 protocol PrivyetDelegate { // Invoked when the current round of Privyet ends func gameDidEnd(privyet: Privyet) // Invoked after a game has begun func gameDidBegin(privyet: Privyet) // Invoked when the falling shape has become part of the game board func gameShapeDidLand(privyet: Privyet) // Invoked when the falling shape has changed its location func gameShapeDidMove(privyet: Privyet) // invoked when the falling shape has changed its location after being dropped func gameShapeDidDrop(privyet: Privyet) // invoked when the game has reached a new level func gameDidLevelUp(privyet: Privyet) } class Privyet { var blockArray: Array2D var nextShape: Shape? var fallingShape: Shape? var delegate: PrivyetDelegate? var score = 0 var level = 1 init() { fallingShape = nil nextShape = nil blockArray = Array2D(columns: NumColumns, rows: NumRows) } func beginGame() { if (nextShape == nil) { nextShape = Shape.random(startingColumn: PreviewColumn, startingRow: PreviewRow) } delegate?.gameDidBegin(privyet: self) } func newShape() -> (fallingShape: Shape?, nextShape: Shape?) { fallingShape = nextShape nextShape = Shape.random(startingColumn: PreviewColumn, startingRow: PreviewRow) fallingShape?.moveTo(column: StartingColumn, row: StartingRow) guard detectIllegalPlacement() == false else { nextShape = fallingShape nextShape!.moveTo(column: PreviewColumn, row: PreviewRow) endGame() return (nil, nil) } return (fallingShape, nextShape) } func detectIllegalPlacement() -> Bool { guard let shape = fallingShape else { return false } for block in shape.blocks { if block.column < 0 || block.column >= NumColumns || block.row < 0 || block.row >= NumRows { return true } else if blockArray[block.column, block.row] != nil { return true } } return false } func settleShape() { guard let shape = fallingShape else { return } for block in shape.blocks { blockArray[block.column, block.row] = block } fallingShape = nil delegate?.gameShapeDidLand(privyet: self) } func detectTouch() -> Bool { guard let shape = fallingShape else { return false } for bottomBlock in shape.bottomBlocks { if bottomBlock.row == NumRows - 1 || blockArray[bottomBlock.column, bottomBlock.row + 1] != nil { return true } } return false } func endGame() { score = 0 level = 1 delegate?.gameDidEnd(privyet: self) } func removeCompletedLines() -> (linesRemoved: Array>, fallenBlocks: Array>) { var removedLines = Array>() for row in (1..() for column in 0..= level * LevelThreshold { level += 1 delegate?.gameDidLevelUp(privyet: self) } var fallenBlocks = Array>() for column in 0..() for row in (1.. 0 { fallenBlocks.append(fallenBlocksArray) } } return (removedLines, fallenBlocks) } func removeAllBlocks() -> Array> { var allBlocks = Array>() for row in 0..() for column in 0..