Last active
December 14, 2015 04:39
-
-
Save tangentstorm/5029722 to your computer and use it in GitHub Desktop.
penominos in haxe
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
import Substance; | |
class Grid | |
{ | |
public var data : Array<Array<Int>>; | |
public var width:Int; | |
public var depth:Int; | |
public function new (proto, width:Int=-1, depth:Int=-1) | |
{ | |
data = proto; | |
// if no width/height given, assume we have a square | |
if (width == -1) | |
{ | |
this.depth = proto.length; | |
this.width = this.depth == 0 ? 0 : proto[0].length; | |
} | |
else | |
{ | |
this.width = width; | |
this.depth = depth; | |
} | |
} | |
// @TODO: factor out the loop and use anonymous functions instead | |
// there should be one version to transform and one to build a new grid | |
public function iterate2(f, g, ulc:Point=null, lrc:Point=null) : Void | |
{ | |
if (ulc == null) ulc = new Point(0,0); // upper left corner | |
if (lrc == null) lrc = new Point(this.width, this.depth); // lower right corner | |
for (row in ulc.y ... lrc.y) | |
{ | |
g(this, row, true); | |
for (col in ulc.x ... lrc.x) | |
{ | |
// function(oldGrid, newX, newY, oldValue) | |
var newCol = col-ulc.x; | |
if (newCol < 0) | |
{ | |
throw "wtf??: ulc.x =" + ulc.x | |
+ '; lrc.x =' + lrc.x | |
+ '; newCol = col-ulc.x = ' + newCol; | |
} | |
f(this, row-ulc.y, newCol, this.data[row][col]); | |
} | |
g(this, row, false); | |
} | |
} | |
public function iterate(f, ulc:Point=null, lrc:Point=null) : Void | |
{ | |
iterate2(f, function(self, row, before) {}, ulc, lrc); | |
} | |
public function transform(f, ulc:Point=null, lrc:Point=null) : Grid | |
{ | |
var newWidth = this.width; | |
var newDepth = this.depth; | |
if (ulc != null) | |
{ | |
newWidth = lrc.x - ulc.x; | |
newDepth = lrc.y - ulc.y; | |
} | |
var proto:Array<Array<Int>> = []; | |
var original = this; | |
iterate2(// for every cell: | |
function(self, row, col, old) | |
{ | |
f(original, proto, row, col, old); | |
}, | |
// for every row: | |
function(self, row, before) | |
{ | |
if (before) | |
{ | |
var newRow = []; | |
for ( i in 0...newWidth) | |
newRow.push(0); | |
proto.push(newRow); | |
} | |
}, | |
// bounding box: | |
ulc, lrc); | |
return new Grid(proto, newWidth, newDepth); | |
} | |
public function copy(ulc:Point=null, lrc:Point=null) : Grid | |
{ | |
var theCopy = transform(function(self, proto, row, col, old) | |
{ | |
//trace('proto[' + row + ',' + col + '] = ' + old); | |
proto[row][col] = old; | |
}, ulc, lrc); | |
if (ulc != null) | |
{ | |
theCopy.width = lrc.x - ulc.x; | |
theCopy.depth = lrc.y - ulc.y; | |
} | |
return theCopy; | |
} | |
public function blankCopy() : Grid | |
{ | |
return transform(function(self, proto, row, col, old) | |
{ | |
proto[row][col] = 0; | |
}); | |
} | |
public function rotateRight() | |
{ | |
return transform(function(self, proto, row, col, old) | |
{ | |
// new row(depth) corresponds to old col | |
// new col(distance right) corresponds | |
// to how far UP the old piece was | |
proto[row][col] = self.data[self.width-col-1][row]; | |
}); | |
} | |
public function rotateLeft() : Grid | |
{ | |
return transform(function(self, proto, row, col, old) | |
{ | |
proto[row][col] = self.data[col][self.depth-row-1]; | |
}); | |
} | |
public function equals(other:Grid) : Bool | |
{ | |
// first check that the two grids are the same height | |
// @TODO: check that both are same width | |
if (! (other.width == this.width) | |
&& (other.width == this.width)) | |
{ | |
return false; | |
} | |
// if so, check that the contents are the same: | |
var isSame:Bool = true; | |
iterate(function(self, row, col, val) | |
{ | |
isSame = isSame && (other.data[row][col] == val); | |
}); | |
return isSame; | |
} | |
public function toString() | |
{ | |
var out:StringBuf = new StringBuf(); | |
out.add("["); | |
iterate2(function(self, row, col, val) | |
{ | |
out.add(val); | |
out.add(","); | |
}, | |
function(self, row, before) | |
{ | |
if (before) | |
{ | |
out.add("["); | |
} | |
else | |
{ | |
out.add("],\n"); | |
} | |
}); | |
out.add("]"); | |
return out.toString(); | |
} | |
public function dump(label:String) : Grid | |
{ | |
trace("\n-- dumping grid (" + label + ") --\n" | |
+ this.toString() | |
+ "\n -- end of grid --\n"); | |
return this; | |
} | |
public function insertColumn(before:Int=0, fill:Int=0) : Grid | |
{ | |
var res = this.copy(); | |
for (row in 0 ... this.depth) | |
{ | |
res.data[row].insert(before, fill); | |
} | |
return res; | |
} | |
public function insertRow(before:Int=0, fill:Int=0) : Grid | |
{ | |
var res = this.copy(); | |
var row = []; | |
for (i in 0 ... this.width) | |
{ | |
row.push(fill); | |
} | |
res.data.insert(before, row); | |
return res; | |
} | |
public function count(what:Int) : Int | |
{ | |
var res:Int = 0; | |
for (row in 0 ... this.depth) | |
{ | |
for (col in 0 ... this.width) | |
{ | |
if (this.data[row][col] == what) | |
{ | |
res++; | |
} | |
} | |
} | |
return res; | |
} | |
} |
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
class GridTest extends haxe.unit.TestCase { | |
private static var X = 1; | |
private static var _ = 0; | |
public function testEqual() { | |
assertTrue(new Grid([[X]]).equals(new Grid([[X]]))); | |
} | |
public function testRotateRight() { | |
var grid = new Grid([[_,X], | |
[_,X]]); | |
assertTrue(grid.rotateRight() | |
.equals(new Grid([[_,_], | |
[X,X]]))); | |
} | |
public function testRotateLeft() { | |
var grid = new Grid([[_,X], | |
[_,X]]); | |
assertTrue(grid.rotateLeft() | |
.equals(new Grid([[X,X], | |
[_,_]]))); | |
} | |
public function testInsertColumn() { | |
var grid = new Grid([[X,X], | |
[X,X]]); | |
assertTrue(grid.insertColumn(0).equals | |
(new Grid([[_,X,X], | |
[_,X,X]]))); | |
assertTrue(grid.insertColumn(1).equals | |
(new Grid([[X,_,X], | |
[X,_,X]]))); | |
assertTrue(grid.insertColumn(2).equals | |
(new Grid([[X,X,_], | |
[X,X,_]]))); | |
} | |
public function testInsertRow() { | |
var grid = new Grid([[X,X], | |
[X,X]]); | |
assertTrue(grid.insertRow(0).equals | |
(new Grid([[_,_], | |
[X,X], | |
[X,X]]))); | |
assertTrue(grid.insertRow(1).equals | |
(new Grid([[X,X], | |
[_,_], | |
[X,X]]))); | |
assertTrue(grid.insertRow(2).equals | |
(new Grid([[X,X], | |
[X,X], | |
[_,_]]))); | |
} | |
public function testCopy() { | |
var grid = new Grid([[00,10,20,30], | |
[01,11,21,31], | |
[02,12,22,32], | |
[03,13,23,33], | |
[00,00,00,00]]); | |
assertTrue(grid.copy().equals(grid)); | |
// start and end points: | |
var theCopy = grid.copy(new Point(1,1), new Point(4,3)); | |
assertTrue(theCopy.equals | |
(new Grid([[11,21,31], | |
[12,22,32]]))); | |
assertTrue(theCopy.width == 3); | |
assertTrue(theCopy.depth == 2); | |
} | |
public function testCopy2() { | |
var grid = new Grid([[00,10,20,30], | |
[01,11,21,31], | |
[02,12,22,32], | |
[03,13,23,33], | |
[04,14,24,34]], 4, 5); | |
// copy a 1x1 point | |
var theCopy = grid.copy(new Point(1,2), new Point(2,3)); | |
assertTrue(theCopy.equals(new Grid([[12]]))); | |
assertTrue(theCopy.width == 1); | |
assertTrue(theCopy.depth == 1); | |
// copy a 1x1 point on bottom | |
var theCopy = grid.copy(new Point(1,4), new Point(2,5)); | |
assertTrue(theCopy.equals(new Grid([[14]]))); | |
assertTrue(theCopy.width == 1); | |
assertTrue(theCopy.depth == 1); | |
// copy a 2x1 point on bottom | |
var theCopy = grid.copy(new Point(1,4), new Point(3,5)); | |
assertTrue(theCopy.equals(new Grid([[14,24]], 2, 1))); | |
assertTrue(theCopy.width == 2); | |
assertTrue(theCopy.depth == 1); | |
} | |
public function testCount() { | |
assertTrue(new Grid([[X,X], | |
[X,X]]) | |
.count(X) == 4); | |
assertTrue(new Grid([[X,_], | |
[_,X]]) | |
.count(X) == 2); | |
assertTrue(new Grid([[_,_], | |
[_,_]]) | |
.count(X) == 0); | |
} | |
} |
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
class Pentomino | |
{ | |
static var _ = 0; | |
static var X = 1; | |
// names from http://en.wikipedia.org/wiki/Pentomino | |
public static var SHAPES = [ | |
// the L/Q | |
[[ _,_,_,_ ], | |
[ X,_,_,_ ], | |
[ X,X,X,X ], | |
[ _,_,_,_ ]], | |
// the Y | |
[[ _,_,_,_ ], | |
[ _,X,_,_ ], | |
[ X,X,X,X ], | |
[ _,_,_,_ ]], | |
// the X | |
[[ _,X,_ ], | |
[ X,X,X ], | |
[ _,X,_ ]], | |
// the V | |
[[ _,_,X ], | |
[ _,_,X ], | |
[ X,X,X ]], | |
// the Z | |
[[ _,_,_,_ ], | |
[ _,_,_,X ], | |
[ _,X,X,X ], | |
[ _,X,_,_ ]], | |
// the W | |
[[ _,_,X ], | |
[ _,X,X ], | |
[ X,X,_ ]], | |
// the I/O | |
[[_,_,_,_,_], | |
[_,_,_,_,_], | |
[X,X,X,X,X], | |
[_,_,_,_,_], | |
[_,_,_,_,_]], | |
// the T; | |
[[ _,_,X ], | |
[ X,X,X ], | |
[ _,_,X ]], | |
// the U | |
[[X,_,X], | |
[X,X,X], | |
[_,_,_]], | |
// the N/S | |
[[_,_,_,_,_], | |
[_,_,_,_,_], | |
[_,X,X,_,_], | |
[_,_,X,X,X], | |
[_,_,_,_,_]], | |
// the P | |
[[ _,_,_ ], | |
[ _,X,X ], | |
[ X,X,X ]], | |
// the F/R | |
[[ _,X,_ ], | |
[ _,X,X ], | |
[ X,X,_ ]] | |
]; | |
public static function atRandom() | |
{ | |
return SHAPES[Math.floor(Math.random() * Pentomino.SHAPES.length)]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment