Το προφίλ μας στο Google Plus
18

Python Game Programming (part 1.5)

Αρχίσατε λοιπόν να διαβάζετε Python με βάση τη νέα σειρά άρθρων που ξεκινά από το deltaHacker 005; Πολύ καλά κάνατε! Το έντυπο άρθρο θα συμπληρώνεται κάθε φορά με ένα αντίστοιχο σ’ αυτό εδώ το site, το οποίο θα δίνει ενδεικτικές λύσεις των ασκήσεων αλλά και θα παρουσιάζει κάποια επιπλέον στοιχεία της γλώσσας.

Τα στοιχεία αυτά θα θεωρούνται δεδομένα στα επόμενα άρθρα της σειράς. Με τον τρόπο αυτό θα μπορούμε στα έντυπα άρθρα να επικεντρώσουμε περισσότερο σε παραδείγματα και στοιχεία της γλώσσας που μας αφορούν πιο άμεσα (hint: αυτά που χρειαζόμαστε για τα παιχνίδια). Καθώς καταλαβαίνετε βέβαια δεν είναι δυνατόν να γράψουμε παιχνίδια χωρίς να κατανοούμε τη βασική φιλοσοφία της Python.

Πιστεύουμε να μη δυσκολευτήκατε ιδιαίτερα με τις ασκήσεις του πρώτου μέρους. Ας δούμε το πρόγρμαμα που είχαμε δώσει.

#
# Βρες τον αριθμό - Απόπειρα 1
#
import random
thenumber = random.randint(1,50)
print "Έχω σκεφτεί ένα αριθμό από το 1 ως το 50."
print "Μπορείς να τον βρεις;"
guess = 0
while guess != thenumber:
	guess=input("Δώσε τον αριθμό: ")
	if guess > thenumber:
		print "Έδωσες μεγαλύτερο αριθμό!"
	if guess < thenumber:
		print "Έδωσες μικρότερο αριθμό!"
	if guess == thenumber:
		print "Τον βρήκες!!!"
&#91;/code&#93;

Αν είστε παρατηρητικοί, θα δείτε ότι αντικαταστήσαμε το "<>" (το σύμβολο του άνισου που γνωρίζουμε οι περισσότεροι από την BASIC) με το "!=". Αν και στην Python λειτουργούν και τα δύο, το πρώτο θεωρείται παρωχημένο και μάλλον δεν θα το συναντήσετε.

Ξαναδιαβάστε τώρα το πρόγραμμα προσεκτικά. Βλέπετε κάτι να περιττεύει; Αν όχι σκεφτείτε λίγο το τελευταίο if. Χρειάζεται στα αλήθεια; Καθώς ο βρόχος while τερματίζει μόνο όταν ο παίκτης βρει τον αριθμό, το τελευταίο if μπορεί να παραλειφθεί εντελώς, και το μήνυμα επιτυχίας να μπει μόνο του, αμέσως μετά το βρόχο. Φτάνουμε έτσι στην Απόπειρα 2 του προγράμματος.


#
# Βρες τον αριθμό - Απόπειρα 2
#
import random
thenumber = random.randint(1,50)
print "Έχω σκεφτεί ένα αριθμό από το 1 ως το 50."
print "Μπορείς να τον βρεις;"
guess = 0
while guess != thenumber:
	guess=input("Δώσε τον αριθμό: ")
	if guess > thenumber:
		print "Έδωσες μεγαλύτερο αριθμό!"
	if guess < thenumber:
		print "Έδωσες μικρότερο αριθμό!"
print "Τον βρήκες!!!"
&#91;/code&#93;

<strong>Λύσεις των Ασκήσεων</strong>
Ας δούμε λίγο τις λύσεις των ασκήσεων του πρώτου μέρους της σειράς μας, στο deltaHacker 005. Θα εστιάσουμε και σε μερικές από τις παγίδες που κρύβουν :)

