diff --git a/core/src/io/github/lonamiwebs/klooni/game/Board.java b/core/src/io/github/lonamiwebs/klooni/game/Board.java index ff7a748..f6e02fb 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/Board.java +++ b/core/src/io/github/lonamiwebs/klooni/game/Board.java @@ -47,14 +47,14 @@ public class Board { } 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) { if (!inBounds(piece, x, y)) 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++) if (!cells[y+i][x+j].isEmpty() && piece.filled(i, j)) return false; @@ -71,11 +71,72 @@ public class Board { 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) { if (!canPutPiece(piece, x, y)) 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++) { if (piece.filled(i, j)) { cells[y+i][x+j].set(piece.color); diff --git a/core/src/io/github/lonamiwebs/klooni/game/Cell.java b/core/src/io/github/lonamiwebs/klooni/game/Cell.java index ff6c559..6aa003a 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/Cell.java +++ b/core/src/io/github/lonamiwebs/klooni/game/Cell.java @@ -10,8 +10,7 @@ class Cell { private Color color; Cell() { - empty = true; - color = Color.WHITE; + setEmpty(); } void set(Color c) { @@ -19,6 +18,11 @@ class Cell { color = c; } + void setEmpty() { + empty = true; + color = Color.WHITE; + } + void draw(SpriteBatch batch, NinePatch patch, float x, float y, int size) { draw(color, batch, patch, x, y, size); } diff --git a/core/src/io/github/lonamiwebs/klooni/game/Piece.java b/core/src/io/github/lonamiwebs/klooni/game/Piece.java index a24bfc9..2a8f2cf 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/Piece.java +++ b/core/src/io/github/lonamiwebs/klooni/game/Piece.java @@ -20,7 +20,7 @@ public class Piece { final Vector2 pos; float cellSize = 10f; // Default - final int cellCols, celRows; + final int cellCols, cellRows; private boolean shape[][]; final Color color; @@ -30,9 +30,9 @@ public class Piece { pos = new Vector2(); cellCols = swapSize ? rows : cols; - celRows = swapSize ? cols : rows; - shape = new boolean[celRows][cellCols]; - for (int i = 0; i < celRows; i++) { + cellRows = swapSize ? cols : rows; + shape = new boolean[cellRows][cellCols]; + for (int i = 0; i < cellRows; i++) { for (int j = 0; j < cellCols; j++) { shape[i][j] = true; } @@ -43,7 +43,7 @@ public class Piece { color = new Color(colors[colorIndex]); pos = new Vector2(); - cellCols = celRows = lSize; + cellCols = cellRows = lSize; shape = new boolean[lSize][lSize]; switch (rotateCount % 4) { case 0: // ┌ @@ -99,11 +99,23 @@ public class Piece { } 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) { - for (int i = 0; i < celRows; i++) { + for (int i = 0; i < cellRows; i++) { for (int j = 0; j < cellCols; j++) { if (shape[i][j]) { Cell.draw(color, batch, patch, diff --git a/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java b/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java index 3a08dd1..36a3a1d 100644 --- a/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java +++ b/core/src/io/github/lonamiwebs/klooni/game/PieceHolder.java @@ -37,7 +37,7 @@ public class PieceHolder { pieces[i].pos.set(pos.x + i * perPieceSize, pos.y); pieces[i].cellSize = Math.min( perPieceSize / pieces[i].cellCols, - height / pieces[i].celRows); + height / pieces[i].cellRows); } } @@ -66,6 +66,10 @@ public class PieceHolder { return false; } + public int calculateHeldPieceArea() { + return pieces[heldPiece].calculateArea(); + } + public boolean dropPiece(Board board) { if (heldPiece > -1) { if (board.putScreenPiece(pieces[heldPiece])) { diff --git a/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java b/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java index 17d3a6f..7ba279f 100644 --- a/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java +++ b/core/src/io/github/lonamiwebs/klooni/screens/GameScreen.java @@ -115,7 +115,13 @@ public class GameScreen implements Screen, InputProcessor { @Override 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