Skip to content

Instantly share code, notes, and snippets.

/OOAPIWay.scala Secret

Created September 2, 2016 12:46
Show Gist options
  • Save anonymous/a995c106d5144f5e2f5d4aa7f05eb3e9 to your computer and use it in GitHub Desktop.
Save anonymous/a995c106d5144f5e2f5d4aa7f05eb3e9 to your computer and use it in GitHub Desktop.
object OOAPIWay extends App {
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))
// Console println f"x0=$x0 y0=$y0 distance=$distance angle=$angle anngleInRads=$angleInRads x1=$x1 y1=$y1"
Position(round2(x1), round2(y1))
}
class Turtle(log:Log) {
var curPosition: Position = Position(0, 0)
var currentAngle: Double = 0.0
var curColor: PenColor.Value = PenColor.Black
var curState: PenState.Value = PenState.Down
def penUp() = {
log.log("Pen Up")
curState = PenState.Up
}
def penDown() = {
log.log("Pen Down")
curState = PenState.Down
}
def turn(angle: Double) = {
log.log(f"Turn $angle")
val newAngle = (currentAngle + angle) % 360.0
currentAngle = newAngle
}
def setColor(penColor: PenColor.Value) = {
log.log(String.format("Set Color : %s", penColor.toString))
this.curColor = penColor
}
def move(distance: Double) = {
log.log(f"Move $distance")
val newPosition = calcNewPosition(distance)(currentAngle)(curPosition)
if (curState == PenState.Down) {
dummyDrawLine(log, curPosition, newPosition, curColor)
}
curPosition = newPosition
}
}
case class TurtleAPIException (msg: String) extends Exception
def validateDistance (distanceStr: String) = {
try {
distanceStr.toDouble
} catch {
case ex:Exception => {
val msg = f"Invalid distance '$distanceStr' [${ex.getMessage}]"
throw new TurtleAPIException(msg)
}
}
}
def validateAngle (angleStr: String) = {
try{
angleStr.toDouble
} catch {
case ex:Exception => {
val msg = f"Invalid angle '$angleStr' [${ex.getMessage}]"
throw new TurtleAPIException(msg)
}
}
}
def validateColor (colorStr: String) = {
colorStr match {
case "Black" => PenColor.Black
case "Blue" => PenColor.Blue
case "Red" => PenColor.Red
case _ => {
val msg = f"Color '$colorStr' is not recognized"
throw new TurtleAPIException(msg)
}
}
}
class TurtleAPI {
val log = new Log()
val turtle = new Turtle(log)
def exec (commandStr:String) = {
val tokens = (commandStr split ' ').map(_.trim).toList
tokens match {
case List("Move", distanceStr) => {
val distance = validateDistance(distanceStr)
turtle.move (distance)
}
case List("Turn", angleStr) => {
val angle = validateAngle(angleStr)
turtle.turn (angle)
}
case List("Pen", "Up") => {
turtle.penUp()
}
case List("Pen", "Down") =>{
turtle.penDown()
}
case List("SetColor", colorStr) => {
val color = validateColor(colorStr)
turtle.setColor(color)
}
case _ => {
val msg = f"Instruction '$commandStr' is not recognized"
throw new TurtleAPIException(msg)
}
}
}
}
def drawPolygon(n:Int) = {
val angle = 360.0 / n
val api = new TurtleAPI
def drawOneSide = {
api.exec("Move 100.0")
api.exec(f"Turn $angle")
}
for( i <- 1 to n) {
drawOneSide
}
}
def triggerError = {
val api = new TurtleAPI
api.exec("Move bad")
}
drawPolygon(3)
// try {
// triggerError
// } catch {
// case TurtleAPIException(msg) => {
// Console println f"Error : $msg"
// }
// }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment