Κρεμάλα Περιεχόμενα Περιγραφή... 1 Ποιες έννοιες σκοπεύει να εισάγει... 1 Προαπαιτούμενα... 2 Λογικό διάγραμμα... 2 Ενδεικτικός κώδικας... 3 Γραφικά... 6 Επεκτάσεις... 6 Αυτοαξιολόγηση της επιλογής του θέματος... 7 Ενδεικτική Επίλυση: hangman.py... 8 Περιγραφή Μία από τις προτεινόμενες ασκήσεις μας γι' αυτό το μήνα είναι η γνωστή κρεμάλα. Στην άσκηση αυτή θα σχεδιάσουμε και θα γράψουμε ένα πρόγραμμα που θα υλοποιεί το παιχνίδι της κρεμάλας. Η κρεμάλα όπως οι περισσότεροι γνωρίζουμε, είναι ένα παιχνίδι για δύο ανθρώπους που συνήθως παίζεται με χαρτί και μολύβι. Ο ένας παίκτης σκέφτεται μία λέξη και ζωγραφίζει μία γραμμή στο χαρτί για κάθε γράμμα της λέξης. Ο δεύτερος παίκτης προσπαθεί να μαντέψει τα γράμματα που θα μπορούσαν να ανήκουν στη λέξη. Αν μαντέψει σωστά, ο πρώτος παίκτης γράφει το γράμμα στο κατάλληλο κενό όσες φορές εμφανίζεται αυτό μέσα στη λέξη. Αν μαντέψει λανθασμένα, ο πρώτος παίκτης ζωγραφίζει ένα τμήμα του σώματος του κρεμασμένου ανθρώπου. Αν ο δεύτερος παίκτης μπορέσει να μαντέψει όλα τα γράμματα στη λέξη πριν ζωγραφιστεί πλήρως κερδίζει διαφορετικά χάνει. Στο πρόγραμμά μας το ρόλο του πρώτου παίκτη τον έχει ο υπολογιστής όπου επιλέγει τυχαία μία λέξη από μία λίστα λέξεων. Ποιες έννοιες σκοπεύει να εισάγει 1. Μεθόδους 2. Λίστες 3. Τις μεθόδους λίστας append() and reverse() 4. Τεμαχισμός λιστών (list slicing) 5. Τις μεθόδους αλφαριθμητικών lower(), upper(), split(), startswith(), και endswith() 6. Τους τελεστές in και not in 7. Τις συναρτήσεις range() και list() που αφορούν σε συναρτήσεις 1
8. Δήλωση del για διαγραφή στοιχείων λίστας 9. for loops 10. Εμβάθυνση στη χρήση των λογικών διαγραμμάτων 11. ASCII arts Προαπαιτούμενα Οι μαθητές χρειάζεται να έχουν οικοδομήσει γνώσεις σχετικά με: την υλοποίηση λογικών διαγραμμάτων (flow charts) την χρήση του κατάλληλου για την ηλικία τους προγράμματος για να γράψουν και να αποθηκεύσουν προγράμματα (π.χ. Thony python IDE for beginners http://thonny.cs.ut.ee/), repl.it Τύπους δεδομένων: ακέραιοι, αριθμοί κινητής υποδιαστολής, αλφαριθμητικοί, λογικοί Μεταβλητές: ονοματολογία, ανάθεση τιμής σε μεταβλητή, τι σημαίνει ο τερματισμός του προγράμματος για τις τιμές των μεταβλητών. Προσαύξηση τιμών των μεταβλητών. Αριθμητικοί και λογικοί τελεστές, τελεστέοι, εκφράσεις και δηλώσεις Συνένωση αλφαριθμητικών Απλά και διπλά εισαγωγικά στ' αλφαριθμητικά. Bllocks κώδικα Έλεγχος ροής προγράμματος (εντολές if, while, break) Συναρτήσεις, κλήσεις συναρτήσεων, συναρτήσεις, input(), επιστροφή τιμής συναρτήσεων, input(), χρήση εκφράσεων στην κλήση συναρτήσεων. Δημιουργία συναρτήσεων, επιστροφή τιμής από συνάρτηση, παράμετροι, ορίσματα Εμβέλεια τοπικών και καθολικών μεταβλητών Συγκριτικοί τελεστές, διαφορά ανάμεσα στα = και ==. Δηλώσεις import, αρθρώματα-modules, αρθρώματα random, time. Οι συναρτήσεις str(), int(), float(), random.randit(), time. Sleep() Χρήση της λέξης κλειδί end ως όρισμα της συνάρτησης για να αποφύγουμε την αλλαγή γραμμής. Πίνακες αλήθειας. Η συνάρτηση random. randint() Βιβλιοθήκες, αρθρώματα Λογικό διάγραμμα Το πρόγραμμα της κρεμάλας θα υλοποιηθεί με τη βοήθεια ενός λογικού διαγράμματος. Η κατασκευή του λογικού διαγράμματος θα προηγηθεί του κώδικα και θα πρέπει οι μαθητές να συνειδητοποιήσουν ότι είναι ευκολότερο να κάνουν αλλαγές και να εντοπίζουν προβλήματα σκεπτόμενοι πώς δουλεύει ένα πρόγραμμα πριν γράψουν τον κώδικά του γιατί αν βιαστούν και γράψουν τον κώδικα πρώτα, ίσως ανακαλύψουν προβλήματα που απαιτούν την αλλαγή του κώδικα που έχουν γράψει. Όμως κάθε φορά που αλλάζουμε τον κώδικά μας υπάρχει η πιθανότητα να δημιουργήσουμε bugs ακόμα και με μικρές αλλαγές. Έτσι είναι πολύ καλύτερα να γνωρίζουμε τι θέλουμε να κάνουμε και να το κάνουμε πριν γράψουμε τον κώδικά μας. Η εικόνα δείχνει το αρχικό διάγραμμα ροής του προγράμματος της κρεμάλας. Το γαλάζιο βελάκι σημαίνει ότι ο παίκτης έχει ξαναπεί το ίδιο γράμμα, οπότε πρέπει να μαντέψει πάλι. 2
Ενδεικτικός κώδικας words='''μυρμηγκι μπαμπουινος ασβος καστορας καμηλα γατα αχιβαδα κομπρα κογιοτ κορακι ελαφι σκυλος γαιδαρος παπια αετος κουναβι αλεπου βατραχος κατσικα χηνα γερακι λιονταρι σαυρα μαιμου μουλαρι κουκουβαγια παντα παπαγαλος περιστερι κορακι ρινοκερος σολομος καραχαριας προβατο φιδι κουνελι αρουραιος αραχνη πελαργος κυκνος τιγρης βατραχος πεστροφα γαλοπουλα χελωνα νυφιτσα φαλαινα λυκος ζεμπρα'''.split() Αυτή η δήλωση εκχώρησης τιμής έχει ένα μεγάλο αλφαριθμητικό απαρτιζόμενο από λέξεις χωρισμένες με κενά. Στο τέλος του αλφαριθμητικού καλείται η μέθοδος split(). Η μέθοδος split() επιστρέφει μία λίστα στην οποία κάθε λέξη του αλφαριθμητικού είναι ένα στοιχείο της λίστας. Είναι πιο εύκολο να πληκτρολογήσετε αυτόν τον κώδικα χρησιμοποιώντας τη μέθοδο split(). Αν αντί αυτού δημιουργήσετε λίστα, θα πρέπει να πληκτρολογήσετε: ['μυρμηγκι', μπαμπουινος', 'ασβος'], κλπ με εισαγωγικά ή κόμμα για κάθε λέξη. Η συνάρτηση getrandomword() Η συνάρτηση αυτή θα πάρει ως όρισμα μία λίστα λέξεων και θα επιστρέψει μία λέξη από τη λίστα. Με αυτόν τον τρόπο επιλέγεται η λέξη που θα πρέπει να μαντέψει ο παίκτης. def getrandomword(wordlist): #επιστρέφει ένα τυχαίο αλφαριθμητικό από το όρισμά της το οποίο #είναι μία λίστα αλφαριθμητικών. wordindex=random.randint(0,len(wordlist)-1) print("index word", wordindex) return wordlist[wordindex] print(wordlist([wordindex])) Εμφάνιση της πίστας στον παίκτη με την συνάρτηση displayboard() Η συνάρτηση αυτή εμφανίζει την τρέχουσα κατάσταση της πίστας, επίσης εμφανίζει τα γράμματα που έχει μαντέψει ο παίκτης μέχρι εκείνη τη στιγμή καθώς και τα λανθασμένα γράμματα που έχει πει. def displayboard(hangmanpics, missedletters, correctletters, secretword): #HANGMANPICS: μία λίστα αλφαριθμητικών πολλαπλών γραμμών, που εμφανίζει την πίστα του παιχνιδιού σε ASCII art #Η καθολική μεταβλητή HANGMANPICS είναι παράμετρος στη συνάρτηση #missedletters: αλφαριθμητικό που περιέχει τα γράμματα που μάντεψε ο παίκτης και δε βρίσκονται στη μυστική λέξη #correctletters: αλφαριθμητικό που περιέχει τα γράμματα που μάντεψε ο παίκτης και βρίσκονται στη μυστική λέξη #secetword: αλφαριρθμητικό που περιέχει τη μυστική λέξη που προσπαθεί να μαντέψει ο παίκτης print(hangmanpics[len(missedletters)]) print('γράμματα που σε στέλνουν στην κρεμάλα, end=' ') 3
for letter in missedletters: print(letter, end=' ') blanks='_'*len(secretword) for i in range(len(secretword)): #αντικατέστησε τα κενά με τα σωστά μαντεμένα γράμματα if secretword[i] in correctletters: blanks=blanks[:i]+secretword[i]+blanks[i+1:] #εμφάνιση της μυστικής λέξης με κενά στα γράμματα που λείπουν for letter in blanks: print(letter, end=' ') Τα γραφικά για την πίστα της κρεμάλας αποτελούνται από χαρακτήρες από το πληκτρολόγιο που παρουσιάζονται στην οθόνη. Αυτός ο τύπος των γραφικών καλείται ASCII art, και ήταν ένα είδος προδρόμου του emojii. Παρακάτω βλέπετε ένα μέρος του γραφικού της κρεμάλας. Η πρώτη κλήση της συνάρτησης θα εμφανίσει την πίστα στον παίκτη. HANGMANPICS[0] δείχνει μία κενή αγχόνη, HANGMANPICS[1] εμφανίζει το κεφάλι όταν ο παίκτης μαντέψει ένα λάθος γράμμα, κλπ. Ο αριθμός των γραμμάτων στην missedletters αντανακλά πόσες λάθος κινήσεις έχει κάνει ο παίκτης. Έτσι αν το missedletters είναι το 'αετρ' έχουμε 4 λανθασμένες κινήσεις και η εκτύπωση του HANGMANPICS[4] θα εμφανίσει την κατάλληλη λίστα κρεμάλας για 4 λάθη, κλπ Η υπόλοιπη από τη συνάρτηση displayboard() εμφανίζει τα γράμματα που λείπουν και δημιουργεί ένα αλφαριθμητικό της μυστικής λέξης με όλα τα γράμματα που δεν έχει μαντέψει ο παίκτης ως κενά και χρησιμοποιείται ο τεμαχισμός λιστών. Η συνάρτηση def getguess(alreadyguessed) Η συνάρτηση getguess() καλείται έτσι ώστε ο παίκτης να μπορέσει να εισάγει το γράμμα που μάντεψε και επιστρέφει το γράμμα αυτό ως αλφαριθμητικό, επιπρόσθετα επιβεβαιώνει πως ο παίκτης πληκτρολόγησε ένα έγκυρο γράμμα και ότι δεν εισάγει ξανά ένα γράμμα που μάντεψε πιο πριν. 4
def getguess(alreadyguessed): # επιστρέφει το γράμμα που πληκτρολογεί ο χρήστης # ελέγχει ότι ο χρήστης πληκτρολογεί μόνο ένα γράμμα και όχι τίποτε άλλο # ελέγχει ότι ο χρήστης δεν έχει μαντέψει προηγούμενα το ίδιο γράμμα # στην παράμετρο alreadyguessed, παίρνει σαν όρισμα τα γράμματα που ήδη έχει μαντέψει ο χρήστης while True: print('δώσε γράμμα==> ) guess = input() guess = guess.lower() if len(guess)!= 1: print( Ενα γράμμα μόνο..') elif guess in alreadyguessed: print('αυτό το γράμμα το έχεις ήδη πει! Διάλεξε άλλο..') elif guess not in 'αβγδεζηθικλμνξοπρστυφχψως': print('μόνο γράμματα μπορείς να δώσεις..') else: return guess Η συνάρτηση def playagain() Η συνάρτηση def playagain() ρωτά αν ο παίκτης θέλει να παίξει άλλο ένα γύρο κρεμάλας. Επσιτρέφει True αν θέλει να ξαναπαίξει ο παίκτης, διαφορετικά επιστρέφει False. def playagain(): #επιστρέφει True αν ο παίκτης θέλει να ξαναπαίξει, #διαφορετικά επιστρέφει False print( Θέλεις να ξαναπαίξεις; (ναι ή οχι) ) return input().lower().startswith('ν') ( ν ) ( ν ) ( ν ) Ο σκοπός της συνάρτησης αυτής είναι να επιτρέψει στον παίκτη να πληκτρολογήσει ναι ή οχι για να πει στο πρόγραμμα αν θέλει να παίξει ακόμα ένα γύρο κρεμάλας. Ο παίκτης θα πρέπει να μπορεί να πληκτρολογήσει ΝΑΙ, ναι, Ν, ν ή οτιδήποτε ξεκινά με Ν και σκοπεύει να σημαίνει ναι. Η συνάρτηση επιστρέφει True αν ο παίκτης θέλει να ξαναπαίξει, διαφορετικά επιστρέφει False. Περιλαμβάνει μόνο μία κλήση της συνάρτησης και μία δήλωση return. Η δήλωση return περιλαμβάνει μία έκφραση που φαίνεται πολύπλοκη αλλά μπορεί να αναλυθεί ως εξής: 5
Γραφικά Η λίστα HANGMANPICS περιλαμβάνει 7 ASCII art αλφαριθμητικά. Έτσι όταν το len(missedletters) γίνει 6, ξέρεις ότι ο παίκτης έχασε γιατί η εικόνα της κρεμάλας τελείωσε. Επεκτάσεις 1. Ίσως οι 6 ευκαιρίες που έχει ο παίκτης να μην είναι αρκετές για κάποιες λέξεις. Μπορείτε εύκολα να δώσετε περισσότερες ευκαιρίες στον παίκτη προσθέτοντας περισσότερα αλφαριθμητικά στην λίστα HANGMANPICS. 2. Μπορείτε να τροποποιήσετε τον κώδικά σας ώστε το παιχνίδι να χρησιμοποιεί σύνολα λέξεων όπως ζώα, χρώμα, σχήμα ή φρούτα κλπ. Το νέο σας πρόγραμμα θα λέει στον παίκτη από πιο σύνολο (ζώο, χρώμα, σχήμα ή φρούτο προέρχεται η μυστική λέξη. Αυτή η αλλαγή θα γίνει χρησιμοποιώντας έναν καινούριο τύπο δεδομένων τα λεξικά. Στα λεξικά έχουμε πρόσβαση στα στοιχεία τους με δείκτη οποιουδήποτε τύπου δεδομένων και όχι απαραίτητα ακέραιο όπως συνέβαινε με τις λίστες. Ας αλλάξουμε τον κώδικα στην κρεμάλα ώστε να υποστηρίζει διαφορετικά σύνολα λέξεων. words={'colors': 'red orange yellow green blue indigo violet white bliack brown'.split(), 'Shapes':'square triangle rectangle circle ellipse rhombus trapezoid chevron pentagon hexagon septagon octagon'.split(), 'Fruits': 'apple orange lemon lime pear watermelon grape grapefruit cherry banana cantaloupe mango strawberry tomato'.split(), 'Animals':'''μυρμηγκι μπαμπουινος ασβος καστορας καμηλα γατα αχιβαδα κομπρα κογιοτ κορακι ελαφι σκυλος γαιδαρος παπια αετος κουναβι αλεπου βατραχος κατσικα χηνα γερακι λιονταρι σαυρα μαιμου μουλαρι κουκουβαγια παντα παπαγαλος περιστερι κορακι ρινοκερος σολομος καραχαριας προβατο φιδι κουνελι αρουραιος αραχνη πελαργος κυκνος τιγρης βατραχος πεστροφα γαλοπουλα χελωνα νυφιτσα φαλαινα λυκος ζεμπρα'''.split()} def getrandomword(worddict): #επιστρέφει ένα τυχαίο αλφαριθμητικό από το λεξικό της λίστας των αλφαριθμητικών #και το κλειδί επίσης. #Αρχικά επέλεξε ένα τυχαίο κλειδί από το λεξικό print("random word") wordkey=random.choice(list(worddict.keys())) print('key',wordkey) #print("index word", wordindex) #Επέλεξε τυχαία μία λέξη από τη λίστα του κλειδιού στο λεξικό wordindex=random.randint(0,len(worddict[wordkey])-1) return [worddict[wordkey][wordindex],wordkey] 6
Αυτοαξιολόγηση της επιλογής του θέματος Σύνδεση με τον πραγματικό κόσμο -Διαθεματικότητα-Συζήτηση ευρύτερων θεμάτων Η δραστηριότητα που προτείνεται - η δημιουργία μιας ηλεκτρονικής κρεμάλας- συνδέεται άμεσα με την πραγματικότητα των μαθητών που είναι σύνθεση διαχρονικών και ηλεκτρονικών παιχνιδιών. Η δραστηριότητα είναι διαθεματική γιατί το συγκεκριμένο παιγνίδι σχετίζεται με ορθογραφία και γραμματική στα ελληνικά, αν μάλιστα οι λέξεις είναι σε μία ξένη γλώσσα αγγλικά, γαλλικά, κλπ εξασκεί τον παίκτη στην ορθογραφία της ξένης γλώσσας. Μπορεί επίσης να είναι οι χημικές ενώσεις σε ένα μάθημα χημείας, πόλεις σε μάθημα γεωγραφίας κλπ. Δίνει την ευκαιρία για συζήτηση για τα πλεονεκτήματα και τα μειονεκτήματα των ηλεκτρονικών παιχνιδιών για παιδιά. Επεκτασιμότητα Παραμετροποίηση κρεμάλας σε κατηγορίες περιεχομένου: ξένες γλώσσες, Γεωγραφία, Χημεία, ορολογία, Αρχαία, ουσιαστικά, επίθετα, ρήματα, ζώα, θηλαστικά, ήρωες, επαγγέλματα, φυτά, πρωτεύουσες, βουνά, ομάδες, παίκτες, ηθοποιοί, συγγραφείς. Μπορεί να συνδυαστεί με το παιχνίδι ΟΝΟΜΑ, ΖΩΟ, ΦΥΤΟ, ΠΟΛΗ ή με τον τροχό της τύχης. Κριτήρια Αξιολόγησης Πηγή: Invent your own computer games with python, Copyright 2008-2015 by Albert Sweigart Some Rights Reserved. "Invent Your Own Computer Games with Python" ("Invent with Python") is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States http://inventwithpython.com 7
Ενδεικτική Επίλυση: hangman.py import random HANGMANPICS = [''' O O O / O /\ O /\ / O /\ / \ ========='''] 8
words='''μυρμηγκι μπαμπουινος ασβος καστορας καμηλα γατα αχιβαδα κομπρα κογιοτ κορακι ελαφι σκυλος γαιδαρος παπια αετος κουναβι αλεπου βατραχος κατσικα χηνα γερακι λιονταρι σαυρα μαιμου μουλαρι κουκουβαγια παντα παπαγαλος περιστερι κορακι ρινοκερος σολομος καραχαριας προβατο φιδι κουνελι αρουραιος αραχνη πελαργος κυκνος τιγρης βατραχος πεστροφα γαλοπουλα χελωνα νυφιτσα φαλαινα λυκος ζεμπρα'''.split() def getrandomword(wordlist): #επιστρέφει ένα τυχαίο αλφαριθμητικό από το όρισμά της το οποίο #είναι μία λίστα αλφαριθμητικών. wordindex=random.randint(0,len(wordlist)-1) return wordlist[wordindex] def displayboard(hangmanpics, missedletters, correctletters, secretword): #HANGMANPICS: μία λίστα αλφαριθμητικών πολλαπλών γραμμών, που εμφανίζει την πίστα του παιχνιδιού σε ASCII art #Η καθολική μεταβλητή HANGMANPICS είναι παράμετρος στη συνάρτηση #missedletters: αλφαριθμητικό που περιέχει τα γράμματα που μάντεψε ο παίκτης και δε βρίσκονται στη μυστική λέξη #correctletters: αλφαριθμητικό που περιέχει τα γράμματα που μάντεψε ο παίκτης και βρίσκονται στη μυστική λέξη #secetword: αλφαριρθμητικό που περιέχει τη μυστική λέξη που προσπαθεί να μαντέψει ο παίκτης print(hangmanpics[len(missedletters)]) print(' Γράμματα που σε στέλνουν στην κρεμάλα : ', end=' ') for letter in missedletters: print(letter, end=' ') print ('Ψάχνεις να βρεις τη λέξη: ', end=' ') blanks='_'*len(secretword) for i in range(len(secretword)): #αντικατέστησε τα κενά με τα σωστά μαντεμένα γράμματα if secretword[i] in correctletters: blanks=blanks[:i]+secretword[i]+blanks[i+1:] #εμφάνιση της μυστικής λέξης με κενά στα γράμματα που λείπουν for letter in blanks: print(letter, end=' ') def getguess(alreadyguessed): # επιστρέφει το γράμμα που πληκτρολογεί ο χρήστης # ελέγχει ότι ο χρήστης πληκτρολογεί μόνο ένα γράμμα και όχι τίποτε άλλο # ελέγχει ότι ο χρήστης δεν έχει μαντέψει προηγούμενα το ίδιο γράμμα # στην παράμετρο alreadyguessed, παίρνει σαν όρισμα τα γράμματα που ήδη έχει μαντέψει ο χρήστης while True: print('δώσε γράμμα',end='==> ') guess = input() guess = guess.lower() if len(guess)!= 1: print('ένα γράμμα μόνο..') elif guess in alreadyguessed: print('αυτό το γράμμα το έχεις ήδη πει! Διάλεξε άλλο.') elif guess not in 'αβγδεζηθικλμνξοπρστυφχψως': print('μόνο γράμματα μπορείς να δώσεις..') else: return guess def playagain(): #επιστρέφει True αν ο παίκτης θέλει να ξαναπαίξει, 9
#διαφορετικά επιστρέφει False print("\nθέλεις να ξαναπαίξεις; (ναι ή οχι)") return input().lower().startswith('ν') #Κυρίως πρόγραμμα print('h A N G M A N') missedletters = '' correctletters = '' secretword = getrandomword(words) gameisdone=false while True: displayboard(hangmanpics, missedletters, correctletters, secretword) #ο χρήστης θα πληκτρολογήσει ένα γράμμα #θα γίνει έλεγχος αν ο χρήστης έχει ξαναδώσει αυτό το γράμμα είτε σωστά είτε λανθασμένα #έτσι πρέπει να συνενώσουμε τα αλφαριθμητικά missedletters, correctletters guess=getguess(missedletters+correctletters) #ελέγχουμε αν το γράμμα που δίνει ο χρήστης περιέχεται στη μυστική λέξη if guess in secretword: correctletters=correctletters+guess #έλεγχος αν ο παίκτης έχει κερδίσει foundallletters=true for i in range(len(secretword)): if secretword[i] not in correctletters: foundallletters=false break if foundallletters: print('μπράβο! Η μυστική λέξη είναι "' + secretword + '"! Κέρδισες!') gameisdone=true else: missedletters=missedletters+guess #έλεγχος αν ο χρήστης έχει μαντέψει πολλές φορές και έχασε if len(missedletters)==len(hangmanpics)-1: displayboard(hangmanpics, missedletters, correctletters, secretword) print("\n\tξεπέρασες το όριο των προσπαθειών!") print("\n\tέπειτα από",len(missedletters), " αποτυχημένες προσπάθειες ") print("\n\tκαι από ", (len(correctletters)),"σωστές προσπάθειες") print("\n\tη λέξη ήταν... ", secretword) gameisdone=true #ρωτήστε τον παίκτη αν θέλει να ξαναπαίξει, αλλά μόνο αν έχει ολοκληρώσει το προηγούμενο παιχνίδι if gameisdone: if playagain(): missedletters=' ' correctletters=' ' gameisdone=false secretword=getrandomword(words) else: break 10