Bug in learn to code 2

Hey,


I was using the learning to code 2, and I was in the Parameters sections in the last challenge "Twin Peaks", I tried every possible option to solve the challenge using "pseudocode" and all other things that we learn throw the lessions, but my character is jumping off the world, and walking into empty space, I would like to know if that is a bug or the developers plan that so we can magically figure out a way to solve that challenge. I am using the swift playground app in an iPad mini 3.


Regards.

Replies

here is the solution below:





let totalGems = randomNumberOfGems

  var gemCounter = 0

  let expertOne = Expert()
  let expertTwo = Expert()



  world.place(expertOne, facing: north, atColumn: 1, row: 4)
  world.place(expertTwo, facing: north, atColumn: 3, row: 0)


  func starting() {
    if expertTwo.isOnGem {
        expertTwo.collectGem()
        gemCounter += 1
    } else {
        expertOne.turnLockUp()
        expertOne.turnLockUp()
        expertOne.turnLockUp()
        expertTwo.turnRight()
        expertTwo.moveForward()
        expertTwo.turnLeft()
    }
  }
  func algorithm() {
    if expertTwo.isOnGem {
        expertTwo.collectGem()
        gemCounter += 1
        expertTwo.moveForward()
    } else {
        expertTwo.moveForward()
    }
    expertTwo.turnLeft()
    if expertTwo.isOnGem {
        expertTwo.collectGem()
        gemCounter += 1
        expertTwo.moveForward()
    } else {
        expertTwo.moveForward()
    }
    expertTwo.turnLeft()
    expertTwo.turnLeft()
    if expertTwo.isOnGem {
        expertTwo.collectGem()
        gemCounter += 1
        expertTwo.moveForward()
    } else {
        expertTwo.moveForward()
    }
    expertTwo.turnLeft()
  }


  func solving() {
    expertOne.turnLockUp()
    algorithm()
    for i in 1 ... 3 {
        expertOne.turnLockDown()
        algorithm()
    }
    expertOne.turnLockUp()
    algorithm()
    expertOne.turnLockDown()
    algorithm()
    expertOne.turnLockUp()
    expertOne.turnLockUp()
    expertTwo.turnRight()
    expertTwo.moveForward()
    if expertTwo.isOnGem {
        expertTwo.collectGem()
        gemCounter += 1
        expertTwo.turnLeft()
        expertTwo.turnLeft()
    } else {
        expertTwo.turnLeft()
        expertTwo.turnLeft()
    }
    expertTwo.moveForward()
    expertTwo.turnLeft()
  }

  /

   starting()
  while gemCounter != totalGems{
    if expertTwo.isOnGem {
        expertTwo.collectGem()
        gemCounter += 1
    } else {
        solving()
    }
  }



// Enjoy it.       Ommshi

hi master,

i have a problem on the "learn to code2" that sounds like a bug. in the 5th part called in french " Création du monde" or World Creation, episode "îles flottantes " (or maybe floating islands): after creating the world, the character doesn't want to move and no error is reported. I've tried everything like turnLeft etc...

Maybe i forgot something...

Can you help me please ?

Here's my code :


let character = Character()

