Skip to content

Instantly share code, notes, and snippets.

@BurntPizza
Created April 11, 2014 22:04
Show Gist options
  • Save BurntPizza/ae0c5f2daead61adb375 to your computer and use it in GitHub Desktop.
Save BurntPizza/ae0c5f2daead61adb375 to your computer and use it in GitHub Desktop.
package wild;
import java.util.*;
import java.util.concurrent.*;
import animals.*;
import animals.Animal.Attack;
import animals.Animal.Move;
/**
* Simply replace
*
* Game game = new Game(size);
*
* with
*
* Game game = new ThreadedGame(size);
*
* in Wild.java to thread
*
*/
public class ThreadedGame extends Game {
private static int numThreads = Runtime.getRuntime().availableProcessors();
private static ExecutorService exec = Executors.newFixedThreadPool(numThreads);
private static ArrayList<Animal>[] board, accumulator;
private List<Callable<Void>> tasks;
private final Random gen = new Random();
protected int SIZE;
@SuppressWarnings("unchecked")
protected ThreadedGame(int size) {
super(0);
if (board == null) {
board = new ArrayList[size * size];
accumulator = new ArrayList[size * size];
for (int i = 0; i < size * size; i++) {
board[i] = new ArrayList<Animal>();
accumulator[i] = new ArrayList<Animal>();
}
} else
for (int i = 0; i < size * size; i++)
board[i].clear();
SIZE = size;
tasks = new ArrayList<Callable<Void>>();
}
@Override
protected <T extends Animal> void populate(Class<T> species, int num) {
while (num > 0) {
int i = gen.nextInt(SIZE * SIZE);
if (board[i].isEmpty()) {
try {
board[i].add(species.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
}
num--;
}
}
}
private void move(int start, int end) {
for (int i = start; i < end; i++) {
if (!board[i].isEmpty()) {
int x = i % SIZE;
int y = i / SIZE;
Animal a = board[i].get(0);
a.surroundings = getArea(y, x);
Move aMove;
try {
aMove = a.move();
} catch (Exception e) {
aMove = Move.HOLD;
}
int index = 0;
switch (aMove) {
case UP:
index = x + (y - 1 + SIZE) % SIZE * SIZE;
//game.board.get((i - 1 + SIZE) % SIZE).get(j).add(a);
break;
case RIGHT:
index = (x + 1) % SIZE + y * SIZE;
//game.board.get(i).get((j + 1) % SIZE).add(a);
break;
case DOWN:
index = x + (y + 1) % SIZE * SIZE;
//game.board.get((i + 1) % SIZE).get(j).add(a);
break;
case LEFT:
index = (x - 1 + SIZE) % SIZE + y * SIZE;
//game.board.get(i).get((j - 1 + SIZE) % SIZE).add(a);
break;
case HOLD:
index = i;
//game.board.get(i).get(j).add(a);
break;
}
accumulator[index].add(a);
}
}
for (int z = start; z < end; z++) {
int y = accumulator[z].size();
board[z].clear();
for (int u = y - 1; u >= 0; u--) {
board[z].add(accumulator[z].remove(u));
}
}
}
@Override
protected void iterate() {
tasks.clear();
for (int i = 0; i < numThreads; i++) {
final int start = i * board.length / numThreads;
final int end = i == numThreads - 1 ? board.length - 1 : (i + 1) * board.length / numThreads;
tasks.add(new Callable<Void>() {
@Override
public Void call() {
move(start, end);
flatten(start, end);
return null;
}
});
}
try {
exec.invokeAll(tasks);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void flatten(int start, int end) {
for (int i = start; i < end; i++) {
ArrayList<Animal> cell = board[i];
while (cell.size() > 1) {
int rand1, rand2;
rand1 = gen.nextInt(cell.size());
do {
rand2 = gen.nextInt(cell.size());
} while (rand1 == rand2);
Animal a = cell.get(rand1);
Animal b = cell.get(rand2);
Attack aTack, bTack;
try {
aTack = a.fight(b.letter);
} catch (Exception e) {
aTack = Attack.SUICIDE;
}
try {
bTack = b.fight(a.letter);
} catch (Exception e) {
bTack = Attack.SUICIDE;
}
if (aTack == bTack) {
cell.remove(Math.random() > 0.5 ? a : b);
} else {
switch (aTack) {
case ROCK:
cell.remove(bTack == Attack.PAPER ? a : b);
break;
case PAPER:
cell.remove(bTack == Attack.SCISSORS ? a : b);
break;
case SCISSORS:
cell.remove(bTack == Attack.ROCK ? a : b);
break;
}
}
}
}
}
@SuppressWarnings("rawtypes")
@Override
protected int poll(Class c) {
int count = 0;
for (int i = 0; i < board.length; i++) {
if (!board[i].isEmpty() && c.isInstance(board[i].get(0))) count++;
}
return count;
}
@Override
public String toString() {
String s = "<html>";
for (int i = 0; i < board.length; i++) {
ArrayList<Animal> cell = board[i];
if (cell.isEmpty())
s += "&nbsp;&nbsp;";
else
s += cell.get(0).letter + "&nbsp;";
if (i % SIZE == 0) s += "<br>";
}
return s + "</html>";
}
private char[][] getArea(int i, int j) {
char[][] area = new char[3][3];
for (int k = -1; k <= 1; k++) {
for (int l = -1; l <= 1; l++) {
int o = (j + l + SIZE) % SIZE + (i + k + SIZE) % SIZE * SIZE;
ArrayList<Animal> cell = board[o];
area[k + 1][l + 1] = cell.isEmpty() ? ' ' : cell.get(0).letter;
}
}
return area;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment