Skip to content

Instantly share code, notes, and snippets.

@timyates
Created November 18, 2014 16:22
Show Gist options
  • Save timyates/1f2a35934a24ea868c52 to your computer and use it in GitHub Desktop.
Save timyates/1f2a35934a24ea868c52 to your computer and use it in GitHub Desktop.
First pass at the Game of Life in Java 8 Streams
import java.awt.*;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class FunctionalGameOfLife {
@FunctionalInterface
interface F3<T,U,V,R> {
public R apply(T t, U u, V v);
}
public static void main(String[] args) {
// Some stats about the playfield
int width = 6;
int height = 6;
// The initial state and something to load it into a List of Integers
String initial =
"......" +
"......" +
"..###." +
".###.." +
"......" +
"......";
Function<String,Integer> isAlive = s -> s.equals("#") ? 1 : 0;
List<Integer> state = Arrays.asList(initial.split("(?!^)")).stream().map(isAlive).collect(Collectors.toList());
// Something to print out out playfield
Consumer<List<Integer>> printer = l -> Stream.iterate(0, i -> i + width)
.limit(l.size()/width)
.map(i -> l.stream().skip(i).limit(width).map(c -> c > 0 ? "#" : ".").collect(Collectors.joining()))
.forEach(System.out::println);
// Given a playfield, a index, and the score for it's neighbours, decide if a cell is dead or alive
F3<List<Integer>, Integer, Long, Integer> rules = (cells, pos, score) -> score < 2 || score > 3 ? 0 : (cells.get(pos) == 1 || score == 3 ? 1 : 0);
// Is a point outside the playfield?
Predicate<Point> inRange = p -> p.x >= 0 && p.x < width && p.y >= 0 && p.y < height;
// Create a new list of integers from the existing one
Function<List<Integer>,List<Integer>> generation = cells ->
IntStream.range(0, cells.size())
.mapToObj(idx -> rules.apply(cells, idx, IntStream.range(0, 9)
.mapToObj(off -> new Point((idx % width) + (off % 3) - 1, (idx / width) + (off / 3) - 1))
.filter(inRange)
.filter(p -> p.x + p.y * height != idx)
.mapToInt(p -> cells.get(p.x + p.y * height))
.summaryStatistics()
.getSum())).collect(Collectors.toList());
// run for 10 generations
for(int i = 0; i < 10; i++) {
System.out.println("Generation " + i);
printer.accept(state);
state = generation.apply(state);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment