Assignment 6 done

This commit is contained in:
beauvill 2019-11-24 19:45:00 +01:00
parent be7ddc9306
commit a308ce1329
3 changed files with 46 additions and 14 deletions

View File

@ -79,7 +79,7 @@ trait GameDef {
* This function returns the block at the start position of
* the game.
*/
def startBlock: Block = ???
def startBlock: Block = Block(startPos, startPos)
/**
@ -146,22 +146,25 @@ trait GameDef {
* Returns the list of blocks that can be obtained by moving
* the current block, together with the corresponding move.
*/
def neighbors: List[(Block, Move)] = ???
def neighbors: List[(Block, Move)] =
List((left, Left), (right, Right), (up, Up), (down, Down))
/**
* Returns the list of positions reachable from the current block
* which are inside the terrain.
*/
def legalNeighbors: List[(Block, Move)] = ???
def legalNeighbors: List[(Block, Move)] = neighbors.filter{
case (b, _) => b.isLegal
}
/**
* Returns `true` if the block is standing.
*/
def isStanding: Boolean = ???
def isStanding: Boolean = b1 == b2
/**
* Returns `true` if the block is entirely inside the terrain.
*/
def isLegal: Boolean = ???
def isLegal: Boolean = terrain(b1) && terrain(b2)
}
}

View File

@ -8,7 +8,7 @@ trait Solver extends GameDef {
/**
* Returns `true` if the block `b` is at the final position
*/
def done(b: Block): Boolean = ???
def done(b: Block): Boolean = b.b1 == goal && b.isStanding
/**
* This function takes two arguments: the current block `b` and
@ -26,7 +26,10 @@ trait Solver extends GameDef {
* It should only return valid neighbors, i.e. block positions
* that are inside the terrain.
*/
def neighborsWithHistory(b: Block, history: List[Move]): LazyList[(Block, List[Move])] = ???
def neighborsWithHistory(b: Block, history: List[Move]): LazyList[(Block, List[Move])] = {
lazy val result = b.legalNeighbors.map({pair=> (pair._1, pair._2 +: history)})
result.to(LazyList)
}
/**
* This function returns the list of neighbors without the block
@ -34,7 +37,9 @@ trait Solver extends GameDef {
* make sure that we don't explore circular paths.
*/
def newNeighborsOnly(neighbors: LazyList[(Block, List[Move])],
explored: Set[Block]): LazyList[(Block, List[Move])] = ???
explored: Set[Block]): LazyList[(Block, List[Move])] = {
neighbors.filter(n => !explored.contains(n._1))
}
/**
* The function `from` returns the lazy list of all possible paths
@ -60,18 +65,28 @@ trait Solver extends GameDef {
* construct the correctly sorted lazy list.
*/
def from(initial: LazyList[(Block, List[Move])],
explored: Set[Block]): LazyList[(Block, List[Move])] = ???
explored: Set[Block]): LazyList[(Block, List[Move])] = {
if (initial.isEmpty) LazyList.empty
else {
val more = for {
pair <- initial
next <- newNeighborsOnly (neighborsWithHistory(pair._1, pair._2), explored)
} yield next
initial #::: from(more, explored ++ (more.map(_._1)))
}
}
/**
* The lazy list of all paths that begin at the starting block.
*/
lazy val pathsFromStart: LazyList[(Block, List[Move])] = ???
lazy val pathsFromStart: LazyList[(Block, List[Move])] = from(neighborsWithHistory(startBlock, List[Move]()), Set(startBlock))
/**
* Returns a lazy list of all possible pairs of the goal block along
* with the history how it was reached.
*/
lazy val pathsToGoal: LazyList[(Block, List[Move])] = ???
lazy val pathsToGoal: LazyList[(Block, List[Move])] = pathsFromStart.filter({case (b, m) => done(b)})
/**
* The (or one of the) shortest sequence(s) of moves to reach the
@ -81,5 +96,8 @@ trait Solver extends GameDef {
* the first move that the player should perform from the starting
* position.
*/
lazy val solution: List[Move] = ???
lazy val solution: List[Move] = pathsToGoal.headOption match {
case None => List.empty
case Some(pair) => (pair._2).reverse
}
}

View File

@ -50,7 +50,13 @@ trait StringParserTerrain extends GameDef {
* a valid position (not a '-' character) inside the terrain described
* by `levelVector`.
*/
def terrainFunction(levelVector: Vector[Vector[Char]]): Pos => Boolean = ???
def terrainFunction(levelVector: Vector[Vector[Char]]): Pos => Boolean = {
case Pos(x,y) => (for{
row <- levelVector.lift(x)
ch <- row.lift(y)
if(ch != '-')
} yield ch).isDefined
}
/**
* This function should return the position of character `c` in the
@ -60,7 +66,12 @@ trait StringParserTerrain extends GameDef {
* Hint: you can use the functions `indexWhere` and / or `indexOf` of the
* `Vector` class
*/
def findChar(c: Char, levelVector: Vector[Vector[Char]]): Pos = ???
def findChar(c: Char, levelVector: Vector[Vector[Char]]): Pos = {
val ys = levelVector.map(_.indexOf(c))
val x = ys.indexWhere(_ >= 0)
Pos(x, ys(x))
}
private lazy val vector: Vector[Vector[Char]] =
Vector(level.split("\r?\n").map(str => Vector(str: _*)).toIndexedSeq: _*)