Last active
February 19, 2020 17:01
-
-
Save timyates/7675299 to your computer and use it in GitHub Desktop.
Rock Paper Scissors in Java 8 with Streams
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
package java8tests; | |
import java.util.Iterator; | |
import java.util.Random; | |
import java.util.stream.Stream; | |
public class RockPaperScissors { | |
enum Result { | |
WIN, LOSE, DRAW | |
} | |
enum Move { | |
ROCK, PAPER, SCISSORS ; | |
static { | |
ROCK.beats = SCISSORS ; | |
PAPER.beats = ROCK ; | |
SCISSORS.beats = PAPER ; | |
} | |
private Move beats ; | |
public boolean beats( Move other ) { | |
return beats == other ; | |
} | |
} | |
class PlayerMove { | |
private final String player ; | |
private final Move move ; | |
public PlayerMove( String player, Move move ) { | |
this.player = player ; | |
this.move = move ; | |
} | |
@Override | |
public String toString() { | |
return String.format( "%s:%s", getPlayer(), getMove()) ; | |
} | |
public String getPlayer() { | |
return player; | |
} | |
public Move getMove() { | |
return move; | |
} | |
} | |
class Turn { | |
private final PlayerMove p1 ; | |
private final PlayerMove p2 ; | |
public Turn( PlayerMove p1, PlayerMove p2 ) { | |
this.p1 = p1 ; | |
this.p2 = p2 ; | |
} | |
@Override | |
public String toString() { | |
return String.format( "%s vs %s", getP1(), getP2()) ; | |
} | |
public PlayerMove getP1() { | |
return p1; | |
} | |
public PlayerMove getP2() { | |
return p2; | |
} | |
} | |
private final Random rnd = new Random() ; | |
Stream<Move> moves() { | |
return Stream.generate( () -> Move.values()[ rnd.nextInt( Move.values().length ) ] ) ; | |
} | |
Stream<PlayerMove> player( String name ) { | |
return moves().map( ( m ) -> new PlayerMove( name, m ) ) ; | |
} | |
Stream<Turn> turn( String player1, String player2 ) { | |
// No zip for Streams :-( | |
Iterator<PlayerMove> p1 = player( player1 ).iterator() ; | |
Iterator<PlayerMove> p2 = player( player2 ).iterator() ; | |
return Stream.generate( () -> new Turn( p1.next(), p2.next() ) ) ; | |
} | |
Result result( Turn t ) { | |
return t.getP1().getMove() == t.getP2().getMove() ? Result.DRAW : | |
t.getP1().getMove().beats( t.getP2().getMove()) ? Result.WIN : | |
Result.LOSE ; | |
} | |
String resultMessage( Turn t, Result r ) { | |
return r == Result.DRAW ? "DRAW" : | |
r == Result.WIN ? String.format( "%s wins", t.getP1().getPlayer()) : | |
String.format( "%s wins", t.getP2().getPlayer()) ; | |
} | |
String message( Turn t ) { | |
return String.format( "%s : %s", t.toString(), resultMessage( t, result( t ) ) ) ; | |
} | |
Stream<String> game( String player1, String player2, int turns ) { | |
return turn( player1, player2 ).limit( turns ) | |
.map( (t) -> message( t ) ) ; | |
} | |
public static void main( String[] args ) { | |
new RockPaperScissors().game( "tim", "alice", 5 ) | |
.forEach( (m) -> System.out.println( m ) ) ; | |
} | |
} |
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
// By popular demand ;-) | |
package java8tests; | |
import java.util.Arrays; | |
import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.Random; | |
import java.util.Set; | |
import java.util.stream.Stream; | |
public class RockPaperScissorsLizardSpock { | |
enum Result { | |
WIN, LOSE, DRAW | |
} | |
enum Move { | |
ROCK, PAPER, SCISSORS, LIZARD, SPOCK ; | |
static { | |
ROCK.beats = new HashSet<>( Arrays.asList( LIZARD, SCISSORS ) ) ; | |
PAPER.beats = new HashSet<>( Arrays.asList( ROCK, SPOCK ) ) ; | |
SCISSORS.beats = new HashSet<>( Arrays.asList( PAPER, LIZARD ) ) ; | |
LIZARD.beats = new HashSet<>( Arrays.asList( SPOCK, PAPER ) ) ; | |
SPOCK.beats = new HashSet<>( Arrays.asList( SCISSORS, ROCK ) ) ; | |
} | |
private Set<Move> beats ; | |
public boolean beats( Move other ) { | |
return beats.contains( other ) ; | |
} | |
} | |
class PlayerMove { | |
private final String player ; | |
private final Move move ; | |
public PlayerMove( String player, Move move ) { | |
this.player = player ; | |
this.move = move ; | |
} | |
@Override | |
public String toString() { | |
return String.format( "%s:%s", getPlayer(), getMove()) ; | |
} | |
public String getPlayer() { | |
return player; | |
} | |
public Move getMove() { | |
return move; | |
} | |
} | |
class Turn { | |
private final PlayerMove p1 ; | |
private final PlayerMove p2 ; | |
public Turn( PlayerMove p1, PlayerMove p2 ) { | |
this.p1 = p1 ; | |
this.p2 = p2 ; | |
} | |
@Override | |
public String toString() { | |
return String.format( "%s vs %s", getP1(), getP2()) ; | |
} | |
public PlayerMove getP1() { | |
return p1; | |
} | |
public PlayerMove getP2() { | |
return p2; | |
} | |
} | |
private final Random rnd = new Random() ; | |
Stream<Move> moves() { | |
return Stream.generate( () -> Move.values()[ rnd.nextInt( Move.values().length ) ] ) ; | |
} | |
Stream<PlayerMove> player( String name ) { | |
return moves().map( ( m ) -> new PlayerMove( name, m ) ) ; | |
} | |
Stream<Turn> turn( String player1, String player2 ) { | |
// No zip for Streams :-( | |
Iterator<PlayerMove> p1 = player( player1 ).iterator() ; | |
Iterator<PlayerMove> p2 = player( player2 ).iterator() ; | |
return Stream.generate( () -> new Turn( p1.next(), p2.next() ) ) ; | |
} | |
Result result( Turn t ) { | |
return t.getP1().getMove() == t.getP2().getMove() ? Result.DRAW : | |
t.getP1().getMove().beats( t.getP2().getMove()) ? Result.WIN : | |
Result.LOSE ; | |
} | |
String resultMessage( Turn t, Result r ) { | |
return r == Result.DRAW ? "DRAW" : | |
r == Result.WIN ? String.format( "%s wins", t.getP1().getPlayer()) : | |
String.format( "%s wins", t.getP2().getPlayer()) ; | |
} | |
String message( Turn t ) { | |
return String.format( "%s : %s", t.toString(), resultMessage( t, result( t ) ) ) ; | |
} | |
Stream<String> game( String player1, String player2, int turns ) { | |
return turn( player1, player2 ).limit( turns ) | |
.map( (t) -> message( t ) ) ; | |
} | |
public static void main( String[] args ) { | |
new RockPaperScissorsLizardSpock().game( "tim", "alice", 5 ) | |
.forEach( (m) -> System.out.println( m ) ) ; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Could the following lines be rewrittenn using method expressions?