Last active
December 30, 2015 11:39
-
-
Save timyates/7823738 to your computer and use it in GitHub Desktop.
Reactive Rock Paper Scissors with Groovy and RxJava
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
@Grab( 'com.netflix.rxjava:rxjava-groovy:0.15.1' ) | |
import groovy.transform.* | |
import rx.* | |
@CompileStatic | |
class RPSRX { | |
enum Result { | |
WIN, LOSE, DRAW | |
} | |
enum Move { | |
ROCK( SCISSORS ), | |
PAPER( ROCK ), | |
SCISSORS( PAPER ) | |
Move beats | |
Move( Move beats ) { | |
this.beats = beats | |
} | |
boolean beats( Move other ) { | |
other == beats | |
} | |
} | |
@Immutable | |
static class PlayerMove { | |
String player | |
Move move | |
String toString() { "$player:$move" } | |
} | |
final Random rnd = new Random() | |
private <T> Observable.OnSubscribeFunc<T> subscriptionBuilder( Closure<T> generator ) { | |
{ Observer<T> observer -> | |
boolean running = true | |
new Thread( { -> | |
while( running ) { | |
observer.onNext( generator() ) | |
} | |
observer.onCompleted(); | |
} ).start() | |
return { -> running = false } as Subscription | |
} | |
} | |
Observable<Integer> numbers() { | |
int n = 1 | |
Observable.create( subscriptionBuilder( { -> n++ } ) ) | |
} | |
Observable<Move> moves() { | |
Observable.create( subscriptionBuilder { | |
Move.values()[ rnd.nextInt( Move.values().length ) ] | |
} ) | |
} | |
Observable<PlayerMove> player( String name ) { | |
moves().map { Move it -> new PlayerMove( name, it ) } | |
} | |
String message( Integer index, PlayerMove m1, PlayerMove m2 ) { | |
"Game $index : $m1 vs $m2 : ${resultMessage( m1, m2, result( m1, m2 ) )}" | |
} | |
Result result( PlayerMove m1, PlayerMove m2 ) { | |
m1.move == m2.move ? Result.DRAW : m1.move.beats == m2.move ? Result.WIN : Result.LOSE | |
} | |
String resultMessage( PlayerMove m1, PlayerMove m2, Result r ) { | |
r == Result.DRAW ? 'draw' : r == Result.WIN ? "$m1.player wins" : "$m2.player wins" | |
} | |
Observable<String> game( String name1, String name2 ) { | |
Observable.zip( numbers(), player( name1 ), player( name2 ) ) { Integer n, PlayerMove a, PlayerMove b -> | |
message( n, a, b ) | |
} | |
} | |
} | |
new RPSRX().game( 'tim', 'alice' ).take( 10 ).subscribe { println it } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Doesn't seem to work anymore: