Skip to content

Instantly share code, notes, and snippets.

@gdulus
Forked from timyates/ReactiveRPS.groovy
Created December 6, 2013 13:40
Show Gist options
  • Select an option

  • Save gdulus/7823981 to your computer and use it in GitHub Desktop.

Select an option

Save gdulus/7823981 to your computer and use it in GitHub Desktop.
@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