<strong>Εισαγωγή Ονόματος Παίκτη</strong>. Πολύ απλή άσκηση: Αρκεί να βάλετε την παρακάτω γραμμή πριν από το πρώτο print...


name = input("Δώσε το όνομα σου: ")

...και να αλλάξετε την τελευταία γραμμή σε

print "Συγχαρητήρια", name, "τον βρήκες!"

Για εκτελέστε το πρόγραμμα, όμως! Θα διαπιστώσετε με έκπληξη ότι δεν δέχεται το όνομα σας -- εκτός αν το δώσετε μέσα σε εισαγωγικά. Όχι, δεν είναι ότι η Python έχει προσωπικά μαζί σας. Απλά, η εντολή input ερμηνεύει την είσοδο ως παράσταση και ψάχνει να βρει το όνομα σας ως κάτι που έχει ήδη οριστεί στο πρόγραμμα! Αν δώσετε ως όνομα το thenumber, μεταβλητή που ήδη έχει ορισθεί στο πρόγραμμά μας, η python θα το δεχθεί. Δοκιμάστε και θα δείτε το αποτέλεσμα! Φυσικά, αυτό δεν είναι κάτι που θέλουμε. Κι ούτε μας αρέσει η ιδέα να βάζουμε εισαγωγικά γύρω από το όνομα μας ή οποιοδήποτε αλφαριθμητικό θέλουμε να δώσουμε στην είσοδο. Η λύση σε αυτό είναι η raw_input:

name = raw_input("Δώσε το όνομα σου: ")

Για την είσοδο αλφαριθμητικών, λοιπόν, από εδώ και πέρα θα χρησιμοποιούμε τη raw_input.

Προσθήκη Μετρητή Προσπαθειών. Επίσης εύκολη άσκηση:

#
# Βρες τον αριθμό - Απόπειρα 3
#
import random
thenumber = random.randint(1,50)
name = raw_input("Δώσε το όνομα σου: ")
print "Έχω σκεφτεί ένα αριθμό από το 1 ως το 50."
print "Μπορείς να τον βρεις;"
guess = 0
tries = 0
while guess != thenumber:
	tries = tries + 1
	guess=input("Δώσε τον αριθμό: ")
	if guess > thenumber:
		print "Έδωσες μεγαλύτερο αριθμό!"
	if guess < thenumber:
		print "Έδωσες μικρότερο αριθμό!"
print "Συγχαρητήρια", name, "τον βρήκες σε", tries, "προσπάθειες!"
&#91;/code&#93;

Η γραμμή που αυξάνει τη μεταβλητή tries μπορεί να γραφεί και έτσι:

&#91;code lang="python"&#93;
tries += 1
&#91;/code&#93;

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

<strong>Κριτική στην ...ικανότητα του παίκτη</strong>
Για να κριτικάρουμε την απόδοση του παίκτη σύμφωνα με τον αριθμό των προσπαθειών που χρειάστηκε, μια πρώτη απόπειρα μοιάζει μ' αυτή (οι γραμμές, φυσικά, μπαίνουν στο τέλος):


if tries == 1:
	print "Beginner's luck!"
if tries <= 5:
	print "Είσαι γρήγορος!"
if tries > 5:
	print "Η γιαγιά μου παίζει πιο καλά!"

Χμ, έχουμε λίγες μόνο γραμμές κώδικα και ήδη υπάρχουν bugs. Πράγματι, αν βρείτε τον αριθμό σε μια προσπάθεια τότε θα πάρετε δύο μηνύματα: το "Beginner's luck!" και το "Είσαι γρήγορος!" Φυσικά, καθώς το 1 είναι επίσης *και* μικρότερο από 5, εκτελούνται δύο εντολές if. Εδώ υπάρχουν δύο πιθανές λύσεις.

