Δευτέρα, 17 Απριλίου 2017

Πρόγραμμα ο Πέτρος, ο Λύκος, το πρόβατο και το χορτάρι

Παλαιότερα είχα δώσε ένα πρόγραμμα με το Πέτρο, το Λύκο και το Πρόβατο. Αυτή τη φορά έβαλα όπως έπρεπε και το χορτάρι. Ο Λύκος τρώει το πρόβατο και το πρόβατο τρώει το χορτάρι.
Χρησιμοποιώ τρια διαφορετικά αντικείμενα, δυο με κλάσεις (κατασκευαστές), μια κλάση για να ετοιμάσουμε τα άτομα, μια αλλη για τις θέσεις, όχθη Α, βάρκα και όχθη Β, και μια ομάδα (με απ΄ευθείας ορισμό) για το χειρισμό της θέσης της βάρκας. Υπάρχει μια επαναληπτική διαδικασία όπου συγχρονίζεται με τη θέση της βάρκας και τερματίζει όταν όλα έχουν περάσει. Υπάρχει ένας τρόπος επιλογής επιβάτη, αλλά και ένας τρόπος επιλογής αν θα πάρει επιβάτη ο Πέτρος. Στην πράξη δεν παίρνει επιβάτη την πρώτη φορά που θα γυρίσει από την όχθη Β και μια ακόμα όταν έχει αφήσει δυο που δεν τρώγονται (Λύκος και χορτάρι).
Η θέση βάρκας είναι αντικείμενο που γυρνάει τιμή, αλλά έχει και ιδιότητες. Έχει μπει και ένας τελεστής στην θέση βάρκας για να γυρνάει αυτόματα το 3 στο 0 (οι θέσεις είναι τέσσερις και μετή την 3 πάμε πάλι στην 1).

Η κεντρική επανάληψη είναι του τύπου Επανέλαβε { } Πάντα και με μια Αν συνθήκη Τότε Έξοδος θα βγούμε από αυτήν.
Οι κλάσεις στην Μ2000 είναι κατασκευαστές ομάδων. Τα μέλη που βρίσκονται μετά το Κλάση: (δείτε την άνω κάτω τελεία στο Κλάση πριν) θα χρησιμοποιηθούν στην κατασκευή αλλά δεν θα συμπεριληφθούν στην επιστρεφόμενη ομάδα.
Από την όχθη Α ο βοσκός Πέτρος πάντα παίρνει έναν επιβάτη, ενώ από την όχθη Β το σκέφτεται! Η σκέψη του δίνεται με την συνάρτηση Ναπάρωένα().
Στη κλάση Τοποθεσία υπάρχει η συνάρτηση Ναπάρωένα() η οποία εκτελεί δυο φωλιασμένα Για, και βγαίνει εκτός με την Διέκοψε.η οποία διακόπτει όλα τα μπλοκ εντολών μέχρι και τη συνάρτηση. Όμως η διακοπή δεν δημιουργεί λάθος, έχουμε ήδη δώσει τιμή για να επιστρέψουμε. Αυτό το κάνουμε γιατί ο έλεγχος δίνει απάντηση με το πρώτο που βρίσκει. Στη χειρότερη θα εκτελέσει και τα δυο φωλιασμένα Για.
Η πιο πολύπλοκη συνάρτηση είναι αυτή που βγάζουμε ένα, επειδή πρέπει να επιλέξουμε το σωστό, αλλιώς θα φαγωθούν όσα μείνουν!



\\ Πρόγραμμα ο Πέτρος, ο Λύκος, το πρόβατο και το χορτάρι
\\ Το πρόγραμμα επιλύει το πρόβλημα, πώς θα περάσουν όλοι
\\ στην απέναντι όχθη σε ένα ποτάμι, μέσω μιας βάρκας.
\\ Στη βάρκα μπορεί να μπει ο βοσκός Πέτρος και ένα ακόμη
\\ Όμως ο λύκος τρώει το πρόβατο, και το πρόβατο τρώει το χορτάρι αν δεν είναι ο βοσκός μαζί!
Φορμα 60,40
Κλάση Άτομο {
όνομα$, τύπος$, Τύπος_επιβάτη$
Κλάση:
      Τμήμα Άτομο (.όνομα$, .τύπος$, .Τύπος_επιβάτη$) {
      }
}
Κλάση Τοποθεσία {
      όνομα$, υπάρχουν_άτομα
      πινακας ατομο()
      Τμήμα βάλε.άτομο (Άτομο) {
            .υπάρχουν_άτομα++
             Πίνακας .άτομο( .υπάρχουν_άτομα)
            .άτομο(.υπάρχουν_άτομα-1)=Άτομο
      }
      Συνάρτηση ΝαΠάρωΈνα {
            =Ψευδές
            Για ι=0 Έως .υπάρχουν_άτομα-1 {
                  Για λ=0 Έως .υπάρχουν_άτομα-1 {
                        Αν ι<>λ Τότε {
                              Αν .άτομο(λ).τύπος$=.άτομο(ι).όνομα$ Τότε =Αληθές : Διέκοψε
                        }
                  }
            }
      }
      Συνάρτηση βγάλεΈνα (τι$) {
            Ποιός=0
            Πρόβλημα=Ψευδές
            Αν .υπάρχουν_άτομα>1 Τότε {
                  Για Ποιός=0 Έως .υπάρχουν_άτομα-1 {
                        Πρόβλημα=Αληθές
                        Αν .άτομο(Ποιος).Τύπος_επιβάτη$=τι$ Τότε {
                             \\ Τύπωσε "Να επιλέξω το "+.άτομο(Ποιός).όνομα$
                              Πρόβλημα=Ψευδές
                              Για ι=0 Έως .υπάρχουν_άτομα-1 {
                                    Αν ι<>Ποιός Τότε {
                                          Για λ=0 Έως .υπάρχουν_άτομα-1 {
                                                Αν ι<>λ και λ<>Ποιός Τότε {
                                                      Αν .άτομο(λ).τύπος$=.άτομο(ι).όνομα$ Τότε Πρόβλημα=Αληθές
                                                }
                                          }
                                    }
                              }
                        }
                        Αν όχι Πρόβλημα τότε έξοδος
                  }
            }      
            Αν Πρόβλημα τότε Λάθος "δεν υπάρχει "+τι$
            =Ποιός
      }
     Συνάρτηση Βγάλε.άτομο {
           \\ Εδώ κοιτάμε αν έχουμε αριθμό
           Αν Ταύτιση("Α") Τότε {
                 Διάβασε Ποιός
                  = .άτομο(Ποιός)
                  Αν Ποιός+1<.υπάρχουν_άτομα Τότε {
                        άλλαξε .άτομο(.υπάρχουν_άτομα-1), .άτομο(Ποιός)
                  }
                  .υπάρχουν_άτομα--
                  Πίνακας .άτομο(.υπάρχουν_άτομα)
            } Αλλιώς {
                  \\ αλλιώς περιμένομε αλφαριθμητικό
                  Διάβασε Τύπος_επιβάτη$
                  Ποιος=-1
                  Για ι=0 Έως .υπάρχουν_άτομα-1 {
                        Αν .ατομο(ι).Τύπος_επιβάτη$=Τύπος_επιβάτη$ τότε Ποιος=ι
                  }
                  Αν Ποιος=-1 τότε Λάθος "Δεν βρέθηκε τύπος επιβάτη "+Τύπος_επιβάτη$
                  = .άτομο(Ποιός)
                  Αν Ποιός+1<.υπάρχουν_άτομα Τότε {
                        άλλαξε .άτομο(.υπάρχουν_άτομα-1), .άτομο(Ποιός)
                  }
                  .υπάρχουν_άτομα--
                  Πίνακας .άτομο(.υπάρχουν_άτομα)
            }
      }
Κλάση:
      Τμήμα Τοποθεσία (.όνομα$) {
            .υπάρχουν_άτομα <= Μέγεθος.Σωρού
            Αν .υπάρχουν_άτομα Τότε {
                  Πίνακας .άτομο(.υπάρχουν_άτομα)
                  ι=0 : Ενώ όχι κενό { διάβασε .άτομο(ι) : ι++}
            }
      }      
}
Πίνακας Θέση_επιβατών(3)
βαρκα=1
Θέση_επιβατών(0)=Τοποθεσία("Όχθη Α", Άτομο("Πέτρος","Τίποτα","βοσκός"),Άτομο("χορτάρι","Τίποτα","Επιβάτης"), Άτομο("λύκος","πρόβατο","Επιβάτης"), Άτομο("πρόβατο","χορτάρι","Επιβάτης") )
Θέση_επιβατών(βάρκα)=Τοποθεσία("Βάρκα")
Θέση_επιβατών(2)=Τοποθεσία("Όχθη Β")
Ομάδα Θέση_βάρκας {
      εδώ=0
      Αξία {=.εδώ}
      Τελεστής "++" {
            .εδώ++
            Αν .εδώ>3 τότε .εδώ<=0
      }
      Συνάρτηση Κατεβάζω {
            = .εδώ υπολοιπο 2 =1
      }
      Ιδιότητα Όχθη {
            Αξία {
                  Ένωσε Γονικό εδώ στο εδώ
                  Επιλεξε Με εδώ
                  Με 0,3
                        Αξία=0
                  Με 1,2
                        Αξία=2
                  Τέλος Επιλογής
            }
      }
      Ιδιότητα Προορισμός$ {
            Αξία {
                  Ένωσε Γονικό εδώ στο εδώ
                  Αξία$=Πίνακας$(("Προς Όχθη Β","Άφιξη στην Όχθη Β","Προς Όχθη Α","Άφιξη στην Όχθη Α"), εδώ)
            }
      }
}
Επανέλαβε {
      Τύπωσε.Θέσεις()
      Αν θέση_βάρκας.Κατεβάζω() Τότε {
            Τύπωσε "κατεβάζω από βάρκα"
            Για Θέση_επιβατών(βάρκα) {
                  Θέση_επιβατών(θέση_βάρκας.όχθη).βάλε.Άτομο .Βγάλε.άτομο("βοσκός")
                  Αν .υπάρχουν_άτομα>0 τότε {
                        Θέση_επιβατών(θέση_βάρκας.όχθη).Βάλε.Άτομο .βγάλε.άτομο(0)
                  }
            }
            θέση_βάρκας++
            Τύπωσε.Θέσεις()
      }
      Αν Θέση_επιβατών(2).υπάρχουν_ατομα<4 Τότε {
            ΝαΠάρωΕπιβάτη=Ψευδές
            Αν θέση_βάρκας.όχθη=0 τότε {
                  ΝαΠάρωΕπιβάτη=Αληθές
            } Αλλιώς {
              ΝαΠάρωΕπιβάτη=Θέση_επιβατών(θέση_βάρκας.όχθη).ΝαΠάρωΈνα()
            }
            Αν ΝαΠάρωΕπιβάτη Τότε {
                  Πένα 12 {Τύπωσε "Χρειάζομαι Επιβάτη" }
                  Για Θέση_επιβατών(θέση_βάρκας.όχθη) {
                        Τοπική κ
                        κ=.βγάλεΈνα("Επιβάτης")
                        Τύπωσε "βρήκα επιβάτη! "; .άτομο(κ).όνομα$
                        Θέση_επιβατών(βάρκα).βαλε.άτομο .Βγάλε.άτομο(κ)
                  }
            }
            Για Θέση_επιβατών(θέση_βάρκας.όχθη) {
                  Πένα 12 {Τύπωσε "Χρειάζομαι οδηγό" }
                  Τοπική κ
                  Ενώ κ<.υπάρχουν_άτομα {
                        Αν .άτομο(κ).Τύπος_επιβάτη$<>"Επιβάτης" Τότε Έξοδος
                        κ++
                  }                        
                  Αν κ<.υπάρχουν_άτομα Τότε {
                        Τύπωσε "βρήκα οδηγό, ο γνωστός ";.άτομο(κ).όνομα$
                        Θέση_επιβατών(βάρκα).βαλε.άτομο .βγάλε.άτομο(κ)
                  }
            }
            θέση_βάρκας++
      } Αλλιώς Έξοδος
      Πένα 11 { Τύπωσε "Πάτα πλήκτρο"}
      α$=κομ$
} Πάντα
Έξοδος
Ρουτίνα Τύπωσε.Θέσεις()
      Τοπική κ
      Για ι=0 Έως 2 {
            Για Θέση_επιβατών(ι) {
                  Πένα 7 { Τύπωσε "Θέση:"; .όνομα$;" ";}
                  Αν ι=1 Τότε Τύπωσε Θέση_βάρκας.Προορισμός$
                  Αν .υπάρχουν_άτομα Τότε {
                        Για κ=0 Έως .υπάρχουν_άτομα-1 {Τύπωσε .άτομο(κ).όνομα$;" ";}
                        Τύπωσε
                  } αλλιώς {
                        Αν ι=1 Τότε Τύπωσε "Κανένας Επιβάτης";
                        Τύπωσε
                  }
            }
      }
Τέλος Ρουτίνας