You must determine whether a given int[4][4] contains a tetromino, regardless of it's location within the int[4][4].
The hope for this, is to eventually use this tetromino detector on a tetromino generator, to see if someone is producing tetrominos properly.
public class Kata {
public static boolean tetrominoDetector(int[][] whatAmI){
//preliminary check to see if it's even possible to be a tetromino.
if(!(containsOnly4Blocks(whatAmI))){
return false;
}
//assuming it is possible to be a tetromino, continue.
if(isSquare(whatAmI)||
(isLong(whatAmI))||
(isT(whatAmI))||
(isZ(whatAmI))||
(isS(whatAmI))||
(isLOrJ(whatAmI))){
return true;
}else{
return false;
}
}
//a method to check if there is the appropriate number of blocks.
public static boolean containsOnly4Blocks(int[][] w){
int numberOfBlocks = 0;
//for each row in the array,
for(int[] row : w){
//for each number in the row,
for(int block : row){
//if I equal one,
if(block == 1){
//increment
numberOfBlocks += 1;
}
}
}
//this should be readable enough on it's own.
if(numberOfBlocks == 4){
return true;
}else{
return false;
}
}
public static boolean isSquare(int[][] w){
//for each column and row, starting at the top left.
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
//if I find a block
if(w[i][j] == 1){
//if the next block and two blocks below are non-empty
if((w[i+1][j] == 1) &&
(w[i][j+1] == 1) &&
(w[i+1][j+1] == 1)){
//we've found a square, return true.
return true;
}else{
//there is no square, return false
return false;
}
}
}
}
//so java doesn't complain, we add a return at the end.
return true;
}
public static boolean isLong(int[][] w){
//checking by column
for(int i = 0; i <= 3; i++){
//if I find a block
if(w[i][0] == 1){
//if there are additional blocks in a straight line below,
if((w[i][1] == 1)&&
(w[i][2] == 1)&&
(w[i][3] == 1)){
return true;
}
}
}
//checking by row
for(int i = 0; i <= 3; i++){
//if I find a block
if(w[0][i] == 1){
//if there are additional blocks in a straight across,
if((w[1][i] == 1)&&
(w[2][i] == 1)&&
(w[3][i] == 1)){
return true;
}
}
}
return false;
}
public static boolean isZ(int[][] w){
//for middle rows in the array,
for(int i = 1; i<=2; i++){
//for middle numbers in the row,
for(int j = 1; j<=2; j++){
//if I equal one,
if(w[i][j] == 1){
//this is for base tetromino
if((w[i-1][j] == 1)&&
(w[i][j-1] == 1)&&
(w[i+1][j-1] == 1)){
return true;
}
//rotated 90 degrees.
if((w[i][j-1] == 1)&&
(w[i+1][j] == 1)&&
(w[i+1][j+1] == 1)){
return true;
}
//rotated 180 degrees
if((w[i+1][j] == 1)&&
(w[i][j+1] == 1)&&
(w[i-1][j+1] == 1)){
return true;
}
//rotated 270 degrees
if((w[i][j+1] == 1)&&
(w[i-1][j] == 1)&&
(w[i-1][j-1] == 1)){
return true;
}
}
}
}
//return false by default, if it fails all tests.
return false;
}
public static boolean isS(int[][] w){
//for middle rows in the array,
for(int i = 1; i<=2; i++){
//for middle numbers in the row,
for(int j = 1; j<=2; j++){
//if I equal one,
if(w[i][j] == 1){
//this is for base tetromino
if((w[i+1][j] == 1)&&
(w[i][j-1] == 1)&&
(w[i-1][j-1] == 1)){
return true;
}
//rotated 90 degrees.
if((w[i][j+1] == 1)&&
(w[i+1][j] == 1)&&
(w[i+1][j-1] == 1)){
return true;
}
//rotated 180 degrees
if((w[i-1][j] == 1)&&
(w[i][j+1] == 1)&&
(w[i+1][j+1] == 1)){
return true;
}
//rotated 270 degrees
if((w[i][j-1] == 1)&&
(w[i-1][j] == 1)&&
(w[i-1][j+1] == 1)){
return true;
}
}
}
}
//return false by default, if it fails all tests.
return false;
}
public static boolean isT(int[][] w){
//for middle rows in the array,
for(int i = 1; i<=2; i++){
//for middle numbers in the row,
for(int j = 1; j<=2; j++){
//if I equal one,
if(w[i][j] == 1){
/*
For context, this first one looks like this.
1,1,1,0
0,1,0,0
0,0,0,0
0,0,0,0
*/
if((w[i-1][j-1] == 1)&&
(w[i][j-1] == 1)&&
(w[i+1][j-1] == 1)){
return true;
}else if((w[i-1][j-1] == 1)&&
(w[i-1][j] == 1)&&
(w[i-1][j+1] == 1)){
return true;
}else if((w[i-1][j+1] == 1)&&
(w[i][j+1] == 1)&&
(w[i+1][j+1] == 1)){
return true;
}else if((w[i+1][j-1] == 1)&&
(w[i+1][j] == 1)&&
(w[i+1][j+1] == 1)){
return true;
}
}
}
}
//return false by default, if it fails all tests.
return false;
}
//the most complex check yet, composed of three others.
public static boolean isLOrJ(int[][] w){
if(centerJs(w)||
centerLs(w)||
outers(w)){
return true;
}
//return false by default, if it fails all tests.
return false;
}
public static boolean centerJs(int[][] w){
for(int i = 1; i<=2; i++){
//for middle numbers in the row,
for(int j = 1; j<=2; j++){
//if I equal one,
if(w[i][j] == 1){
if((w[i][j+1] == 1)&&
(w[i][j-1] == 1)&&
(w[i+1][j-1] == 1)){
return true;
}else if((w[i-1][j] == 1)&&
(w[i+1][j] == 1)&&
(w[i+1][j-1] == 1)){
return true;
}else if((w[i][j-1] == 1)&&
(w[i][j+1] == 1)&&
(w[i+1][j+1] == 1)){
return true;
}else if((w[i+1][j] == 1)&&
(w[i-1][j] == 1)&&
(w[i-1][j+1] == 1)){
return true;
}
}
}
}
return false;
}
public static boolean centerLs(int[][] w){
for(int i = 1; i<=2; i++){
//for middle numbers in the row,
for(int j = 1; j<=2; j++){
//if I equal one,
if(w[i][j] == 1){
if((w[i][j+1] == 1)&&
(w[i][j-1] == 1)&&
(w[i-1][j-1] == 1)){
return true;
}else if((w[i-1][j] == 1)&&
(w[i+1][j] == 1)&&
(w[i+1][j+1] == 1)){
return true;
}else if((w[i][j-1] == 1)&&
(w[i][j+1] == 1)&&
(w[i-1][j+1] == 1)){
return true;
}else if((w[i+1][j] == 1)&&
(w[i-1][j] == 1)&&
(w[i-1][j-1] == 1)){
return true;
}
}
}
}
return false;
}
public static boolean outers(int[][] w){
if((w[0][1] == 1)&&
(w[0][0] == 1)&&
(w[1][0] == 1)&&
(w[2][0] == 1)){
return true;
}
if((w[1][0] == 1)&&
(w[0][0] == 1)&&
(w[0][1] == 1)&&
(w[0][2] == 1)){
return true;
}
if((w[2][0] == 1)&&
(w[3][0] == 1)&&
(w[3][1] == 1)&&
(w[3][2] == 1)){
return true;
}
if((w[2][0] == 1)&&
(w[1][0] == 1)&&
(w[3][0] == 1)&&
(w[3][1] == 1)){
return true;
}
if((w[2][0] == 1)&&
(w[1][0] == 1)&&
(w[3][0] == 1)&&
(w[3][1] == 1)){
return true;
}
if((w[1][3] == 1)&&
(w[0][3] == 1)&&
(w[0][2] == 1)&&
(w[0][1] == 1)){
return true;
}
if((w[2][3] == 1)&&
(w[3][3] == 1)&&
(w[3][2] == 1)&&
(w[3][1] == 1)){
return true;
}
if((w[3][2] == 1)&&
(w[3][3] == 1)&&
(w[2][3] == 1)&&
(w[1][3] == 1)){
return true;
}
return false;
}
}
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class SolutionTest {
@Test
void testTooFew() {
assertEquals(false, Kata.tetrominoDetector(new int[][]{{0,1,1,0},
{0,0,0,0},
{0,1,0,0},
{0,0,0,0}}));
}
@Test
void testTooMany() {
assertEquals(false, Kata.tetrominoDetector(new int[][]{{0,1,1,0},
{0,0,1,1},
{0,1,1,0},
{0,0,1,1}}));
}
@Test
void testJustRight() {
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,1,1},
{0,0,1,1},
{0,0,0,0},
{0,0,0,0}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{1,1,1,1}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,0,1},
{0,0,0,1},
{0,0,0,1},
{0,0,0,1}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,0,0},
{0,0,1,0},
{0,0,1,1},
{0,0,0,1}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,0,0},
{0,0,0,1},
{0,0,1,1},
{0,0,0,1}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,0,0},
{0,0,0,1},
{0,0,1,1},
{0,0,1,0}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,0,0},
{0,0,0,1},
{0,0,0,1},
{0,0,1,1}}));
assertEquals(true, Kata.tetrominoDetector(new int[][]{{0,0,1,0},
{0,0,1,0},
{0,1,1,0},
{0,0,0,0}}));
}
@Test
void testJustWrong() {
assertEquals(false, Kata.tetrominoDetector(new int[][]{{0,0,0,0},
{0,1,1,0},
{1,0,1,0},
{0,0,0,0}}));
}
}