class Balloon : Movable { static val sideSpeed = 20 // AirBalloon sets this to SOUTH. var direction = NORTH override fun begin() { super.begin() speed = speed / 2 } override fun myTurn() { val north = lookNorth() if (north.squashable( NORTH )) { moveNorth() } else { if ( north.rounded( SOUTH_WEST ) && canRoll(-1) ) { roll( -1 ) } else if ( north.rounded( SOUTH_EAST ) && canRoll(1) ) { roll( 1 ) } } } fun roll( dx : int) { moveDelta(dx, 0, sideSpeed ) } fun canRoll( dx : int ) : boolean { val side = lookDelta( dx, 0, sideSpeed ) if (! ( side.isEmpty() ) ) { return false } val above = lookDelta( dx, if (direction == NORTH) 1 else -1 ) return above.squashable( direction ) } override fun canPush( direction : int, speed : int, strength : int ) : boolean { if ( isMoving() ) return false if ( direction == this.direction) return false val next = look( direction, speed ) if ( next.squashable( direction ) ) { return true } if (next == this) { println( "Eek! Ballon would have caused stack overflow!" ) return false } return next.canPush( direction, speed, 0 ) } override fun rounded( direction : int ) = true override fun copyable() = true }