Πέμπτη, 18 Φεβρουαρίου 2016

Εγχειρίδιο της Μ2000 - Τεύχος 11ο

5.10 Παραδείγματα Ροής Εκτέλεσης

Θα δούμε μερικά παραδείγματα όπου η ροή προγράμματος αλλάζει με μη συνηθισμένο τρόπο!

5.10.1 Παράδειγμα Αντιπρόσωπος!

Εδώ έχουμε ένα παράδειγμα με αντικείμενα που η αλλαγή ροής γίνεται σε Αντιπρόσωπο, που κρατάει τη αλλαγή! Δηλαδή το αντικείμενο Αντιπρόσωπος κρατάει το αντικείμενο που θα χρησιμοποιήσει, και δύναται να το αλλάξει. Αλλάζοντας το αντικείμενο αλλάζει και το αποτέλεσμα μιας συγκεκριμένης ενέργειας

(Αυτό θέλαμε, να αλλάξουμε την ροή προγράμματος, αλλά δεν το κάνουμε με όλους τους άλλους τρόπους αλλά μέσω αντικειμένου, αντικειμένων στην περίπτωσή μας)

Κλάση Για_Εκτυπωτή {
      Τμήμα Αποστολή {
            Διάβασε α$
            Τύπωσε "Προς Εκτυπωτή "+α$
      }
}
Κλάση Για_Οθόνη {
      Τμήμα Αποστολή {
            Διάβασε α$
            Τύπωσε "Προς Οθόνη "+α$
      }
}
Κλάση Αντιπρόσωπος {
     Πίνακας α(1)
     Κλάση Για_Κάδο {
           Τμήμα Αποστολή {
                 Διάβασε α$
                 Τύπωσε "Προς Κάδο Ανακύκλωσης "+α$
           }
     }
      Τμήμα Αντιπρόσωπος {
            Αν Ταύτιση("Ο") Τότε {Διάβασε .α(0) } Αλλιώς .α(0)=.Για_Κάδο()
      }
      Συνάρτηση Αποστολή {
      .α(0).Αποστολή
      =0
      }
}
Πίνακας β(4)
β(1)=Αντιπρόσωπος(Για_Οθόνη())
Για β(1) {
      Κάλεσε .Αποστολή("Στη Κατασκευή")
}
γ=Αντιπρόσωπος()
Για γ {
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος Για_Οθόνη()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος Για_Εκτυπωτή()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
}
Για β(1) {
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος Για_Οθόνη()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος Για_Εκτυπωτή()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            Τύπωσε Έγκυρο(.αα)
}
Τύπωσε Τύπος$(β(2)) \\ Empty


Ο πίνακας β() δεν έχει αρχικοποιηθεί με κάποια κλάση ή ομάδα, οπότε άλλα στοιχεία όπως το 2 είναι άδεια. Αυτό δείχνει η τελευταία εντολή. Ένας πίνακας αν αρχικοποιηθεί με μια κλάση ή ομάδα τότε συναρτήσεις και τα τμήματα γράφονται σε έναν κοινό χώρο, και δεν δύναται να αλλαχθούν μόνιμα (πρόσκαιρα όλα γίνονται). Εδώ η β() μπορεί να πάρει διάφορα αντικείμενα, επειδή δεν έχει αρχικοποιηθεί με ένα. Ακόμα και στην περίπτωση που έχουμε αρχικοποίηση με αντικείμενο, μπορούμε να προσθέτουμε ιδιότητες/πίνακες επειδή αυτά γράφονται χωριστά σε κάθε αντικείμενο.

Στο παράδειγμα φαίνεται η χρήση επώνυμου αντικειμένου (γ) και η χρήση ανώνυμου (β(1))

Χωρίς χρήση πρόσθετων κλάσεων. Κρατάμε απλά μια ισχνή αναφορά!