α) να αλλάξουμε τη δεύτερη συνθήκη ώστε να εκτελείται όταν η tries είναι μικρότερη από 5 και ταυτόχρονα διαφορετική του 1 (ή μεγαλύτερη του 1)
β) να φτιάξουμε την if με τέτοιο τρόπο ώστε αν εκτελεστεί μια συνθήκη να μην εκτελείται καμιά άλλη

Εφαρμόζοντας την α), θα μπορούσαμε να γράψουμε τον κώδικα ως ακολούθως:

if tries == 1:
	print "Beginner's luck!"
if (tries <= 5 and tries !=1):
	print "Είσαι γρήγορος!"
if tries > 5:
	print "Η γιαγιά μου παίζει πιο καλά!"

Φτιάξαμε μια σύνθετη συνθήκη χρησιμοποιώντας τον λογικό τελεστή and. Η συνθήκη θα είναι αληθής και θα εκτελεστεί, μόνον αν αληθεύουν και οι δύο συνθήκες που ενώνει: το tries είναι μικρότερο ή ίσο από 5 *και* διαφορετικό από το 1 (θα μπορούσατε επίσης να το γράψετε *και* μεγαλύτερο από το 1). Καθώς φαντάζεστε υπάρχουν και οι λογικοί τελεστές or και not, που θα δούμε σε επόμενα παραδείγματα.

Η λύση β) είναι να χρησιμοποιήσουμε μια πιο πλήρη μορφή της if, που περιλαμβάνει το elif (else if, αλλιώς αν) και το else:

if tries == 1:
	print "Beginner's luck!"
elif tries <= 5:
	print "Είσαι γρήγορος!"
else:
	print "Η γιαγιά μου παίζει πιο καλά!"
&#91;/code&#93;

Εδώ η συνθήκη που βρίσκεται στο elif θα εκτελεστεί μόνο αν το tries είναι μικρότερο ή ίσο του 5 και *δεν* έχει εκτελεστεί το πρώτο if. H δομή της if-elif εξασφαλίζει ότι μόλις εκτελεστεί μια οποιαδήποτε από τις συνθήκες (είτε ή if είτε κάποια από τις elif - μπορούμε να βάλουμε πολλές elif) οι υπόλοιπες περιπτώσεις δεν εξετάζονται. Αν υπάρχουν εντολές κάτω από τη δομή if-elif-else, η εκτέλεση θα συνεχιστεί από εκεί. Καθώς φαντάζεστε, η εντολή μετά το else εκτελείται μόνο όταν *δεν* εκτελεστούν καμιά elif *ούτε* η αρχική if.

<strong>Λίστες</strong>
Η Python έχει μανία με τις <strong>λίστες</strong> και γενικά με δομές δεδομένων που είναι γνωστές ως <strong>sequences</strong> ή ακολουθίες αν το προτιμάτε. Είναι εύκολο να φτιάξετε μια λίστα...


shoppinglist = [ "Cheese" , "Rice", "Coffee", "Milk", "Camba" ]

...κι εξίσου εύκολο να διατρέξετε όλα τα στοιχεία της:

for element in shoppinglist:
	print element

Είναι επίσης αστεία εύκολο να δούμε αν κάτι ανήκει σε μια λίστα ή όχι:

shoppinglist = [ "Cheese", "Rice", "Coffee", "Milk", "Camba" ]
element = raw_input("What are you buying today? ")
if element in shoppinglist:
	print "Yes, this is on the list"
else:
	print "Not on the list, you don't need it"

Αν έχετε συνηθίσει σε άλλες γλώσσες να χρησιμοποιείτε την for για να δημιουργείτε βρόχο με μετρητή, στην Python θα το κάνετε ως εξής:

for i in [1,2,3,4,5,6,7,8,9,10]:
	print i

Αυτό δεν βολεύει αν θέλουμε να μετρήσουμε μέχρι το 1000, οπότε σε μια τέτοια περίπτωση γράφουμε:

for i in range(1,1001):
	print i

