-
Notifications
You must be signed in to change notification settings - Fork 6
/
PaperScissorsRock.groovy
81 lines (62 loc) · 1.67 KB
/
PaperScissorsRock.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.github.mperry.fg
/**
* Created with IntelliJ IDEA.
* User: MarkPerry
* Date: 22/11/13
* Time: 12:51 PM
* To change this template use File | Settings | File Templates.
*/
import fj.*
import fj.data.*
import fj.test.*
import groovy.transform.TypeChecked
import groovy.transform.TypeCheckingMode
@TypeChecked
class PaperScissorsRock {
enum Move { PAPER, SCISSORS, ROCK }
enum MoveResult { WIN, LOSE, DRAW }
static void main(def args) {
new PaperScissorsRock().gameSequence()
}
void gameSequence() {
gameMessages().take(20).toList().each {
println it
}
}
Stream<String> gameMessages() {
messages().zipIndex().map { P2<String, Integer> p2 ->
"game: ${p2._2()} ${p2._1()}"
}
}
Stream<String> messages() {
moves().zip(moves()).map { P2<Move, Move> p ->
gameMessage(p._1(), p._2(), result(p._1(), p._2()))
}
}
String gameMessage(Move m1, Move m2, MoveResult r) {
"p1: $m1 p2: $m2 result: ${gameResultMessage(r, "p1 wins", "p2 wins", "draw")}"
}
String gameResultMessage(MoveResult r, String win, String lost, String draw) {
r == MoveResult.DRAW ? draw : (r == MoveResult.WIN ? win : lost)
}
@TypeChecked(TypeCheckingMode.SKIP)
Stream<Move> moves() {
Stream.range(1).map {
randomMove(new Random())._2()
}
}
P2<Random, Move> randomMove(Random r) {
def v = Move.values()
P.p(r, v[r.nextInt(v.size())])
}
boolean beats(Move p1, Move p2) {
def map = [(Move.PAPER): Move.ROCK, (Move.SCISSORS): Move.PAPER, (Move.ROCK): Move.SCISSORS]
map[p1] == p2
}
boolean draw(Move m1, Move m2) {
m1 == m2
}
MoveResult result(Move m1, Move m2) {
draw(m1, m2) ? MoveResult.DRAW : (beats(m1, m2) ? MoveResult.WIN : MoveResult.LOSE)
}
}