Συνάρτηση Για_Εκτυπωτή {
            Διάβασε α$
            Τύπωσε "Προς Εκτυπωτή "+α$
}
Συνάρτηση Για_Οθόνη {
            Διάβασε α$
            Τύπωσε "Προς Οθόνη "+α$
}
Κλάση Αντιπρόσωπος {
Ιδιωτικό:
      κ$
      Συνάρτηση Για_Κάδο {
            Διάβασε α$
            Τύπωσε "Προς Κάδο Ανακύκλωσης "+α$
      }
Δημόσιο:
      Τμήμα Αντιπρόσωπος {
            Αν Ταύτιση("Γ") τότε Διάβασε .κ$
      }
      Συνάρτηση Αποστολή {
      \\ δεν σηκώνουμε από το σωρό
      \\ την εισαγωγή, θα περάσει στη συνάρτηση
      \\ μέσω της Κάλεσε
      Αν .κ$=""  τότε {
                  \\ η .Για_Κάδο είναι ιδιωτική
                 Κάλεσε κενή Συνάρτηση .Για_Κάδο
      } Αλλιώς {
                  Ένωσε ισχνή .κ$ στο αα()
                  Κάλεσε Κενή Συνάρτηση αα
            }
      }
}
Πίνακας β(4)
β(1)=Αντιπρόσωπος(&Για_Οθόνη())
Για β(1) {
      Κάλεσε .Αποστολή("Στη Κατασκευή")
}
γ=Αντιπρόσωπος()
Για γ {
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος &Για_Οθόνη()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος &Για_Εκτυπωτή()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
}
Για β(1) {
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος &Για_Οθόνη()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            .Αντιπρόσωπος &Για_Εκτυπωτή()
            Κάλεσε .Αποστολή("Κάτι γράφει εδώ!")
            Τύπωσε Έγκυρο(.αα)
}


5.10.2 Ο Πέτρος, ο Λύκος και το Πρόβατο!

Στο παράδειγμα τα αντικείμενα εναλλάσσονται, με συνέπεια η ροή του προγράμματος να εξαρτιέται από το ποιο αντικείμενο κάθε φορά επεξεργαζόμαστε!
Στην εντολή αυτή βάζουμε στην θέση_επιβατών με αριθμό 0, ένα αντικείμενο που λέγεται όχθη και έχει τρία άτομα. Μπορούμε να μπερδέψουμε τα άτομα, αλλά στο τέλος το πρόγραμμα θα δώσει μια λύση, αν και η σειρά που θα δώσει εξαρτιέται από αυτήν εδώ τη σειρά. Εδώ η λύση δεν περιλαμβάνει και την σειρά εμφάνισης!

Θέση_επιβατών(0)=μέρος("Όχθη Α"άτομο("λύκος","Τρώει","Επιβάτης")άτομο("Πέτρος","Αδιάφορο","Οδηγός")άτομο("πρόβατο","Τρώγεται","Επιβάτης") )

Το πρόγραμμα πρέπει να περάσει τα άτομα από την όχθη Α στην Β. Και το κάνει με απλούς κανόνες. Κατά μια έννοια είναι παράδειγμα τεχνητής νοημοσύνης, γιατί δεν θα αφήσει σε καμία περίπτωση τον λύκο με το πρόβατο μαζί! Αυτό που γίνεται όμως είναι να έχει την λογική γραμμένη με κώδικα, όχι να την "μαθαίνει" (το καλύτερο για να λέμε για Τ.Ν.)
Θα μπορούσε κανείς να μην το δει σαν Τ.Ν. αλλά σαν ένα αυτόματο. Σημασία έχει ότι δέχεται διαφορετική είσοδο (στη θέση επιβατών 0) και δίνει μια λύση με το ποιος θα περάσει με τι, και αυτή είναι πάντα εντός του "επιτρεπτού" ακόμα και αν είναι με διαφορετικό μονοπάτι, π.χ. να πάρει το λύκο πρώτα.
Η απόκριση του προγράμματος (τα μηνύματα και το τι γίνεται) μπορεί να είναι διαφορετική (ανάλογα με την σειρά που μπαίνουν στη θέση τα άτομα) αλλά στην ουσία να έχουμε το επιθυμητό αποτέλεσμα, μια διαδικασία άψογη! Δηλαδή εδώ δεν μας ενδιαφέρει μόνο το τελικό αποτέλεσμα αλλά και τα επιμέρους μερικά αποτελέσματα (Δεν θέλουμε λύκο και πρόβατο μαζί).

Το πρόγραμμα μεταφέρει αντικείμενα βάσει ιδιοτήτων, Η μεταφορά είναι συνδυασμός ελέγχου ιδιοτήτων. Η ροή του προγράμματος ελέγχεται από τη θέση των αντικειμένων. Όταν συμπληρωθούν στην όχθη Β τότε τερματίζει το πρόγραμμα. Υπάρχει αυτός ο "κανόνας"που δηλώνει και το επιθυμητό αποτέλεσμα:
            Αν όχθη=2 και .υπάρχουν_άτομα=3 Τότε προς τελικο
Το μυστήριο εδώ είναι ότι δεν φαίνεται αν αυτό θα συμβεί ή όχι. Στην ουσία αν βάλουμε λάθος δεδομένα, δηλαδή τρία πρόβατα...δεν θα μπορέσει ποτέ να τερματίσει το πρόγραμμα.
Δηλαδή η ροή του προγράμματος..μέχρι το τέλος εξαρτιέται από την ύπαρξη ενός "οδηγού" τουλάχιστον. Αυτό το ζήτημα δεν το είχε το προηγούμενο πρόγραμμα. 
Εδώ επειδή έχει περαστεί με το χέρι όπως λέμε η σύνθεση ατόμων στην όχθη Α ξέρουμε ότι δεν υπάρχει θέμα.


Φορμα 80,74
\\ κάθε άτομο Τρώει 1, Τρώγεται 2 , Αδιάφορο 3
Γενικές ενέργεια$(3), ιδιότητα$(2)
ενέργεια$(0)="Τρώει","Τρώγεται","Αδιάφορο"
ιδιότητα$(0)="Οδηγός","Επιβάτης"
Κλάση άτομο {
      όνομα$, τύπος$, ιδιότητα$
      Τμήμα άτομο {
                  Αν Ταύτιση("γ") Τότε Διάβασε .όνομα$
                  Αν Ταύτιση("γ") Τότε Διάβασε .τύπος$
                  Αν Ταύτιση("γ") Τότε Διάβασε .ιδιότητα$
      }
}
Κλάση Μέρος {
      όνομα$, υπάρχουν_άτομα
      Πίνακας ατομο()
      Τμήμα βάλε.άτομο {
            Διάβασε άτομο
            .υπάρχουν_άτομα++
             Πίνακας .άτομο( .υπάρχουν_άτομα)
            .άτομο(.υπάρχουν_άτομα-1)=άτομο
      }
      Τμήμα Μέρος {
            Αν Ταύτιση("S") Τότε Διάβασε .όνομα$
            .υπάρχουν_άτομα <= μέγεθος.σωρού
            Αν .υπάρχουν_άτομα Τότε {
                  Πίνακας .άτομο(.υπάρχουν_άτομα)
                  ι=0 : ενώ όχι κενό { Διάβασε .άτομο(ι) : ι++}
            }
      }
      Συνάρτηση Θα.βγει {
            Διάβασε Ποιος
            Καθαρό υπολογισε
            Αν .υπάρχουν_άτομα>2 Τότε {
                  Πίνακας α(2)
                        Καθαρό κ
                        Για ι=0 Έως 2 {
                              Αν ποιος<>ι Τότε α(κ)=ι : κ++
                        }
                        \\ Τρώει -1
                        \\ Τρώγεται 0
                        \\ Αδιάφορο 1
                        Για ι=0 Έως 1 {
                        Αν .άτομο(α(ι)).τύπος$=ενέργεια$(0) Τότε {υπολογισε-=1
                        } αλλιώς.αν .άτομο(α(ι)).τύπος$=ενέργεια$(2) Τότε υπολογισε+=1
                        }
                 }      
          =υπολογισε>=0
      }
     Συνάρτηση Βγάλε.άτομο {
            Διάβασε ποιος
            = .άτομο(ποιος)
            Αν ποιος+1<.υπάρχουν_άτομα Τότε {
                  Άλλαξε .άτομο(.υπάρχουν_άτομα-1), .άτομο(ποιος)
            }
            .υπάρχουν_άτομα--
            Πίνακας .άτομο(.υπάρχουν_άτομα)
      }
   
}


Γενική Θέση_επιβατών(3)
Θέση_επιβατών(0)=μέρος("Όχθη Α", άτομο("λύκος","Τρώει","Επιβάτης"), άτομο("Πέτρος","Αδιάφορο","Οδηγός"),άτομο("πρόβατο","Τρώγεται","Επιβάτης") )
Θέση_επιβατών(1)=μέρος("Βάρκα")
Θέση_επιβατών(2)=μέρος("Όχθη Β")
Πίνακας Προορισμός$(4)
Προορισμός$(0)="Προς Όχθη Β","Άφιξη στην Όχθη Β","Προς Όχθη Α","Άφιξη στην Όχθη Α"
Θέση_βάρκας=0
Τύπωσε.Θέσεις()


\\ ξεκίνα!
Για Θέση_επιβατών(0) {
      Τοπική κ
      Ενώ κ<.υπάρχουν_άτομα {
            Αν Δεν .Θα.Βγει(κ) Τότε { κ++ } Αλλιώς Έξοδος
      }
      Αν κ<.υπάρχουν_άτομα Τότε {
            Πένα 12 { Τύπωσε "Μπορεί να βγει ο/το "; .ατομο(κ).ονομα$}
            Θέση_επιβατών(1).βαλε.άτομο .βγάλε.άτομο(κ)
       }
}
Τύπωσε.Θέσεις()
\\ θα δούμε Αν μπορεί να φύγει η βάρκα!


