Skip to content

Instantly share code, notes, and snippets.

@timyates
Last active June 15, 2020 13:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timyates/112627bf46040a8099ac to your computer and use it in GitHub Desktop.
Save timyates/112627bf46040a8099ac to your computer and use it in GitHub Desktop.
RxJava and Java 8 Game of Life
import rx.Observable;
import rx.functions.Action1;
import rx.subjects.BehaviorSubject;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ReactiveGameOfLife {
private static class Iteration {
final int generation;
final List<Integer> cells;
public Iteration(int generation, List<Integer> cells) {
this.generation = generation;
this.cells = cells;
}
Iteration next(List<Integer> cells) {
return new Iteration(generation + 1, cells);
}
}
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
Action1<Iteration> printer = l -> {
System.out.println("GENERATION " + l.generation);
Observable.from(l.cells).map(c -> c > 0 ? "#" : ".").buffer(width).map(s -> String.join("", s)).forEach(System.out::println);
};
BehaviorSubject<Iteration> subject = BehaviorSubject.create(new Iteration(0, state));
Action1<Iteration> loop = i -> {
printer.call(i);
Observable.range(0, i.cells.size())
.flatMap(idx -> Observable.range(0, 9)
.map(off -> new Point((idx % width) + (off % 3) - 1, (idx / width) + (off / 3) - 1))
.filter(pt -> pt.x >= 0 && pt.x < width && pt.y >= 0 && pt.y < height)
.filter(pt -> pt.x + pt.y * width != idx)
.reduce(0, (a, p) -> a + i.cells.get(p.x + p.y * width))
.map(score -> score < 2 || score > 3 ? 0 : (i.cells.get(idx) == 1 || score == 3 ? 1 : 0)))
.toList()
.subscribe(cells -> subject.onNext(i.next(cells)));
};
subject.take(10).subscribe(loop);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment