Bygg et Hus

Introduksjon

I denne leksjonen vil vi se litt på hvordan vi kan få en robot til å bygge et hus for oss. Underveis vil vi lære hvordan vi kan bruke løkker og funksjoner for å gjenta ting som gjøres flere ganger.

Steg 1: Prøv selv først

Vi har tidligere lært om hvordan roboter behøver fuel for å kjøre og byggemateriell for å bygge. Pass på at roboten din har nok fuel mens du gjør oppgavene under.

Tidligere har vi sett hvordan vi bruker turtle-biblioteket for å få roboter til å gjøre forskjellige ting. Spesielt bruker vi kommandoene

turtle.forward(), turtle.back(), turtle.turnLeft(), turtle.turnRight(), turtle.up(), turtle.down()

for å flytte roboten. Videre kan vi bruke turtle.place() eller turtle.placeDown() for å plassere ut en kloss, og vi har sett at vi kan bruke for-løkker for å gjenta ting.

Sjekkliste

  • for i = 1, 5 do
        turtle.back()
        turtle.place()
    end
    

    Kjør programmet. Bygger roboten en liten vegg av klosser?

Prøv selv

Jobb videre med bygghus-programmet, og se om du klarer å utvide det slik at roboten bygger et enkelt hus med fire vegger og tak. Bruk litt tid på denne oppgaven slik at du får tenkt gjennom hva som kreves for å bygge et enkelt hus.

Et par små tips:

  • Det er nok å bruke kommandoene vi har nevnt så langt.

  • Du vil helst bruke flere for-løkker. For at dette skal virke må du bruke forskjellige variabler, det vil si at du må bytte ut i men andre bokstaver eller variabelnavn i de andre løkkene du lager.

  • For å lage dør eller vinduer i huset ditt vil det enkleste være å bruke if-tester for å sjekke hvor på huset roboten bygger.

Sjekkliste

  • Ingen skriver programmer riktig første gangen, og det er veldig nyttig å diskutere både hvordan man løser en utfordring, og hvilke metoder som ikke virker.

I de neste stegene vil vi utvikle et mer avansert program for husbyggeroboten vår. Underveis vil vi lære om noen nye kommandoer og konsepter som gjør at programmet blir både kraftigere og enklere.

Steg 2: Flyvende robot

Et problem du kanskje allerede har oppdaget er at roboten innimellom krasjer i ting, og derfor ender opp litt andre steder enn du hadde tenkt. Et eksempel på dette er i den følgende koden, hvor meningen var å bygge grunnmuren til et hus.

Sjekkliste

  • for i = 1, 4 do
        for j = 1, 5 do
            turtle.back()
            turtle.place()
        end
        turtle.turnLeft()
    end
    

    Lagre og kjør programmet? Ser du problemet?

  • Endre programmet som følger:

    turtle.up()                                   -- ny linje
    for j = 1, 4 do
        for i = 1, 5 do
            turtle.forward()                      -- endret linje
            turtle.placeDown()                    -- endret linje
        end
        turtle.turnLeft()
    end
    

    Når du kjører programmet nå klarer roboten å bygge hele firkanten uten å krasje! Vi vil bruke turtle.placeDown() i resten av denne leksjonen.

Steg 3: Bygg en vegg

Når vi skal skrive større programmer (som for eksempel et som bygger et hus) er det lurt å prøve dele programmer i deloppgaver som er relativt enkle. Da kan vi heller kode disse deloppgavene som typisk er enklere enn hele det store programmet.

En naturlig deloppgave når vi skal bygge et hus er å bygge en vegg. La oss starte med det! Husk å teste at robotprogrammet ditt virker etterhvert som du skriver det inn.

Sjekkliste

  • turtle.up()
    for i = 1, 5 do
        turtle.placeDown()
        turtle.forward()
    end
    
  • for j = 1, 3 do                               -- ny linje
        turtle.up()
        for i = 1, 5 do
            turtle.placeDown()
            turtle.forward()
        end
    
        for i = 1, 5 do                           -- ny linje
            turtle.back()                         -- ny linje
        end                                       -- ny linje
    end                                           -- ny linje
    
  • local hoyde = 3                               -- ny linje
    local lengde = 5                              -- ny linje
    
    for j = 1, hoyde do                           -- endret linje
        turtle.up()
        for i = 1, lengde do                      -- endret linje
            turtle.placeDown()
            turtle.forward()
        end
    
        for i = 1, lengde do                      -- endret linje
            turtle.back()
        end
    end
    

    Legg merke til at vi skriver hoyde med o og ikke med ø. Siden ComputerCraft er et engelsk programmeringsspråk kan ikke variabler ha navn som inneholder de norske bokstavene æ, ø og å.

Prøv selv

Prøv å endre verdiene av variablene hoyde og lengde. Gjør roboten som du ber den om?

Steg 4: Funksjoner

Vi har nå lært roboten hvordan den lager en vegg. For at vi enkelt skal kunne bruke dette senere vil vi definere som en funksjon. I praksis betyr det at vi lærer roboten en ny kommando, som vi senere kan bruke på samme måte som de innebygde kommandoene (som for eksempel turtle.forward()).

Sjekkliste

  • function byggVegg()                           -- ny linje
        local hoyde = 3
        local lengde = 5
    
        for j = 1, hoyde do
            turtle.up()
            for i = 1, lengde do
                turtle.placeDown()
                turtle.forward()
            end
    
            for i = 1, lengde do
                turtle.back()
            end
        end
    end                                           -- ny linje
    
  • byggVegg()
    

    Nå sier vi at roboten også skal bygge veggen.

  • function byggVegg(hoyde, lengde)              -- endret linje
        for j = 1, hoyde do
            turtle.up()
            for i = 1, lengde do
                turtle.placeDown()
                turtle.forward()
            end
    
            for i = 1, lengde do
                turtle.back()
            end
        end
    end
    
    byggVegg(3, 5)                                -- endret linje
    

Prøv selv

Endre tallene 3 og 5 i den siste linjen. Bygger roboten vegger av forskjellig størrelse?

Steg 5: Bygg et hus

Nå som vi vet hvordan vi bygger en vegg er vi ikke veldig langt unna å bygge et enkelt hus. La oss prøve å sette sammen fire vegger!

Sjekkliste

  • for i = 1, 4 do
        byggVegg(3, 5)
        turtle.turnLeft()
    end
    

    Hva skjer når du kjører programmet ditt?

  • Vi burde legge til litt kode i byggVegg() slik at roboten er klar til å bygge neste vegg. Dette kan vi gjøre ved å gå nedover i stedet for bakover etter at vi har bygd ferdig veggen. Endre funksjonen byggVegg slik at den ser slik ut:

    function byggVegg(hoyde, lengde)
        for j = 1, hoyde do
            turtle.up()
            for i = 1, lengde do
                turtle.placeDown()
                turtle.forward()
            end
    
            if j < hoyde then                     -- ny linje
                for i = 1, lengde do
                    turtle.back()
                end
            end                                   -- ny linje
        end
    
        for j = 1, hoyde do                       -- ny linje
            turtle.down()                         -- ny linje
        end                                       -- ny linje
    end
    
  • function byggVegg(hoyde, lengde)
        for j = 1, hoyde do
            turtle.up()
            for i = 1, lengde do
                turtle.placeDown()
                if i < lengde then                -- ny linje
                    turtle.forward()
                end                               -- ny linje
            end
    
            if j < hoyde then
                for i = 1, lengde - 1 do          -- endret linje
                    turtle.back()
                end
            end
        end
    
        turtle.forward()                          -- ny linje
        for j = 1, hoyde do
            turtle.down()
        end
    end
    

Nå har huset vårt fått fire vegger. Vi skal snart se på hvordan vi kan bygge taket, men først skal vi se på hvordan vi kan passe på at roboten har materiale å bygge med.

Steg 6: Mer byggemateriale

Et problem du helt sikkert har oppdaget nå, er at roboten stadig går tom for byggemateriale. Selv om roboten har 16 slots for materiale, vil den bare bruke en av dem. Ved hjelp av funksjonene getItemCount(), getSelectedSlot() og select() i turtle-biblioteket kan vi gjøre noe med dette.

Sjekkliste

  • function byggVegg(hoyde, lengde)
        for j = 1, hoyde do
            turtle.up()
            for i = 1, lengde do
                plasser()                         -- endret linje
                if i < lengde then
                    turtle.forward()
                end
            end
    
            if j < hoyde then
                for i = 1, lengde - 1 do
                    turtle.back()
                end
            end
        end
    
        turtle.forward()
        for j = 1, hoyde do
            turtle.down()
        end
    end
    
    function plasser()                            -- ny linje
        while turtle.getItemCount() == 0 do       -- ny linje
            slot = turtle.getSelectedSlot()       -- ny linje
            if slot < 16 then                     -- ny linje
                turtle.select(slot + 1)           -- ny linje
            else                                  -- ny linje
                turtle.select(1)                  -- ny linje
            end                                   -- ny linje
        end                                       -- ny linje
    
        turtle.placeDown()                        -- ny linje
    end                                           -- ny linje
    
    for i = 1, 4 do
        byggVegg(3, 5)
        turtle.turnLeft()
    end
    

    Les nøye gjennom den nye funksjonen plasser(). Skjønner du hva den gjør?

    Det siste funksjonen gjør er å plassere ut en kloss med turtle.placeDown(). Men før den plasserer ut klossen bruker vi turtle.getItemCount() til å sjekke om det finnes tilgjengelig byggemateriale. Hvis det er 0 klosser i sloten roboten bruker, går vi inn i while-løkken hvor vi velger en annen slot. Vi sjekker først hvilken slot roboten bruker med turtle.getSelectedSlot(). Hvis dette ikke er den siste sloten (slot 16), bruker vi turtle.select() til å velge den neste sloten. Hvis vi allerede er på den siste sloten velger vi heller den første.

Prøv selv

Nå som roboten bruker flere slotter kan du eksperimentere med å legge forskjellig materiale i de forskjellige slottene. På den måten kan du for eksempel få roboten til å bygge et fargerikt hus!

Steg 7: Vi trenger et tak!

Nå er det på tide å lære roboten hvordan den bygger tak på huset vårt!

Sjekkliste

  • function byggHus(hoyde, bredde, dybde)
        byggVegg(hoyde, bredde - 1)
        turtle.turnLeft()
        byggVegg(hoyde, dybde - 1)
        turtle.turnLeft()
        byggVegg(hoyde, bredde - 1)
        turtle.turnLeft()
        byggVegg(hoyde, dybde - 1)
        turtle.turnLeft()
    end
    
    byggHus(3, 5, 4)
    

    Ser du hvorfor vi bruker bredde - 1 i stedet for bredde? Sjekk at huset ditt får riktig størrelse med denne koden!

  • byggTak(bredde, dybde)
    
  • function byggTak(bredde, dybde)
        turtle.up()
        for j = 1, dybde do
            for i = 1, bredde do
                plasser()
                turtle.forward()
            end
    
            for i = 1, bredde do
                turtle.back()
            end
            turtle.turnLeft()
            turtle.forward()
            turtle.turnRight()
        end
    end
    

Steg 8: Dører og vinduer

Da er vi nesten ferdig med programmet vårt. Det som mangler på at dette ligner et skikkelig hus er dører og vinduer.

Sjekkliste

  • function byggVegg(hoyde, lengde, dor, vindu)    -- endret linje
        for j = 1, hoyde do
            turtle.up()
            for i = 1, lengde do
                if not (j <= 2 and i == dor or      -- ny linje
                        j == 2 and i == vindu) then -- ny linje
                    plasser()
                end                                 -- ny linje
                if i < lengde then
                    turtle.forward()
                end
            end
    
            if j < hoyde then
                for i = 1, lengde - 1 do
                    turtle.back()
                end
            end
        end
    
        turtle.forward()
            for j = 1, hoyde do
                turtle.down()
        end
    end
    

    Med den nye if-testen lager vi en dør ved å ikke bygge de to nederste klossene, mens vinduene lages i høyde 2.

  • function byggHus(hoyde, bredde, dybde)
        byggVegg(hoyde, bredde - 1, 2, nil)
        turtle.turnLeft()
        byggVegg(hoyde, dybde - 1, nil, math.floor(dybde / 2))
        turtle.turnLeft()
        byggVegg(hoyde, bredde - 1, nil, bredde - 2)
        turtle.turnLeft()
        byggVegg(hoyde, dybde - 1, nil, 2)
        turtle.turnLeft()
    
        byggTak(bredde, dybde)
    end
    

    Legg merke til at vi bruker det spesielle ordet nil hvis vi ikke skal lage en dør eller et vindu på en gitt vegg. Skjønner du hvor vinduene på de forskjellige veggene plasseres?

Steg 9: Forskjellige hus

Vi har nå laget et program som gjør at roboten vår er en husbyggerobot! Vi skal bare gjøre en ørliten forbedring før vi sier oss helt ferdige!

Nå har vi kodet hvor stort huset skal være inn i den siste linjen i programmet vårt, byggHus(3, 5, 4). Det betyr at om vi vil bygge et større eller mindre hus, må vi forandre på programmet. Dette er tungvint. Det vil være bedre om vi kan fortelle hvor stort huset skal være når vi starter programmet.

Sjekkliste

  • local tArgs = { ... }
    if #tArgs ~= 3 then
        print('Skriv: bygghus <høyde> <bredde> <dybde>')
        print('F.eks. bygghus 3 5 4')
        return
    end
    
    byggHus(tonumber(tArgs[1]), tonumber(tArgs[2]),
            tonumber(tArgs[3]))
    

    Dette kan virke litt mystisk, og vi skal ikke forklare alt som skjer her nå. Vi vil komme tilbake til dette i senere leksjoner.

Forbedre denne siden

Funnet en feil? Kunne noe vært bedre? Hvis ja, vennligst gi oss tilbakemelding ved å lage en sak på Github eller fiks feilen selv om du kan. Vi er takknemlige for enhver tilbakemelding!

Rapporter et problemVis koden og fiks selv