Skip to content

Instantly share code, notes, and snippets.

@timyates
Last active December 30, 2015 11:39
Show Gist options
  • Save timyates/7823738 to your computer and use it in GitHub Desktop.
Save timyates/7823738 to your computer and use it in GitHub Desktop.
Reactive Rock Paper Scissors with Groovy and RxJava
@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 }
@timyates
Copy link
Author

timyates commented Dec 6, 2013

@tednaleid Cool! Top tip :-) I hadn't noticed that in the rx-java deps, thanks! :-)

Rock Paper Scissors is my new Hello World ;-) Got my groovy-stream version, a Java 8 one, this one and next I might try project reactor ;-)

@rgrinberg
Copy link

Doesn't seem to work anymore:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/Users/rgrinberg/reps/snippets/groovy/rx-rps.groovy: 34: [Static type checking] - Cannot return value of type groovy.lang.Closure <rx.Subscription> on method returning type rx.Observable$OnSubscribeFunc <T>
 @ line 34, column 13.
               { Observer<T> observer ->
               ^

1 error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment