Java tutorial
/* * Copyright 2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.tenorite.game; import net.tenorite.core.Special; import java.util.StringTokenizer; import java.util.function.Supplier; import static java.lang.String.valueOf; import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; import static org.apache.commons.lang3.RandomUtils.nextInt; /** * @author Johan Siebens */ public final class Field { public static final int WIDTH = 12; public static final int HEIGHT = 22; private static final char EMPTY = '0'; public static Field of(String fieldString) { return new Field(readFieldString(fieldString)); } public static Field empty() { return new Field(readFieldString(EMPTY_FIELDSTRING)); } public static Field randomCompletedField() { return new Field(readFieldString(RANDOM_FILLED_FIELDSTRING.get())); } private static final char[] BLOCKS = { EMPTY, '1', '2', '3', '4', '5', Special.ADDLINE.getLetter(), Special.CLEARLINE.getLetter(), Special.NUKEFIELD.getLetter(), Special.RANDOMCLEAR.getLetter(), Special.SWITCHFIELD.getLetter(), Special.CLEARSPECIAL.getLetter(), Special.GRAVITY.getLetter(), Special.QUAKEFIELD.getLetter(), Special.BLOCKBOMB.getLetter() }; private char[][] field = new char[WIDTH][HEIGHT]; private Field(char[][] field) { this.field = field; } public Field update(String fieldString) { if (fieldString == null || fieldString.trim().isEmpty()) { return this; } if (isFullUpdate(fieldString)) { return new Field(readFieldString(fieldString)); } else { char[][] newField = readFieldString(this.getFieldString()); StringTokenizer tokenizer = new StringTokenizer(fieldString, "!\"#$%&'()*+,-./", true); while (tokenizer.hasMoreTokens()) { // block type String type = tokenizer.nextToken(); char color = BLOCKS[type.charAt(0) - 0x21]; // locations String locations = tokenizer.nextToken(); for (int i = 0; i < locations.length(); i = i + 2) { int x = locations.charAt(i) - '3'; int y = HEIGHT - (locations.charAt(i + 1) - '3') - 1; newField[x][y] = color; } } return new Field(newField); } } public String getFieldString() { char[] buffer = new char[WIDTH * HEIGHT]; int k = 0; for (int j = HEIGHT - 1; j >= 0; j--) { for (int i = 0; i < WIDTH; i++) { buffer[k++] = field[i][j]; } } return new String(buffer); } public int getHighest() { for (int i = HEIGHT - 1; i >= 0; i--) { for (int j = 0; j < WIDTH; j++) { if (field[j][i] != EMPTY) { return i + 1; } } } return 0; } public int getNrOfSpecials() { int count = 0; for (int i = HEIGHT - 1; i >= 0; i--) { for (int j = 0; j < WIDTH; j++) { if (Character.isLetter(field[j][i])) { count++; } } } return count; } public int getNrOfBlocks(Special special) { char target = special.getLetter(); int count = 0; for (int i = HEIGHT - 1; i >= 0; i--) { for (int j = 0; j < WIDTH; j++) { if (field[j][i] == target) { count++; } } } return count; } char getBlock(int x, int y) { return field[x][y]; } private static char[][] readFieldString(String fieldString) { char[][] blocks = new char[WIDTH][HEIGHT]; for (int i = 0; i < fieldString.length(); i++) { char c = fieldString.charAt(i); blocks[i % WIDTH][HEIGHT - i / WIDTH - 1] = c; } return blocks; } private static boolean isFullUpdate(String update) { return update.length() == Field.WIDTH * Field.HEIGHT; } private static final String EMPTY_FIELDSTRING = range(0, HEIGHT * WIDTH).mapToObj(i -> valueOf(EMPTY)) .collect(joining()); private static final Supplier<String> RANDOM_FILLED_FIELDSTRING = () -> range(0, HEIGHT * WIDTH) .mapToObj(i -> valueOf(nextInt(1, 6))).collect(joining()); }