Last active
August 29, 2015 14:05
-
-
Save Pastez/8f20f70b7cb82347096e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Playground - noun: a place where people can play | |
import Cocoa | |
import SpriteKit | |
import XCPlayground | |
/** Possible values for new cells **/ | |
let kPossibleRandomValues = [2,4] | |
struct Position | |
{ | |
var column = -1; | |
var row = -1; | |
} | |
struct Size | |
{ | |
let colums:Int | |
let rows:Int | |
var length:Int { | |
return colums * rows | |
} | |
} | |
/** Possible playground move directions **/ | |
enum MoveDirection | |
{ | |
case Left | |
case Right | |
case Top | |
case Bottom | |
} | |
/** 2048 Game Main Class **/ | |
class Playground | |
{ | |
class Cell : Printable | |
{ | |
var value = 0 | |
var position:Position | |
var description:String { | |
return "Cell(\(self.position.column),\(self.position.row)" | |
} | |
init(position:Position) | |
{ | |
self.position = position | |
} | |
} | |
var size:Size | |
var cells:[Cell] | |
subscript(c:Int, r:Int) -> Cell? { | |
get { | |
return cells[c + r * size.colums] | |
} | |
set { | |
cells[ c + r * size.colums] = newValue! | |
} | |
} | |
/** Creates 2048 Game Playground with provided size | |
:param: size size of playground board | |
*/ | |
init(size:Size) | |
{ | |
self.size = size | |
self.cells = [Cell](count: size.length, repeatedValue: Cell(position: Position(column: 0, row: 0))) | |
for c in 0..<size.colums { | |
for r in 0..<size.rows { | |
self[c,r] = Cell(position: Position(column: c, row: r)) | |
} | |
} | |
} | |
/** inits playground with default size 5 by 5 **/ | |
convenience init() | |
{ | |
var s = Size(colums: 5, rows: 5); | |
self.init(size: s) | |
} | |
/** | |
:returns: Array of cells that have value equal to 0 | |
**/ | |
func emptyCells() -> [Cell] | |
{ | |
var result = [Cell]() | |
for r in 0..<self.size.rows { | |
for c in 0..<self.size.colums | |
{ | |
if let cell = self[c,r] { | |
if cell.value == 0 { | |
result.append(cell) | |
} | |
} | |
} | |
} | |
return result | |
} | |
/** | |
Adds random number from kPossibleRandomValues in empty place | |
:returns: if empty field was found**/ | |
func add() -> Bool | |
{ | |
let emptyCellsArray = emptyCells(); | |
if emptyCellsArray.count <= 0 { return false } | |
let rndIdx = Int(arc4random_uniform(UInt32(emptyCellsArray.count))) | |
let rndValueIdx = Int(arc4random_uniform(UInt32(kPossibleRandomValues.count))) | |
emptyCellsArray[rndIdx].value = kPossibleRandomValues[rndValueIdx]; | |
return true | |
} | |
/** | |
Move cells in designated direction | |
:param: direction direction of move | |
**/ | |
func move(direction:MoveDirection) | |
{ | |
func moveCells(inout c:Int,inout r:Int, dir:(horizontal:Int,vertical:Int)) | |
{ | |
let cell = self[c, r]! | |
var cellToCheck:Cell? = nil | |
var pnt = Position(column: c, row: r) | |
while cellToCheck == nil | |
{ | |
pnt.column += dir.horizontal; | |
pnt.row += dir.vertical; | |
if pnt.column >= 0 && pnt.column < size.colums && | |
pnt.row >= 0 && pnt.row < size.rows | |
{ | |
cellToCheck = self[pnt.column,pnt.row] | |
if cellToCheck?.value == 0 | |
{ | |
cellToCheck = nil | |
} | |
} | |
else | |
{ | |
break; | |
} | |
} | |
if let ctc = cellToCheck | |
{ | |
switch(cell.value, ctc.value) | |
{ | |
case (0,_): | |
cell.value = ctc.value | |
ctc.value = 0 | |
c = dir.horizontal >= 0 ? 0 : size.colums-1 | |
r = dir.vertical >= 0 ? 0 : size.rows-1 | |
return | |
case (let x, let y) where x == y: | |
cell.value += ctc.value | |
ctc.value = 0 | |
c = dir.horizontal >= 0 ? 0 : size.colums-1 | |
r = dir.vertical >= 0 ? 0 : size.rows-1 | |
return | |
default: | |
return; | |
} | |
} | |
} | |
switch direction | |
{ | |
case .Left: | |
for var r = 0; r < size.rows; r++ { | |
for var c = 0; c < size.colums; c++ { | |
moveCells(&c, &r, (horizontal: +1, vertical: 0)) | |
} | |
} | |
case .Right: | |
for var r = 0; r < size.rows; r++ { | |
for var c = size.colums-1; c >= 0; c-- { | |
moveCells(&c, &r, (horizontal: -1, vertical: 0)) | |
} | |
} | |
case .Top: | |
for var c = 0; c < size.colums; c++ { | |
for var r = 0; r < size.rows; r++ { | |
moveCells(&c, &r, (horizontal: 0, vertical: 1)) | |
} | |
} | |
case .Bottom: | |
for var c = 0; c < size.colums; c++ { | |
for var r = size.rows-1; r >= 0; r-- { | |
moveCells(&c, &r, (horizontal: 0, vertical: -1)) | |
} | |
} | |
} | |
} | |
/** | |
:returns: playground as printable string | |
**/ | |
func debugString() -> String | |
{ | |
var result = "" | |
for r in 0...self.size.rows - 1 { | |
for c in 0...self.size.colums - 1 | |
{ | |
if c % self.size.colums == 0 { | |
result += "\n" | |
} | |
if let cell = self[c,r] | |
{ | |
result += cell.value == 0 ? ". " : "\(cell.value) " | |
} | |
} | |
} | |
return result | |
} | |
} | |
/* I couldn't resist to do this :) */ | |
postfix operator ⬅️ {} | |
postfix func ⬅️ (playground:Playground) -> () | |
{ | |
playground.move(.Left) | |
} | |
postfix operator ➡️ {} | |
postfix func ➡️ (playground:Playground) -> () | |
{ | |
playground.move(.Right) | |
} | |
postfix operator ⬆️ {} | |
postfix func ⬆️ (playground:Playground) -> () | |
{ | |
playground.move(.Top) | |
} | |
postfix operator ⬇️ {} | |
postfix func ⬇️ (playground:Playground) -> () | |
{ | |
playground.move(.Bottom) | |
} | |
postfix operator ✳️ {} | |
postfix func ✳️ (playground:Playground) -> () | |
{ | |
playground.add() | |
} | |
var p:Playground = Playground() | |
/* | |
p[1,1]!.value = 16 | |
p[2,1]!.value = 8 | |
p[3,1]!.value = 0 | |
p[4,1]!.value = 8 | |
*/ | |
//p[0,0]!.value = 4 | |
//p[0,2]!.value = 4 | |
p✳️; p✳️; p✳️; p✳️; p✳️; p✳️; p✳️; p✳️; | |
var s = "" | |
for c in 0..<p.size.colums | |
{ | |
for r in 0..<p.size.rows | |
{ | |
if p[c,r]!.value != 0 | |
{ | |
s += "p[\(c),\(r)]!.value = \(p[c,r]!.value) \n" | |
} | |
} | |
} | |
println("saved board:\n\(s)"); | |
print( "\(p.debugString())\n" ) | |
p⬇️ | |
print( "down:\(p.debugString())\n" ) | |
p⬅️ | |
print( "left:\(p.debugString())\n" ) | |
p⬇️ | |
print( "down:\(p.debugString())\n" ) | |
class GameScene :SKScene | |
{ | |
} | |
/* | |
let scene = GameScene(size: CGSize(width: 500, height: 500)) | |
let view = SKView(frame: NSRect(x: 0, y: 0, width: 500, height: 500)) | |
view.presentScene(scene) | |
XCPShowView("result", view) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment