Clear complete rows/cols, calculate piece area

This commit is contained in:
Lonami Exo 2017-01-26 11:19:14 +01:00
parent 30f5a16e9d
commit 5a680ad262
5 changed files with 101 additions and 14 deletions

View file

@ -47,14 +47,14 @@ public class Board {
} }
private boolean inBounds(Piece piece, int x, int y) { private boolean inBounds(Piece piece, int x, int y) {
return inBounds(x, y) && inBounds(x + piece.cellCols - 1, y + piece.celRows - 1); return inBounds(x, y) && inBounds(x + piece.cellCols - 1, y + piece.cellRows - 1);
} }
private boolean canPutPiece(Piece piece, int x, int y) { private boolean canPutPiece(Piece piece, int x, int y) {
if (!inBounds(piece, x, y)) if (!inBounds(piece, x, y))
return false; return false;
for (int i = 0; i < piece.celRows; i++) for (int i = 0; i < piece.cellRows; i++)
for (int j = 0; j < piece.cellCols; j++) for (int j = 0; j < piece.cellCols; j++)
if (!cells[y+i][x+j].isEmpty() && piece.filled(i, j)) if (!cells[y+i][x+j].isEmpty() && piece.filled(i, j))
return false; return false;
@ -71,11 +71,72 @@ public class Board {
return putPiece(piece, x, y); return putPiece(piece, x, y);
} }
public int clearComplete() {
// This will clear both complete rows and columns, all at once.
// The reason why we can't check first rows and then columns
// (or vice versa) is because the following case (* filled, _ empty):
//
// 4x4 board piece
// _ _ * * * *
// _ * * * *
// * * _ _
// * * _ _
//
// If the piece is put on the top left corner, all the cells will be cleared.
// If we first cleared the columns, then the rows wouldn't have been cleared.
int clearCount = 0;
boolean[] clearedRows = new boolean[count];
boolean[] clearedCols = new boolean[count];
// Analyze rows and columns that will be cleared
for (int i = 0; i < count; i++) {
clearedRows[i] = true;
for (int j = 0; j < count; j++) {
if (cells[i][j].isEmpty()) {
clearedRows[i] = false;
break;
}
}
if (clearedRows[i])
clearCount++;
}
for (int j = 0; j < count; j++) {
clearedCols[j] = true;
for (int i = 0; i < count; i++) {
if (cells[i][j].isEmpty()) {
clearedCols[j] = false;
break;
}
}
if (clearedCols[j])
clearCount++;
}
if (clearCount > 0) {
// Do clear those rows and columns
for (int i = 0; i < count; i++) {
if (clearedRows[i]) {
for (int j = 0; j < count; j++) {
cells[i][j].setEmpty();
}
}
}
for (int j = 0; j < count; j++) {
if (clearedCols[j]) {
for (int i = 0; i < count; i++) {
cells[i][j].setEmpty();
}
}
}
}
return clearCount;
}
public boolean putPiece(Piece piece, int x, int y) { public boolean putPiece(Piece piece, int x, int y) {
if (!canPutPiece(piece, x, y)) if (!canPutPiece(piece, x, y))
return false; return false;
for (int i = 0; i < piece.celRows; i++) { for (int i = 0; i < piece.cellRows; i++) {
for (int j = 0; j < piece.cellCols; j++) { for (int j = 0; j < piece.cellCols; j++) {
if (piece.filled(i, j)) { if (piece.filled(i, j)) {
cells[y+i][x+j].set(piece.color); cells[y+i][x+j].set(piece.color);

View file

@ -10,8 +10,7 @@ class Cell {
private Color color; private Color color;
Cell() { Cell() {
empty = true; setEmpty();
color = Color.WHITE;
} }
void set(Color c) { void set(Color c) {
@ -19,6 +18,11 @@ class Cell {
color = c; color = c;
} }
void setEmpty() {
empty = true;
color = Color.WHITE;
}
void draw(SpriteBatch batch, NinePatch patch, float x, float y, int size) { void draw(SpriteBatch batch, NinePatch patch, float x, float y, int size) {
draw(color, batch, patch, x, y, size); draw(color, batch, patch, x, y, size);
} }

View file

@ -20,7 +20,7 @@ public class Piece {
final Vector2 pos; final Vector2 pos;
float cellSize = 10f; // Default float cellSize = 10f; // Default
final int cellCols, celRows; final int cellCols, cellRows;
private boolean shape[][]; private boolean shape[][];
final Color color; final Color color;
@ -30,9 +30,9 @@ public class Piece {
pos = new Vector2(); pos = new Vector2();
cellCols = swapSize ? rows : cols; cellCols = swapSize ? rows : cols;
celRows = swapSize ? cols : rows; cellRows = swapSize ? cols : rows;
shape = new boolean[celRows][cellCols]; shape = new boolean[cellRows][cellCols];
for (int i = 0; i < celRows; i++) { for (int i = 0; i < cellRows; i++) {
for (int j = 0; j < cellCols; j++) { for (int j = 0; j < cellCols; j++) {
shape[i][j] = true; shape[i][j] = true;
} }
@ -43,7 +43,7 @@ public class Piece {
color = new Color(colors[colorIndex]); color = new Color(colors[colorIndex]);
pos = new Vector2(); pos = new Vector2();
cellCols = celRows = lSize; cellCols = cellRows = lSize;
shape = new boolean[lSize][lSize]; shape = new boolean[lSize][lSize];
switch (rotateCount % 4) { switch (rotateCount % 4) {
case 0: // case 0: //
@ -99,11 +99,23 @@ public class Piece {
} }
Rectangle getRectangle() { Rectangle getRectangle() {
return new Rectangle(pos.x, pos.y, cellCols * cellSize, celRows * cellSize); return new Rectangle(pos.x, pos.y, cellCols * cellSize, cellRows * cellSize);
}
int calculateArea() {
int area = 0;
for (int i = 0; i < cellRows; i++) {
for (int j = 0; j < cellCols; j++) {
if (shape[i][j]) {
area++;
}
}
}
return area;
} }
void draw(SpriteBatch batch, NinePatch patch) { void draw(SpriteBatch batch, NinePatch patch) {
for (int i = 0; i < celRows; i++) { for (int i = 0; i < cellRows; i++) {
for (int j = 0; j < cellCols; j++) { for (int j = 0; j < cellCols; j++) {
if (shape[i][j]) { if (shape[i][j]) {
Cell.draw(color, batch, patch, Cell.draw(color, batch, patch,

View file

@ -37,7 +37,7 @@ public class PieceHolder {
pieces[i].pos.set(pos.x + i * perPieceSize, pos.y); pieces[i].pos.set(pos.x + i * perPieceSize, pos.y);
pieces[i].cellSize = Math.min( pieces[i].cellSize = Math.min(
perPieceSize / pieces[i].cellCols, perPieceSize / pieces[i].cellCols,
height / pieces[i].celRows); height / pieces[i].cellRows);
} }
} }
@ -66,6 +66,10 @@ public class PieceHolder {
return false; return false;
} }
public int calculateHeldPieceArea() {
return pieces[heldPiece].calculateArea();
}
public boolean dropPiece(Board board) { public boolean dropPiece(Board board) {
if (heldPiece > -1) { if (heldPiece > -1) {
if (board.putScreenPiece(pieces[heldPiece])) { if (board.putScreenPiece(pieces[heldPiece])) {

View file

@ -115,7 +115,13 @@ public class GameScreen implements Screen, InputProcessor {
@Override @Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) { public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return holder.dropPiece(board); int area = holder.calculateHeldPieceArea();
if (holder.dropPiece(board)) {
int cleared = board.clearComplete();
return true;
} else {
return false;
}
} }
@Override @Override