#java
#java
Вопрос:
Для изучения программирования я создаю игру 2048 на Java. В игре есть класс, в котором много повторяющихся фрагментов — циклов итерации полей. Вопрос в том, возможно ли создать такой метод, который будет принимать значения границ перечисления и исполняемый код?
Что-то вроде этого как для назначения, так и для сравнения.
public void forField(int borderX, int borderY, ??? code){
for (int x = 0; x < borderX; x )
for (int y = 0; y < borderY; y )
do code;
}
public boolean checkField(int borderX, int borderY, ??? code, boolean default_answer){
for (int x = 0; x < borderX; x )
for (int y = 0; y < borderY; y )
return code;
return default_answer;
}
Если нет, можете ли вы порекомендовать, как улучшить мой код? Спасибо за внимание.
public class Field {
private int[][] field;
private int width, heigth;
public Field(int sizeX, int sizeY) {
this.width = sizeX;
this.heigth = sizeY;
this.field = new int[sizeX][sizeY];
}
public int getCell(int x, int y) {
return this.field[x][y];
}
public void setCell(int val, int x, int y) {
this.field[x][y] = val;
}
// for restart
public void reset() {
for (int x = 0; x < width; x )
for (int y = 0; y < heigth; y )
this.field[x][y] = 0;
}
// for step cancelling function
public void copyOf(Field f) {
for (int x = 0; x < width; x )
for (int y = 0; y < heigth; y )
this.field[x][y] = f.getCell(x, y);
}
// can field changed after pressing a key
public boolean isEqualTo(Field f) {
for (int x = 0; x < width; x )
for (int y = 0; y < heigth; y )
if (field[x][y] != f.getCell(x, y))
return false;
return true;
}
private boolean canMergeByY() {
for (int x = 0; x < width; x )
for (int y = 0; y < heigth - 1; y )
if (field[x][y] == field[x][y 1])
return true;
return false;
}
private boolean canMergeByX() {
for (int x = 0; x < width - 1; x )
for (int y = 0; y < heigth; y )
if (field[x][y] == field[x 1][y])
return true;
return false;
}
// checking the possibility of continuing the game
public boolean canMerge() {
return canMergeByX() amp;amp; canMergeByY();
}
// checking 0 and 2048 cells for different tasks
public boolean contains(int i) {
for (int x = 0; x < width; x )
for (int y = 0; y < heigth; y )
if (field[x][y] == i)
return true;
return false;
}
}
Ответ №1:
???
In forField
может быть просто a BiConsumer<Integer, Integer>
, или вы можете объявить свой собственный IntBiConsumer
интерфейс, если вам не нравится бокс:
interface IntBiConsumer {
void accept(int i, int j);
}
forField
затем может быть объявлен как:
public void forField(int borderX, int borderY, IntBiConsumer code){
for (int x = 0; x < borderX; x )
for (int y = 0; y < borderY; y )
code.accept(x, y);
}
copyOf
затем можно записать как:
public void copyOf(Field f) {
forField(width, height, (x, y) -> {
this.field[x][y] = f.getCell(x, y);
});
}
checkField
немного сложнее, предлагаемый вами код на самом деле не будет работать, потому что вы ничего не проверяете перед собой return
во внутреннем цикле. Циклы будут зацикливаться только один раз и немедленно возвращаться. Это должно быть больше похоже:
public boolean checkField(int borderX, int borderY, ??? condition, boolean default_answer){
for (int x = 0; x < borderX; x )
for (int y = 0; y < borderY; y )
if (condition)
return !default_answer;
return default_answer;
}
???
здесь может быть a BiPredicate<Integer, Integer>
или ваш собственный интерфейс, подобный этому:
interface IntBiPredicate {
boolean test(int i, int j);
}
checkField
затем может быть объявлено следующим образом:
public boolean checkField(int borderX, int borderY, IntBiPredicate condition, boolean defaultAnswer){
for (int x = 0; x < borderX; x )
for (int y = 0; y < borderY; y )
if (condition.test())
return !defaultAnswer;
return defaultAnswer;
}
isEqualTo
может быть переписан как:
public boolean isEqualTo(Field f) {
return checkField(width, height, (x, y) -> field[x][y] != f.getCell(x, y), true);
}