-
-
Save anonymous/a995c106d5144f5e2f5d4aa7f05eb3e9 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
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