Clear complete rows/cols, calculate piece area
This commit is contained in:
parent
30f5a16e9d
commit
5a680ad262
5 changed files with 101 additions and 14 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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])) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue