-
-
Save jinuk17/cbd0ea108e859dd0edc3911448cf26a3 to your computer and use it in GitHub Desktop.
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
import Common._ | |
/** | |
* Created by jaydenuk on 2016. 8. 26.. | |
*/ | |
object FPTurtle extends App{ | |
case class TurtleState( | |
position: Position, | |
angle: Double, | |
color: PenColor.Value, | |
penState: PenState.Value | |
){ | |
def |>(f: (TurtleState) => TurtleState): TurtleState ={ | |
f(this) | |
} | |
def |>[T](f: (T, TurtleState) => TurtleState)(t: T): TurtleState ={ | |
f(t, this) | |
} | |
} | |
val initialTurtleState = TurtleState(Position(0, 0), 0.0d, PenColor.Black, PenState.Down) | |
object Turtle { | |
def move(log: Log, distance: Double, state: TurtleState ) = { | |
log.log(f"Move $distance") | |
val newPosition = calcNewPosition(distance)(state.angle)(state.position) | |
if (state.penState == PenState.Down) { | |
dummyDrawLine(log, state.position, newPosition, state.color) | |
} | |
TurtleState( | |
newPosition, | |
state.angle, | |
state.color, | |
state.penState | |
) | |
} | |
def turn(log: Log, angle: Double, state: TurtleState) = { | |
log.log(f"Turn $angle") | |
val newAngle = (state.angle + angle) % 360.0 | |
TurtleState( | |
state.position, | |
newAngle, | |
state.color, | |
state.penState | |
) | |
} | |
def penUp(log: Log, state: TurtleState) = { | |
log.log("Pen Up") | |
TurtleState( | |
state.position, | |
state.angle, | |
state.color, | |
PenState.Up | |
) | |
} | |
def penDown(log: Log, state: TurtleState) = { | |
log.log("Pen Down") | |
TurtleState( | |
state.position, | |
state.angle, | |
state.color, | |
PenState.Down | |
) | |
} | |
def setColor(log: Log, color: PenColor.Value, state: TurtleState) = { | |
log.log(String.format("Set Color : %s", state.color.toString)) | |
TurtleState( | |
state.position, | |
state.angle, | |
color, | |
state.penState | |
) | |
} | |
} | |
val log = new Log() | |
val move = Turtle.move(log, _:Double, _:TurtleState) | |
val turn = Turtle.turn(log, _:Double, _:TurtleState) | |
val penDown = Turtle.penDown(log, _:TurtleState) | |
val penUp = Turtle.penUp(log, _:TurtleState) | |
val setColor = Turtle.setColor(log, _:PenColor.Value, _:TurtleState) | |
def drawTriangle() = { | |
initialTurtleState | |
.|>(move)(100.0) | |
.|>(turn)(120.0) | |
.|>(move)(100.0) | |
.|>(turn)(120.0) | |
.|>(move)(100.0) | |
.|>(turn)(120.0) | |
} | |
def drawPolygon(n: Integer):Unit = { | |
val angleDegree = 360.0/n | |
def oneSide(state:TurtleState, sideNumber: Integer): TurtleState = { | |
state | |
.|>(move)(100.0) | |
.|>(turn)(angleDegree) | |
} | |
(1 to n).foldLeft(initialTurtleState)((state, i) => oneSide(state, i)) | |
} | |
drawPolygon(3) | |
} | |
object Common { | |
object PenState extends Enumeration { | |
type PenState = Value | |
val Up, Down = Value | |
} | |
object PenColor extends Enumeration { | |
type PenColor = Value | |
val Black, Red, Blue = Value | |
} | |
case class Position(x:Double, y:Double) | |
class Log { | |
def log(line:String) = { Console.println(line) } | |
} | |
def dummyDrawLine(log:Log, oldPos:Position, newPos:Position, color:PenColor.Value) = { | |
log.log(f"...Draw line from (${oldPos.x},${oldPos.y}) to (${newPos.x},${newPos.y}) using $color") | |
} | |
def round2(d:Double):Double = { | |
Math.round(d * 100) / 100.0 | |
} | |
def calcNewPosition(distance:Double)(angle:Double)(currentPos:Position) = { | |
val angleInRads = math.toRadians(angle) | |
val x0 = currentPos.x | |
val y0 = currentPos.y | |
val x1 = x0 + (distance * Math.cos(angleInRads)) | |
val y1 = y0 + (distance * Math.sin(angleInRads)) | |
Position(round2(x1), round2(y1)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment