Last active
June 15, 2020 13:39
-
-
Save timyates/112627bf46040a8099ac to your computer and use it in GitHub Desktop.
RxJava and Java 8 Game of Life
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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