/******************************************************************************* * Copyright (c) 2009, 2017 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(); } } }