blob: 98470224efb736e95f54bcaba40dd20be4d00470 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc R. Hoffmann - initial API and implementation
*
*******************************************************************************/
package org.jacoco.core.test.perf.targets;
import java.util.Random;
import java.util.concurrent.Callable;
/**
* "Game of Life" implementation as a more reference scenario. Obviously the
* implementation could be more elegant using several classes, but the test
* runner targets one class only. Also one could think about more efficient
* implementations which again is not the focus here.
*/
public class Target03 implements Callable<Void> {
private final int width;
private final int height;
private boolean[][] field;
public Target03(int width, int height) {
this.width = width;
this.height = height;
this.field = createField();
}
public Target03() {
this(64, 64);
}
private boolean[][] createField() {
boolean[][] f = new boolean[height][];
for (int i = 0; i < height; i++) {
f[i] = new boolean[width];
}
return f;
}
public void set(int x, int y, boolean flag) {
field[wrap(x, width)][wrap(y, height)] = flag;
}
public boolean get(int x, int y) {
return field[wrap(x, width)][wrap(y, height)];
}
public void clear() {
field = createField();
}
public void randomFill(long seed, int count) {
Random r = new Random(seed);
for (int i = 0; i < count; i++) {
set(r.nextInt(), r.nextInt(), true);
}
}
public void tick() {
boolean[][] next = createField();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
final int n = getNeighbors(x, y);
if (get(x, y)) {
next[x][y] = 2 <= n && n <= 3;
} else {
next[x][y] = n == 3;
}
}
}
field = next;
}
// Neighbor
private int getNeighbors(int x, int y) {
int count = 0;
if (get(x - 1, y - 1)) {
count++;
}
if (get(x + 0, y - 1)) {
count++;
}
if (get(x + 1, y - 1)) {
count++;
}
if (get(x + 1, y + 0)) {
count++;
}
if (get(x + 1, y + 1)) {
count++;
}
if (get(x + 0, y + 1)) {
count++;
}
if (get(x - 1, y + 1)) {
count++;
}
if (get(x - 1, y + 0)) {
count++;
}
return count;
}
private int wrap(int value, int size) {
int res = value % size;
if (res < 0) {
res += size;
}
return res;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
sb.append(get(x, y) ? 'O' : '.');
}
sb.append('\n');
}
return sb.toString();
}
public Void call() throws Exception {
clear();
randomFill(123, width * height / 2);
for (int i = 0; i < 20; i++) {
tick();
}
return null;
}
// Demo
public static void main(String[] args) {
Target03 t = new Target03(10, 10);
t.randomFill(123, 20);
for (int i = 0; i < 10; i++) {
System.out.println("Generation " + i + ":");
System.out.println(t);
t.tick();
}
}
}