class Board {
field Array grid;
field int nTurn;
field int seed;
constructor Board new() {
var int i, j;
var Array t;
let grid = Array.new(4);
let i = 0;
while (i < 4) {
let j = 0;
let grid[i] = Array.new(4);
let t = grid[i];
while (j < 4) {
let t[j] = 32;
let j = j + 1;
}
let i = i + 1;
}
let t = grid[0];
let t[0] = 65;
let nTurn = 0;
let seed = 0;
return this;
}
method void arrange(Array xs, boolean isHorizontal) {
if (isHorizontal) {
do deepcopy(xs, grid);
} else {
do transpose(xs, grid);
}
do dispose4(xs);
return;
}
method void copy(Array xs, Array ys) {
var int i;
let i = 0;
while (i < 4) {
let ys[i] = xs[i];
let i = i + 1;
}
return;
}
method void deepcopy(Array xs, Array ys) {
var int i;
let i = 0;
while (i < 4) {
do copy(xs[i], ys[i]);
let i = i + 1;
}
return;
}
method void transpose(Array xs, Array ys) {
var int i, j;
var Array t, s;
let i = 0;
while (i < 4) {
let j = 0;
let t = ys[i];
while (j < 4) {
let s = xs[j];
let t[j] = s[i];
let j = j + 1;
}
let i = i + 1;
}
return;
}
method void dispose4(Array xs){
var int i;
var Array t;
let i = 0;
while (i < 4) {
let t = xs[i];
do t.dispose();
let i = i + 1;
}
do xs.dispose();
return;
}
method Array new4(){
var Array xs;
var int i;
let xs = Array.new(4);
let i = 0;
while (i < 4) {
let xs[i] = Array.new(4);
let i = i + 1;
}
return xs;
}
method Array getStrips(boolean isHorizontal){
var Array xs;
let xs = new4();
if (isHorizontal) {
do deepcopy(grid, xs);
} else {
do transpose(grid, xs);
}
return xs;
}
method Array align(Array xs, boolean left){
var int i, j;
let i = 0;
let j = 0;
if (left) {
while (i < 4) {
if (xs[i] > 64) {
let xs[j] = xs[i];
let j = j + 1;
}
let i = i + 1;
}
while (j < 4) {
let xs[j] = 32;
let j = j + 1;
}
} else {
while (i < 4) {
if (xs[3 - i] > 64) {
let xs[3 - j] = xs[3 - i];
let j = j + 1;
}
let i = i + 1;
}
while (j < 4) {
let xs[3 - j] = 32;
let j = j + 1;
}
}
return xs;
}
method Array reduce(Array xs, boolean left){
if ((xs[0] = xs[1]) & (xs[2] = xs[3]) & (xs[0] > 64) & (xs[2] > 64)) {
if (left) {
let xs[0] = xs[0] + 1;
let xs[1] = xs[2] + 1;
let xs[2] = 32;
let xs[3] = 32;
} else {
let xs[3] = xs[3] + 1;
let xs[2] = xs[1] + 1;
let xs[1] = 32;
let xs[0] = 32;
}
return xs;
}
if ((xs[0] = xs[1]) & (xs[0] > 64)) {
if (left) {
let xs[0] = xs[0] + 1;
let xs[1] = xs[2];
let xs[2] = xs[3];
let xs[3] = 32;
} else {
let xs[1] = xs[1] + 1;
let xs[0] = 32;
}
return xs;
}
if ((xs[2] = xs[3]) & (xs[2] > 64)) {
if (left) {
let xs[2] = xs[2] + 1;
let xs[3] = 32;
} else {
let xs[3] = xs[3] + 1;
let xs[2] = xs[1];
let xs[1] = xs[0];
let xs[0] = 32;
}
return xs;
}
if ((xs[1] = xs[2]) & (xs[1] > 64)) {
if (left) {
let xs[1] = xs[1] + 1;
let xs[2] = xs[3];
let xs[3] = 32;
} else {
let xs[2] = xs[2] + 1;
let xs[1] = xs[0];
let xs[0] = 32;
}
return xs;
}
return xs;
}
method void addTile(){
var Array t;
var int r, c, parity, newTile;
/*
let t = grid[1];
if (t[1] = 32) {
let t[1] = 65;
}
*/
let seed = seed * 25173 + 13849;
if (seed < 0) {
let seed = - seed;
}
if (seed - (seed / 2 * 2) = 0) {
let parity = 1;
} else {
let parity = -1;
}
let seed = seed - (seed / 16 * 16);
let r = seed / 4;
let c = seed - (4 * r);
let t = grid[r];
let newTile = 65;
while (t[c] > 64){
let seed = seed + parity;
if (seed < 0) {
let seed = 15;
}
let seed = seed - (seed / 16 * 16);
let r = seed / 4;
let c = seed - (4 * r);
let t = grid[r];
let newTile = 131 - newTile;
}
let t[c] = newTile;
return;
}
method void transform(char dir){
var boolean isHorizontal, left;
var Array xs;
var int i;
if ((dir = 0) | (dir = 1)) {
let left = true;
} else {
let left = false;
}
if ((dir = 0) | (dir = 2)) {
let isHorizontal = true;
} else {
let isHorizontal = false;
}
let xs = getStrips(isHorizontal);
let i = 0;
while (i < 4) {
let xs[i] = reduce(align(xs[i], left), left);
let i = i + 1;
}
do arrange(xs, isHorizontal);
return;
}
method void next(char dir){
let nTurn = nTurn + 1;
do transform(dir);
do addTile();
return;
}
method void draw(){
var int r, c, i, j;
var Array t;
let r = 9;
let c = 30;
do Output.moveCursor(r - 1, c - 1);
do Output.printString("+----+");
do Output.moveCursor(r + 4, c - 1);
do Output.printString("+----+");
let i = 0;
while (i < 4) {
let j = 0;
do Output.moveCursor(r + i, c - 1);
do Output.printString("|");
let t = grid[i];
while (j < 4) {
do Output.printChar(t[j]);
let j = j + 1;
}
do Output.printString("|");
let i = i + 1;
}
do Output.moveCursor(r + 6, c - 2);
do Output.printString("Turn: ");
do Output.printInt(nTurn);
return;
}
method void dispose() {
do Memory.deAlloc(this);
return;
}
}