Ментор говорит, что "Исключение системы безопасности JavaRush. Вы выполняете потенциально опасную или запрещенную операцию.".
Хотя у меня на ПК все отлично.
Помогите :)
P. S. У меня в стриме меняется массив, может, в этом причина?
package com.javarush.games.game2048;
import com.javarush.engine.cell.*;
import static com.javarush.engine.cell.Color.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.stream.*;
class Pair<A, B> {
public final A first;
public final B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair<?, ?> pair = (Pair<?, ?>) o;
return Objects.equals(first, pair.first) &&
Objects.equals(second, pair.second);
}
@Override
public int hashCode() {
return Objects.hash(first, second);
}
@Override
public String toString() {
return "Pair{" +
"first=" + first +
", second=" + second +
'}';
}
}
class Utils {
public static<A, B, C> Stream<C> zip(Stream<? extends A> a,
Stream<? extends B> b,
BiFunction<? super A, ? super B, ? extends C> zipper) {
Objects.requireNonNull(zipper);
Spliterator<? extends A> aSpliterator = Objects.requireNonNull(a).spliterator();
Spliterator<? extends B> bSpliterator = Objects.requireNonNull(b).spliterator();
// Zipping looses DISTINCT and SORTED characteristics
int characteristics = aSpliterator.characteristics() & bSpliterator.characteristics() &
~(Spliterator.DISTINCT | Spliterator.SORTED);
long zipSize = ((characteristics & Spliterator.SIZED) != 0)
? Math.min(aSpliterator.getExactSizeIfKnown(), bSpliterator.getExactSizeIfKnown())
: -1;
Iterator<A> aIterator = Spliterators.iterator(aSpliterator);
Iterator<B> bIterator = Spliterators.iterator(bSpliterator);
Iterator<C> cIterator = new Iterator<C>() {
@Override
public boolean hasNext() {
return aIterator.hasNext() && bIterator.hasNext();
}
@Override
public C next() {
return zipper.apply(aIterator.next(), bIterator.next());
}
};
Spliterator<C> split = Spliterators.spliterator(cIterator, zipSize, characteristics);
return (a.isParallel() || b.isParallel())
? StreamSupport.stream(split, true)
: StreamSupport.stream(split, false);
}
public static <T> Stream<Pair<Integer, T>> index(Stream<? extends T> original) {
AtomicInteger i = new AtomicInteger(0);
return zip(
IntStream.generate(i::getAndIncrement).boxed(),
original,
Pair::new
);
}
public static int log2(int bits) {
if (bits == 0) return 0;
return 31 - Integer.numberOfLeadingZeros(bits);
}
}
public class Game2048 extends Game {
private static final int SIDE = 4;
private int[][] gameField = new int[SIDE][SIDE];
private static final List<Color> COLORS = Arrays.asList(
YELLOW,
ORANGE,
RED,
GREEN,
BLUE,
VIOLET,
BROWN,
GOLD,
SILVER,
LIME,
MAGENTA,
PINK,
YELLOWGREEN
);
@Override
public void initialize() {
setScreenSize(SIDE,SIDE);
createGame();
drawScene();
}
private Color getColorByValue(int val) {
int log = Utils.log2(val);
return COLORS.get(log > COLORS.size() ? COLORS.size()-1 : log);
}
private void createNewNumber() {
int x, y;
do {
x = getRandomNumber(SIDE);
y = getRandomNumber(SIDE);
} while (gameField[y][x] != 0);
int val = getRandomNumber(10) == 9 ? 4 : 2;
gameField[y][x] = val;
}
private void setCellColoredNumber(int x, int y, int val) {
Color c = getColorByValue(val);
setCellValueEx(x, y, c, val == 0 ? "" : "" + val);
}
private void createGame() {
for (int i = 0; i < 2; i++) {
createNewNumber();
}
}
private boolean compressRow(int[] row) {
int[] newArr = Arrays.stream(row)
.boxed()
.sorted((a, b) -> {
if (a == 0) return 1;
if (b == 0) return -1;
return 0;
})
.mapToInt(i -> i)
.toArray();
boolean eq = Arrays.equals(row, newArr);
System.arraycopy(newArr, 0, row, 0, row.length);
return !eq;
}
private boolean mergeRow(int[] row) {
int[] old = Arrays.copyOf(row, row.length);
for (int i = 0; i < row.length - 1; i++) {
if (row[i+1] == row[i]) {
row[i] *= 2;
row[i+1] = 0;
i++;
}
}
return !Arrays.equals(old, row);
}
private void drawScene() {
long t1 = System.currentTimeMillis();
IntStream gfstream = Stream.of(gameField)
.flatMapToInt(IntStream::of)
.parallel();
Utils.index(gfstream.boxed())
.forEach(p -> {
int index = p.first;
setCellColoredNumber(index % SIDE, index / SIDE, p.second);
});
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);
}
private void moveLeft() {
final AtomicBoolean[] r = {new AtomicBoolean(false)};
Stream.of(gameField)
.parallel()
.forEach(x -> {
boolean r1;
r1 = compressRow(x);
r1 |= mergeRow(x);
r1 |= compressRow(x);
if (!r[0].get() && r1) {
createNewNumber();
r[0].set(true);
}
});
}
private void moveRight() {
}
private void moveUp() {
}
private void moveDown() {
}
public void onKeyPress(Key k) {
switch (k) {
case LEFT: moveLeft(); break;
case RIGHT: moveRight(); break;
case DOWN: moveDown(); break;
case UP: moveUp(); break;
default: return;
}
drawScene();
}
// public static void main(String[] args) {
// for (int[] row : new int[][] {
// { 2, 2, 0, 0 },
// { 2, 0, 2, 0 },
// { 2, 0, 0, 2 },
// { 8, 2, 2, 0 },
// { 2, 2, 2, 2 }
// }) {
// System.out.println("old: " + Arrays.toString(row));
// System.out.println("res: " + new Game2048().mergeRow(row));
// System.out.println("new: " + Arrays.toString(row));
// }
// }
}