Skip to content

Instantly share code, notes, and snippets.

@jinuk17
Created August 26, 2016 12:53
Show Gist options
  • Save jinuk17/cbd0ea108e859dd0edc3911448cf26a3 to your computer and use it in GitHub Desktop.
Save jinuk17/cbd0ea108e859dd0edc3911448cf26a3 to your computer and use it in GitHub Desktop.
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