Skip to content

Instantly share code, notes, and snippets.

@Pastez
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pastez/8f20f70b7cb82347096e to your computer and use it in GitHub Desktop.
Save Pastez/8f20f70b7cb82347096e to your computer and use it in GitHub Desktop.
// 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