Για Θέση_επιβατών(1) {
     Τοπική κ
      Ενώ κ<.υπάρχουν_άτομα {
            Αν .άτομο(κ).ιδιότητα$=ιδιότητα$(1) Τότε { κ++ } Αλλιώς Έξοδος
      }
      Αν κ<.υπάρχουν_άτομα Τότε {
            Πένα 7 { Τύπωσε "Έχουμε οδηγό"}
      } Αλλιως {
            Πένα 12 {Τύπωσε "Χρειάζομαι οδηγό" }
            Τοπική όχθη=0
            Αν θέση_βάρκας>1 Τότε όχθη=2
            Για Θέση_επιβατών(όχθη) {
                  Τοπική κ
                  Ενώ κ<..υπάρχουν_άτομα {
                        Αν ..άτομο(κ).ιδιότητα$=ιδιότητα$(1) Τότε { κ++ } Αλλιώς Έξοδος
                  }                        
                  Αν κ<..υπάρχουν_άτομα Τότε {
                  Τύπωσε "βρήκα οδηγό, ο γνωστός ";..άτομο(κ).όνομα$
                         .βαλε.άτομο ..βγάλε.άτομο(κ)
                         θέση_βάρκας++ : Αν θέση_βάρκας>3 Τότε θέση_βάρκας=0
                  }
            }
      }
}
Τύπωσε.Θέσεις()
Για κκ=1 Έως 3 {
      Αν θέση_βάρκας υπολοιπο 2 =1 Τότε {
            Τύπωσε "κατεβάζω από βάρκα"
            Για Θέση_επιβατών(1) {
                  Τοπική όχθη=0
                  Αν θέση_βάρκας =1 Τότε όχθη=2
                  Τοπική κ =.υπάρχουν_άτομα -1
                  Ενώ κ>=0 {
                        Θέση_επιβατών(όχθη).βαλε.άτομο .βγάλε.άτομο(κ)
                        κ--
                  }
                   θέση_βάρκας++ : Αν θέση_βάρκας>3 Τότε θέση_βάρκας=0
            }
      }
      Τύπωσε.Θέσεις()
      Αν θέση_βάρκας=0 Τότε {
            Πένα 12 {Τύπωσε "Χρειάζομαι Επιβάτη" }
            όχθη=0
            Αν θέση_βάρκας>1 Τότε όχθη=2
            Για Θέση_επιβατών(όχθη) {
                  Τοπική κ
                  Ενώ κ<.υπάρχουν_άτομα {
                        Αν .άτομο(κ).ιδιότητα$=ιδιότητα$(0) Τότε { κ++ } Αλλιώς Έξοδος
                  }                        
                  Αν κ<.υπάρχουν_άτομα Τότε {
                  Τύπωσε "βρήκα επιβάτη! "; .άτομο(κ).όνομα$
                         Θέση_επιβατών(1).βαλε.άτομο .βγάλε.άτομο(κ)
                  }
            }
      }
      όχθη=0
      Αν θέση_βάρκας>1 Τότε όχθη=2
      Για Θέση_επιβατών(όχθη) {
            Αν όχθη=2 και .υπάρχουν_άτομα=3 Τότε προς τελικο
            Πένα 12 {Τύπωσε "Χρειάζομαι οδηγό" }
            Τοπική κ
            Ενώ κ<.υπάρχουν_άτομα {
                  Αν .άτομο(κ).ιδιότητα$=ιδιότητα$(1) Τότε { κ++ } Αλλιώς Έξοδος
            }                        
            Αν κ<.υπάρχουν_άτομα Τότε {
            Τύπωσε "βρήκα οδηγό, ο γνωστός ";.άτομο(κ).όνομα$
                   Θέση_επιβατών(1).βαλε.άτομο .βγάλε.άτομο(κ)
                   θέση_βάρκας++ : Αν θέση_βάρκας>3 Τότε θέση_βάρκας=0
            }
      }
      Τύπωσε.Θέσεις()
}
Τελικο:
Τύπωσε.Θέσεις()
Τέλος
Ρουτίνα Τύπωσε.Θέσεις()
      Τοπική κ
      Για ι=0 Έως 2
            Για Θέση_επιβατών(ι) {
            Πένα 7 { Τύπωσε "Θέση:"; .όνομα$}
               Αν ι=1 Τότε Τύπωσε "Προορισμός:", Προορισμός$(θέση_βάρκας)
                  Αν .υπάρχουν_άτομα Τότε {
                        Για κ=0 Έως .υπάρχουν_άτομα-1
                              Τύπωσε .άτομο(κ).όνομα$;" ";
                        Επόμενο κ
                        Τύπωσε
                  } Αλλιώς {
                        Τύπωσε "Κανένας"
                  }
            }
      Επόμενο ι
Τελος Ρουτινας


Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου