class Board { field Array grid; field int nTurn; constructor Board new() { let grid = Array.new(4); var int i, j; let i = 0; while (i < 4) { let j = 0; let grid[i] = Array.new(4); while (j < 4) { let grid[i][j] = 32; } let i = i + 1; } let grid[0][0] = 65; let nTurn = 0; return this; } method void arrange(Array xs, boolean isHorizontal) { if (isHorizontal) { let grid = copy(xs) } else { let grid = transpose(xs) } } method Array copy(Array xs) { var Array ys; let ys = Array.new(4); var int i; let i = 0; while (i < 4) { let ys[i] = xs[i]; let i = i + 1; } return ys; } method Array deepcopy(Array xs) { var Array ys; let ys = Array.new(4); var int i; let i = 0; while (i < 4) { let ys[i] = copy(xs[i]); let i = i + 1; } return ys; } mothod Array transpose(Array xs){ var Array ys; var int i, j; let i = 0; let ys = Array.new(4); while (i < 4) { let ys[i] = Array.new(4) let j = 0; while (j < 4) { let ys[i][j] = xs[j][i]; let j = j + 1; } let i = i + 1; } return ys; } method Array getStrip(boolean isHorizontal){ var Array xs; if (isHorizontal) { let xs = deepcopy(grid); } else { let xs = transpose(grid); } return xs; } method Array align(Array xs, boolean left){ var int i, j; let i = 0; let j = 0; if (left = true) { while (i < 4) { if (xs[i] > 96) { 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] > 96) { 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])) { if (left = true) { 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]) { if (left = true) { 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]) { if (left = true) { 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]) { if (left = true) { 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 int x, y; var char z; let x = nTurn; let y = 23 * x * x + 79; let x = y - (y / 16 * 16); let r = x / 4; let c = x - (r * 4); let z = 97; while (grid[r][c] > 96) { let y = 23 * x * x + 79; let x = y - (y / 16 * 16); let r = x / 4; let c = x - (r * 4); let z = 195 - z; } let grid[r][c] = z; return; } method void transform(char dir){ var boolean isHorizontal, left; if ((dir = 0) or (dir = 1)) { let left = true; } else { let left = false; } if ((dir = 0) or (dir = 2)) { let isHorizontal = true; } else { let isHorizontal = false; } var Array xs; let xs = getStrip(isHorizontal); var int i; let i = 0; while (i < 4) { xs[i] = reduce(align(xs[i], left), left); } do arrange(xs, isHorizontal); return; } method void next(char dir){ do addTile(); let nTurn = nTurn + 1; do transform(dir); return; } method void draw(){ var int r, c, i, j; let r = 9; let c = 30; let i = 0; while (i < 4) { let j = 0; do Output.moveCursor(r + i, c); while (j < 4) { do Output.printChar(grid[i][j]); let j = j + 1; } let i = i + 1; } } method void dispose() { do Memory.deAlloc(this); } }