Η συνάρτηση range παράγει μια λίστα με τα στοιχεία από 1 ως 1000 κι όχι ως 1001, αφού η δεξιά παράμετρος έχει το ρόλο άνω φράγματος. Καλό είναι να γνωρίζετε ότι μια λίστα στην Python μπορεί να περιέχει οτιδήποτε: αριθμούς, αλφαριθμητικά, ακόμα και άλλες λίστες! Εκτός από τις λίστες, η Python παρέχει επίσης και τα tuples, τα οποία είναι παρόμοια με τις λίστες αλλά μετά τη δημιουργία τους δεν μπορούν να μεταβληθούν. Σε μια λίστα μπορούμε, όπως θα δούμε σε επόμενα άρθρα, να προσθέτουμε και να διαγράφουμε στοιχεία, καθώς και να εκτελούμε μια σειρά από χρήσιμες λειτουργίες όπως, π.χ., ταξινόμηση. Όπως θα παρατηρήσατε, η λίστα είναι μια δομή δεδομένων που διατηρεί τη σειρά των στοιχείων που της δίνουμε.

Τώρα που έχετε δει μερικά ακόμα από τα βασικά στοιχεία της Python είστε έτοιμοι για την επόμενή μας περιπέτεια, στο deltaHacker Μαρτίου (τεύχος 006). Το παιχνίδι μάς περιμένει!