let redPortal = Portal(color: #colorLiteral(red: 0.925490200519562, green: 0.235294118523598, blue: 0.10196078568697, alpha: 1.0))

let greenPortal = Portal(color: #colorLiteral(red: 0.341176480054855, green: 0.623529434204102, blue: 0.168627455830574, alpha: 1.0))

world.place(Character(), facing: south, atColumn: 3, row: 3)

world.place(Stair(), facing: north, atColumn: 3, row: 2)

world.place(Block(), atColumn: 3, row: 1)

world.place(Block(), atColumn: 5, row: 3)

world.place(Block(), atColumn: 7, row: 3)

world.place(Block(), atColumn: 7, row: 5)

world.place(Block(), atColumn: 7, row: 4)

world.place(Block(), atColumn: 3, row: 0)

world.place(Block(), atColumn: 1, row: 6)

world.place(redPortal, atStartColumn: 3, startRow: 0, atEndColumn: 6, endRow: 6)

world.place(greenPortal, atStartColumn: 7, startRow: 5, atEndColumn: 3, endRow: 7)

world.place(Stair(), facing: west, atColumn: 2, row: 0)

world.place(Stair(), facing: east, atColumn: 2, row: 7)

world.place(Block(), atColumn: 1, row: 2)

world.place(Stair(), facing: north, atColumn: 5, row: 5)

world.place(Stair(), facing: south, atColumn: 7, row: 4)

character.moveForward()



Thanks !

This is a simple fix. You created a Character constant as shown below:


let character = Character()


The problem in the code is that you did not place the constant, character, in the world. Instead, you created a new instance of Character() in the code shown below:


world.place(Character(), facing: south, atColumn: 3, row: 3)


Therefore, you are trying to move the constant, character, that was not placed. Replace the above code with the code shown below, and the move command, character.moveForward(), will work correctly.


world.place(character, facing: south, atColumn: 3, row: 3)




NOTE: It is not a good idea to name variables or constants using the name of a type, even though the first letter is lowercase. To avoid this mistake in the future, use either a prefix or suffix when naming variables or constants. If you would have named the constant myCharacter or character1, you would have quickly found the error yourself.


I hope this reply has been helpful, and keep up the good work with learning to code my friend.

I have a solution too. So I guess you had not tried everything possible. They are not easy.

let expert0 = Expert()
let expert1 = Character()
var gemNum = 0
var ctrlNum = 0
world.place(expert0, facing: .north, atColumn: 0, row: 4)
world.place(expert1, facing: .north, atColumn: 3, row: 0)
func turnAround()
{
    expert1.turnRight()
    expert1.turnRight()
}
func ctrlLock()
{
    if expert1.isBlocked
    {
        turn()
        if ctrlNum < 4
        {
            expert0.turnLockUp()
            ctrlNum += 1
        }
        else
        {
            for i in 1 ... 4
            {
                expert0.turnLockDown()
                ctrlNum -= 1
            }
        }
        turnAround()
    }
}
func turn()
{
    if expert1.isBlockedLeft && !expert1.isBlockedRight
    {
        expert1.turnRight()
        expert1.moveForward()
        if expert1.isOnGem
        {
            expert1.collectGem()
            gemNum += 1
        }
        turnAround()
        expert1.moveForward()
        expert1.turnRight()
    }
    else if !expert1.isBlockedLeft && expert1.isBlockedRight
    {
        
        expert1.turnLeft()
        expert1.moveForward()
        if expert1.isOnGem
        {
            expert1.collectGem()
            gemNum += 1
        }
        turnAround()
        expert1.moveForward()
        expert1.turnLeft()
    }
    if !expert1.isBlockedLeft && !expert1.isBlockedRight
    {
        expert1.turnLeft()
        expert1.moveForward()
        if expert1.isOnGem
        {
            expert1.collectGem()
            gemNum += 1
        }
        turnAround()
        expert1.moveForward()
        expert1.moveForward()
        if expert1.isOnGem
        {
            expert1.collectGem()
            gemNum += 1
        }
        turnAround()
        expert1.moveForward()
        expert1.turnRight()
    }
}
while gemNum != totalGems
{
    if expert1.isOnGem
    {
        expert1.collectGem()
        gemNum += 1
    }
    if !expert1.isBlocked
    {
        expert1.moveForward()
    }
    ctrlLock()
    turn()
}

//hope this helps ^_^

hi, regarding this, i had another problem.


when calling the method "moveForward()" i have to define which instance is using it, so it would be

" expertOne.moveForward()"

but if i want to create a new function, to tell the instance to move forward a certain number of steps, i would write:



let expertOne = Expert()

func moveSteps(steps : Int)

{for i in 1...steps {expertOne.moveForward()}

}


however if i have two or more instance of Expert(), i don't want to make different functions for each instance, so

is there a way to code like this:


func moveSteps(who: [some-data-type], steps: Int)

{for i in 1...steps

{who.moveForward()}

}


so that everytime i can just call

moveSteps (who: expertTwo; steps: 4)

then expertTwo will execute "expertTwo.moveForward()" 4 times,

my code was definitely unacceptable, it's just for discussion sake. Any idea if i can realize this? like letting String becoming an instance name?


Much appriciated.

i ah... i think i did it in a wrong way. Since i know that the character can jump, so i just ask one charactor jump and sweep the map for required gems. and it worked.


but if the character can't jump at all, then i haven't figured out how to solve it yet.


=====update======

for the sake of seeking the true, i just did my thought through version which uses two experts, no jumping. and i'm super lazy, so i created several functions for the computer to determind what to do. i only lower or raise the level like several time until task complete.


in a word, i let it automate.

i've done 2 versions since the game asked me to exhaust all resource acquired previously. so here are my two solutions:

==============cheating code==============


let xp=Expert()
let ch=Character()
world.place(xp, facing:.north, atColumn: 0, row: 4)
world.place(ch, facing:.north, atColumn: 2, row: 0)

var countGem=0

func aCycle(){
    for i in 1...6{
        if countGem < totalGems {
            if ch.isOnGem{
                ch.collectGem()
                countGem += 1
            }
            ch.jump()
        }
       
    }
   
}
func halfMission(){
    aCycle()
    ch.turnRight()
    ch.jump()
    ch.turnRight()
    aCycle()
    ch.turnLeft()
    ch.jump()
    ch.turnLeft()
    aCycle()
}
halfMission()
ch.turnLeft()
ch.turnLeft()
halfMission()



===============thought through code========


let totalGems = randomNumberOfGems

let xp1 = Expert()
let xp2 = Expert()

var levelCount=0 //count where the levels are, to determind to move up or down
var gemCount=0
world.place(xp1, facing:.north, atColumn:0, row:4)
world.place(xp2, facing:.north, atColumn:3, row:0)
// place expert 1 and 2 on the map
func collectCount (){
    if xp2.isOnGem{
        xp2.collectGem()
        gemCount += 1
    }
}
//create a function that determins whether isOnGem, then collect and countGem

func solveSpot(){
    if xp2.isOnGem{
        collectCount()
    }
    if !xp2.isBlockedLeft{
        xp2.turnLeft()
        xp2.moveForward()
        collectCount()
        xp2.turnLeft()
        xp2.turnLeft()
        xp2.moveForward()
        xp2.turnLeft()
    }
    if !xp2.isBlockedRight{
        xp2.turnRight()
        xp2.moveForward()
        collectCount()
        xp2.turnRight()
        xp2.turnRight()
        xp2.moveForward()
        xp2.turnRight()
    }
    else if xp2.isBlockedLeft && xp2.isBlockedRight {
    }
    if !xp2.isBlocked{xp2.moveForward()}
    else if xp2.isBlocked {xp2.turnLeft()
        xp2.turnLeft() //turn around at the end of the road
    }
   
}
//this function solve each row, if it's not block left or right, go and check gems, yes gem? get it and return, no gem? just return.

func solveColumn(){
    for i in 1...7 {
        if gemCount < totalGems {
            solveSpot()
        }
    }
}
//solve the whole column automatically

func upCycle(){
    xp1.turnLockUp()
    levelCount += 1
    solveColumn()
}
//move the lock up and solve a column automatically

func downCycle(){
    xp1.turnLockDown()
    levelCount -= 1
    solveColumn()
}
//move the lock down and solve a column automatically

while gemCount < totalGems {
    xp1.turnLockUp()
    if levelCount == 1{
        for i in 1...3 {
            upCycle()
        }
    }
    if levelCount == 3{
        for i in 1...3 {
            downCycle()
        }
    }
}
//b4 required gems are collected, move up level then sweep the whole 3 column for accessible avilable gems. then at the end, if still need more gems, move down and repeat the cycle.

i like the idea of level count. I was inpired by it.

then i belived i took a different approach to solve the problem.

In some case if totalGems > 10, the problem may not be solved. Since total gems is random sometimes it have to moveforward the whole way and turn around 2 times and keep moveForward to continue collecting Gems. You can try more times after your coding.



Here is my solution.


let expert=Expert()
world.place(expert, facing: north, atColumn: 0, row: 4)
expert.turnLockUp()

let character=Character()
world.place(character, facing: south, atColumn: 4, row: 6)

var numOfCollected = 0
var numOfStep = 0
while numOfCollected < randomNumberOfGems {
   
    if character.isOnGem{
        character.collectGem()
        numOfCollected += 1
    }
    else if numOfStep == 14 || numOfStep == 29 {
        //every cycle plus 15 of steps
        character.turnRight()
        character.turnRight()
        numOfStep += 1
    }
    else if character.isBlocked {
        numOfStep += 1
        if character.isBlockedLeft && (numOfStep == 7 || numOfStep == 22 || numOfStep == 37){
            //every cycle plus 15 of steps
            character.turnRight()
            character.moveForward()
            character.turnRight()
        }
           
        else if character.isBlockedRight && (numOfStep == 8 || numOfStep == 23 || numOfStep == 38) {
            //every cycle plus 15 of steps
            character.turnLeft()
            character.moveForward()
            character.turnLeft()
        }
        else {
            character.jump()
           
        }
    }
    else {
        character.moveForward()
    }
}

Here is my solution. Character is looped and checking Gems count.

let totalGems = randomNumberOfGems

let expert = Expert() 
let character = Character()

var gemCounter = 0

func go() {
        if character.isBlocked {
            character.jump()
        }
        else {
            character.moveForward()
        }

            if character.isOnGem {
                character.collectGem()
                gemCounter += 1
            }
        }

func went() {
    for i in 1 ... 6 {
        go()
    }

}

world.place(expert, facing: .north, atColumn: 0, row: 4)
expert.turnLockUp()
world.place(character, facing: .south, atColumn: 4, row: 6)

while gemCounter != totalGems { 
went()

if !character.isBlockedRight {
    character.turnRight()
    character.moveForward()
    character.turnRight()
}

if character.isOnGem {
    character.collectGem()
}

went()

if !character.isBlockedLeft {
    character.turnLeft()
    character.moveForward()
    character.turnLeft()
}

went()

    world.place(character, facing: .south, atColumn: 4, row: 6)
}

let totalGems = randomNumberOfGems var gemCounter = 0 let character = Character() while gemCounter < totalGems {     for j in 0...6 {         for i in 2...4 {             world.place(character, atColumn: i, row: j)             if character.isOnGem {                 character.collectGem()                 gemCounter = gemCounter + 1             }         }     } }