So I want to access isInBounds
Navigation.kt:
data class Coordinate(val x:Int , val y:Int){
val isInBounds = x >= 0 && y >= 0
operator fun plus(other:Coordinate) = Coordinate(x other.x, y other.y)
}
But when I try to access it I get an unresolved reference.
Game.kt
private fun move(directionInput: String) = try {
val direction = Direction.valueOf(directionInput.uppercase())
val newPosition = direction.updateCoordinate(player.currentPosition)
if (!newPosition.isInBounds){
}
else{
}
} catch (e: Exception){
}
enum class Direction(private val coordinate: Coordinate){
NORTH(Coordinate(0 , -1)),
EAST(Coordinate(1 , 0)),
SOUTH(Coordinate(0 , 1)),
WEST(Coordinate(-1 , 0));
fun updateCoordinate(playerCoordinate:Coordinate) {
coordinate playerCoordinate
}
}
CodePudding user response:
The mistake is in Direction
. Note that you did not specify a return type for updateCoordinate
, and you used a block body for it. This means that it implicitly returns Unit
. So updateCoordinate
calculates coordinate playerCoordinate
, discards the result, and returns Unit
. This causes newPosition
to be Unit
, and that is obviously not going to be have an isInBounds
property.
Clearly that is not what you want. You should instead declare updateCoordinate
with an expression body:
fun updateCoordinate(playerCoordinate:Coordinate) =
coordinate playerCoordinate
or if you like block bodies:
fun updateCoordinate(playerCoordinate:Coordinate): Coordinate {
return coordinate playerCoordinate
}
This is just my opinion, but I think it is more readable to have updateCoordinate
as a method on Coordinate
, called moveTowards
:
data class Coordinate(val x: Int, val y: Int) {
operator fun plus(coord: Coordinate) = ...
fun moveTowards(direction: Direction) =
this direction.coordinate // you'd have to make direction.coordinate public
}
CodePudding user response:
Your updateCoordinate
function doesn't actually accomplish anything because it calculates something without doing anything with the result, like returning it. Therefore, it implicitly returns Unit, so newPosition
is just a reference to Unit.
Change the function to return the new coordinate:
fun updateCoordinate(playerCoordinate: Coordinate): Coordinate {
return coordinate playerCoordinate
}
I recommend giving this function a better name. The word "update" implies that it is mutating the instance that is passed to it instead of calculating a new one.
Logically, since this function is something that adds something to a coordinate, it would make more sense for legibility and easy reasoning of your code to invert it (swap the receiver and parameter). So I would pull this function out of the enum class and make it a Coordinate extension function.
fun Coordinate.moved(direction: Direction): Coordinate {
return this direction.coordinate
}
but you'll have to make the Direction's coordinate
property public or internal
.