[plm] 01/13: re-enable scala now that Scala 2.11 is in Debian
Martin Quinson
mquinson at moszumanska.debian.org
Sat Jan 2 21:09:10 UTC 2016
This is an automated email from the git hooks/post-receive script.
mquinson pushed a commit to branch master
in repository plm.
commit fbccdfc4c7394baf1020ff096a96776e83401ab9
Author: Martin Quinson <martin.quinson at loria.fr>
Date: Fri Jan 1 11:47:57 2016 +0100
re-enable scala now that Scala 2.11 is in Debian
---
debian/changelog | 7 +
debian/control | 13 +-
debian/patches/no-scala | 2660 -----------------------------------------------
debian/patches/series | 1 -
4 files changed, 12 insertions(+), 2669 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 6e1555e..8c3aa8f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+plm (2.4.11+repack-3) UNRELEASED; urgency=medium
+
+ * Enable scala teaching, now that Scala 2.11 is in Debian
+ (Fix: #809482) Thanks Rogério Brito for the reminder.
+
+ -- Martin Quinson <mquinson at debian.org> Fri, 01 Jan 2016 11:41:48 +0100
+
plm (2.4.11+repack-2) unstable; urgency=medium
* Specify to jh_build that javac will encounter UTF-8 files
diff --git a/debian/control b/debian/control
index f3f66c0..d8b1be0 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,7 @@ Section: java
Priority: extra
Maintainer: Martin Quinson <mquinson at debian.org>
Build-Depends: debhelper (>> 8), javahelper (>= 0.32), ant, quilt
-Build-Depends-Indep: openjdk-7-jdk, libmiglayout-java, librsyntaxtextarea-java,
+Build-Depends-Indep: openjdk-7-jdk, scala, libmiglayout-java, librsyntaxtextarea-java,
junit4, libgettext-commons-java, libjson-simple-java, libhttpclient-java, libhttpmime-java, libjgit-java,
jython, libgettext-ant-tasks-java, imagemagick
Standards-Version: 3.9.6
@@ -17,11 +17,11 @@ Depends: java-wrappers, ${java:Depends}, ${misc:Depends},
libhttpmime-java,
Recommends: ${java:Recommends}
Suggests: jython
-Description: Programming exerciser in Java, Python and others
+Description: Programming exerciser in Java, Python, Scala and others
The Programmer's Learning Machine (PLM) is a free cross-platform programming
exerciser. It lets you explore various concepts of programming through
- over 190 interactive exercises, that you can solve in either Java or
- Python.
+ over 190 interactive exercises, that you can solve in either Java,
+ Python or Scala.
.
The PLM interface and content is thoughtfully translated to English
and French; we hope that other translations will be contributed in
@@ -40,8 +40,5 @@ Description: Programming exerciser in Java, Python and others
.
Other lessons are planned to explore new concepts, such as the
backtracking, dynamic programming, object-oriented programming or the
- standard libraries of python and Java. Other programming languages
+ standard libraries of python, Scala and Java. Other programming languages
(such as Ruby or JavaScript) may be added in the future.
- .
- The Scala language was cut of the package because the Debian version
- of that language is too ancient for the PLM.
\ No newline at end of file
diff --git a/debian/patches/no-scala b/debian/patches/no-scala
deleted file mode 100644
index 2affd88..0000000
--- a/debian/patches/no-scala
+++ /dev/null
@@ -1,2660 +0,0 @@
----
- src/lessons/lander/Main.fr.html | 23
- src/lessons/lander/Main.html | 21
- src/lessons/lander/Main.scala | 14
- src/lessons/lander/icon.svg | 104 ----
- src/lessons/lander/lvl1_lander_101/Lander101.fr.html | 49 -
- src/lessons/lander/lvl1_lander_101/Lander101.html | 41 -
- src/lessons/lander/lvl1_lander_101/Lander101.it.html | 45 -
- src/lessons/lander/lvl1_lander_101/Lander101.pt_BR.html | 45 -
- src/lessons/lander/lvl1_lander_101/Lander101.scala | 17
- src/lessons/lander/lvl1_lander_101/Lander101Entity.java | 14
- src/lessons/lander/lvl1_lander_101/Lander101Entity.py | 13
- src/lessons/lander/lvl1_lander_101/ScalaLander101Entity.scala | 17
- src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.fr.html | 39 -
- src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.html | 34 -
- src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.scala | 19
- src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.java | 57 --
- src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.py | 43 -
- src/lessons/lander/lvl2_locate_landing_zone/ScalaLocateLandingZoneEntity.scala | 54 --
- src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.fr.html | 41 -
- src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.html | 33 -
- src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.pt_BR.html | 37 -
- src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.scala | 20
- src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.java | 48 -
- src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.py | 45 -
- src/lessons/lander/lvl3_fly_the_lander/ScalaFlyTheLanderEntity.scala | 53 --
- src/lessons/lander/short_desc.fr.html | 9
- src/lessons/lander/short_desc.html | 7
- src/lessons/lander/universe/Configurations.scala | 77 ---
- src/lessons/lander/universe/DelegatingLanderWorld.fr.html | 48 -
- src/lessons/lander/universe/DelegatingLanderWorld.html | 44 -
- src/lessons/lander/universe/DelegatingLanderWorld.java | 71 --
- src/lessons/lander/universe/DelegatingLanderWorld.pt_BR.html | 43 -
- src/lessons/lander/universe/Geometry.scala | 47 -
- src/lessons/lander/universe/LanderEntity.scala | 59 --
- src/lessons/lander/universe/LanderWorld.scala | 148 -----
- src/lessons/lander/universe/LanderWorldView.scala | 207 --------
- src/plm/core/lang/JVMCompiledLang.java | 9
- src/plm/core/lang/LangScala.java | 247 ----------
- src/plm/core/model/Game.java | 51 --
- src/plm/core/model/lesson/ExerciseTemplated.java | 4
- src/plm/core/model/lesson/ExerciseTemplatingEntity.java | 19
- src/plm/core/ui/ChooseLessonDialog.java | 2
- src/plm/core/ui/JavaEditorPanel.java | 2
- src/plm/core/ui/editor/MissionEditor.java | 6
- src/plm/test/ExoTest.java | 13
- src/plm/test/LessonTest.java | 10
- src/plm/test/simple/test/AllSimpleExerciseTests.java | 2
- src/plm/test/simple/test/ScalaSimpleExerciseTest.java | 52 --
- src/plm/universe/bat/BatExercise.java | 2
- src/plm/universe/bat/BatTest.java | 16
- 50 files changed, 17 insertions(+), 2104 deletions(-)
-
-Index: b/src/lessons/lander/universe/Configurations.scala
-===================================================================
---- a/src/lessons/lander/universe/Configurations.scala
-+++ /dev/null
-@@ -1,77 +0,0 @@
--package lessons.lander.universe
--
--import plm.universe.World
--
--object Configurations {
-- import NumUtil._
--
-- // helper creation functions
--
-- private case class Terrain(width: Int, height: Int, ground: List[Point])
--
-- private def makeWorld(name: String, terrain: Terrain, position: Point, speed: Point,
-- angle: Double, thrust: Int, fuel: Int) =
-- new DelegatingLanderWorld(name, terrain.width, terrain.height, terrain.ground, position, speed,
-- angle, thrust, fuel)
--
-- // helper geometric functions
--
-- private def angleToSpeed(angle: Double, speed: Double) =
-- radianToVector(gameAngleToRadian(angle)) * speed
--
-- // terrains
--
-- private val SIMPLE_TERRAIN = Terrain(
-- width = 2000,
-- height = 1000,
-- ground = List(Point(0, 100), Point(125, 414), Point(205, 271),
-- Point(348, 597), Point(460, 257), Point(534, 438), Point(637, 160),
-- Point(760, 371), Point(854, 200), Point(1468, 200), Point(1585, 440),
-- Point(1682, 280), Point(1845, 668), Point(2000, 294)))
--
-- private val CHALLENGING_TERRAIN = Terrain(
-- width = 2000,
-- height = 1000,
-- ground = List(Point(0,260), Point(37,160), Point(160,371), Point(254,200),
-- Point(430,200), Point(535,394), Point(639,300), Point(780,300), Point(890,440),
-- Point(1082,280), Point(1245,668), Point(1400,294), Point(1580, 410), Point(1730, 360),
-- Point(1870, 560), Point(2000, 400)))
--
-- // worlds
--
-- val SIMPLE_TERRAIN_TRIVIAL_CONFIG = makeWorld(
-- name = "Simple Terrain, Simple Configuration",
-- terrain = SIMPLE_TERRAIN,
-- position = Point(1200, 700),
-- speed = Point(0, 0),
-- angle = 0.0,
-- thrust = 0,
-- fuel = 3000)
--
-- val CHALLENGING_TERRAIN_SIMPLE_CONFIG = makeWorld(
-- name = "Challenging Terrain, Simple Configuration",
-- terrain = CHALLENGING_TERRAIN,
-- position = Point(530, 600),
-- speed = Point(0, 10),
-- angle = 0,
-- thrust = 4,
-- fuel = 3000)
--
-- val SIMPLE_TERRAIN_CHALLENGING_CONFIG = makeWorld(
-- name = "Simple Terrain, Challenging Configuration",
-- terrain = SIMPLE_TERRAIN,
-- position = Point(500, 500),
-- speed = angleToSpeed(-20, 20),
-- angle = -20,
-- thrust = 3,
-- fuel = 3000)
--
-- val SIMPLE_TERRAIN_HARD_CONFIG = makeWorld(
-- name = "Simple Terrain, Hard Configuration",
-- terrain = SIMPLE_TERRAIN,
-- position = Point(1900, 900),
-- speed = angleToSpeed(90, 80),
-- angle = 90,
-- thrust = 4,
-- fuel = 3000)
--}
-\ No newline at end of file
-Index: b/src/lessons/lander/universe/Geometry.scala
-===================================================================
---- a/src/lessons/lander/universe/Geometry.scala
-+++ /dev/null
-@@ -1,47 +0,0 @@
--package lessons.lander.universe
--
--import Math.PI
--import Math.cos
--import Math.sin
--
--object NumUtil {
-- def clamp(min: Double, max: Double, value: Double): Double = {
-- if (value < min) min else if (value > max) max else value
-- }
-- def clamp(min: Int, max: Int, value: Int): Int = {
-- if (value < min) min else if (value > max) max else value
-- }
--
-- def radianToVector(angle: Double) = Point(cos(angle), sin(angle))
--
-- def gameAngleToRadian(angle: Double) = (angle + 90) * PI / 180
--}
--
--case class Point(x: Double, y: Double) {
-- def +(p: Point): Point = new Point(x + p.x, y + p.y)
-- def -(p: Point): Point = new Point(x - p.x, y - p.y)
-- def *(l: Double): Point = new Point(x * l, y * l)
-- def /(l: Double): Point = new Point(x / l, y / l)
-- def unary_- = this * -1
--
-- def length: Double = Math.sqrt(x * x + y * y)
-- def normed = this / length
-- def dot(p: Point) = x * p.x + y * p.y
-- def cross(p: Point) = x * p.y - y * p.x
--}
--
--case class Segment(start: Point, end: Point)
--
--case class Ray(origin: Point, direction: Point) {
-- def intersects(s: Segment): Boolean = {
-- val v = s.end - s.start
-- val cross = direction.cross(v);
-- if (cross == 0) {
-- false
-- } else {
-- val f1 = (s.start - origin).cross(v) / cross
-- val f2 = (s.start - origin).cross(direction) / cross
-- f1 >= 0 && f2 >= 0 && f2 <= 1
-- }
-- }
--}
-Index: b/src/lessons/lander/universe/LanderEntity.scala
-===================================================================
---- a/src/lessons/lander/universe/LanderEntity.scala
-+++ /dev/null
-@@ -1,59 +0,0 @@
--package lessons.lander.universe
--
--import plm.universe.Entity
--import scala.collection.JavaConversions._
--
--class LanderEntity extends Entity {
--
-- private def landerWorld = getWorld().asInstanceOf[DelegatingLanderWorld].realWorld
--
-- override def command(command: String, out: java.io.BufferedWriter){
--
-- }
--
-- override def run() = {
-- initialize()
-- while (isFlying()) {
-- step()
-- simulateStep()
-- }
-- }
--
-- // methods to be overridden by the player
-- def initialize(): Unit = ()
-- def step(): Unit = ()
--
-- // query terrain2
-- def getGround(): java.util.List[Point] = landerWorld.ground
--
-- // query lander state
-- def getX(): Double = landerWorld.position.x
-- def getY(): Double = landerWorld.position.y
-- def getSpeedX(): Double = landerWorld.speed.x
-- def getSpeedY(): Double = landerWorld.speed.y
-- def getAngle(): Double = landerWorld.angle
-- def getThrust(): Int = landerWorld.thrust
-- def getFuel(): Int = landerWorld.fuel
--
-- def setDesiredAngle(desiredAngle: Double) {
-- landerWorld.desiredAngle = desiredAngle
-- }
-- def setDesiredThrust(desiredThrust: Int) {
-- landerWorld.desiredThrust = desiredThrust
-- }
--
-- /* Internal commands used by the python entities to simulate the above run method */
-- def isFlying(): Boolean = (landerWorld.state == LanderWorld.State.FLYING)
-- def simulateStep() = {
-- landerWorld.simulate(0.1)
-- stepUI()
-- }
--
-- /* BINDINGS TRANSLATION: French */
-- def getSol() = getGround()
-- def getVitesseX(): Double = getSpeedX()
-- def getVitesseY(): Double = getSpeedY()
-- def getPoussee(): Int = getThrust()
-- def setAngleDesire(desiredAngle: Double) = setDesiredAngle(desiredAngle)
-- def setPousseeDesiree(desiredThrust: Int) = setDesiredThrust(desiredThrust)
--}
-Index: b/src/lessons/lander/universe/LanderWorld.scala
-===================================================================
---- a/src/lessons/lander/universe/LanderWorld.scala
-+++ /dev/null
-@@ -1,148 +0,0 @@
--package lessons.lander.universe
--
--import Math.PI
--
--import javax.script.ScriptEngine
--import javax.swing.ImageIcon
--import plm.core.lang.ProgrammingLanguage
--import plm.core.model.Game
--import plm.core.lang.ProgrammingLanguage
--import plm.core.ui.ResourcesCache
--import plm.universe.World
--
--object LanderWorld {
-- object State extends Enumeration {
-- val FLYING, LANDED, CRASHED, OUT = Value
-- }
--
-- private val GRAVITY = Point(0, -1) * 3.711;
--}
--
--class LanderWorld(val parent: DelegatingLanderWorld) {
--
-- import LanderWorld.State._
-- import NumUtil._
--
-- var width: Int = 0
-- var height: Int = 0
-- var ground: List[Point] = null
-- var position: Point = null
-- var speed: Point = null
-- /** Angle in degrees, 0 points north, 90 points west. */
-- var angle: Double = 0
-- var thrust: Int = 0
-- var fuel: Int = 0
-- var state = FLYING
--
-- var desiredAngle: Double = 0
-- var desiredThrust: Int = 0
--
-- parent.setDelay(10)
-- parent.addEntity(new LanderEntity())
--
-- // "inherited" methods
--
-- def getIcon = ResourcesCache.getIcon("img/world_lander.png");
--
-- def setupBindings(lang: ProgrammingLanguage, engine: ScriptEngine) {
-- if (lang.equals(Game.PYTHON)) {
-- engine.put("Segment", Segment.getClass())
-- engine.eval(
-- "def isFlying():\n"+
-- " return entity.isFlying()\n"+
-- "def simulateStep():\n"+
-- " entity.simulateStep()\n"+
-- "def getGround():\n"+
-- " return [ (elm.x(), elm.y()) for elm in entity.getGround() ]\n"+
-- "def getX():\n"+
-- " return entity.getX()\n"+
-- "def getY():\n"+
-- " return entity.getY()\n"+
-- "def getSpeedX():\n"+
-- " return entity.getSpeedX()\n"+
-- "def getSpeedY():\n"+
-- " return entity.getSpeedY()\n"+
-- "def getAngle():\n"+
-- " return entity.getAngle()\n"+
-- "def setDesiredAngle(a):\n"+
-- " entity.setDesiredAngle(a)\n"+
-- "def getThrust():\n"+
-- " return entity.getThrust()\n"+
-- "def setDesiredThrust(t):\n"+
-- " entity.setDesiredThrust(t)\n"+
-- "def getFuel():\n"+
-- " return entity.getFuel()\n"+
-- "")
-- } else {
-- throw new RuntimeException("No binding of LanderWorld for "+lang)
-- }
-- }
--
-- /** Returns true if both worlds have same name and same state. */
-- def winning(target: World): Boolean = state == LANDED
--
-- def diffTo(world: World): String = null
--
-- def reset(initialWorld: LanderWorld): Unit = {
-- width = initialWorld.width
-- height = initialWorld.height
-- ground = initialWorld.ground
-- position = initialWorld.position
-- speed = initialWorld.speed
-- angle = initialWorld.angle
-- thrust = initialWorld.thrust
-- fuel = initialWorld.fuel
-- state = initialWorld.state
-- desiredAngle = angle
-- desiredThrust = thrust
-- }
--
-- def getView() = new LanderWorldView(parent)
--
-- override def toString() = "scala lander world"
--
-- // simulation
--
-- def angleRadian = gameAngleToRadian(angle)
--
-- private def groundSegments = {
-- if (ground.isEmpty) List()
-- else (ground, ground.tail).zipped map (Segment(_, _))
-- }
--
-- private def flatSegments = groundSegments.filter((s) => s.start.y == s.end.y)
--
-- private def touchesSomeFlatSegment(p: Point) = flatSegments
-- .find((s) => p.x > s.start.x && p.x < s.end.x && p.y - s.start.y < 1)
-- .isDefined
--
-- private def isUnderground(p: Point) =
-- groundSegments.filter(new Ray(p, Point(0, 1)).intersects(_)).length % 2 == 1
--
-- def simulate(dt: Double) {
-- if (state == FLYING) {
-- angle = clamp(-90.0 max (angle - 5), 90.0 min (angle + 5), desiredAngle)
-- thrust = clamp(0 max (thrust - 1), 5 min (thrust + 1), desiredThrust) min fuel
-- val force = radianToVector(angleRadian) * thrust + LanderWorld.GRAVITY
-- position = position + speed * dt
-- speed = speed + force * dt
-- fuel = (fuel - thrust) max 0
--
-- lazy val underground = isUnderground(position)
-- lazy val goodConfig = speed.y.abs <= 10 && speed.x.abs <= 5 && (angleRadian - PI/2) < 1e-2
-- lazy val touchesFlat = touchesSomeFlatSegment(position)
-- lazy val outOfWorldX = position.x < 0 || position.x > width
-- lazy val outOfWorldY = position.y < 0 || position.y > height
-- lazy val outOfWorld = outOfWorldX || outOfWorldY
--
-- state =
-- if (underground) {
-- if (goodConfig && touchesFlat) LANDED
-- else CRASHED
-- } else {
-- if (outOfWorld) OUT
-- else FLYING
-- }
-- }
-- }
--}
-Index: b/src/lessons/lander/universe/LanderWorldView.scala
-===================================================================
---- a/src/lessons/lander/universe/LanderWorldView.scala
-+++ /dev/null
-@@ -1,207 +0,0 @@
--package lessons.lander.universe
--
--import plm.core.ui.WorldView
--import plm.universe.World
--import java.awt.Graphics
--import java.awt.Graphics2D
--import java.awt.RenderingHints
--import java.awt.Color
--import java.awt.geom.Rectangle2D
--import java.awt.geom.Line2D
--import java.awt.BasicStroke
--import java.awt.geom.AffineTransform
--import java.awt.geom.GeneralPath
--import java.awt.geom.Path2D
--import Math.PI
--import java.awt.geom.QuadCurve2D
--import scala.util.Random
--import java.awt.Font
--import java.awt.event.MouseListener
--import java.awt.event.MouseMotionListener
--import java.awt.event.MouseMotionAdapter
--import java.awt.event.MouseEvent
--import java.awt.event.MouseAdapter
--import java.awt.geom.Point2D
--
--object LanderWorldView {
-- private val LANDER_SHAPE = List(
-- List(Point(-2, 3), Point(-3, 4), Point(-3, 7), Point(-2, 8), Point(2, 8), Point(3, 7),
-- Point(3, 4), Point(2, 3), Point(-2, 3)),
-- List(Point(-6, 0), Point(-4, 0)),
-- List(Point(6, 0), Point(4, 0)),
-- List(Point(-5, 0), Point(-4, 2.8), Point(-2, 3)),
-- List(Point(5, 0), Point(4, 2.8), Point(2, 3)))
--
-- private val EXPLOSION_SHAPE = List(
-- Point(-4, 3), Point(-1, 2), Point(0, 4), Point(1, 2), Point(4, 2), Point(2, 0),
-- Point(3, -2), Point(0, -1), Point(-3, -3), Point(-2, 0), Point(-4, 3))
--}
--
--class LanderWorldView(delagatingWorld: DelegatingLanderWorld) extends WorldView(delagatingWorld) {
--
-- import LanderWorld.State._
--
-- private def realWorld = world.asInstanceOf[DelegatingLanderWorld].realWorld
--
-- private var mouseIn : Boolean = false
-- private var mousePos : Point = Point(0, 0)
--
-- addMouseListener(new MouseAdapter() {
-- override def mouseEntered(e: MouseEvent) {
-- mouseIn = true
-- }
-- override def mouseExited(e: MouseEvent) {
-- mouseIn = false
-- repaint()
-- }
-- })
--
-- addMouseMotionListener(new MouseMotionAdapter() {
-- override def mouseMoved(event: MouseEvent) = {
-- mousePos = Point(event.getX, event.getY)
-- repaint()
-- }
-- })
--
-- override def paintComponent(g: Graphics) = {
-- super.paintComponent(g);
-- val g2 = g.asInstanceOf[Graphics2D];
-- new Painter(g2).paint()
-- }
--
-- private class Painter(g2: Graphics2D) {
-- def paint() {
-- val initialTransform = g2.getTransform()
-- setupRendering()
-- clearWidgetBackground()
-- setupGlobalTransform()
-- clearWorldBackground()
-- drawGround()
-- drawStats(initialTransform)
-- realWorld.state match {
-- case FLYING => drawLander(drawFlame = true)
-- case LANDED => drawLander(drawFlame = false)
-- case OUT => drawQuestionMarks()
-- case CRASHED => drawExplosion()
-- }
-- }
--
-- def setupRendering() {
-- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
-- }
--
-- def clearWidgetBackground() = {
-- g2.setColor(Color.gray)
-- g2.fill(new Rectangle2D.Double(0, 0, getWidth, getHeight))
-- }
--
-- def setupGlobalTransform() = {
-- val scale = (getWidth.toDouble / realWorld.width) min (getHeight.toDouble / realWorld.height)
-- val translateX = (getWidth - realWorld.width * scale) / 2
-- val translateY = (getHeight + realWorld.height * scale) / 2
-- g2.translate(translateX, translateY)
-- g2.scale(scale, -scale)
-- }
--
-- def clearWorldBackground() = {
-- g2.setColor(Color.black);
-- g2.fill(new Rectangle2D.Double(0, 0, realWorld.width, realWorld.height));
-- }
--
-- /** Sets the line width to 1px no matter the transform, and the color to white. */
-- def resetPen() {
-- val transform = g2.getTransform();
-- val scale = (transform.getScaleX() min transform.getScaleY()).abs;
-- g2.setStroke(new BasicStroke((1 / scale).toFloat))
-- g2.setColor(Color.white)
-- }
--
-- def drawPath(path: List[Point], fill: Boolean) {
-- if (!path.isEmpty) {
-- val polyLine = new GeneralPath(Path2D.WIND_EVEN_ODD, path.length)
-- polyLine.moveTo(path.head.x, path.head.y)
-- for (point <- path.tail) {
-- polyLine.lineTo(point.x, point.y)
-- }
-- if (fill) {
-- g2.fill(polyLine)
-- } else {
-- g2.draw(polyLine)
-- }
-- }
-- }
--
-- def drawText(text: String, x: Double, y: Double) {
-- val oldTransform = g2.getTransform()
-- g2.translate(x, y)
-- g2.scale(1, -1)
-- g2.drawString(text, 0, 0)
-- g2.setTransform(oldTransform)
-- }
--
-- def drawGround() = {
-- resetPen()
-- drawPath(realWorld.ground, fill = false)
-- }
--
-- def randomScaleFactor() = 1 + Random.nextDouble() * 0.2
--
-- def drawLander(drawFlame: Boolean) = {
-- val oldTransform = g2.getTransform()
-- g2.translate(realWorld.position.x, realWorld.position.y)
-- g2.scale(6, 6) // the lander shape is small
-- resetPen()
-- g2.rotate(realWorld.angleRadian - PI/2)
-- LanderWorldView.LANDER_SHAPE.foreach(drawPath(_, fill = false))
-- val thrust = realWorld.thrust
-- if (drawFlame && thrust > 0) {
-- val controlX = (0.4 + thrust * 0.1) * randomScaleFactor()
-- val endY = (-2 * thrust) * randomScaleFactor()
-- val controlY = (endY + 3) / 2
-- g2.draw(new QuadCurve2D.Double(-0.25, 3, -controlX, controlY, 0, endY))
-- g2.draw(new QuadCurve2D.Double(0.25, 3, controlX, controlY, 0, endY))
-- }
-- g2.setTransform(oldTransform)
-- }
--
-- def drawExplosion() = {
-- val oldTransform = g2.getTransform()
-- g2.translate(realWorld.position.x, realWorld.position.y)
-- g2.scale(15, 15) // the explosion shape is small
-- resetPen()
-- drawPath(LanderWorldView.EXPLOSION_SHAPE, fill = true)
-- g2.setTransform(oldTransform)
-- }
--
-- def drawQuestionMarks() = {
-- val x = realWorld.position.x
-- val y = realWorld.position.y
-- val textX = if (x >= realWorld.width) realWorld.width - 100 else if (x <= 0) 5 else x
-- val textY = if (y >= realWorld.height) realWorld.height - 40 else if (y <= 0) 5 else y - 30
-- g2.setColor(Color.WHITE)
-- g2.setFont(new Font(Font.MONOSPACED, Font.BOLD, 40))
-- drawText("???", textX, textY)
-- }
--
-- def drawStats(initialTransform: AffineTransform) {
-- g2.setColor(Color.LIGHT_GRAY)
-- g2.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 30))
-- drawText(f"x: ${realWorld.position.x}%.2f", 5, realWorld.height - 30)
-- drawText(f"y: ${realWorld.position.y}%.2f", 5, realWorld.height - 2 * 30)
-- drawText(f"speed x: ${realWorld.speed.x}%.2f", 5, realWorld.height - 3 * 30)
-- drawText(f"speed y: ${realWorld.speed.y}%.2f", 5, realWorld.height - 4 * 30)
-- drawText(f"angle: ${realWorld.angle}%.2f°", 5, realWorld.height - 5 * 30)
-- drawText(f"thrust: ${realWorld.thrust}", 5, realWorld.height - 6 * 30)
-- drawText(f"fuel: ${realWorld.fuel}", 5, realWorld.height - 7 * 30)
--
-- if (mouseIn) {
-- val deltaTransform = new AffineTransform(g2.getTransform())
-- deltaTransform.invert()
-- deltaTransform.concatenate(initialTransform)
-- val coord = deltaTransform.transform(new Point2D.Double(mousePos.x, mousePos.y), null)
-- drawText(f"x: ${coord.getX.round}", realWorld.width - 130, realWorld.height - 30)
-- drawText(f"y: ${coord.getY.round}", realWorld.width - 130, realWorld.height - 2 * 30)
-- }
-- }
-- }
--}
-Index: b/src/lessons/lander/Main.fr.html
-===================================================================
---- a/src/lessons/lander/Main.fr.html
-+++ /dev/null
-@@ -1,23 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Alunisseur</h1>
--
--<p>Dans cette leçon, vous pilotez un alunisseur dans des situations de plus en
--plus complexes.</p>
--
--<p>À chaque pas de la simulation, le joueur donne des commandes contrôlant
--l'angle et la poussée du module d'alunissage.</p>
--
--<p>Idées d'exercices à ajouter à la progression proposée :</p>
--<ul>
-- <li>Un alunisseur en position verticale au dessus d'un sol plat. Le joueur ne
--peut régler que la poussée (c'est fait).</li>
-- <li>Un alunisseur en position verticale pas au dessus d'un sol plat. Le joueur
--peut régler la poussée et l'angle (c'est fait).</li>
-- <li>Un alunisseur avec un angle et une vitesse difficile, pas au dessus d'un sol
--plat. Le joueur contrôle la poussée et l'angle.</li>
-- <li>Un alunisseur avec un angle et une vitesse difficile, pas au dessus d'un sol
--plat dans une configuration difficile. Le joueur contrôle la poussée et
--l'angle.</li>
-- <li>La même chose avec du vent ?</li>
--</ul>
-Index: b/src/lessons/lander/Main.html
-===================================================================
---- a/src/lessons/lander/Main.html
-+++ /dev/null
-@@ -1,21 +0,0 @@
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Lunar Lander</h1>
--
--<p>In this lesson you pilot a lunar landing module in increasingly complex
--situations.</p>
--
--<p>At each step of the simulation, the player issues a command controlling how
--much the angle and thrust of the lander should change</p>
--
--<p>Ideas concerning the progression of exercises:</p>
--<ul>
-- <li>A lander in vertical position above flat ground, the player can only
--control thrust (done)</li>
-- <li>A lander in vertical position not above flat ground, the player control
--thrust and angle (done)</li>
-- <li>A lander with difficult angle and speed not above flat ground, the
--player control thrust and angle</li>
-- <li>A lander with difficult angle and speed not above flat ground, with
--difficult ground, the player control thrust and angle</li>
-- <li>Same with wind?</li>
--</ul>
-Index: b/src/lessons/lander/Main.scala
-===================================================================
---- a/src/lessons/lander/Main.scala
-+++ /dev/null
-@@ -1,14 +0,0 @@
--package lessons.lander
--
--import plm.core.model.lesson.Lesson
--import lessons.lander.lvl1_lander_101.Lander101
--import lessons.lander.lvl2_locate_landing_zone.LocateLandingZone
--import lessons.lander.lvl3_fly_the_lander.FlyTheLander
--
--class Main extends Lesson {
-- override def loadExercises = {
-- addExercise(new Lander101(this));
-- addExercise(new LocateLandingZone(this));
-- addExercise(new FlyTheLander(this));
-- }
--}
-Index: b/src/lessons/lander/icon.svg
-===================================================================
---- a/src/lessons/lander/icon.svg
-+++ /dev/null
-@@ -1,104 +0,0 @@
--<?xml version="1.0" encoding="UTF-8" standalone="no"?>
--<!-- Created with Inkscape (http://www.inkscape.org/) -->
--
--<svg
-- xmlns:dc="http://purl.org/dc/elements/1.1/"
-- xmlns:cc="http://creativecommons.org/ns#"
-- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-- xmlns:svg="http://www.w3.org/2000/svg"
-- xmlns="http://www.w3.org/2000/svg"
-- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-- width="64"
-- height="64"
-- id="svg2"
-- version="1.1"
-- inkscape:version="0.48.4 r9939"
-- sodipodi:docname="lander.svg"
-- inkscape:export-filename="/home/polux/projects/PLM/src/lessons/lander/lander.png"
-- inkscape:export-xdpi="90"
-- inkscape:export-ydpi="90">
-- <defs
-- id="defs4" />
-- <sodipodi:namedview
-- id="base"
-- pagecolor="#ffffff"
-- bordercolor="#666666"
-- borderopacity="1.0"
-- inkscape:pageopacity="0.0"
-- inkscape:pageshadow="2"
-- inkscape:zoom="7.9195959"
-- inkscape:cx="29.558295"
-- inkscape:cy="29.181329"
-- inkscape:document-units="px"
-- inkscape:current-layer="layer1"
-- showgrid="true"
-- inkscape:window-width="1600"
-- inkscape:window-height="883"
-- inkscape:window-x="0"
-- inkscape:window-y="17"
-- inkscape:window-maximized="0">
-- <inkscape:grid
-- type="xygrid"
-- id="grid2985"
-- empspacing="5"
-- visible="true"
-- enabled="true"
-- snapvisiblegridlinesonly="true" />
-- </sodipodi:namedview>
-- <metadata
-- id="metadata7">
-- <rdf:RDF>
-- <cc:Work
-- rdf:about="">
-- <dc:format>image/svg+xml</dc:format>
-- <dc:type
-- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-- <dc:title></dc:title>
-- </cc:Work>
-- </rdf:RDF>
-- </metadata>
-- <g
-- inkscape:label="Layer 1"
-- inkscape:groupmode="layer"
-- id="layer1"
-- transform="translate(0,-988.36215)">
-- <g
-- id="g3008"
-- transform="translate(2,8)">
-- <path
-- sodipodi:nodetypes="ccccccccc"
-- transform="translate(0,988.36215)"
-- inkscape:connector-curvature="0"
-- id="path2987"
-- d="m 20,4 20,0 5,5 0,15 -5,5 -20,0 -5,-5 0,-15 z"
-- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-- <path
-- sodipodi:nodetypes="ccc"
-- transform="translate(0,988.36215)"
-- inkscape:connector-curvature="0"
-- id="path2989"
-- d="M 20,29 10,30 5,44"
-- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-- <path
-- sodipodi:nodetypes="ccc"
-- transform="translate(0,988.36215)"
-- inkscape:connector-curvature="0"
-- id="path2993"
-- d="m 40,29 10,1 5,14"
-- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-- <path
-- transform="translate(0,988.36215)"
-- inkscape:connector-curvature="0"
-- id="path3004"
-- d="m 0,44 10,0"
-- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-- <path
-- transform="translate(0,988.36215)"
-- inkscape:connector-curvature="0"
-- id="path3006"
-- d="m 50,44 10,0"
-- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-- </g>
-- </g>
--</svg>
-Index: b/src/lessons/lander/lvl1_lander_101/Lander101.fr.html
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/Lander101.fr.html
-+++ /dev/null
-@@ -1,49 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Se poser pour les nuls</h1>
--
--<p>Bravo ! Vous avez gagné dans une boîte de céréales un voyage (aller simple)
--pour Mars. La NASA vous a même fourni un module d'excursion lunaire pour
--l'occasion, et c'est donc avec ce véhicule que vous voyagerez.</p>
--
--<p>Avant le décollage, vous devez vous entraîner sur simulateur aux bases de
--l'alunissage. Si tout se passe comme prévu, vous ne devriez pas avoir à
--voler en mode manuel, mais mieux vaut prévenir que guérir, comme ils disent.</p>
--
--<p>Votre mission est de <b>poser le module avec une vitesse verticale
--inférieure à 10 m/s</b>. Il y a deux façons d'influer sur la trajectoire du
--module : en modifiant son angle, ou en réglant la poussée de son
--moteur. Dans cette simulation, nous ne nous intéressons qu'à la poussée,
--exprimée en m/s².</p>
--
--<p>Vous devez écrire le [!python]corps de la fonction <code>step()</code>, qui
--sera appelée[/!][!scala|java|c]code qui sera appellé[/!] tous les dixièmes
--de seconde pendant la simulation. Il faut ajuster la poussée du moteur en
--utilisant la fonction <code>[!java]void [/!]setPousseeDesiree([!java]int
--[/!]poussee[!scala]:Integer[/!])</code> où <code>poussee</code> est un
--entier entre 0 et 4 (représentant une poussée entre 0 m/s² et 4 m/s²). Vous
--ne pouvez incrémenter ou décrémenter la poussée que de 1 entre deux pas de
--la simulation. Ainsi, si la poussée du moteur est actuellement de 2 et que
--vous demandez 4, vous n'aurez que 3 à la prochaine étape. Si vous demandez
--une valeur inférieure à 0 (ou supérieure à 4), tout se passera comme si vous
--aviez demandé 0 (ou 4).</p>
--
--<p>Afin de prendre des décisions informées, vous pouvez demander des
--informations sur l'état actuel du module. Dans cette simulation, vous ne
--serez probablement intéressé que par sa position verticale (accessible grâce
--à <code>[!java]double [/!]getY()[!scala]:Double[/!]</code>) et sa vitesse
--verticale (accessible grâce à <code>[!java]double
--[/!]getVitesseY()[!scala]:Double[/!]</code>). Vous pouvez également demander
--la poussée actuelle du moteur (avec <code>[!java]int
--[/!]getPoussee()[!scala]:Integer[/!]</code>) si vous avez oublié ce que vous
--avez demandé. Rappelez vous que la gravité martienne est de 3.711 m/s², cela
--peut vous être utile.</p>
--
--<p>Une dernière chose : le module est plutôt petit, et vous n'avez pas tant de
--carburant que cela. À chaque pas de simulation, il consomme autant d'unité
--de carburant que la poussée actuelle du moteur. Si vous tombez en panne
--sèche, vous serez en chute libre alors attention ! Vous pouvez consulter le
--niveau du réservoir avec <code>[!java]int
--[/!]getFuel()[!scala]:Integer[/!]</code>.</p>
--
--<p>Bon courage !</p>
-Index: b/src/lessons/lander/lvl1_lander_101/Lander101.html
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/Lander101.html
-+++ /dev/null
-@@ -1,41 +0,0 @@
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Lander 101</h1>
--
--<p>Congratulations! You won a (one-way) trip to Mars in a cereal box. NASA was
--kind enough to donate the Lunar Excursion Module for this mission, so
--that's what you'll be flying.</p>
--
--<p>Before you take off, you must go through some basic landing simulation. You
--shouldn't have to fly the lander if all goes as planned but, as they say,
--"better safe than sorry".</p>
--
--<p>Your mission is to <b>land the lander with a vertical speed of at most 10
--m/s.</b> There are two ways you can influence the lander's course: by adjusting
--its angle or by adjusting its thrust. In this simulation we only care about
--adjusting the thrust, expressed in m/s².</p>
--
--<p>The [!python]<code>step()</code> function[/!][!scala|java|c]code[/!] that you
--should write now will be called every 0.1 second during the simulation. It should
--set the desired thrust of the next simulation step, by calling
--<code>[!java]void [/!]setDesiredThrust([!java]int [/!]desiredThrust[!scala]:Integer[/!])</code>
--where <code>desiredThrust</code> is some integer between 0 and 4 (that is, a thrust
--between 0 m/s² and 4 m/s²). You can only increment or decrement the thrust by 1
--between two simulation steps, so if the current thrust is 2 and you ask for 4,
--you'll only get 3 in the next step. If you ask for less than 0 (resp. more than 4),
--everything will be as if you had asked for 0 (resp. 4).</p>
--
--<p>In order to take informed decisions, you can query the lander's state. In
--this simulation you'll probably be interested in its vertical position:
--<code>[!java]double [/!]getY()[!scala]:Double[/!]</code>, and its vertical speed:
--<code>[!java]double [/!]getSpeedY()[!scala]:Double[/!]</code>. You can also ask for
--the thrust via <code>[!java]int [/!]getThrust()[!scala]:Integer[/!]</code> in case
--you don't remember what you asked for. Remember that Mars' gravity is 3.711 m/s²,
--it might come in handy.</p>
--
--<p>One last thing: the lander is pretty small so you don't have much fuel. At
--each step of the simulation the lander consumes as many fuel units as the
--current thrust. Once you run out of fuel you're in free fall so beware! You can
--consult the remaining amount of available fuel units using
--<code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.</p>
--
--<p>Good luck!</p>
-Index: b/src/lessons/lander/lvl1_lander_101/Lander101.it.html
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/Lander101.it.html
-+++ /dev/null
-@@ -1,45 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Lander 101</h1>
--
--<p>Congratulations! You won a (one-way) trip to Mars in a cereal box. NASA was
--kind enough to donate the Lunar Excursion Module for this mission, so that's
--what you'll be flying.</p>
--
--<p>Before you take off, you must go through some basic landing simulation. You
--shouldn't have to fly the lander if all goes as planned but, as they say,
--"better safe than sorry".</p>
--
--<p>Your mission is to <b>land the lander with a vertical speed of at most 10
--m/s.</b> There are two ways you can influence the lander's course: by
--adjusting its angle or by adjusting its thrust. In this simulation we only
--care about adjusting the thrust, expressed in m/s².</p>
--
--<p>The [!python]<code>step()</code> function[/!][!scala|java|c]code[/!] that
--you should write now will be called every 0.1 second during the
--simulation. It should set the desired thrust of the next simulation step, by
--calling <code>[!java]void [/!]setDesiredThrust([!java]int
--[/!]desiredThrust[!scala]:Integer[/!])</code> where
--<code>desiredThrust</code> is some integer between 0 and 4 (that is, a
--thrust between 0 m/s² and 4 m/s²). You can only increment or decrement the
--thrust by 1 between two simulation steps, so if the current thrust is 2 and
--you ask for 4, you'll only get 3 in the next step. If you ask for less than
--0 (resp. more than 4), everything will be as if you had asked for 0
--(resp. 4).</p>
--
--<p>In order to take informed decisions, you can query the lander's state. In
--this simulation you'll probably be interested in its vertical position:
--<code>[!java]double [/!]getY()[!scala]:Double[/!]</code>, and its vertical
--speed: <code>[!java]double [/!]getSpeedY()[!scala]:Double[/!]</code>. You
--can also ask for the thrust via <code>[!java]int
--[/!]getThrust()[!scala]:Integer[/!]</code> in case you don't remember what
--you asked for. Remember that Mars' gravity is 3.711 m/s², it might come in
--handy.</p>
--
--<p>One last thing: the lander is pretty small so you don't have much fuel. At
--each step of the simulation the lander consumes as many fuel units as the
--current thrust. Once you run out of fuel you're in free fall so beware! You
--can consult the remaining amount of available fuel units using
--<code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.</p>
--
--<p>Buona fortuna!</p>
-Index: b/src/lessons/lander/lvl1_lander_101/Lander101.pt_BR.html
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/Lander101.pt_BR.html
-+++ /dev/null
-@@ -1,45 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Lander 101</h1>
--
--<p>Congratulations! You won a (one-way) trip to Mars in a cereal box. NASA was
--kind enough to donate the Lunar Excursion Module for this mission, so that's
--what you'll be flying.</p>
--
--<p>Before you take off, you must go through some basic landing simulation. You
--shouldn't have to fly the lander if all goes as planned but, as they say,
--"better safe than sorry".</p>
--
--<p>Your mission is to <b>land the lander with a vertical speed of at most 10
--m/s.</b> There are two ways you can influence the lander's course: by
--adjusting its angle or by adjusting its thrust. In this simulation we only
--care about adjusting the thrust, expressed in m/s².</p>
--
--<p>The [!python]<code>step()</code> function[/!][!scala|java|c]code[/!] that
--you should write now will be called every 0.1 second during the
--simulation. It should set the desired thrust of the next simulation step, by
--calling <code>[!java]void [/!]setDesiredThrust([!java]int
--[/!]desiredThrust[!scala]:Integer[/!])</code> where
--<code>desiredThrust</code> is some integer between 0 and 4 (that is, a
--thrust between 0 m/s² and 4 m/s²). You can only increment or decrement the
--thrust by 1 between two simulation steps, so if the current thrust is 2 and
--you ask for 4, you'll only get 3 in the next step. If you ask for less than
--0 (resp. more than 4), everything will be as if you had asked for 0
--(resp. 4).</p>
--
--<p>In order to take informed decisions, you can query the lander's state. In
--this simulation you'll probably be interested in its vertical position:
--<code>[!java]double [/!]getY()[!scala]:Double[/!]</code>, and its vertical
--speed: <code>[!java]double [/!]getSpeedY()[!scala]:Double[/!]</code>. You
--can also ask for the thrust via <code>[!java]int
--[/!]getThrust()[!scala]:Integer[/!]</code> in case you don't remember what
--you asked for. Remember that Mars' gravity is 3.711 m/s², it might come in
--handy.</p>
--
--<p>One last thing: the lander is pretty small so you don't have much fuel. At
--each step of the simulation the lander consumes as many fuel units as the
--current thrust. Once you run out of fuel you're in free fall so beware! You
--can consult the remaining amount of available fuel units using
--<code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.</p>
--
--<p>Boa Sorte!</p>
-Index: b/src/lessons/lander/lvl1_lander_101/Lander101.scala
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/Lander101.scala
-+++ /dev/null
-@@ -1,17 +0,0 @@
--package lessons.lander.lvl1_lander_101
--
--import plm.core.model.lesson.ExerciseTemplated
--import plm.core.model.lesson.Lesson
--import lessons.lander.universe.DelegatingLanderWorld
--import lessons.lander.universe.Point
--import lessons.lander.universe.LanderEntity
--import lessons.lander.universe.Configurations._
--import Math.PI
--import scala.collection.JavaConversions._
--import lessons.lander.universe.LanderWorld
--import plm.universe.World
--
--class Lander101(lesson: Lesson) extends ExerciseTemplated(lesson, null) {
-- tabName = "Lander"
-- setup(SIMPLE_TERRAIN_TRIVIAL_CONFIG)
--}
-Index: b/src/lessons/lander/lvl1_lander_101/Lander101Entity.java
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/Lander101Entity.java
-+++ /dev/null
-@@ -1,14 +0,0 @@
--package lessons.lander.lvl1_lander_101;
--
--import lessons.lander.universe.LanderEntity;
--
--public class Lander101Entity extends LanderEntity {
-- @Override
-- public void step() {
-- /* BEGIN TEMPLATE */
-- /* BEGIN SOLUTION */
-- setDesiredThrust(getSpeedY() < -9 ? 4 : 3);
-- /* END SOLUTION */
-- /* END TEMPLATE */
-- }
--}
-Index: b/src/lessons/lander/lvl1_lander_101/Lander101Entity.py
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/Lander101Entity.py
-+++ /dev/null
-@@ -1,13 +0,0 @@
--# BEGIN TEMPLATE
--def step():
--# BEGIN SOLUTION
-- if getSpeedY() < -9:
-- setDesiredThrust(4)
-- else:
-- setDesiredThrust(3)
--# END SOLUTION
--# END TEMPLATE
--
--while isFlying():
-- step()
-- simulateStep()
-Index: b/src/lessons/lander/lvl1_lander_101/ScalaLander101Entity.scala
-===================================================================
---- a/src/lessons/lander/lvl1_lander_101/ScalaLander101Entity.scala
-+++ /dev/null
-@@ -1,17 +0,0 @@
--package lessons.lander.lvl1_lander_101;
--
--import lessons.lander.universe._;
--
--class ScalaLander101Entity extends LanderEntity {
-- override def step() {
-- /* BEGIN TEMPLATE */
-- /* BEGIN SOLUTION */
-- if (getSpeedY() < -9) {
-- setDesiredThrust(4)
-- } else {
-- setDesiredThrust(3);
-- }
-- /* END SOLUTION */
-- /* END TEMPLATE */
-- }
--}
-Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.fr.html
-===================================================================
---- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.fr.html
-+++ /dev/null
-@@ -1,39 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h2>Repérer une zone plate</h2>
--
--<p>Après 200 jours de voyage intersidéral à manger des céréales, vous êtes
--enfin parvenu à la planète rouge. Il est enfin temps de se poser !</p>
--
--<p>Le module est en pilote automatique, et vous n'avez qu'à regarder autour de
--vous pour sélectionner une zone d'alunissage. Vous devez vous poser sur
--<b>une zone plate</b> si vous ne voulez pas vous scratcher. Vous indiquez au
--pilote automatique où se poser en modifiant la fonction
--<code>getLandingZone</code> de façon à ce qu'elle retourne [!java|scala]un
--Segment représentant la zone de votre choix.
--
--<p>Un Segment est composé de deux <code>Point</code>s, chacun composé de deux
--doubles. On construit un nouveau segment de la façon suivante :
--<code>Segment([!java]Point [/!]debut[!scala]:Point[/!], [!java]Point
--[/!]fin[!scala]:Point[/!])</code>. Pour créer de nouveaux points, il faut
--utiliser le constructeur <code>Point([!java]double [/!]x[!scala]:Double[/!],
--[!java]double [/!]y[!scala]:Double[/!])</code>. Les coordonnées d'un point
--sont accessibles grâce à ses méthodes <code>[!java]double
--[/!]x()[!scala]:Double[/!]</code> et <code>[!java]double
--[/!]y()[!scala]:Double[/!]</code>.</p>[/!] [!python]tuple de deux coordonnées X délimitant la zone de votre
--choix.[/!]
--
--<p>Pour déterminer la zone cible, vous devez appeler
--<code>[!java]List<Point> [/!]getSol()[!scala]:List[Point][/!]</code>,
--qui retourne les points qui composent la surface sous la forme d'une list de
--[!java|scala]<code>Point</code>[/!] [!python]tuples (x,y)[/!].</p>
--
--<p>Une dernière chose : votre fonction doit retourner une zone valide dans
--toutes les situations, pas seulement celle que l'on voit en ce moment. C'est
--que votre code sera utilisé dans ce cas, mais également dans la
--configuration que nous avions dans l'exercice précédent. Comme d'habitude,
--vous pouvez voir les autres mondes en les sélectionnant dans le combobox au
--dessus de la vue du monde.</p>
--
--<p>Bon alunissage ! N'oubliez pas de mettre votre combinaison spatiale en
--sortant.</p>
-Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.html
-===================================================================
---- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.html
-+++ /dev/null
-@@ -1,34 +0,0 @@
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h2>Locate a Landing Zone</h2>
--
--<p>After 200 days of traveling space and eating cereals you finally reach
--Mars. Time to land at last!</p>
--
--<p>The lander is on autopilot and all you have to do is look around and tell it
--where to land. The lander must <b>land on a flat zone</b> it you want to remain
--in one piece. You indicate the lander where to land by modifying the
--<code>getLandingZone</code> function so that it returns a
--[!java|scala]<code>Segment</code> representing the zone of your choice.
--
--<p>A segment is composed of two <code>Point</code>s, each of them composed of
--two <code>double</code>s. A segment is built via the
--<code>Segment([!java]Point [/!]start[!scala]:Point[/!], [!java]Point [/!]end[!scala]:Point[/!])</code> constructor.
--A point is built via the <code>Point([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</code> constructor. A point's coordinates are accessible via its
--<code>[!java]double [/!]x()[!scala]:Double[/!]</code> and
--<code>[!java]double [/!]y()[!scala]:Double[/!]</code> methods.</p>[/!]
--
--[!python]tuple of two X coordinates representing the zone of your choice.[/!]
--
--<p>In order to determine which zone to return, you'll need to call
--<code>[!java]List<Point> [/!]getGround()[!scala]List[Point][/!]</code>, which returns
--the vertices of the ground's profile as a list of
--[!java|scala]<code>Point</code>[/!] [!python]tuples (x,y)[/!].</p>
--
--<p>One more thing: your function should return a valid flat zone in any kind of
--situation, not just for the currently visualized one. That's because it will
--be not only tested against that world, but also against the one we had in the
--previous exercise. As usual, you can see the other existing worlds with the
--appropriate combobox.</p>
--
--<p>Have a safe landing! Don't forget to put on your space suit on your way
--out.</p>
-Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.scala
-===================================================================
---- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.scala
-+++ /dev/null
-@@ -1,19 +0,0 @@
--package lessons.lander.lvl2_locate_landing_zone
--
--import plm.core.model.lesson.ExerciseTemplated
--import plm.core.model.lesson.Lesson
--import lessons.lander.universe.DelegatingLanderWorld
--import lessons.lander.universe.Point
--import lessons.lander.universe.LanderEntity
--import lessons.lander.universe.Configurations._
--import Math.PI
--import scala.collection.JavaConversions._
--import lessons.lander.universe.LanderWorld
--import plm.universe.World
--
--class LocateLandingZone(lesson: Lesson) extends ExerciseTemplated(lesson, null) {
-- tabName = "Lander"
-- setup(Array(
-- CHALLENGING_TERRAIN_SIMPLE_CONFIG,
-- SIMPLE_TERRAIN_TRIVIAL_CONFIG))
--}
-Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.java
-===================================================================
---- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.java
-+++ /dev/null
-@@ -1,57 +0,0 @@
--package lessons.lander.lvl2_locate_landing_zone;
--
--import java.util.Iterator;
--
--import lessons.lander.universe.LanderEntity;
--import lessons.lander.universe.Point;
--import lessons.lander.universe.Segment;
--
--public class LocateLandingZoneEntity extends LanderEntity {
-- /* BEGIN TEMPLATE */
-- public Segment getLandingZone() {
-- /* return new Segment(new Point(0,0), new Point(0,0)); */
-- /* BEGIN SOLUTION */
-- Iterator<Point> ground = getGround().iterator();
-- Point lastPoint = ground.next();
-- while (ground.hasNext()) {
-- Point point = ground.next();
-- if (lastPoint.y() == point.y()) {
-- return new Segment(lastPoint, point);
-- }
-- lastPoint = point;
-- }
-- return null;
-- /* END SOLUTION */
-- }
-- /* END TEMPLATE */
--
-- /* BEGIN HIDDEN */
-- double targetStart = 0;
-- double targetEnd = 0;
--
-- @Override
-- public void initialize() {
-- Segment landingZone = getLandingZone();
-- targetStart = landingZone.start().x();
-- targetEnd = landingZone.end().x();
-- }
--
-- @Override
-- public void step() {
-- if (getX() < targetStart) {
-- setDesiredAngle(-30);
-- } else if (getX() > targetEnd) {
-- setDesiredAngle(30);
-- } else {
-- if (getSpeedX() > 5) {
-- setDesiredAngle(25);
-- } else if (getSpeedX() < -5) {
-- setDesiredAngle(-25);
-- } else {
-- setDesiredAngle(0);
-- }
-- }
-- setDesiredThrust(getSpeedY() < -9 ? 4 : 3);
-- }
-- /* END HIDDEN */
--}
-Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.py
-===================================================================
---- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.py
-+++ /dev/null
-@@ -1,43 +0,0 @@
--# BEGIN TEMPLATE
--def getLandingZone():
-- # BEGIN SOLUTION
-- lastPoint = getGround()[0]
-- for point in getGround():
-- if (point != lastPoint):
-- if lastPoint[1] == point[1]:
-- return (lastPoint[0],point[0])
-- lastPoint = point
-- # END SOLUTION
--# END TEMPLATE
--
--targetStart = 0;
--targetEnd = 0;
--
--def initialize():
-- global targetStart
-- global targetEnd
-- (targetStart, targetEnd) = getLandingZone()
-- if (targetStart > targetEnd):
-- print ("Your starting point is after your ending point ("+str(targetStart)+">"+str(targetEnd)+"). Bad things will happen")
--
--def step():
-- if (getX() < targetStart):
-- setDesiredAngle(-30)
-- elif (getX() > targetEnd):
-- setDesiredAngle(30)
-- elif (getSpeedX() > 5):
-- setDesiredAngle(25)
-- elif (getSpeedX() < -5):
-- setDesiredAngle(-25)
-- else:
-- setDesiredAngle(0);
--
-- if (getSpeedY() <-9):
-- setDesiredThrust(4)
-- else:
-- setDesiredThrust(3)
--
--initialize()
--while isFlying():
-- step()
-- simulateStep()
-Index: b/src/lessons/lander/lvl2_locate_landing_zone/ScalaLocateLandingZoneEntity.scala
-===================================================================
---- a/src/lessons/lander/lvl2_locate_landing_zone/ScalaLocateLandingZoneEntity.scala
-+++ /dev/null
-@@ -1,54 +0,0 @@
--package lessons.lander.lvl2_locate_landing_zone;
--
--import java.util.Iterator;
--import scala.collection.JavaConversions._
--
--import lessons.lander.universe._;
--
--class ScalaLocateLandingZoneEntity extends LanderEntity {
-- /* BEGIN TEMPLATE */
-- def getLandingZone():Segment = {
-- /* BEGIN SOLUTION */
-- var lastPoint:Point = getGround.get(0);
-- for (point <- getGround()) {
-- if (point != lastPoint) { // Avoid the loop when point is on the first element
-- if (point.y == lastPoint.y)
-- return new Segment(lastPoint,point)
-- }
-- lastPoint = point
-- }
-- return null;
-- /* END SOLUTION */
-- }
-- /* END TEMPLATE */
--
-- var targetStart = 0.0;
-- var targetEnd = 0.0;
--
-- override def initialize() {
-- var landingZone = getLandingZone();
-- targetStart = landingZone.start.x;
-- targetEnd = landingZone.end.x;
-- }
--
-- override def step() {
-- if (getX() < targetStart) {
-- setDesiredAngle(-30);
-- } else if (getX() > targetEnd) {
-- setDesiredAngle(30);
-- } else {
-- if (getSpeedX() > 5) {
-- setDesiredAngle(25);
-- } else if (getSpeedX() < -5) {
-- setDesiredAngle(-25);
-- } else {
-- setDesiredAngle(0);
-- }
-- }
--
-- if (getSpeedY() < -9)
-- setDesiredThrust(4)
-- else
-- setDesiredThrust(3)
-- }
--}
-Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.fr.html
-===================================================================
---- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.fr.html
-+++ /dev/null
-@@ -1,41 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Aux commandes du module</h1>
--
--<p>Après 30 jours à regarder des cailloux en mangeant des céréales, vous
--décidez qu'il est temps d'aller explorer d'autres coins de cette planète.</p>
--
--<p>Vous volez un moment, avant de réaliser soudain que vous êtes presque à
--court d'essence. Le pilote automatique est malheureusement inutile dans ce
--genre de situation périlleuse, et vous allez devoir vous poser en mode
--manuel. Votre mission et de vous <b>poser sur une zone plate, avec une
--vitesse verticale inférieure à 10 m/s, une vitesse horizontale inférieure à
--5 m/s et un angle de 0°</b>.</p>
--
--<p>Vous devez définir deux fonctions : <code>[!java]void
--[/!]initialize()</code> et <code>[!java]void
--[/!]step()</code>. <code>initialize()</code> est appelée au moment où l'on
--appuie sur le bouton «Exécuter». Vous pouvez l'utiliser pour choisir une
--zone plate. Comme avant, <code>step()</code> est appelée tous les dixièmes
--de seconde pour vous permettre d'ajuster la poussée (avec la fonction
--<code>[!java]void [/!]setPousseedesiree([!java]int
--[/!]poussee[!scala]:Integer[/!])</code>). Vous pouvez également contrôler
--l'angle du module avec la fonction <code>[!java]void
--[/!]setAngleDesire([!java]double [/!]angle[!scala]:Double[/!])</code>. Un
--angle de O° dénote une position verticale, avec le sommet du module dirigé
--vers le haut. C'est l'angle avec lequel vous devez vous poser. Un angle
--positif indique que le module penche vers la gauche tandis qu'un angle
--négatif indique au contraire qu'il penche à droite. Il est impossible de se
--pencher à plus de ±90°, et on ne peut pas pencher le module de plus de ±5°
--en une fois.</p>
--
--<p>Comme dans les exercices précédents, <code>[!java]List<Point>
--[/!]getSol()[!scala]:List[Point][/!]</code> retourne les points qui
--composent l'horizon. Le manuel de référence de votre module est disponible
--dans la documentation (Aide/À propos de ce monde).</p>
--
--<p>Comme d'habitude, votre programme doit se poser sans heurt dans toutes les
--situations que nous avons rencontré jusqu'à présent, ainsi que dans ce
--nouveau cas.</p>
--
--<p>Bonne chance. Essayez de ne pas vous scratcher ;)</p>
-Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.html
-===================================================================
---- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.html
-+++ /dev/null
-@@ -1,33 +0,0 @@
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Fly the Lander!</h1>
--
--<p>After 30 days of staring at rocks and eating cereals you decide it's time to
--go explore other parts of the planet.</p>
--
--<p>You fly for a while and suddenly realize you're almost out of fuel.
--Unfortunately you're in a delicate situation and the autopilot is helpless.
--You will have to pilot the lander yourself. Your mission is to <b>land the
--lander on a flat zone with a vertical speed less than 10 m/s, an horizontal
--speed less than 5 m/s and an angle of 0°.</b></p>
--
--<p>You must define two functions: <code>[!java]void [/!]initialize()</code> and
--<code>[!java]void [/!]step()</code>. <code>initialize()</code> is called once just
--after you press "Run". You can use it to chose some flat zone. As before,
--<code>step()</code> is called every 0.1 second and is used for adjusting the
--lander's thrust and angle. As in the first exercise the lander's thrust is adjusted
--via <code>[!java]void [/!]setDesiredThrust([!java]int [/!]desiredThrust[!scala]:Integer[/!])</code>.
--But you can also control its angle via
--<code>[!java]void [/!]setDesiredAngle([!java]double [/!]desiredAngle[!scala]:Double[/!])</code>.
--An angle of 0° denotes a vertical position where the "head" of the lander points up.
--This is the angle you must land with. A positive angle denotes a left-leaning lander,
--a negative angle a right-leaning one. You cannot lean more than by ±90°, and the angle can vary by
--at most ±5° in one step.</p>
--
--<p>As in the previous exercise, <code>[!java]List<Point> [/!]getGround()[!scala]:List[Point][/!]</code> returns
--the vertices of the ground's profile from left to right.
--Please refer to the documentation (Help/About this world) for a reference manual of your lunar lander.</p>
--
--<p>As before, your program must safely land the lander in all the situations
--encountered so far in addition to this new one.</p>
--
--<p>Good luck, try not to crash!</p>
-Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.pt_BR.html
-===================================================================
---- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.pt_BR.html
-+++ /dev/null
-@@ -1,37 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h1>Fly the Lander!</h1>
--
--<p>After 30 days of staring at rocks and eating cereals you decide it's time to
--go explore other parts of the planet.</p>
--
--<p>You fly for a while and suddenly realize you're almost out of fuel.
--Unfortunately you're in a delicate situation and the autopilot is helpless.
--You will have to pilot the lander yourself. Your mission is to <b>land the
--lander on a flat zone with a vertical speed less than 10 m/s, an horizontal
--speed less than 5 m/s and an angle of 0°.</b></p>
--
--<p>You must define two functions: <code>[!java]void [/!]initialize()</code> and
--<code>[!java]void [/!]step()</code>. <code>initialize()</code> is called
--once just after you press "Run". You can use it to chose some flat zone. As
--before, <code>step()</code> is called every 0.1 second and is used for
--adjusting the lander's thrust and angle. As in the first exercise the
--lander's thrust is adjusted via <code>[!java]void
--[/!]setDesiredThrust([!java]int
--[/!]desiredThrust[!scala]:Integer[/!])</code>. But you can also control its
--angle via <code>[!java]void [/!]setDesiredAngle([!java]double
--[/!]desiredAngle[!scala]:Double[/!])</code>. An angle of 0° denotes a
--vertical position where the "head" of the lander points up. This is the
--angle you must land with. A positive angle denotes a left-leaning lander, a
--negative angle a right-leaning one. You cannot lean more than by ±90°, and
--the angle can vary by at most ±5° in one step.</p>
--
--<p>As in the previous exercise, <code>[!java]List<Point>
--[/!]getGround()[!scala]:List[Point][/!]</code> returns the vertices of the
--ground's profile from left to right. Please refer to the documentation
--(Help/About this world) for a reference manual of your lunar lander.</p>
--
--<p>As before, your program must safely land the lander in all the situations
--encountered so far in addition to this new one.</p>
--
--<p>Boa sorte, tente não cair!</p>
-Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.scala
-===================================================================
---- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.scala
-+++ /dev/null
-@@ -1,20 +0,0 @@
--package lessons.lander.lvl3_fly_the_lander
--
--import plm.core.model.lesson.ExerciseTemplated
--import plm.core.model.lesson.Lesson
--import lessons.lander.universe.DelegatingLanderWorld
--import lessons.lander.universe.Point
--import lessons.lander.universe.LanderEntity
--import lessons.lander.universe.Configurations._
--import Math.PI
--import scala.collection.JavaConversions._
--import lessons.lander.universe.LanderWorld
--import plm.universe.World
--
--class FlyTheLander(lesson: Lesson) extends ExerciseTemplated(lesson, null) {
-- tabName = "Lander"
-- setup(Array(
-- SIMPLE_TERRAIN_CHALLENGING_CONFIG,
-- CHALLENGING_TERRAIN_SIMPLE_CONFIG,
-- SIMPLE_TERRAIN_TRIVIAL_CONFIG))
--}
-Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.java
-===================================================================
---- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.java
-+++ /dev/null
-@@ -1,48 +0,0 @@
--package lessons.lander.lvl3_fly_the_lander;
--
--import java.util.List;
--
--import lessons.lander.universe.LanderEntity;
--import lessons.lander.universe.Point;
--
--public class FlyTheLanderEntity extends LanderEntity {
-- /* BEGIN TEMPLATE */
-- /* BEGIN HIDDEN */
-- double targetStart;
-- double targetEnd;
-- /* END HIDDEN */
-- public void initialize() {
-- /* BEGIN HIDDEN */
-- List<Point> ground = getGround();
-- Point lastPoint = ground.get(0);
-- for (Point point: ground) {
-- if (point!=lastPoint && lastPoint.y() == point.y()) {
-- targetStart = lastPoint.x();
-- targetEnd = point.x();
-- return;
-- }
-- lastPoint = point;
-- }
-- /* END HIDDEN */
-- }
--
-- public void step() {
-- /* BEGIN SOLUTION */
-- if (getX() < targetStart) {
-- setDesiredAngle(-30);
-- } else if (getX() > targetEnd) {
-- setDesiredAngle(30);
-- } else {
-- if (getSpeedX() > 5) {
-- setDesiredAngle(25);
-- } else if (getSpeedX() < -5) {
-- setDesiredAngle(-25);
-- } else {
-- setDesiredAngle(0);
-- }
-- }
-- setDesiredThrust(getSpeedY() < -9 ? 4 : 3);
-- /* END SOLUTION */
-- }
-- /* END TEMPLATE */
--}
-Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.py
-===================================================================
---- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.py
-+++ /dev/null
-@@ -1,45 +0,0 @@
--# BEGIN HIDDEN
--(startPos,endPos) = (0,0)
--# END HIDDEN
--
--# BEGIN TEMPLATE
--def initialize():
-- pass
--# BEGIN SOLUTION
-- global startPos
-- global endPos
-- lastPoint = getGround()[0]
-- for point in getGround():
-- if (point != lastPoint):
-- if lastPoint[1] == point[1]:
-- (startPos,endPos) = (lastPoint[0],point[0])
-- lastPoint = point
--# END SOLUTION
--
--def step():
-- pass
--# BEGIN HIDDEN
-- if (getX() < startPos):
-- setDesiredAngle(-30)
-- elif (getX() > endPos):
-- setDesiredAngle(30)
-- elif (getSpeedX() > 5):
-- setDesiredAngle(25)
-- elif (getSpeedX() < -5):
-- setDesiredAngle(-25)
-- else:
-- setDesiredAngle(0);
--
-- if (getSpeedY() <-9):
-- setDesiredThrust(4)
-- else:
-- setDesiredThrust(3)
--
--# END HIDDEN
--
--# END TEMPLATE
--
--initialize()
--while isFlying():
-- step()
-- simulateStep()
-Index: b/src/lessons/lander/lvl3_fly_the_lander/ScalaFlyTheLanderEntity.scala
-===================================================================
---- a/src/lessons/lander/lvl3_fly_the_lander/ScalaFlyTheLanderEntity.scala
-+++ /dev/null
-@@ -1,53 +0,0 @@
--package lessons.lander.lvl3_fly_the_lander;
--
--import java.util.Iterator;
--import scala.collection.JavaConversions._
--
--import lessons.lander.universe._;
--
--class ScalaFlyTheLanderEntity extends LanderEntity {
-- /* BEGIN TEMPLATE */
-- /* BEGIN HIDDEN */
-- var targetStart=0.0
-- var targetEnd=0.0
-- /* END HIDDEN */
-- override def initialize() {
-- /* BEGIN HIDDEN */
-- var lastPoint:Point = getGround.get(0);
-- for (point <- getGround()) {
-- if (point != lastPoint) { // Avoid the loop when point is on the first element
-- if (point.y == lastPoint.y) {
-- targetStart = lastPoint.x
-- targetEnd = point.x
-- }
-- }
-- lastPoint = point
-- }
-- /* END HIDDEN */
-- }
--
-- override def step() {
-- /* BEGIN SOLUTION */
-- if (getX() < targetStart) {
-- setDesiredAngle(-30);
-- } else if (getX() > targetEnd) {
-- setDesiredAngle(30);
-- } else {
-- if (getSpeedX() > 5) {
-- setDesiredAngle(25);
-- } else if (getSpeedX() < -5) {
-- setDesiredAngle(-25);
-- } else {
-- setDesiredAngle(0);
-- }
-- }
--
-- if (getSpeedY() < -9) {
-- setDesiredThrust(4)
-- } else {
-- setDesiredThrust(3);
-- }
-- /* END SOLUTION */
-- }
-- /* END TEMPLATE */
--}
-Index: b/src/lessons/lander/short_desc.fr.html
-===================================================================
---- a/src/lessons/lander/short_desc.fr.html
-+++ /dev/null
-@@ -1,9 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h3>Alunisseur</h3>
--
--<p>Dans cette leçon, vous pilotez un alunisseur dans des situations de plus en
--plus complexes.</p>
--
--<p>Vous êtes supposé maîtriser les bases de la programmation et posséder
--quelques notions de mécanique du point avant de tenter cette leçon.</p>
-Index: b/src/lessons/lander/short_desc.html
-===================================================================
---- a/src/lessons/lander/short_desc.html
-+++ /dev/null
-@@ -1,7 +0,0 @@
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h3>Lunar Lander</h3>
--
--<p>In this lesson you pilot a lunar landing module in increasingly complex
--situations.</p>
--
--<p>This lesson assumes some basic programming and physics skills.</p>
-Index: b/src/lessons/lander/universe/DelegatingLanderWorld.fr.html
-===================================================================
---- a/src/lessons/lander/universe/DelegatingLanderWorld.fr.html
-+++ /dev/null
-@@ -1,48 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h2>Alunisseur</h2>
--
--<p>Dans cet univers, vous contrôlez un module d'alunissage. À chaque pas de la
--simulation, vous avez accès à la position du module, sa vitesse, son angle
--et la poussée de son moteur. Vous devez alors décider de l'angle et de la
--poussée pour l'étape suivante. </p>
--
--<h2>Fonctions fournies</h2>
--
--<pre>[!java|c]double [/!]getX()[!scala]:Double[/!]
--[!java|c]double [/!]getY()[!scala]:Double[/!]</pre>
--Retourne la position en X et Y du module d'alunissage.
--<pre>[!java|c]double [/!]getVitesseX()[!scala]:Double[/!]
--[!java|c]double [/!]getVitesseY()[!scala]:Double[/!]</pre>
--Obtenir les vitesses horizontale et verticale du module.
--
--<pre>[!java|c]double [/!]getAngle()[!scala]:Double[/!]
--[!java|c]void [/!]setAngleDesire([!java|c]double [/!]angle[!scala]:Double[/!])</pre>
--Retourne ou fixe l'angle du module d'alunissage.<br/>
--Un angle de O° dénote une position verticale, avec le sommet du module
--dirigé vers le haut. C'est l'angle avec lequel vous devez vous poser. Un
--angle positif indique que le module penche vers la gauche tandis qu'un angle
--négatif indique au contraire qu'il penche à droite. Il est impossible de se
--pencher à plus de ±90°, et on ne peut pas pencher le module de plus de ±5°
--en une fois.
--
--<pre>[!java|c]int [/!]getPoussee()[!scala]:Int[/!]
--[!java|c]void [/!]setPousseeDesiree([!java|c]int [/!]poussée[!scala]:Int[/!])</pre>
--Retourne ou fixe la poussée du module. <br/>Vous ne pouvez incrémenter ou décrémenter la poussée que d'une unité à
--chaque fois. Si votre poussée actuelle est de 2 et que vous demandez une
--poussée de 4, vous n'obtiendrez que 3 au prochain pas de temps. Si vous
--demandez moins que 0 (ou plus que 4), tout se passera comme si vous
--demandiez 0 (ou 4).
--
--<pre>[!java|c]int [/!]getFuel()[!scala]:Int[/!]</pre>
--Obtient la quantité de fuel restant dans le réservoir. À chaque pas de
--simulation, le module consomme entre 0 et 4 unités de fuel, en fonction de
--sa poussée. Une fois que vous avez utilisé tout votre carburant, vous êtes
--en chute libre alors prenez garde !
--
--<pre>[!java]List<Point> [/!]getSol()[! scala]:List[Point][/!]</pre>
--Obtenir les points du sol de gauche à droite. [!java|scala]Vous pouvez
--retrouver les coordonnées X et Y de chaque point avec les méthodes
--correspondantes de votre point : <code>p.x()</code> et
--<code>p.y()</code>.[/!] [!python]Chaque point est un tableau de deux entiers
--représentant respectivement les coordonnées X et Y de chaque point.[/!]
-\ No newline at end of file
-Index: b/src/lessons/lander/universe/DelegatingLanderWorld.html
-===================================================================
---- a/src/lessons/lander/universe/DelegatingLanderWorld.html
-+++ /dev/null
-@@ -1,44 +0,0 @@
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h2>Lunar Lander</h2>
--
--<p>In this universe you pilot a lunar lander. At each simulation step you're
--given the lander's position, speed, angle and thrust and must issue a command
--adjusting its angle and thrust.</p>
--
--<h2>Provided functions</h2>
--
--<pre>[!java|c]double [/!]getX()[!scala]:Double[/!]
--[!java|c]double [/!]getY()[!scala]:Double[/!]</pre>
--Get the X and Y position of the lander.
--<pre>[!java|c]double [/!]getSpeedX()[!scala]:Double[/!]
--[!java|c]double [/!]getSpeedY()[!scala]:Double[/!]</pre>
--Get the horizontal and vertical speed of the lander.
--
--<pre>[!java|c]double [/!]getAngle()[!scala]:Double[/!]
--[!java|c]void [/!]setDesiredAngle([!java|c]double [/!]desiredAngle[!scala]:Double[/!])</pre>
--Get or set the angle of the lander.<br/>
--An angle of 0° denotes a vertical position where the "head" of the lander points up.
--This is the angle you must land with. A positive angle denotes a left-leaning lander,
--a negative angle a right-leaning one. You cannot lean more than by ±90°, and the angle can vary by
--at most ±5° in one step.
--
--<pre>[!java|c]int [/!]getThrust()[!scala]:Int[/!]
--[!java|c]void [/!]setDesiredThrust([!java|c]int [/!]thrust[!scala]:Int[/!])</pre>
--Get or set the thrust of the lander. <br/>You can only
--increment or decrement the thrust by 1 between two simulation steps, so if the
--current thrust is 2 and you ask for 4, you'll only get 3 in the next step. If
--you ask for less than 0 (resp. more than 4), everything will be as if you had
--asked for 0 (resp. 4).
--
--<pre>[!java|c]int [/!]getFuel()[!scala]:Int[/!]</pre>
--Get the remaining fuel in the lander. At each step of the simulation the lander
--consumes as many fuel units as the current thrust. Once you run out of fuel you're
--in free fall so beware!
--
--<pre>[!java]List<Point> [/!]getGround()[! scala]:List[Point][/!]</pre>
--Get the vertices of the ground's profile from left to right.
--[!java|scala]You can retrieve the X and Y coordinates of each point
--with the corresponding methods of your point: <code>p.x()</code> and
--<code>p.y()</code>.[!/]
--[!python]Each point is an array of two integers denoting respectively
--the X and Y coordinates of that point.[/!]
-\ No newline at end of file
-Index: b/src/lessons/lander/universe/DelegatingLanderWorld.java
-===================================================================
---- a/src/lessons/lander/universe/DelegatingLanderWorld.java
-+++ /dev/null
-@@ -1,71 +0,0 @@
--package lessons.lander.universe;
--
--import javax.script.ScriptEngine;
--import javax.script.ScriptException;
--import javax.swing.ImageIcon;
--
--import plm.core.lang.ProgrammingLanguage;
--import plm.core.ui.WorldView;
--import plm.universe.World;
--import scala.collection.immutable.List;
--
--public class DelegatingLanderWorld extends World {
--
-- final LanderWorld realWorld;
--
-- public DelegatingLanderWorld(String name, int width, int height,
-- List<Point> ground, Point position, Point speed, double angle, int thrust, int fuel) {
-- super(name);
-- realWorld = new LanderWorld(this);
-- realWorld.width_$eq(width);
-- realWorld.height_$eq(height);
-- realWorld.ground_$eq(ground);
-- realWorld.position_$eq(position);
-- realWorld.speed_$eq(speed);
-- realWorld.angle_$eq(angle);
-- realWorld.thrust_$eq(thrust);
-- realWorld.fuel_$eq(fuel);
-- }
--
-- public DelegatingLanderWorld(DelegatingLanderWorld world) {
-- super(world.getName());
-- realWorld = new LanderWorld(this);
-- reset(world);
-- }
--
-- @Override
-- public ImageIcon getIcon() {
-- return realWorld.getIcon();
-- }
--
-- @Override
-- public void setupBindings(ProgrammingLanguage lang, ScriptEngine engine) throws ScriptException {
-- realWorld.setupBindings(lang, engine);
-- }
--
-- @Override
-- public boolean winning(World target) {
-- return realWorld.winning(target);
-- }
--
-- @Override
-- public String diffTo(World world) {
-- return realWorld.diffTo(world);
-- }
--
-- @Override
-- public void reset(World initialWorld) {
-- realWorld.reset(((DelegatingLanderWorld) initialWorld).realWorld);
-- super.reset(initialWorld);
-- }
--
-- @Override
-- public WorldView getView() {
-- return realWorld.getView();
-- }
--
-- @Override
-- public String toString() {
-- return realWorld.toString();
-- }
--}
-Index: b/src/lessons/lander/universe/DelegatingLanderWorld.pt_BR.html
-===================================================================
---- a/src/lessons/lander/universe/DelegatingLanderWorld.pt_BR.html
-+++ /dev/null
-@@ -1,43 +0,0 @@
--
--<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
--<h2>Lunar Lander</h2>
--
--<p>In this universe you pilot a lunar lander. At each simulation step you're
--given the lander's position, speed, angle and thrust and must issue a
--command adjusting its angle and thrust.</p>
--
--<h2>Provided functions</h2>
--
--<pre>[!java|c]double [/!]getX()[!scala]:Double[/!]
--[!java|c]double [/!]getY()[!scala]:Double[/!]</pre>
--Obter (Get) as posições X e Y do "lander".
--<pre>[!java|c]double [/!]getVelocidadeX()[!scala]:Double[/!]
--[!java|c]double [/!]getVelocidadeY()[!scala]:Double[/!]</pre>
--Get the horizontal and vertical speed of the lander.
--
--<pre>[!java|c]double [/!]getÂngulo()[!scala]:Double[/!]
--[!java|c]void [/!]setÂnguloDesejado([!java|c]double [/!]ÂnguloDesejado[!scala]:Double[/!])</pre>
--Get or set the angle of the lander.<br/>
--An angle of 0° denotes a vertical position where the "head" of the lander
--points up. This is the angle you must land with. A positive angle denotes a
--left-leaning lander, a negative angle a right-leaning one. You cannot lean
--more than by ±90°, and the angle can vary by at most ±5° in one step.
--
--<pre>[!java|c]int [/!]getImpulso()[!scala]:Int[/!]
--[!java|c]void [/!]setImpulsoDesejado([!java|c]int [/!]thrust[!scala]:Int[/!])</pre>
--Get or set the thrust of the lander. <br/>You can only increment or decrement the thrust by 1 between two simulation
--steps, so if the current thrust is 2 and you ask for 4, you'll only get 3 in
--the next step. If you ask for less than 0 (resp. more than 4), everything
--will be as if you had asked for 0 (resp. 4).
--
--<pre>[!java|c]int [/!]getCombustível()[!scala]:Int[/!]</pre>
--Get the remaining fuel in the lander. At each step of the simulation the
--lander consumes as many fuel units as the current thrust. Once you run out
--of fuel you're in free fall so beware!
--
--<pre>[!java]List<Point> [/!]getChão()[! scala]:List[Point][/!]</pre>
--Get the vertices of the ground's profile from left to right.
--[!java|scala]You can retrieve the X and Y coordinates of each point with the
--corresponding methods of your point: <code>p.x()</code> and
--<code>p.y()</code>.[!/] [!python]Each point is an array of two integers
--denoting respectively the X and Y coordinates of that point.[/!]
-\ No newline at end of file
-Index: b/src/plm/core/ui/ChooseLessonDialog.java
-===================================================================
---- a/src/plm/core/ui/ChooseLessonDialog.java
-+++ b/src/plm/core/ui/ChooseLessonDialog.java
-@@ -78,7 +78,7 @@ public class ChooseLessonDialog extends
- {"lessons/welcome", "lessons/maze", "lessons/turmites", "lessons/turtleart"},
- {"lessons/sort/basic", "lessons/sort/dutchflag", "lessons/sort/baseball", "lessons/sort/pancake"},
- {"lessons/recursion/cons", "lessons/recursion", "lessons/recursion/hanoi" },
-- {"lessons/lightbot", "lessons/bat/string1", "lessons/lander" },
-+ {"lessons/lightbot", "lessons/bat/string1" },
- });
-
-
-Index: b/src/plm/test/ExoTest.java
-===================================================================
---- a/src/plm/test/ExoTest.java
-+++ b/src/plm/test/ExoTest.java
-@@ -39,7 +39,7 @@ public class ExoTest {
- "lessons.sort.basic", "lessons.sort.dutchflag", "lessons.sort.baseball", "lessons.sort.pancake",
- "lessons.recursion.cons", "lessons.recursion", "lessons.recursion.hanoi",
- // "lessons.lightbot", // Well, testing this requires testing the swing directly I guess
-- "lessons.bat.string1", "lessons.lander",
-+ "lessons.bat.string1",
- };
-
- @BeforeClass
-@@ -122,7 +122,7 @@ public class ExoTest {
- // For compiled languages, we mutate to the compiled entity.
- // For script languages, we mutate to the correction entity.
- StudentOrCorrection what = StudentOrCorrection.CORRECTION;
-- if (lang == Game.JAVA || lang == Game.SCALA || lang == Game.C)
-+ if (lang == Game.JAVA || lang == Game.C)
- what = StudentOrCorrection.STUDENT;
- exo.mutateEntities(WorldKind.CURRENT, what);
-
-@@ -157,14 +157,7 @@ public class ExoTest {
- public void testJavaEntity() {
- testCorrectionEntity(Game.JAVA);
- }
--
-- @Test(timeout=30000) // The compiler sometimes takes time to kick in
-- public void testScalaEntity() {
-- if (!exo.getProgLanguages().contains(Game.SCALA))
-- fail("Exercise "+exo.getId()+" does not support scala");
-- testCorrectionEntity(Game.SCALA);
-- }
--
-+
- // @Test(timeout=30000) // The compiler sometimes takes time to kick in
- public void testCEntity() {
- if (!exo.getProgLanguages().contains(Game.C))
-Index: b/src/plm/test/LessonTest.java
-===================================================================
---- a/src/plm/test/LessonTest.java
-+++ b/src/plm/test/LessonTest.java
-@@ -30,7 +30,7 @@ public class LessonTest {
- "lessons.sort.basic", "lessons.sort.dutchflag", "lessons.sort.baseball", "lessons.sort.pancake",
- "lessons.recursion.cons", "lessons.recursion", "lessons.recursion.hanoi",
- // "lessons.lightbot", // Well, testing this requires testing the swing directly I guess
-- "lessons.bat.string1", "lessons.lander",
-+ "lessons.bat.string1",
- };
-
- private String lessonName;
-@@ -82,13 +82,7 @@ public class LessonTest {
- Lesson lesson = loadLesson(Game.JAVA);
- assertTrue("An error arose while loading lesson "+lesson.getName()+"...", lesson.getLoadingOutcomeState() == LoadingOutcome.SUCCESS);
- }
--
-- @Test
-- public void testScalaLesson() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-- Lesson lesson = loadLesson(Game.SCALA);
-- assertTrue("An error arose while loading lesson "+lesson.getName()+"...", lesson.getLoadingOutcomeState() == LoadingOutcome.SUCCESS);
-- }
--
-+
- @Test
- public void testPythonLesson() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- Lesson lesson = loadLesson(Game.PYTHON);
-Index: b/src/plm/core/lang/LangScala.java
-===================================================================
---- a/src/plm/core/lang/LangScala.java
-+++ /dev/null
-@@ -1,247 +0,0 @@
--package plm.core.lang;
--
--import java.util.HashMap;
--import java.util.LinkedList;
--import java.util.List;
--import java.util.Map;
--import java.util.Vector;
--
--import plm.core.PLMCompilerException;
--import plm.core.model.Game;
--import plm.core.model.LogWriter;
--import plm.core.model.lesson.ExecutionProgress;
--import plm.core.model.lesson.Exercise;
--import plm.core.model.lesson.Exercise.StudentOrCorrection;
--import plm.core.ui.ResourcesCache;
--import plm.universe.Entity;
--import scala.Option;
--import scala.collection.JavaConverters;
--import scala.reflect.internal.util.BatchSourceFile;
--import scala.reflect.internal.util.Position;
--import scala.reflect.internal.util.SourceFile;
--import scala.reflect.io.VirtualDirectory;
--import scala.reflect.io.VirtualFile;
--import scala.tools.nsc.Global;
--import scala.tools.nsc.Global.Run;
--import scala.tools.nsc.Settings;
--import scala.tools.nsc.interpreter.AbstractFileClassLoader;
--import scala.tools.nsc.reporters.AbstractReporter;
--
--public class LangScala extends JVMCompiledLang {
--
-- ScalaCompiler compiler = new ScalaCompiler();
--
-- public LangScala() {
-- super("Scala","scala",ResourcesCache.getIcon("img/lang_scala.png"));
-- }
--
-- @Override
-- public void compileExo(Exercise exo, LogWriter out, StudentOrCorrection whatToCompile)
-- throws PLMCompilerException {
-- /* Make sure each run generate a new package to avoid that the loader cache prevent the reloading of the newly generated class */
-- packageNameSuffix++;
-- runtimePatterns.put("\\$package",
-- "package "+packageName()+";import java.awt.Color;");
--
-- List<plm.core.model.session.SourceFile> sfs = exo.getSourceFilesList(this);
-- if (sfs == null || sfs.isEmpty()) {
-- String msg = exo.getName()+": No source to compile";
-- System.err.println(msg);
-- PLMCompilerException e = new PLMCompilerException(msg, null, null);
-- exo.lastResult = ExecutionProgress.newCompilationError(e.getMessage());
-- throw e;
-- }
--
-- try {
-- compiler.reset();
-- for (plm.core.model.session.SourceFile sf : sfs) {
-- compiler.compile(className(sf.getName()), sf.getCompilableContent(runtimePatterns,whatToCompile), sf.getOffset());
-- }
-- } catch (PLMCompilerException e) {
-- System.err.println(Game.i18n.tr("Compilation error:"));
-- System.err.println(e.getMessage());
-- exo.lastResult = ExecutionProgress.newCompilationError(e.getMessage());
--
-- throw e;
-- }
--
-- }
--
-- /** Converts {@code "foo.bar.baz"} to {@code "foo.bar.Scalabaz"}. */
-- @Override
-- public String nameOfCorrectionEntity(Exercise exo){
-- String path = super.nameOfCorrectionEntity(exo);
--
-- String[] components = path.split("\\.");
-- StringBuilder result = new StringBuilder();
-- int last = components.length - 1;
-- for (int i = 0; i < last; i++) {
-- result.append(components[i] + ".");
-- }
-- result.append("Scala" + components[last]);
-- return result.toString();
-- }
--
-- @Override
-- protected Entity mutateEntity(String newClassName)
-- throws InstantiationException, IllegalAccessException,
-- ClassNotFoundException {
-- return (Entity) compiler.findClass(className(newClassName)).newInstance();
-- }
--}
--
--/** In memory compiler of scala code.
-- * This is highly inspired of https://github.com/twitter/util/blob/master/util-eval/src/main/scala/com/twitter/util/Eval.scala */
--class ScalaCompiler {
--
-- private PLMReporter reporter;
-- private Settings settings;
-- private Map<String, Class<?>> cache = new HashMap<String, Class<?>>();
-- private Global global;
-- private VirtualDirectory target;
-- private ClassLoader classLoader = new AbstractFileClassLoader(target, this.getClass().getClassLoader());
--
-- public ScalaCompiler() {
-- super();
-- settings = new Settings();
-- settings.nowarnings().tryToSetFromPropertyValue("true"); // warnings seem to be exceptions, and we don't want them to mess with us
--
-- Option<VirtualDirectory> noAncestor = scala.Option$.MODULE$.apply(null);
-- target = new VirtualDirectory("(memory)", noAncestor);
-- settings.outputDirs().setSingleOutput(target);
--
-- settings.usejavacp().tryToSetFromPropertyValue("true");
-- //settings.usemanifestcp().tryToSetFromPropertyValue("true");
-- reporter = new PLMReporter(settings);
-- global = new Global(settings,reporter);
-- }
--
-- public void reset() {
-- reporter.reset();
-- reporter.setOffset(0);
-- target.clear();
-- cache = new HashMap<String, Class<?>>();
-- classLoader = new AbstractFileClassLoader(target, this.getClass().getClassLoader());
-- }
--
-- public void compile(String name,String content,int offset) throws PLMCompilerException {
-- if (Game.getInstance().isDebugEnabled())
-- System.out.println("Compiline souce "+name+" to scala (offset:"+offset+"):\n"+content);
--
-- Run compiler = global.new Run();
-- List<SourceFile> sources = new LinkedList<SourceFile>();
--
-- sources.add(new BatchSourceFile(new VirtualFile(name) , content.toCharArray()));
-- reporter.setOffset(offset);
--
-- compiler.compileSources(JavaConverters.asScalaBufferConverter(sources).asScala().toList());
--
-- if (Game.getInstance().isDebugEnabled() && reporter.hasErrors())
-- System.out.println("Here is the scala source code of "+name+" (offset:"+offset+"): "+content);
-- reporter.throwExceptionOnNeed();
-- }
-- public Class<?> findClass(String className) {
-- synchronized (this) {
-- if (!cache.containsKey(className)) {
-- Class<?> res;
-- try {
-- res = classLoader.loadClass(className);
-- } catch (ClassNotFoundException e) {
-- res = null;
-- }
-- cache.put(className, res);
-- }
--
-- return cache.get(className);
-- }
-- }
--
-- class PLMReporter extends AbstractReporter {
-- final static int INFO = 0;
-- final static int WARNING = 1;
-- final static int ERROR = 2;
-- int offset=0;
-- Vector<String> messages = new Vector<String>();
-- Settings settings;
--
-- public PLMReporter(Settings s) {
-- settings = s;
-- }
-- public void setOffset(int _offset) {
-- this.offset = _offset;
-- }
-- @Override
-- public Settings settings() {
-- return settings;
-- }
-- @Override
-- public void displayPrompt() {
-- /* Don't do that, pal. */
-- }
-- @Override
-- public void display(Position pos, String message, Severity _severity) {
-- String severityName = _severity.toString();
-- String label = "";
-- int severity = -1;
-- if (severityName.equals("INFO") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 0"))
-- severity = INFO;
-- if (severityName.equals("WARNING") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 1")) {
-- severity = WARNING;
-- label= "warning: ";
-- }
-- if (severityName.equals("ERROR") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 2")) {
-- severity = ERROR;
-- label = "error: ";
-- }
-- if (severity == -1)
-- throw new RuntimeException("Got an unknown severity: "+severityName+". Please adapt the PLM to this new version of scala (or whatever).");
-- if (severity == INFO && !Game.getInstance().isDebugEnabled())
-- return;
--
-- int lineNum = -1;
-- try {
-- lineNum = pos.line() - offset;
-- } catch (Throwable t) {
-- // That's fine if the line number is not defined.
-- }
--
-- String name = pos.source().path();
-- int lastDot = name.lastIndexOf('.');
-- if (lastDot != -1)
-- name = name.substring(lastDot+1);
-- String msg = name+(lineNum == -1? "": ":"+lineNum) +": "+label+message;
--
-- // Append the line content and a position marker, if possible
-- if (pos != null && pos.isDefined()) {
-- msg += "\n"+pos.inUltimateSource(pos.source()).lineContent()+"\n";
-- for (int i=0;i<pos.column()-1;i++)
-- msg += " ";
-- msg += "^";
-- }
--
-- messages.add(msg);
-- }
-- public void throwExceptionOnNeed() throws PLMCompilerException {
-- if (hasErrors()) {
-- StringBuffer sb = new StringBuffer();
-- for (String s : messages)
-- sb.append(s);
-- throw new PLMCompilerException(sb.toString(), null, null);
-- }
-- }
-- @Override
-- public void reset() {
-- super.reset();
-- messages.removeAllElements();
-- }
--
-- /* These methods are mandated by scala 2.11, but I dunno what to do with it, so ignore that for now */
-- public int count(Object o) {
-- return 0;
-- }
-- public void resetCount(Object o) {}
-- public void info0(Position arg0, String arg1, Object arg2, boolean arg3) {
-- // TODO Auto-generated method stub
-- }
-- }
--}
-\ No newline at end of file
-Index: b/src/plm/core/model/Game.java
-===================================================================
---- a/src/plm/core/model/Game.java
-+++ b/src/plm/core/model/Game.java
-@@ -43,7 +43,6 @@ import plm.core.lang.LangJava;
- import plm.core.lang.LangLightbot;
- import plm.core.lang.LangPython;
- import plm.core.lang.LangRuby;
--import plm.core.lang.LangScala;
- import plm.core.lang.ProgrammingLanguage;
- import plm.core.model.lesson.Exercise;
- import plm.core.model.lesson.Exercise.WorldKind;
-@@ -99,14 +98,13 @@ public class Game implements IWorldView
-
- public static final ProgrammingLanguage JAVA = new LangJava();
- public static final ProgrammingLanguage PYTHON = new LangPython();
-- public static final ProgrammingLanguage SCALA = new LangScala();
- public static final ProgrammingLanguage C = new LangC();
- //public static final ProgrammingLanguage JAVASCRIPT = new ProgrammingLanguage("JavaScript","js",ResourcesCache.getIcon("img/lang_javascript.png"));
- public static final ProgrammingLanguage RUBY = new LangRuby();
- public static final ProgrammingLanguage LIGHTBOT = new LangLightbot();
-
- public static final ProgrammingLanguage[] programmingLanguages = new ProgrammingLanguage[] {
-- JAVA, PYTHON, SCALA, RUBY, LIGHTBOT, C // TODO: re-add JAVASCRIPT to this list once it works at least a bit
-+ JAVA, PYTHON, RUBY, LIGHTBOT, C // TODO: re-add JAVASCRIPT to this list once it works at least a bit
- };
- private ProgrammingLanguage programmingLanguage = JAVA;
-
-@@ -164,10 +162,6 @@ public class Game implements IWorldView
- i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
- loadProperties();
-
-- if (checkScala())
-- System.err.println(i18n.tr("Scala is usable on your machine. Congratulations."));
-- else
-- System.err.println(i18n.tr("Please install Scala version 2.10 or higher to use it in the PLM."));
- if (checkPython())
- System.err.println(i18n.tr("Jython is usable on your machine. Congratulations."));
- else
-@@ -180,17 +174,13 @@ public class Game implements IWorldView
- String defaultProgrammingLanguage = Game.getProperty(PROP_PROGRAMING_LANGUAGE,Game.JAVA.getLang(),true);
- if (!defaultProgrammingLanguage.equalsIgnoreCase(Game.JAVA.getLang()) &&
- !defaultProgrammingLanguage.equalsIgnoreCase(Game.PYTHON.getLang()) &&
-- !defaultProgrammingLanguage.equalsIgnoreCase(Game.SCALA.getLang()) &&
- !defaultProgrammingLanguage.equalsIgnoreCase(Game.C.getLang()))
- System.err.println(i18n.tr("Warning, the default programming language is neither ''Java'' nor ''python'' or ''Scala'' or ''C'' but {0}.\n"+
- " This language will be used to setup the worlds, possibly leading to severe issues for the exercises that don''t expect it.\n" +
- " It is safer to change the current language, and restart the PLM before proceeding.\n"+
- " Alternatively, the property {1} can be changed in your configuration file ({2}/plm.properties)",defaultProgrammingLanguage,PROP_PROGRAMING_LANGUAGE, getSavingLocation()));
-
-- if (defaultProgrammingLanguage.equalsIgnoreCase(Game.SCALA.getLang()) && !canScala) {
-- System.err.println(i18n.tr("The default programming language is Scala, but your scala installation is not usable. Switching to Java instead.\n"));
-- setProgramingLanguage(JAVA);
-- } else if (defaultProgrammingLanguage.equalsIgnoreCase(Game.PYTHON.getLang()) && !canPython) {
-+ if (defaultProgrammingLanguage.equalsIgnoreCase(Game.PYTHON.getLang()) && !canPython) {
- System.err.println(i18n.tr("The default programming language is python, but your python installation is not usable. Switching to Java instead.\n"));
- setProgramingLanguage(JAVA);
- } else if (defaultProgrammingLanguage.equalsIgnoreCase(Game.C.getLang()) && !canC) {
-@@ -231,35 +221,7 @@ public class Game implements IWorldView
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private boolean checkScala() {
-- String[] resources = new String[] {"/scala/tools/nsc/Interpreter", "/scala/ScalaObject", "/scala/reflect/io/AbstractFile"};
-- String[] hints = new String[] {"scala-compiler.jar", "scala-library.jar", "scala-reflect.jar"};
-- for (int i=0;i<resources.length;i++) {
-- scalaError = canResolve(resources[i],hints[i]);
-- if (!scalaError.isEmpty()) {
-- System.err.println(scalaError);
-- return canScala;
-- }
-- }
--
-- String version = null;
-- try {
-- Class props = Class.forName("scala.util.Properties");
-- Method meth = props.getMethod("versionString", new Class[] {});
-- version = (String) meth.invoke(props);
-- } catch (Exception e) {
-- scalaError = i18n.tr("Error {0} while retrieving the Scala version: {1}", e.getClass().getName() ,e.getLocalizedMessage());
-- System.err.println( scalaError );
-- return canScala;
-- }
--
-- if (version.contains("version 2.10") || version.contains("version 2.11")) {
-- canScala = true;
-- return canScala;
-- } else {
-- scalaError = i18n.tr("Scala is too ancient. Found {0} while I need 2.10 or higher.",version);
-- System.err.println(scalaError);
-- return canScala;
-- }
-+ return false;
- }
-
- public boolean canPython = false;
-@@ -972,11 +934,6 @@ public class Game implements IWorldView
-
- if (isValidProgLanguage(newLanguage)) {
- //System.out.println("Switch programming language to "+newLanguage);
-- if (newLanguage.equals(Game.SCALA) && !canScala) {
-- JOptionPane.showMessageDialog(null, i18n.tr("Please install Scala version 2.10 or higher to use it in the PLM.\n\n")+scalaError ,
-- i18n.tr("Scala is missing"), JOptionPane.ERROR_MESSAGE);
-- return;
-- }
- if (newLanguage.equals(Game.PYTHON) && !canPython) {
- JOptionPane.showMessageDialog(null, i18n.tr("Please install jython and its dependencies to use the python programming language in the PLM.\n\n")+pythonError,
- i18n.tr("Python is missing"), JOptionPane.ERROR_MESSAGE);
-@@ -999,7 +956,7 @@ public class Game implements IWorldView
- }
- this.programmingLanguage = newLanguage;
- fireProgLangChange(newLanguage);
-- if (newLanguage.equals(Game.JAVA) || newLanguage.equals(Game.PYTHON) || newLanguage.equals(Game.SCALA) || newLanguage.equals(Game.C)) // Only save it if it's stable enough
-+ if (newLanguage.equals(Game.JAVA) || newLanguage.equals(Game.PYTHON) || newLanguage.equals(Game.C)) // Only save it if it's stable enough
- setProperty(PROP_PROGRAMING_LANGUAGE, newLanguage.getLang());
- return;
- }
-Index: b/src/plm/core/model/lesson/ExerciseTemplated.java
-===================================================================
---- a/src/plm/core/model/lesson/ExerciseTemplated.java
-+++ b/src/plm/core/model/lesson/ExerciseTemplated.java
-@@ -212,7 +212,7 @@ public abstract class ExerciseTemplated
- String initialContent = templateHead.toString() + templateTail.toString();
- String skelContent;
- String headContent;
-- if (lang == Game.PYTHON || lang == Game.SCALA || lang == Game.C) {
-+ if (lang == Game.PYTHON || lang == Game.C) {
- skelContent = skel.toString();
- headContent = head.toString();
- } else {
-@@ -358,7 +358,7 @@ public abstract class ExerciseTemplated
- System.out.println("Found suitable templating entity "+lang.nameOfCorrectionEntity(this)+" in "+lang);
-
- } catch (NoSuchEntityException e) {
-- if (lang.equals(Game.PYTHON) || lang.equals(Game.SCALA) || lang.equals(Game.JAVA))
-+ if (lang.equals(Game.PYTHON) || lang.equals(Game.JAVA))
- System.out.println("No templating entity found: "+e);
-
- if (getProgLanguages().contains(lang))
-Index: b/src/plm/universe/bat/BatTest.java
-===================================================================
---- a/src/plm/universe/bat/BatTest.java
-+++ b/src/plm/universe/bat/BatTest.java
-@@ -165,9 +165,7 @@ public class BatTest {
- }
- private void displayParameter(Object o, StringBuffer sb, ProgrammingLanguage pl) {
- if (o == null) {
-- if (pl == Game.SCALA)
-- sb.append("Nil");
-- else if (pl == Game.PYTHON)
-+ if (pl == Game.PYTHON)
- sb.append("None");
- else
- sb.append("null");
-@@ -175,8 +173,6 @@ public class BatTest {
- } else if (o instanceof String[]) {
- if (pl.equals(Game.JAVA)) {
- sb.append("{");
-- } else if (pl.equals(Game.SCALA)) {
-- sb.append("Array(");
- } else if (pl.equals(Game.PYTHON)) {
- sb.append("[");
- } else {
-@@ -191,8 +187,6 @@ public class BatTest {
- sb.deleteCharAt(sb.length()-1);
- if (pl.equals(Game.JAVA)) {
- sb.append("}");
-- } else if (pl.equals(Game.SCALA)) {
-- sb.append(")");
- } else if (pl.equals(Game.PYTHON)) {
- sb.append("]");
- } else {
-@@ -204,8 +198,6 @@ public class BatTest {
-
- if (pl.equals(Game.JAVA)) {
- sb.append("{");
-- } else if (pl.equals(Game.SCALA)) {
-- sb.append("Array(");
- } else if (pl.equals(Game.PYTHON)) { // Python
- sb.append("[");
- } else {
-@@ -231,8 +223,6 @@ public class BatTest {
- }
- if (pl.equals(Game.JAVA)) {
- sb.append("}");
-- } else if (pl.equals(Game.SCALA)) {
-- sb.append(")");
- } else if (pl.equals(Game.PYTHON)) {
- sb.append("]");
- } else {
-@@ -240,7 +230,7 @@ public class BatTest {
- }
- } else if (o instanceof Boolean) {
- Boolean b = (Boolean) o;
-- if (pl.equals(Game.JAVA) || pl.equals(Game.SCALA)) {
-+ if (pl.equals(Game.JAVA)) {
- sb.append(b ? "true":"false");
- } else if (pl.equals(Game.PYTHON)) {
- sb.append(b ? "True" : "False");
-@@ -296,8 +286,6 @@ public class BatTest {
- displayParameter(o, sb, Game.getProgrammingLanguage());
- return sb.toString();
- } else {
-- if (Game.getProgrammingLanguage() == Game.SCALA)
-- return "Nil";
- if (Game.getProgrammingLanguage() == Game.PYTHON)
- return "None";
- return "null";
-Index: b/src/plm/test/simple/test/ScalaSimpleExerciseTest.java
-===================================================================
---- a/src/plm/test/simple/test/ScalaSimpleExerciseTest.java
-+++ /dev/null
-@@ -1,52 +0,0 @@
--package plm.test.simple.test;
--
--import plm.core.model.Game;
--
--public class ScalaSimpleExerciseTest extends JVMCompiledSimpleExerciseTest {
--
-- public ScalaSimpleExerciseTest() {
-- super(Game.SCALA);
-- }
--
-- @Override
-- public String generateSyntaxErrorCode() {
-- return "zqkdçajdé\"\"";
-- }
--
-- @Override
-- public String generateVariableErrorCode() {
-- return "toto += 1;\n";
-- }
--
-- @Override
-- public String generateNullPointerErrorCode() {
-- return "override def run() {\n"
-- + " var s:String = null;\n"
-- + " println(s.length());\n"
-- + "}";
-- }
--
-- @Override
-- public String generateOutOfBoundsErrorCode() {
-- return "override def run() {\n"
-- + " var t:Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n"
-- + " println(t(42));\n"
-- + "}";
-- }
--
-- @Override
-- public String generateWrongCode() {
-- return "override def run() {\n"
-- + " world.asInstanceOf[SimpleWorld].setObjectif(false);\n"
-- + "}";
-- }
--
-- @Override
-- public String generateSolutionFollowedByError() {
-- return "override def run() {\n"
-- + " world.asInstanceOf[SimpleWorld].setObjectif(true);\n"
-- + " var t:Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n"
-- + " println(t(42));\n"
-- + "}";
-- }
--}
-Index: b/src/plm/core/lang/JVMCompiledLang.java
-===================================================================
---- a/src/plm/core/lang/JVMCompiledLang.java
-+++ b/src/plm/core/lang/JVMCompiledLang.java
-@@ -48,15 +48,6 @@ public abstract class JVMCompiledLang ex
- ent = (Entity)getClass().getClassLoader().loadClass(newClassName).newInstance();
- } catch (Exception e2) {
- if (whatToMutate == StudentOrCorrection.STUDENT) {
-- if (Game.getProgrammingLanguage() == Game.SCALA)
-- throw new PLMCompilerException(Game.i18n.tr(
-- "Your entity failed to start. Did you forgot to put your code within a method?\n\n"
-- + "This problem often arises when the exercise expects you to put all the code within a \n"
-- + "method e.g. run(), but you put some statements (e.g. forward()) outside of any method.\n\n"
-- + "The easiest solution to sort it out is to copy all your code (Ctrl-A Ctrl-C), use the \n"
-- + "'Exercise/Revert' menu to reset the template, and paste (Ctrl-V) your code within the\n"
-- + "provided method."));
-- else
- throw new PLMCompilerException(Game.i18n.tr("Your entity failed to start. Your constructor seems to be broken, but I have no clue."));
- } else {
- throw new PLMEntityNotFound("Cannot find an entity of name "+className(newClassName)+" or "+newClassName+". Broken lesson.", e2);
-Index: b/src/plm/core/model/lesson/ExerciseTemplatingEntity.java
-===================================================================
---- a/src/plm/core/model/lesson/ExerciseTemplatingEntity.java
-+++ b/src/plm/core/model/lesson/ExerciseTemplatingEntity.java
-@@ -83,19 +83,7 @@ public abstract class ExerciseTemplating
- javaFile.setCorrection("$package "+template+" @SuppressWarnings(\"unchecked\") public void run(BatTest t) {\n"+javaFile.getTemplate()+"}\n"+javaFile.getCorrection()+" }");
- javaFile.setTemplate ("$package "+template+" @SuppressWarnings(\"unchecked\") public void run(BatTest t) { "+javaFile.getTemplate()+"} $body }");
- //System.out.println("New template: "+sf.getTemplate());
--
-- if (getProgLanguages().contains(Game.SCALA)) {
-- SourceFile scalaFile = sourceFiles.get(Game.SCALA).get(0);
-- String header = "$package\n"
-- + "import plm.universe.bat.{BatEntity,BatWorld,BatTest}; \n"
-- + "import plm.universe.World; \n"
-- + "import scala.collection.JavaConverters._;\n"
-- + "class "+entName+" extends BatEntity { ";
--
-- scalaFile.setCorrection(header+scalaFile.getCorrection()+" }");
-- scalaFile.setTemplate (header+scalaFile.getTemplate() +" }");
-- }
--
-+
- computeAnswer();
- setSetup(true);
- }
-@@ -114,8 +102,6 @@ public abstract class ExerciseTemplating
- protected void templateScala(String entName, String[] types, String initialCode, String correction) {
- if (isSetup())
- throw new RuntimeException("The exercise "+getName()+" is already setup, too late to add a programming language template.");
-- if (this.getProgLanguages().contains(Game.SCALA))
-- throw new RuntimeException("The exercise "+getName()+" has two Scala templates. Please fix this bug.");
-
- StringBuffer skeleton = new StringBuffer(" val res = ");
- skeleton.append(entName);
-@@ -146,9 +132,6 @@ public abstract class ExerciseTemplating
- skeleton.append(" case e:java.lang.ClassCastException => t.setResult(res)\n"); // primitive types cannot be converted to java, but I don't care (and cannot test whether res is a primitive type)
- skeleton.append("}\n");
-
-- newSource(Game.SCALA, entName, initialCode, "\n override def run(t: BatTest) {\n"+skeleton+"\n }\n$body",14,
-- "\n override def run(t: BatTest) {\n"+skeleton+"\n }\n"+initialCode+correction);
-- addProgLanguage(Game.SCALA);
- }
- public boolean isSetup() {
- return isSetup;
-Index: b/src/plm/core/ui/editor/MissionEditor.java
-===================================================================
---- a/src/plm/core/ui/editor/MissionEditor.java
-+++ b/src/plm/core/ui/editor/MissionEditor.java
-@@ -110,7 +110,6 @@ public class MissionEditor extends JFram
- selectorAll.setSelected(true);
- final JCheckBox selectorC = new JCheckBox("C");
- final JCheckBox selectorJava = new JCheckBox("Java");
-- final JCheckBox selectorScala = new JCheckBox("Scala");
- final JCheckBox selectorPython = new JCheckBox("Python");
-
- final ItemListener il = new ItemListener() {
-@@ -129,9 +128,6 @@ public class MissionEditor extends JFram
- if(selectorJava.isSelected()){
- l.add(Game.JAVA);
- }
-- if(selectorScala.isSelected()){
-- l.add(Game.SCALA);
-- }
- if(selectorPython.isSelected()){
- l.add(Game.PYTHON);
- }
-@@ -162,7 +158,6 @@ public class MissionEditor extends JFram
- selectorAll.addItemListener(il);
- selectorC.addItemListener(il);
- selectorJava.addItemListener(il);
-- selectorScala.addItemListener(il);
- selectorPython.addItemListener(il);
-
- editor = new JEditorPane();
-@@ -183,7 +178,6 @@ public class MissionEditor extends JFram
- box.add(selectorAll);
- box.add(selectorC);
- box.add(selectorJava);
-- box.add(selectorScala);
- box.add(selectorPython);
-
- rightDisplay.add(box, BorderLayout.NORTH);
-Index: b/src/plm/core/ui/JavaEditorPanel.java
-===================================================================
---- a/src/plm/core/ui/JavaEditorPanel.java
-+++ b/src/plm/core/ui/JavaEditorPanel.java
-@@ -31,8 +31,6 @@ public class JavaEditorPanel extends RTe
- codeEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
- } else if (lang.equals(Game.PYTHON)) {
- codeEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
-- } else if (lang.equals(Game.SCALA)) {
-- codeEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SCALA);
- } else if (lang.equals(Game.C)) {
- codeEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_C);
- } else {
-Index: b/src/plm/universe/bat/BatExercise.java
-===================================================================
---- a/src/plm/universe/bat/BatExercise.java
-+++ b/src/plm/universe/bat/BatExercise.java
-@@ -98,7 +98,7 @@ public abstract class BatExercise extend
- }
-
- for (ProgrammingLanguage pl : getProgLanguages()) {
-- if (!pl.equals(Game.JAVA) && !pl.equals(Game.SCALA))
-+ if (!pl.equals(Game.JAVA))
- worlds.get(0).getEntity(0).setScript(pl, corrections.get(pl));
- }
-
-Index: b/src/plm/test/simple/test/AllSimpleExerciseTests.java
-===================================================================
---- a/src/plm/test/simple/test/AllSimpleExerciseTests.java
-+++ b/src/plm/test/simple/test/AllSimpleExerciseTests.java
-@@ -5,7 +5,7 @@ import org.junit.runners.Suite;
- import org.junit.runners.Suite.SuiteClasses;
-
- @RunWith(Suite.class)
-- at SuiteClasses({ JavaSimpleExerciseTest.class, ScalaSimpleExerciseTest.class, PythonSimpleExerciseTest.class })
-+ at SuiteClasses({ JavaSimpleExerciseTest.class, PythonSimpleExerciseTest.class })
- public class AllSimpleExerciseTests {
-
- }
diff --git a/debian/patches/series b/debian/patches/series
index d6eccd6..135fdba 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,3 @@
system-ant-tasks
-no-scala
no-github
translate
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/plm.git
More information about the pkg-java-commits
mailing list