18 Responses to “Python Game Programming (part 1.5)”

  1. KeyFr3ak | 17/02/2012 at 01:52

    Γιατί μου βγάζει 2 διαφορετικά προβλήματα

    1:
    python guess1.py
    File “guess1.py”, line 2
    SyntaxError: Non-ASCII character ‘\xce’ in file guess1.py on line 2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

    2:
    python guess.py
    File “guess.py”, line 10
    guess=input(“Give the number: “)
    ^
    IndentationError: expected an indented block

  2. KeyFr3ak | 17/02/2012 at 01:55

    Το λόγο που μου βγάζει το πρώτο πρόβλημα τον διάβασα στην ιστοσελίδα αλλά το 2ο τι είναι? Συγνώμη για τισ τόσες ερωτήσεις αλλά τώρα μαθαίνω python!

    • sonic2000gr | 17/02/2012 at 07:52

      To 2o είναι ότι κάπου έχεις βάλει λάθος αριθμό κενών διαστημάτων ή tabs. Προσοχή τα κενά αποτελούν μέρος του συντακτικού της γλώσσας!
      Για παράδειγμα τη γραμμή που λες την έχεις βάλει πιο μέσα ή πιο έξω από την επόμενη (ενδιάμεσα σε σχέση με το while), ενώ και οι δύο ξεκινάνε στο ίδιο σημείο.

    • georgep138 | 13/03/2012 at 20:03

      Και εγώ, έχοντας το ίδιο πρόβλημα, διάβασα την ιστοσελίδα, αλλά δεν κατάλαβα τι πρέπει να κάνω για να διαβάζει τα Ελληνικά που έγραψα με το nano στο ubuntu 11.10
      Παρακαλώ για την βοήθειά σας

      • sonic2000gr | 13/03/2012 at 20:46

        Δες και τα σχόλια εδώ.

        Μπορείς να βάλεις για πρώτη γραμμή στο πρόγραμμα σου:

        #coding=utf-8

        ή όποιο άλλο encoding έχει το αρχείο σου (φυσιολογικά για Linux θα είναι utf-8). To encoding θα μπορέσεις να το δεις συνήθως με την εντολή file, π.χ.

        file guess1.py

        guess1.py: UTF-8 Unicode program text

  3. antoni4040 | 11/03/2012 at 08:40

    Εγώ έκανα το εξής:
    name=raw_input(“Πώς σε λένε; “)
    print “Καλημέρα”, name, “!”
    import random
    thenumber=random.randint(1,10)
    print “Έχω σκεφτεί έναν αριθμό απ’το 1 ως το 10…”
    print “Μπορείς να τον βρεις;”
    count=0
    guess=0
    while guessthenumber:
    guess=input(“Δώσε έναν αριθμό: “)
    if guess>thenumber:
    print ” Έδωσες μεγαλύτερο αριθμό…”
    count=count+1
    if guess<thenumber:
    print " Έδωσες μικρότερο αριθμό…"
    count=count+1
    if guess==thenumber:
    print "Συγχαρητήρια", name, ",τον βρήκες!!!"
    count=count+1
    print "Προσπάθειες:", count
    if count==1:
    print "Είχες την Τύχη του Πρωτάρη…"
    if count1:
    print “Είσαι γρήγορος/η…”
    if count>5:
    print “Η γιαγιά μου να θα το ‘βρισκε νωρίτερα!!!”

  4. antoni4040 | 11/03/2012 at 08:43

    Αν στις string που έχουν αριστερά τους την εντολή print τους έβαζα παρενθέσεις, όπως γίνεται στην Python 3.x, θα είχε το πρόγραμμα κάποιο προβλημα?

  5. antoni4040 | 10/04/2012 at 13:14

    Sorry που άργησα να απαντήσω, το είχα ξεχάσει εντελώς και σήμερα το θυμήθηκα…
    Απ’ότι φαίνεται, η raw_input έχει αφαιρεθεί απ’την 3.x οπότε έβαλα σκέτο input και πριν απ’αυτό την function int για να το μετρήσει ως αριθμό και όχι ως string…
    name=input(“Πώς σε λένε; “)
    print ((“Καλημέρα”), name, (“!”))
    import random
    thenumber=random.randint(1,10)
    print (“Έχω σκεφτεί έναν αριθμό απ’το 1 ως το 10…”)
    print (“Μπορείς να τον βρεις;”)
    count=0
    guess=0
    while guess!=thenumber:
    guess=int(input(“Δώσε έναν αριθμό: “))
    if guess>thenumber:
    print (” Έδωσες μεγαλύτερο αριθμό…”)
    count=count+1
    if guess<thenumber:
    print (" Έδωσες μικρότερο αριθμό…")
    count=count+1
    if guess==thenumber:
    print ("Συγχαρητήρια"), name, (",τον βρήκες!!!")
    count=count+1
    print (("Προσπάθειες:"), count)
    if count==1:
    print ("Είχες την Τύχη του Πρωτάρη…")
    if count1:
    print (“Είσαι γρήγορος/η…”)
    if count>5:
    print (“Η γιαγιά μου να θα το ‘βρισκε νωρίτερα!!!”)
    Any other ideas?

    • r3ckl3ss | 15/04/2012 at 10:11

      Καλησπέρα φίλε antoni4040. Παρατηρήσεις σχετικά με τον κώδικα που δημοσίευσες:
      1) Είναι καλή προγραμματιστική τεχνική, σε όλες τις γλώσσες προγραμματισμού, η εισαγωγή βιβλιοθηκών, κεφαλίδων ή modules, όπως στην περίπτωση σου το import random, να γίνετε στην αρχή του προγράμματος, πριν από οτιδήποτε άλλο. Ακόμη καλύτερο είναι τα imports να βρίσκονται σε ένα ξεχωριστό αρχείο, το οποίο γίνεται import σαν ένα αρχείο αργότερα, αλλά αυτό δεν χρειάζεται να σε απασχολεί σε τόσο μικρά προγράμματα.
      2) Επίσης καλή προγραμματιστική τεχνική είναι η μεταβλητές – σταθερές να δηλώνονται στην αρχή του code block – δομικού στοιχείου του προγράμματος που τις χρησιμοποιεί, δηλαδή στην αρχή μίας κλάσης ή μίας μεθόδου.
      3) Μάθε (όσο πιο νωρίς μπορείς, από τώρα δηλαδή), να κάνεις σχόλια στον κώδικα σου. Σχολίαζε το οτιδήποτε. Αυτό επιτρέπει και σε συναδέλφους σου να κατανοήσουν τον κώδικα σου πιο εύκολα (ή αν δεν δώσεις τον κώδικα, θα μπορέσεις να το διαβάσεις και να το κατανοήσεις ευκολότερα αύριο-μεθαύριο). Μπορεί να ακούγεται γελοίο, το να σχολιάζεις τόσο μικρά κομματάκια κώδικα, αλλά είναι ένα καλό συνήθειο, το οποίο αν το αποκτήσεις, η ζωή σου σαν προγραμματιστής θα γίνει ευκολότερη, καθώς θα γράφεις μεγαλύτερα σε μέγεθος προγράμματα με τον καιρό.

      Και οι δύο παραπάνω μέθοδοι έχουν να κάνουν με σωστές προγραμματιστικές τεχνικές, που και οι δύο αυξάνουν την αναγνωσημότητα του προγράμματος μας, και επιτρέπουν αργότερα σε άλλους προγραμματιστές να κατανοήσουν εύκολα το πρόγραμμα μας. Στην περίπτωση του δικού σου κώδικα:

      #importing random module
      import random

      #declaring variables within scope of __main__
      guess = 0
      count = 0

      Και μία ακόμη παρατήρηση: Γράφεις while guessthenumber:

      Υποθέτω ότι ήθελες να γράψεις: while guess != thenumber:

  6. antoni4040 | 15/04/2012 at 11:46

    Ευχαριστώ για το σχόλιο σου, r3ckl3ss…
    Πάντως, το copy-paste του κώδικα που έκανα δημιούργησε προβλήματα…
    Όπως τα tabs,πχ, που είναι ανύπαρκτα…
    Τουλάχιστον το while guess != thenumber: είναι εντάξει στο δεύτερο μέρος του κώδικα…

    • subZraw | 16/04/2012 at 09:50

      Καλημέρα! Μέχρι να βάλουμε το κατάλληλο plugin στο bbPress, καλύτερα είναι τον κώδικα να τον ανεβάζετε στο Pastebin και να δίνετε link προς τα εκεί…

  7. Sak9 | 26/04/2012 at 20:31

    Καμιά ιδέα για κανένα καλο βιβλίο για python κατά προτίμηση στα EL

    ……………………………………………………………………………………..

  8. alkiviadis | 05/05/2012 at 17:02

    Παιδια εμενα με ενεπνευσαν τα παρακατω και εφτιαξα το παρακατω :

    #!/usr/bin/python
    def exhausted():
    howmany = input(“how many times : “)
    toshop = [‘creme’,’food’,’dog’,’bananas’,’apple’]
    x = range(howmany)
    for i in x :
    inp = raw_input(“Checker : “)
    if inp in toshop :
    print “Yes you have to buy a/an ” + inp
    else :
    print “No , You don\’t have to buy ” + inp

    exhausted()

  9. sonic2000gr | 05/05/2012 at 17:33

    Nice! Αυτός είναι και ο πραγματικός σκοπός των άρθρων: να σε εμπνεύσουν να ασχοληθείς παραπάνω μόνος σου!

  10. alkiviadis | 07/05/2012 at 16:48

    Ρε παιδιά στήν 3 εκδοσή πού εχεί αφαρεθεί το raw_input τί γινεταί με τα string? α καί στην 3 τί παιζει με τις παρενθεσεις?

  11. alkiviadis | 07/05/2012 at 16:52

    Α και αντι για αυτη τη μεθοδο που χρησιμοποιησες για να πεις καλήμερα στο χρηστη υπαρχει και αυτη : x = raw_input(“Γραψε το ονομα σου : “) y = “Γεια σου %s , Καλημέρα” print y % x

Leave a Reply

You must be logged in to post a comment.

Σύνδεση

Αρχείο δημοσιεύσεων