Δημιουργία ενός παιχνιδιού tic-tac-toe. Θεωρητικά θεμέλια ανάπτυξης

Χαιρετισμούς, αγαπητοί φίλοι! Σε αυτό το μάθημα θα δείξω πώς μπορείτε να φτιάξετε ένα παιχνίδι προγράμματος περιήγησης - tic-tac-toe, σε javascript! Όλοι γνωρίζετε τι είναι αυτό το παιχνίδι και πώς να το παίξετε, αλλά επιτρέψτε μου να σας υπενθυμίσω ξανά:

Το Tic-tac-toe είναι ένα λογικό παιχνίδι μεταξύ δύο παικτών σε ένα τετράγωνο πεδίο 3 επί 3 κελιών (πιθανώς μεγαλύτερο). Ο ένας παίζει με «σταυρούς» και ο δεύτερος με «δάχτυλα των ποδιών».

ΥΣΤΕΡΟΓΡΑΦΟ. όπως σε όλα τα παρόμοια μαθήματα javascript, στο τέλος του άρθρου μπορείτε να κατεβάσετε το αρχείο προέλευσης, αλλά και να δείτε το αποτέλεσμα της εργασίας σε ένα παράδειγμα επίδειξης!

Περιγραφή του παιχνιδιού που δημιουργείται

Ας δούμε τα χαρακτηριστικά του παιχνιδιού:

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

Λογικές

Δεν βρήκα πολύπλοκους (καθολικούς) αλγόριθμους για ένα τετράγωνο πεδίο 3 επί 3, πήγα στον άλλο δρόμο - ωμή βία! (περισσότερα για αυτό λίγο αργότερα). Έχω εντοπίσει τρία κύρια διαδοχικά στάδια στα οποία στηρίζεται όλη η λογική:

Στάδιο 1: έλεγχος για να δούμε αν ο παίκτης έχει κερδίσει;

Σε αυτό το στάδιο, ελέγχουμε αν υπάρχουν 3 κελιά (στην ίδια γραμμή) γεμάτα με τα ίδια σύμβολα παίκτη (σταυροί ή μηδενικά). Εκείνοι. ανεξάρτητα από το ποια είναι η κίνηση (ακόμα και η πρώτη), πάντα ελέγχουμε πρώτα αν ο παίκτης έχει κερδίσει. Έτσι μοιάζει η νίκη:

Στάδιο 2: έλεγχος - μπορεί ο υπολογιστής να κερδίσει με την επόμενη κίνηση;

Σε αυτό το στάδιο, αναζητούμε μια γραμμή όπου θα υπάρχουν 2 κελιά που θα γεμίζουν ο υπολογιστής και ένα κενό κελί - δηλαδή, προσπαθούμε να κερδίσουμε λόγω της απροσεξίας του παίκτη. Έτσι μοιάζει η ήττα (δηλαδή, μια νίκη υπολογιστή):

Στάδιο 3: δεν σας αφήνουμε να κερδίσετε!

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

Εκτέλεση

Η διάταξη του αγωνιστικού χώρου είναι πολύ απλή - το κύριο μπλοκ περιέχει μια γραμμή πληροφοριών (κλάση - αποτέλεσμα) και 9 μπλοκ, τα οποία είναι κελιά (κλάση - μπλοκ) διάταξη HTML των κελιών:

Σειρά σου!

Το κελί της βοηθητικής κλάσης είναι απαραίτητο για την ακριβή αναγνώριση του επιθυμητού κελιού στον αγωνιστικό χώρο. Στυλ CSS για τον αγωνιστικό χώρο:

Krestiki_noliki( πλάτος: 306 εικονοστοιχεία; περιθώριο: 0 αυτόματο; ) .krestiki_noliki .block( πλάτος: 100 εικονοστοιχεία; ύψος: 100 εικονοστοιχεία; περίγραμμα: 1 εικονοστοιχεία συμπαγές #cccc; δρομέας: δείκτης; float: αριστερά; στοίχιση κειμένου: κέντρο; μέγεθος γραμματοσειράς: 100 εικονοστοιχεία, ύψος γραμμής: 94 εικονοστοιχεία; )

Τώρα ας δούμε ολόκληρο τον κώδικα JS, μετά τον οποίο θα μιλήσω για τα κύρια σημεία:

$(document).ready(function())( var znak_user = "O"; var znak_comp = "X"; var rand_num = Math.round((Math.random() * (9 - 1) + 1)); if (rand_num > 3)( var znak_comp = "O"; var znak_user = "X"; $(".cell"+rand_num).text(znak_comp); ) var exit_flag = false; var win_user_array = ["123", " 456","789","147","258","369","159","357"]; //Προσδιορισμός της συνάρτησης νίκης του παίκτη check_3_user(znak)( για (var i = 0; i< 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first+",."+second+",."+third).css("background-color", "#83e2c3"); $(".result").text("Вы выиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем возможность победы компьютера function check_2_comp(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == "" && exit_flag == false){ $("."+third).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak && exit_flag == false){ $("."+second).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak && exit_flag == false){ $("."+first).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем ход компьютера function check_2_user(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == ""){ $("."+third).text(znak_comp); exit_flag = true; } } if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak){ $("."+second).text(znak_comp); exit_flag = true; } } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first).text(znak_comp); exit_flag = true; } if(exit_flag) break; } } $(".krestiki_noliki .block").click(function(){ //Если клетка пустая if($(this).text() == ""){ $(this).text(znak_user); check_3_user(znak_user); check_2_comp(znak_comp); check_2_user(znak_user); if(exit_flag == false){ for (var i = 1; i < 10; i++) { if($(".cell"+i).text() == ""){ $(".cell"+i).text(znak_comp); break; } } }else exit_flag = false; } }); });

Πρώτα, δηλώνουμε τις μεταβλητές: znak_user - σε αυτήν τη μεταβλητή αποθηκεύουμε το σύμβολο με το οποίο θα παίξει ο χρήστης (από προεπιλογή, εκεί αποθηκεύεται ένα μηδέν - αυτό είναι το αγγλικό πλαίσιο "O"). znak_comp - σε αυτήν τη μεταβλητή αποθηκεύουμε το σύμβολο με το οποίο θα παίξει ο υπολογιστής (από προεπιλογή, αποθηκεύεται ένας σταυρός - αυτό είναι το αγγλικό πλαίσιο "X").

Η λογική είναι η εξής: αν ο τυχαίος αριθμός είναι μεγαλύτερος από 3, τότε ο υπολογιστής παίζει με μηδενικά και αυτός (ο υπολογιστής) κάνει την πρώτη κίνηση.

Μπορείτε να αλλάξετε αυτήν τη λογική όπως σας βολεύει, για παράδειγμα, μπορείτε να δημιουργήσετε πολλούς τυχαίους αριθμούς για να κάνετε περισσότερες επιλογές για το ποιος θα είναι πρώτος και ποια σημάδια. exit_flag - αυτή η σημαία (μεταβλητή) είναι υπεύθυνη για την έξοδο από τη συνάρτηση, δηλαδή, για παράδειγμα, όταν ο υπολογιστής έχει ήδη κάνει την κίνησή του και πρέπει να βγείτε από τη συνάρτηση και να περάσετε τη μετακίνηση στη συσκευή αναπαραγωγής. win_user_array - αυτός ο πίνακας αποθηκεύει όλες τις επιλογές που κερδίζουν για την πλήρωση των κελιών. Για να το καταλάβουμε, ας ρίξουμε μια ματιά σε αυτήν την εικόνα:

Κάθε στοιχείο του πίνακα είναι μια συμβολοσειρά τριών αριθμών, που είναι ένας συνδυασμός που κερδίζει, δηλαδή, για παράδειγμα, εάν συμπληρώσετε τα κελιά κάτω από τους αριθμούς 1, 2 και 3, τότε θα συμβεί νίκη (ή ήττα). Όπως μπορείτε να δείτε, υπάρχουν 8 επιλογές νίκης συνολικά· καθήκον μας είναι να περάσουμε από όλες αυτές τις επιλογές. Ακολουθούν 3 λειτουργίες:

  1. check_3_user();
  2. check_2_comp();
  3. check_2_user();

Ο σκοπός αυτών των συναρτήσεων περιγράφεται (σε ​​τρία βήματα) στην ενότητα Λογική (παραπάνω). Αυτές οι συναρτήσεις καλούνται κάνοντας κλικ σε οποιοδήποτε από τα κελιά του πεδίου. Μια παράμετρος (znak) μεταβιβάζεται σε καθεμία από τις συναρτήσεις - αυτό είναι το σύμβολο του παίκτη ή του υπολογιστή (ένας σταυρός ή ένα μηδέν), για παράδειγμα, στη συνάρτηση που καθορίζει τη νίκη του παίκτη (check_3_user), περνάμε το σύμβολο του παίκτη με τη σειρά για να βρείτε 3 πανομοιότυπα σημάδια στην ίδια γραμμή.

Μετά από τρεις λειτουργίες (εάν ο υπολογιστής δεν έχει κάνει ακόμη κίνηση), ο υπολογιστής γεμίζει ένα από τα ελεύθερα κελιά. Εδώ, μπορείτε να περιπλέκετε το παιχνίδι, για παράδειγμα, κάνοντάς το έτσι ώστε εάν το κεντρικό κελί είναι ελεύθερο (αριθμός κελί 5), τότε πρώτα ποντάρετε σε αυτό· εάν είναι κατειλημμένο, τότε ποντάρετε σε μια από τις ελεύθερες γωνίες (αυτές είναι κελιά Νο. 1, 3, 7 και 9) και ούτω καθεξής - σε γενικές γραμμές, εδώ είναι στη διακριτική σας ευχέρεια.

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

Τώρα μπορείτε να παρακολουθήσετε το παιχνίδι χρησιμοποιώντας ένα παράδειγμα επίδειξης και να κάνετε λήψη του αρχείου πηγής (1 αρχείο συνολικά).

06/08/2018 - ευχαριστώ για την προσοχή σας στον συντάκτη της επιστολής: Patvakan Baghdasaryan, ένα σφάλμα διορθώθηκε όταν ο υπολογιστής είχε πολλά πιθανές επιλογέςνίκες και όλες οι νικητήριες κινήσεις του ήταν ζωγραφισμένες (από 4 έως 6 κελιά, αντί για 3).

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

Πώς να γράψετε ένα bot που δεν μπορεί να νικηθεί στο tic-tac-toe ή Εισαγωγή στον κανόνα minimax

Είναι πολύ πιθανό μετά από εκατοντάδες παιχνίδια τικ-τακ, να έχετε αναρωτηθεί: ποιος είναι ο βέλτιστος αλγόριθμος; Αλλά αν είστε εδώ, τότε πιθανότατα προσπαθήσατε επίσης να γράψετε μια υλοποίηση αυτού του παιχνιδιού. Θα πάμε παρακάτω και θα γράψουμε ένα bot που θα είναι αδύνατο να νικηθεί στο τικ-τακ. Προβλέποντας την ερώτησή σας «γιατί;», θα απαντήσουμε: χάρη στον αλγόριθμο.

Όπως ένας επαγγελματίας σκακιστής, αυτός ο αλγόριθμος υπολογίζει τις ενέργειες του αντιπάλου αρκετές κινήσεις μπροστά - μέχρι να φτάσει στο τέλος του παιχνιδιού, είτε είναι νίκη, ήττα ή ισοπαλία. Μόλις σε αυτή την τελική κατάσταση, το AI θα απονείμει στον εαυτό του έναν θετικό αριθμό πόντων (στην περίπτωσή μας +10) για μια νίκη, αρνητικό (-10) για μια ήττα και ουδέτερο (0) για την ισοπαλία.

Ταυτόχρονα, ο αλγόριθμος πραγματοποιεί παρόμοιους υπολογισμούς για τις κινήσεις του παίκτη. Θα επιλέξει την κίνηση με την υψηλότερη βαθμολογία εάν μετακινηθεί το AI και την κίνηση με τη χαμηλότερη αν μετακινηθεί ο παίκτης. Χρησιμοποιώντας αυτή τη στρατηγική, το minimax αποφεύγει την ήττα.

Δοκιμάστε να παίξετε αυτό το παιχνίδι.

Ο αλγόριθμος minimax περιγράφεται πιο εύκολα ως μια αναδρομική συνάρτηση που:

  1. επιστρέφει μια τιμή εάν βρεθεί η τελική κατάσταση (+10, 0, -10),
  2. περνά από όλα τα άδεια κελιά στο γήπεδο,
  3. καλεί τη συνάρτηση minimax για καθένα από αυτά (αναδρομή),
  4. αξιολογεί τις λαμβανόμενες τιμές
  5. και επιστρέφει το καλύτερο.

Εάν δεν είστε εξοικειωμένοι με την αναδρομή, τότε θα πρέπει να παρακολουθήσετε αυτήν τη διάλεξη από το μάθημα Harvard CS50:

Για να κατανοήσουμε πώς λειτουργεί το minimax, ας γράψουμε την υλοποίησή του και ας μοντελοποιήσουμε τη συμπεριφορά του. Θα ασχοληθούμε με αυτό στις επόμενες δύο ενότητες.

Minimax υλοποίηση

Θα εξετάσουμε μια κατάσταση όπου το παιχνίδι πλησιάζει στο τέλος του (δείτε την παρακάτω εικόνα). Δεδομένου ότι το minimax περνά από όλες τις πιθανές καταστάσεις παιχνιδιού (και υπάρχουν εκατοντάδες χιλιάδες από αυτές), είναι λογικό να εξετάσουμε το τελικό παιχνίδι - με αυτόν τον τρόπο θα πρέπει να παρακολουθήσουμε μικρότερο αριθμό αναδρομικών κλήσεων συναρτήσεων (9 συνολικά).

Αφήστε το AI να παίξει με σταυρούς, το άτομο - με μηδενικά.

Για να διευκολύνουμε την εργασία με το πεδίο, ας το δηλώσουμε ως έναν πίνακα 9 στοιχείων με τιμές ίσες με τα περιεχόμενα των κελιών. Ας το γεμίσουμε με σταυρούς και τα δάχτυλα των ποδιών, όπως στην παραπάνω εικόνα, και ας το ονομάσουμε origBoard.

Var origBoard = ["O",1,"X","X",4,"X",6,"O","O"];

Στη συνέχεια, θα δηλώσουμε τις μεταβλητές aiPlayer και huPlayer και θα τους εκχωρήσουμε τις τιμές "X" και "O" αντίστοιχα.

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

/* αρχική κατάστασησανίδες Ο | | X --------- X | | Χ --------- | O | O */ var origBoard = [“O”,1 ,”X”,”X”,4 ,”X”, 6 ,”O”,”O”]; // άτομο var huPlayer = "O"; // AI var aiPlayer = "X"; // επιστρέφει μια λίστα με δείκτες κενών κελιών στη συνάρτηση πίνακα κενόIndices(board)( return board.filter(s => s != "O" && s != "X"); ) // νικηφόρους συνδυασμούς λαμβάνοντας υπόψη συνάρτηση δεικτών που κερδίζει(ταμπλό, παίκτης)( αν((ταμπλό == παίκτης && ταμπλό == παίκτης && ταμπλό == παίκτης) || (σανίδα == παίκτης && ταμπλό == παίκτης && ταμπλό == παίκτης) || (ταμπλό == παίκτης = παίκτης && ταμπλό == παίκτης && ταμπλό == παίκτης) || (σανίδα == παίκτης && ταμπλό == παίκτης && ταμπλό == παίκτης) || (σανίδα == παίκτης && ταμπλό == παίκτης && ταμπλό == παίκτης) | | (σανίδα == παίκτης && ταμπλό == παίκτης && ταμπλό == παίκτης) || (σανίδα == παίκτης && ταμπλό == παίκτης && ταμπλό == παίκτης) || (σανίδα == παίκτης && ταμπλό == παίκτης && ταμπλό = = παίκτης)) ( επιστροφή αληθής; ) αλλιώς (επιστροφή ψευδής; ) )

Ας ορίσουμε λοιπόν μια συνάρτηση minimax με δύο ορίσματα: newBoard και player. Στη συνέχεια, θα βρούμε τους δείκτες των ελεύθερων κελιών στο πεδίο και θα τους περάσουμε στη μεταβλητή availSpots.

// κύρια συνάρτηση minimax minimax(newBoard, player)( // διαθέσιμα κελιά var availSpots = κενό Indices(newBoard);

Επιπλέον, πρέπει να παρακολουθούμε τις τελικές καταστάσεις και να επιστρέφουμε τις κατάλληλες τιμές. Εάν το "μηδέν" κερδίσει, πρέπει να επιστρέψετε -10, εάν το "σταυρό" - +10. Εάν το μέγεθος του πίνακα availSpots είναι μηδέν, τότε δεν υπάρχουν ελεύθερα κελιά, το παιχνίδι θα τελειώσει με ισοπαλία και το μηδέν πρέπει να επιστραφεί.

// έλεγχος για την κατάσταση τερματικού (νίκη/ήττα/ισοπαλία) //και επιστροφή μιας τιμής ανάλογα εάν (winning(newBoard, huPlayer))( return (score:-10); ) other if (winning(newBoard, aiPlayer)) ( επιστροφή (βαθμολογία: 10); ) αλλιώς εάν (availSpots.length === 0) (επιστροφή (βαθμολογία: 0); )

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

Στη συνέχεια ορίσαμε το ευρετήριο του κενού κελιού, το οποίο αποθηκεύτηκε ως αριθμός στο origBoard, ίσο με την ιδιότητα ευρετηρίου του αντικειμένου move. Στη συνέχεια, θα πάμε ως ο τρέχων παίκτης σε ένα κενό κελί του νέου πεδίου newBoard και θα καλέσουμε τη συνάρτηση minimax από τον άλλο παίκτη και το πεδίο που προκύπτει newBoard. Μετά από αυτό, πρέπει να βάλετε την ιδιότητα score του αντικειμένου που επιστρέφεται από τη συνάρτηση minimax στην ιδιότητα score του αντικειμένου κίνησης.

Αν το minimax δεν βρει τερματική κατάσταση, συνεχίζει να κινείται αναδρομικά βαθύτερα στο παιχνίδι μέχρι να φτάσει σε τερματική κατάσταση. Μετά από αυτό, μεταφέρει τα σημεία αυτού του «επιπέδου» αναδρομής σε ένα επίπεδο υψηλότερα.

Τέλος, η συνάρτηση επαναφέρει τις αλλαγές στο newBoard και τοποθετεί το αντικείμενο μετακίνησης στον πίνακα κινήσεων.

// πίνακας για την αποθήκευση όλων των αντικειμένων var moves = ; // βρόχο μέσω των διαθέσιμων κελιών για (var i = 0; i< availSpots.length; i++){ //create an object for each and store the index of that spot var move = {}; move.index = newBoard]; // совершить ход за текущего игрока newBoard] = player; //получить очки, заработанные после вызова минимакса от противника текущего игрока if (player == aiPlayer){ var result = minimax(newBoard, huPlayer); move.score = result.score; } else{ var result = minimax(newBoard, aiPlayer); move.score = result.score; } // очистить клетку newBoard] = move.index; // положить объект в массив moves.push(move); }

Στη συνέχεια, το Minimax πρέπει να επιλέξει την καλύτερη κίνηση από τον πίνακα κινήσεων. Χρειάζεται την κίνηση με την υψηλότερη βαθμολογία εάν το AI κινείται και με τη χαμηλότερη αν είναι ανθρώπινη κίνηση. Έτσι, εάν η τιμή του παίκτη είναι aiPlayer, ο αλγόριθμος αρχικοποιεί τη μεταβλητή bestScore σε έναν πολύ μικρό αριθμό και περιστρέφεται μέσω του πίνακα κινήσεων: εάν μια βαθμολογία κίνησης αξίζει περισσότερο σκορ από το bestScore, ο αλγόριθμος θυμάται αυτή την κίνηση. Στην περίπτωση κινήσεων με ίσα σημεία, ο αλγόριθμος θυμάται την πρώτη.

Στην περίπτωση που ο παίκτης είναι ίσος με τον huPlayer , όλα είναι παρόμοια - μόνο τώρα το bestScore αρχικοποιείται σε μεγάλο αριθμό και το minimax αναζητά την κίνηση με τους λιγότερους πόντους.

Ως αποτέλεσμα, το minimax επιστρέφει το αντικείμενο που είναι αποθηκευμένο στο bestMove .

// εάν πρόκειται για κίνηση τεχνητής νοημοσύνης, κάντε κύκλο μέσα από τις κινήσεις και επιλέξτε την κίνηση με τους περισσότερους πόντους var bestMove. if(player === aiPlayer)( var bestScore = -10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score >bestScore)( bestScore = moves[i].score; bestMove = i; ) ) )else( // διαφορετικά κάντε βρόχο στις κινήσεις και επιλέξτε την κίνηση με τους λιγότερους πόντους var bestScore = 10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score < bestScore){ bestScore = moves[i].score; bestMove = i; } } } // вернуть выбранный ход (объект) из массива ходов return moves; }

Στην επόμενη ενότητα, θα προσομοιώσουμε το πρόγραμμά μας για να κατανοήσουμε πώς λειτουργεί.

Minimax σε δράση

Χρησιμοποιώντας το παρακάτω διάγραμμα, θα αναλύσουμε βήμα προς βήμα το μοντέλο του αλγορίθμου.

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

  1. Το origBoard και το aiPlayer τροφοδοτούνται στον αλγόριθμο. Δημιουργεί μια λίστα με τα τρία κενά κελιά που βρέθηκαν, ελέγχει το πεπερασμένο της κατάστασης και πραγματοποιεί βρόχους σε όλα τα κενά κελιά. Στη συνέχεια, ο αλγόριθμος αλλάζει το newBoard, τοποθετώντας το aiPlayer στο πρώτο κενό τετράγωνο. Μετά από αυτό, καλεί τον εαυτό του από το newBoard και το huPlayer και περιμένει τη δεύτερη κλήση για να επιστρέψει μια τιμή.
  2. Ενώ η πρώτη κλήση συνάρτησης εκτελείται ακόμα, εκτελείται η δεύτερη, δημιουργώντας μια λίστα με δύο κενά κελιά, ελέγχοντας για πεπερασμένη κατάσταση και πραγματοποιώντας βρόχο σε όλα τα κενά κελιά. Στη συνέχεια, η δεύτερη κλήση τροποποιεί το newBoard τοποθετώντας το huPlayer στο πρώτο κενό τετράγωνο. Μετά από αυτό, καλεί τον εαυτό του από το newBoard και το aiPlayer και περιμένει την τρίτη κλήση για να επιστρέψει μια τιμή.

  3. Επειδή η δεύτερη κλήση βρήκε δύο κενά κελιά, το minimax τροποποιεί το newBoard τοποθετώντας το huPlayer στο δεύτερο κενό κελί. Στη συνέχεια καλεί τον εαυτό του από το newBoard και το aiPlayer.

  4. Ο αλγόριθμος συντάσσει μια λίστα με κενά κελιά και καταγράφει τη νίκη του παίκτη αφού ελέγξει το πεπερασμένο της κατάστασης. Άρα επιστρέφει ένα αντικείμενο με πεδίο βαθμολογίας (-10).

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

    Σε αυτό το σημείο, η πρώτη κλήση συνάρτησης έλαβε μια εκτίμηση της μετακίνησης του aiPlayer στο πρώτο κενό κελί. Στη συνέχεια, τροποποιεί το newBoard τοποθετώντας το aiPlayer στο δεύτερο κενό τετράγωνο. Μετά από αυτό, καλεί τον εαυτό του από το newBoard και το huPlayer.

  5. Στην πέμπτη κλήση συνάρτησης, ο αλγόριθμος συντάσσει μια λίστα κενών κελιών και καταγράφει τη νίκη του AI αφού ελέγξει το πεπερασμένο της κατάστασης. Έτσι επιστρέφει ένα αντικείμενο με πεδίο βαθμολογίας +10.

    Μετά από αυτό, η πρώτη κλήση τροποποιεί το newBoard τοποθετώντας το aiPlayer στο τρίτο κενό κελί. Στη συνέχεια καλεί τον εαυτό του από το newBoard και το huPlayer.

  6. Η έκτη κλήση δημιουργεί μια λίστα με δύο κενά κελιά, ελέγχει το πεπερασμένο της κατάστασης και κάνει βρόχο σε όλα τα κενά κελιά. Στη συνέχεια, τροποποιεί το newBoard τοποθετώντας το huPlayer στο πρώτο κενό τετράγωνο. Στη συνέχεια καλεί τον εαυτό του από το newBoard και το aiPlayer και περιμένει την έβδομη κλήση για να επιστρέψει μια τιμή.
  7. Η νέα κλήση δημιουργεί μια λίστα με ένα κενό κελί, ελέγχει για πεπερασμένη κατάσταση και τροποποιεί το newBoard για να τοποθετήσει το aiPlayer στο κενό κελί. Μετά από αυτό, καλεί τον εαυτό του από το newBoard και το huPlayer και περιμένει αυτή η κλήση να επιστρέψει μια τιμή.
  8. Η όγδοη πρόκληση είναι κενή λίστααδειάζει κελιά και καταγράφει τη νίκη του aiPlayer αφού ελέγξει την κατάσταση του άκρου. Επομένως, επιστρέφει ένα αντικείμενο με πεδίο μέτρησης ίσο με (+10) στο παραπάνω επίπεδο, την έβδομη κλήση.

    Η έβδομη κλήση έλαβε μόνο μία, θετική τιμή από τα χαμηλότερα επίπεδα. Δεδομένου ότι αυτή η τιμή ελήφθη κατά τη διάρκεια της σειράς του aiPlayer, ο αλγόριθμος επιστρέφει τη μεγαλύτερη τιμή που ελήφθη. Έτσι επιστρέφει μια θετική τιμή (+10) στο επίπεδο προς τα πάνω, την έκτη κλήση.

    Επειδή η έκτη κλήση βρήκε δύο κενά κελιά, το minimax τροποποιεί το newBoard τοποθετώντας το huPlayer στο δεύτερο κενό κελί. Στη συνέχεια καλεί τον εαυτό του από το newBoard και το aiPlayer.

  9. Μετά από αυτό, ο αλγόριθμος συντάσσει μια λίστα με κενά κελιά και καταγράφει τη νίκη του aiPlayer αφού ελέγξει το πεπερασμένο της κατάστασης. Επομένως, επιστρέφει ένα αντικείμενο με πεδίο βαθμολογίας ίσο με (+10) στο παραπάνω επίπεδο.

    Σε αυτό το σημείο, η έκτη πρόκληση πρέπει να επιλέξει μεταξύ του σκορ (+10) που επέστρεψε η έβδομη πρόκληση και του σκορ (-10) που επέστρεψε η ένατη πρόκληση. Εφόσον η κίνηση του huPlayer παρήγαγε αυτά τα δύο αποτελέσματα, ο αλγόριθμος επιλέγει το μικρότερο και το επιστρέφει στο επόμενο επίπεδο ως αντικείμενο με πεδία βαθμολογίας και ευρετηρίου.

    Τέλος, αξιολογούνται και οι τρεις κλάδοι της πρώτης κλήσης (-10, +10, -10). Εφόσον η κίνηση του aiPlayer παρήγαγε αυτά τα τρία αποτελέσματα, ο αλγόριθμος επιλέγει το αντικείμενο που περιέχει την υψηλότερη βαθμολογία (+10) και τον δείκτη του (4).

Στο παραπάνω σενάριο, το minimax το αποφασίζει βέλτιστη επιλογήθα γίνει μετακόμιση στην κεντρική πλατεία του γηπέδου.

Τέλος!

Μέχρι τώρα θα έπρεπε να έχετε καταλάβει πώς λειτουργεί ο αλγόριθμος minimax. Δοκιμάστε να γράψετε μόνοι σας μια υλοποίηση ή δείτε ένα παράδειγμα στο GitHub ή το CodePen και βελτιστοποιήστε το.

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

ΒΗΜΑ 1. ΔΙΑΜΟΡΦΩΣΗ ΠΑΡΑΜΕΤΡΩΝ ΦΟΡΜΑΣ1. Για να προσαρμόσετε μια φόρμα, ορίστε το μέγεθός της
510 κουκκίδες οριζόντια και 480 κουκκίδες οριζόντια
κατακόρυφος. Μέγιστο και ελάχιστο
υποδεικνύουν το μέγεθος ίσο με τις ίδιες τιμές.
2. Ονομάστε το σχήμα "Tic Tac Toe".
3. Για το φόντο της φόρμας, χρησιμοποιήστε ένα αρχείο από το φάκελο
Εικόνες κάτω από το όνομα background.png και τοποθετήστε το
στο κέντρο της φόρμας.
4. Για ένα εικονίδιο στη γραμμή τίτλου
χρησιμοποιήστε χρήση αρχείου από φάκελο
Εικόνες κάτω από το όνομα menu4.ico.
5. Πρέπει να οριστεί το χρώμα φόντου της φόρμας
MintCream.

ΒΗΜΑ 2. ΠΡΟΣΘΗΚΗ ΚΟΥΜΠΙΟΥ ΚΑΙ ΕΤΙΚΕΤΑΣ ΣΤΗ ΦΟΡΜΑ

1. Για τοποθετημένα στοιχεία, αλλάξτε
μέγεθος γραμματοσειράς σε 12 και σετ φόντου
διαφανής.

1. Δημιουργήστε μια γραμμή μενού με στοιχεία μέσα
όπως φαίνεται στην εικόνα.

ΒΗΜΑ 3. ΠΡΟΣΘΗΚΗ ΜΙΑΣ ΜΕΝΟΥ ΜΠΑΡ ΣΤΗ ΦΟΡΜΑ

1. Στο στοιχείο μενού Αρχείο, δημιουργήστε μια εντολή
Εξοδος.
2. Για
της ομάδας
Εξοδος
ας συνταγογραφήσουμε
ο κωδικός του προγράμματος είναι ο ίδιος όπως στο
προηγούμενη αίτηση.

ΒΗΜΑ 3. ΠΡΟΣΘΗΚΗ ΜΙΑΣ ΜΕΝΟΥ ΜΠΑΡ ΣΤΗ ΦΟΡΜΑ

1. Στο στοιχείο μενού Παιχνίδι, δημιουργήστε μια ομάδα
Ένα νέο παιχνίδι.
2. Για την εντολή Νέο παιχνίδι θα γράψουμε
κώδικα προγράμματος στο μέλλον μέσω
μερικά βήματα.

ΒΗΜΑ 3. ΠΡΟΣΘΗΚΗ ΜΙΑΣ ΜΕΝΟΥ ΜΠΑΡ ΣΤΗ ΦΟΡΜΑ

1. Στο στοιχείο μενού Βοήθεια, δημιουργήστε μια εντολή
Σχετικά με το πρόγραμμα.
2. Για την εντολή About the program, δημιουργήστε μια νέα
σχηματίστε και γράψτε τον κώδικα του προγράμματος
παρόμοια με την προηγούμενη
εφαρμογή.

1. Σύροντας ένα αντικείμενο PictureBox στη φόρμα
αλλάξτε το μέγεθός του σε 100x100.
2. Ορίστε ένα διαφανές φόντο.
3. Τοποθετήστε το PictureBox όπως φαίνεται στο
εικόνα πάνω από το πρώτο κελί του πεδίου παιχνιδιού.

ΒΗΜΑ 4. ΠΡΟΣΘΗΚΗ ΑΝΤΙΚΕΙΜΕΝΩΝ PICTUREBOX ΣΤΗ ΦΟΡΜΑ

1
2
3
4
5
6
7
8
9
1. Πάνω από τα υπόλοιπα κελιά τοποθετούμε
Αντικείμενα PictureBox, αντίγραφα του πρώτου
αντικείμενο, σύμφωνα με την αρίθμηση που αναγράφεται στο
εικόνες.

1. Πριν γράψετε κώδικα
χρειάζεται στον φάκελο
\Visual Studio
2010\Projects\Tic Tac Toe\X's
Το zeros\bin\Debug\ πρέπει να επαναφερθεί
αρχεία x.png, 0.png, none.png από το φάκελο Images.
2. Κάντε διπλό κλικ με το αριστερό ποντίκι στο πρώτο
PictureBox.

ΒΗΜΑ 5. ΠΡΟΣΘΗΚΗ ΚΩΔΙΚΟΥ ΓΙΑ ΑΝΤΙΚΕΙΜΕΝΑ PICTUREBOX

1. Δημιουργήστε έναν δισδιάστατο πίνακα προσβάσιμο σε όλα τα στοιχεία του
δημιουργήθηκε με τη μορφή στοιχείων 3x3 που αποτελούνται από ακέραιους αριθμούς. Αμέσως
το γεμίζουμε με μηδενικά όταν το δηλώνουμε. Για άδεια κελιά εμείς
Θα χρησιμοποιήσουμε το 0, για "σταυρούς" - 1, και για "μηδενικά" - -1.

ΒΗΜΑ 5. ΠΡΟΣΘΗΚΗ ΚΩΔΙΚΟΥ ΓΙΑ ΑΝΤΙΚΕΙΜΕΝΑ PICTUREBOX

Στη διαδικασία όταν κάνετε κλικ στο πρώτο
PictureBox, προσθέστε έναν τελεστή
επιλογή
οι οποίες
θα
ελέγξετε την κατάσταση
κελιά πίνακα. Εάν η τιμή
Τα κελιά του πίνακα θα είναι ίσα με 0, το οποίο
αυτό σημαίνει ότι δεν υπάρχει ούτε «μηδέν» ούτε
"σταυρός", μετά σε αυτό το κελί
Ο πίνακας γράφεται 1 και σε
PictureBox1
εκτεθειμένος
εικόνα ενός «σταυρού», και αν
η τιμή του κελιού του πίνακα θα είναι
ισούται με 1 τότε περιέχει
"σταυρός" και 0 είναι γραμμένο σε αυτό, και
Εμφανίζεται ένα κενό κελί.

ΒΗΜΑ 5. ΠΡΟΣΘΗΚΗ ΚΩΔΙΚΟΥ ΓΙΑ ΑΝΤΙΚΕΙΜΕΝΑ PICTUREBOX

1
2
3
4
5
6
7
8
9



Για τα υπόλοιπα κελιά του πεδίου, προσθέστε τον κωδικό
το ίδιο όπως στο πρώτο αλλάζει μόνο
Αριθμός αντικειμένου PictureBox και διεύθυνση κελιού
πίνακας.
ΠΑΡΑΔΕΙΓΜΑ για το δεύτερο κελί:

Στη διαδικασία όταν κάνετε κλικ σε ένα κουμπί
Προσθήκη
χειριστής
κύκλος
που ελέγχει
όλα τα κύτταρα ξεκινώντας από το πρώτο έως
παρουσία κενών κελιών. Κι αν
το κελί είναι άδειο,
μετά μέσα της
Το «μηδέν» γράφεται, δηλαδή στο
το κελί του πίνακα γράφεται -1.
Για διευκόλυνση σε μελλοντικές εργασίες
μεταβλητές
ΕΓΩ,
ι
οι οποίες
χρησιμοποιείται για την επανάληψη βρόχων
Θα ανακοινώσουμε για ολόκληρο το έντυπο.

ΒΗΜΑ 6. ΠΡΟΣΘΗΚΗ ΚΩΔΙΚΟΥ ΓΙΑ ΤΟ ΚΟΥΜΠΙ ΠΕΡΠΑΤΗΣΗΣ

Για να εμφανίσετε μηδενικά ενεργά
gaming
πεδίο
απαραίτητη
προσθέστε κώδικα προγράμματος στο σώμα
κύκλος ελέγχου κελιών για κενό.
Χρήση ένθετης δήλωσης
διακλάδωση
θα
λαμβάνει χώρα
ανάλυση διεύθυνσης κελιού πίνακα για
έξοδος μηδέν στη σωστή
PictureBox.
Προσθέτουμε επίσης μια δήλωση διακοπής
για πρόωρο τέλος
βρόχο κατά την εύρεση κενού
κύτταρα.

ΒΗΜΑ 6. ΠΡΟΣΘΗΚΗ ΚΩΔΙΚΟΥ ΓΙΑ ΤΟ ΚΟΥΜΠΙ ΠΕΡΠΑΤΗΣΗΣ

Για να υποδείξετε την κατάσταση του παιχνιδιού
χρησιμοποιείται το στοιχείο διεπαφής
Ετικέτα 1. Αφού ο παίκτης κινείται πάντα
πρώτα
Οτι
στο
λήψεις
εφαρμογές
απαραίτητη
V
στοιχείο
Ετικέτα 1
απαραίτητη
κατοπτρίζω
φράσεις «Σου
κίνηση."
Για
Αυτό
ας δημιουργήσουμε
μεταβλητός
απάντηση
οι οποίες
Ας αντιστοιχίσουμε αυτή τη φράση. ΕΝΑ
κατά τη φόρτωση της φόρμας μιας μεταβλητής
πρέπει να αντιστοιχιστεί στο στοιχείο
Label1, για να δημιουργήσετε τα απαραίτητα
διαδικασίες
απαραίτητη
διπλό κλικ πρώτα
σύμφωνα με τη μορφή

ΒΗΜΑ 7. ΠΡΟΣΘΗΚΗ ΚΩΔΙΚΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ ΓΙΑ ΤΟ ΝΕΟ ΣΤΟΙΧΕΙΟ ΜΕΝΟΥ ΠΑΙΧΝΙΔΙΟΥ

Όταν πατηθεί στην εντολή new
το παιχνίδι θα μηδενιστεί
όλα τα κελιά του πίνακα, αντικαθιστώντας όλα
«σταυροί» και «δάχτυλα των ποδιών» επάνω
άδεια κελιά. Επίσης το συμπέρασμα
Ταμπέλες «Η κίνησή σου».

ΒΗΜΑ 8. ΑΠΟΤΕΛΕΣΜΑ ΠΑΙΧΝΙΔΙΟΥ

Για να ελέγξετε τα αποτελέσματα των κινήσεων
απαραίτητη
αναλύει
περιεχόμενα σειρών, στηλών και
διαγώνιους. Αν και τα τρία στοιχεία
είναι ίσα με 1, τότε αυτή είναι μια νίκη για τον παίκτη, και
αν τρεις -1 τότε αυτό είναι ήττα
παίχτης.
Απαιτείται έλεγχος νίκης
συμπεριφορά
πριν
πρόοδος
υπολογιστή,
ΕΝΑ
έλεγχος
ήττα μετά.
Η τελευταία εντολή της διαδικασίας
τα αποτελέσματα θα εμφανιστούν στην οθόνη
πρόοδος.

ΒΗΜΑ 8. ΑΠΟΤΕΛΕΣΜΑ ΠΑΙΧΝΙΔΙΟΥ

Κωδικός προγράμματος για να ελέγξετε τη νίκη του χρήστη:
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
αν (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Εσύ κερδίζεις";
Κωδικός προγράμματος για να ελέγξετε τη νίκη του χρήστη:
αν (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Έχασες";
αν (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Έχασες";
αν (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Έχασες";
αν (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Έχασες";
αν (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Έχασες";
αν (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Έχασες";
label1.Text = απάντηση;

ΒΗΜΑ 9 ΒΕΛΤΙΩΣΗ ΤΗΣ ΠΑΙΚΤΙΚΟΤΗΤΑΣ

Για βελτίωση της δυνατότητας αναπαραγωγής
αντί για σειριακή έξοδο
στα πρώτα άδεια
κελιά των «μηδενικών», υλοποιούμε
έξοδο μέσω τυχαίας γεννήτριας
αριθμοί.
Για να γίνει αυτό πρέπει να προσθέσετε
μία λογική μεταβλητή
uslovie και αλλάξτε τον τύπο βρόχου από For
on Ενώ, αφού δεν ξέρουμε
ακριβής αριθμός επαναλήψεων
γεννήτρια τυχαίους αριθμούςΑντίο
δεν θα πέσει σε ένα άδειο κελί.

ΥΠΟΥΡΓΕΙΟ ΠΑΙΔΕΙΑΣ ΚΑΙ ΕΠΙΣΤΗΜΗΣ ΤΗΣ ΡΩΣΙΑΣ

Ομοσπονδιακό κρατικό προϋπολογισμό εκπαιδευτικό ίδρυμα τριτοβάθμιας επαγγελματικής εκπαίδευσης

"Κρατικό Πανεπιστήμιο Vologda"

Τμήμα Μηχανικών Αυτοματισμού και Μηχανικών Υπολογιστών

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

Βασικές αρχές προγραμματισμού και αλγοριθμικών

"Τρίλιζα"

Ολοκληρώθηκε τομαθητής της ομάδας ΕΜ-21

Butorova L.Yu.

Αποδεκτό Rzheutskaya S. Yu.

ΕΙΣΑΓΩΓΗ

1. ΑΝΑΛΥΣΗ ΤΟΥ ΠΡΟΒΛΗΜΑΤΟΣ ΚΑΙ ΠΡΟΣΔΙΟΡΙΣΜΟΣ ΑΠΑΙΤΗΣΕΩΝ ΓΙΑ ΤΟ ΠΡΟΓΡΑΜΜΑ ΠΡΟΣ ΑΝΑΠΤΥΞΗ

1 Σκοπός του προγράμματος, χρήστες του, κύριες λειτουργίες και στόχοι που επιδιώκονται κατά την ανάπτυξη

2 Ανασκόπηση γνωστών προγραμμάτων που εκτελούν παρόμοιες λειτουργίες

3 Θεωρητική βάση ανάπτυξης

4 Επιλογή εργαλείων ανάπτυξης

ΣΧΕΔΙΑΣΜΟΣ ΜΕΡΟΣ ΤΗΣ ΑΝΑΠΤΥΞΗΣ

1 Ανάπτυξη διεπαφής χρήστη

2.2 Ανάπτυξη δομών δεδομένων (σε εξωτερικό και RAM)

2.3 Ανάπτυξη και ανάλυση αλγορίθμων

ΕΦΑΡΜΟΓΗ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ ΣΕ ΓΛΩΣΣΑ C++

1 Αρχιτεκτονική προγράμματος

2 Επιλογή τυπικών οπτικών και μη εξαρτημάτων

ΑΠΟΤΕΛΕΣΜΑΤΑ ΤΕΣΤ

ΣΥΜΠΕΡΑΣΜΑ

Βιβλιογραφία

Εφαρμογές

ΕΙΣΑΓΩΓΗ

Το Tic-tac-toe είναι ένα λογικό παιχνίδι μεταξύ δύο αντιπάλων σε ένα τετράγωνο πεδίο 3 επί 3 κελιών ή μεγαλύτερο (μέχρι ένα «ατελείωτο πεδίο»). Ένας από τους παίκτες παίζει με "σταυρούς", ο δεύτερος - με "δάχτυλα των ποδιών". Αυτό το παιχνίδι έγινε δημοφιλές πολύ πριν από την εμφάνιση των υπολογιστών, μόνο πριν παιζόταν με ένα κανονικό κομμάτι χαρτί και ένα στυλό. Το παραδοσιακό κινέζικο παιχνίδι χρησιμοποιεί ασπρόμαυρες πέτρες.

Σε αυτό εργασία μαθημάτωνΟι βασικοί κανόνες και το τυπικό μέγεθος του πεδίου παιχνιδιού (3x3 κελιά) διατηρούνται. Για τη διευκόλυνση του παιχνιδιού, το δικαίωμα να κάνει την πρώτη κίνηση αφήνεται στον χρήστη, δηλαδή «σταυροί».

Το Tic Tac Toe είναι ένα πρόγραμμα που έχει σχεδιαστεί για να ψυχαγωγεί τον χρήστη, επομένως η διεπαφή του, σε αυτήν την εργασία μαθήματος, είναι κατασκευασμένη σε στυλ παιχνιδιού με συνδυασμό θετικών χρωμάτων που ενισχύουν το συναισθηματικό μέρος της διαδικασίας του παιχνιδιού.

Υπάρχουν τρεις τύποι στο παιχνίδι: X έναντι 0 - χρήστης έναντι χρήστη, "1ο επίπεδο με υπολογιστή" - για όσους μόλις μαθαίνουν τα βασικά του παγκόσμιου παιχνιδιού και επίπεδο "2ο επίπεδο με υπολογιστή" - για όσους είναι απόλυτα σίγουροι για τη νίκη τους. Στα επίπεδα 1 και 2, υπάρχουν τρία πιθανά αποτελέσματα: «νίκη», «ήττα» και «ισοπαλία». Τα κέρδη καθορίζονται εάν οι κάθετες, οριζόντιες ή διαγώνιες γραμμές είναι πλήρως γεμάτες με σταυρούς ή μηδενικά.

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

1. ΑΝΑΛΥΣΗ ΤΟΥ ΠΡΟΒΛΗΜΑΤΟΣ ΚΑΙ ΠΡΟΣΔΙΟΡΙΣΜΟΣ ΑΠΑΙΤΗΣΕΩΝ ΓΙΑ ΤΟ ΠΡΟΓΡΑΜΜΑ ΠΡΟΣ ΑΝΑΠΤΥΞΗ

διασύνδεση προγράμματος

1.1 Σκοπός του προγράμματος, χρήστες του, κύριες λειτουργίες και στόχοι που επιδιώκονται κατά την ανάπτυξη

Ο σκοπός αυτού του προγράμματος είναι, πρώτα απ 'όλα, να διασκεδάσει τους χρήστες, να φωτίσει τον χρόνο αναμονής ενός ατόμου, επειδή οποιαδήποτε εργασία απαιτεί ξεκούραση και αυτό το απλό παιχνίδι θα σας βοηθήσει να χαλαρώσετε και να απομακρύνετε το μυαλό σας από τις καθημερινές υποθέσεις. Το "Tic Tac Toe" ανήκει επίσης στην κατηγορία των πνευματικών και λογικών παιχνιδιών, τα οποία έχουν σχεδιαστεί για να εκπαιδεύουν τη λογική σκέψη, να σας επιτρέπουν να συγκεντρώνετε την προσοχή και να αναπτύσσετε τη μνήμη.

Το κοινό-στόχος των χρηστών είναι παιδιά και έφηβοι, καθώς και ενήλικες. Τα κύρια κριτήρια για τη χρήση του προϊόντος είναι η δυνατότητα ανάγνωσης κειμένου γραμμένου στο πρόγραμμα και η δυνατότητα επιλογής της απαραίτητης εργασίας για τον υπολογιστή χρησιμοποιώντας κουμπιά.

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

1.2 Ανασκόπηση γνωστών προγραμμάτων που εκτελούν παρόμοιες λειτουργίες

Στο Διαδίκτυο μπορείτε να βρείτε μεγάλο αριθμό έργων που υλοποιούν αυτό το παιχνίδι. Επί του παρόντος, υπάρχουν πολλά ανάλογα αυτού του παιχνιδιού που έχουν απομακρυνθεί από τα αρχικά πρότυπα. Ένα παράδειγμα τέτοιων προγραμμάτων είναι τα "Tic-tac-toe σε ένα ατελείωτο πεδίο" και "Tic-tac-toe 3D". Επίσης, σε πολλά παιχνίδια, οι «σταυροί» και τα «δάχτυλα των ποδιών» αντικαθίστανται με άλλα σύμβολα, όπως, για παράδειγμα, «πέτρες».

Το μάθημά μου είναι μια εφαρμογή υπολογιστή. Το παιχνίδι προορίζεται τόσο για έναν χρήστη, του οποίου ο αντίπαλος είναι η τεχνητή νοημοσύνη (ή ένας υπολογιστής), όσο και για δύο χρήστες. Παρουσιάζεται σε ένα κλασικό πεδίο 3x3.

Το πιο ενδιαφέρον και ασυνήθιστο, κατά τη γνώμη μου, ήταν το παιχνίδι "Tic Tac Toe 3D". Γι' αυτό το επέλεξα για σύγκριση.

Το 3D tic-tac-toe είναι πολύ πιο ενδιαφέρον από ό,τι στο χαρτί ή σε έναν κανονικό πίνακα. Υπάρχουν περισσότερες ευκαιρίες για νίκη και ήττα, ενώ οι ισοπαλίες είναι λιγότερο συχνές. Μπορείτε να παίξετε μόνοι - ενάντια στον υπολογιστή - ή μαζί με έναν φίλο. Και το πιο ασυνήθιστο πράγμα εδώ είναι ότι για να κερδίσετε, μπορείτε να κάνετε έναν συνδυασμό από τρεις μπάλες του χρώματός σας (μαύρες ή άσπρες) όχι μόνο σε οποιοδήποτε επίπεδο, αλλά και κατά μήκος του επιπέδου των τοίχων και ακόμη και διαγώνια σε ολόκληρο το γήπεδο ( Εικ. 1.1).

Ρύζι. 1.1

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

1.3 Θεωρητική βάση ανάπτυξης

Ανάλυση

Για κάθε ένα από τα μέρη, υπάρχουν γνωστοί αλγόριθμοι που εγγυώνται την ισοπαλία στο παιχνίδι οποιουδήποτε αντιπάλου, και αν ο αντίπαλός του κάνει λάθος, του επιτρέπουν να κερδίσει. Άρα το παιχνίδι είναι σε κατάσταση «κανένας θάνατος»<#"877528.files/image002.gif">

Εικ.1.2. Το δέντρο των καταστάσεων παιχνιδιού

Ένα μερικό δέντρο καταστάσεων παιχνιδιού φαίνεται στο Σχ. 1.2 για το παιχνίδι tic-tac-toe. Ένα δέντρο καταστάσεων παιχνιδιού για το παιχνίδι tic-tac-toe, όπου ο παίκτης για τους «σταυρούς» πηγαίνει πρώτος και ενεργεί σύμφωνα με τον παραπάνω αλγόριθμο και ο παίκτης για τα «δάχτυλα των ποδιών» μπορεί να κάνει ό,τι θέλει (και μια κορυφή είναι που δίνεται για μια λογική και για μια παράλογη ενέργεια, δηλαδή οποιαδήποτε άλλη), αποτελείται από 50 κόμβους.

1.4 Επιλογή εργαλείων ανάπτυξης

Για να πετύχουμε τους στόχους μας, χρειαζόμαστε ένα ολοκληρωμένο περιβάλλον ανάπτυξης εφαρμογών. Επομένως, η ανάπτυξη του έργου πραγματοποιήθηκε στο περιβάλλον προγραμματισμού Microsoft Visual Studio 2008.

Το Microsoft Visual Studio είναι μια σειρά προϊόντων της Microsoft , συμπεριλαμβανομένου ενός ολοκληρωμένου περιβάλλοντος ανάπτυξης λογισμικό και μια σειρά από άλλα εργαλεία. Αυτά τα προϊόντα σάς επιτρέπουν να εξελίσσεστε με βάση την κονσόλα εφαρμογές και εφαρμογές GUI , συμπεριλαμβανομένης της υποστήριξης για την τεχνολογία Windows Forms , καθώς και ιστοσελίδες , διαδικτυακές υπηρεσίες όπως σε μητρική και ελεγχόμενη κωδικούς για όλες τις πλατφόρμες που υποστηρίζονται από τα Windows ,Windows Mobile ,Windows CE , .Πλαίσιο δικτύου , Xbox , Windows Phone .NET Compact Framework και Silverlight .

2. ΣΧΕΔΙΑΣΜΟΣ ΜΕΡΟΣ ΤΗΣ ΑΝΑΠΤΥΞΗΣ

2.1 Ανάπτυξη διεπαφής χρήστη

Κατά τη δημιουργία μιας εφαρμογής παιχνιδιού, είναι απαραίτητο να λάβετε υπόψη ένα από τα κύρια στοιχεία της επιτυχίας του προϊόντος - τη διεπαφή. Η διεπαφή χρήστη του προγράμματος πρέπει πρώτα από όλα να είναι κατανοητή και ελκυστική για τον χρήστη. Πρέπει να προσπαθήσετε να αφαιρέσετε όλες τις στιγμές που θα αποσπάσουν την προσοχή του χρήστη ή θα του προκαλέσουν δυσφορία. Ολόκληρη η διεπαφή προγράμματος μπορεί να χωριστεί σε δύο στοιχεία.

) Κύριο μενού του προγράμματος

Ρύζι. 2.1 - Κύριο μενού του προγράμματος

Το κύριο μενού έχει σχεδιαστεί για να επιτρέπει στον χρήστη να ενταχθεί στην ατμόσφαιρα του παιχνιδιού, επομένως η διεπαφή έχει σχεδιαστεί σε πολύχρωμα, παιχνιδιάρικα χρώματα. Μέσω του μενού μπορείτε να μεταβείτε στον αγωνιστικό χώρο, να δείτε τους κανόνες του παιχνιδιού ή να βγείτε από το παιχνίδι.

) Αγωνιστικό χώρο

Εικ. 2.2 - Παιχνίδι

Ο αγωνιστικός χώρος περιέχει την άμεση περιοχή για παιχνίδι, όπου ο παίκτης και ο υπολογιστής τοποθετούν τα εικονίδια τους. Πριν ξεκινήσει το παιχνίδι, ο χρήστης πρέπει να επιλέξει τον τύπο παιχνιδιού όπως "X vs 0", "1 επίπεδο με υπολογιστή" ή "2 επίπεδο με υπολογιστή", διαφορετικά το πρόγραμμα θα δώσει ένα μήνυμα σχετικά με το τι πρέπει να κάνει. Ένα κουμπί που θα βοηθήσει τον παίκτη να επιστρέψει στο κύριο μενού. Στο τέλος, θα εμφανιστούν επιπλέον παράθυρα για να ενημερώσουν τον συμμετέχοντα για τα αποτελέσματα του αγώνα.

Ρύζι. 2.3 - πρόσθετα παράθυρα αποτελεσμάτων παιχνιδιού

2.2 Ανάπτυξη δομών δεδομένων (σε εξωτερικό και RAM)

Η μνήμη RAM χρησιμοποιείται για έναν μονοδιάστατο πίνακα που αποτελείται από 9 στοιχεία που αποθηκεύει τις καταστάσεις του αγωνιστικού χώρου, όπου κάθε κελί του πίνακα αντιστοιχεί σε ένα κελί στον αγωνιστικό χώρο. Η μνήμη δαπανάται επίσης σε στατικές μεταβλητές: αριθμός επιπέδου, σειρά στροφής.

Απαιτεί 803 KB ελεύθερης μνήμης για να λειτουργήσει.

.3 Ανάπτυξη και ανάλυση αλγορίθμων

Για να εφαρμόσετε τον αλγόριθμο σκέψης του παιχνιδιού, πρέπει να ορίσετε έναν στατικό πίνακα gcnew (9); στο οποίο θα αποθηκευτούν οι καταστάσεις του αγωνιστικού χώρου, όπου κάθε κελί του πίνακα αντιστοιχεί σε ένα κελί. "0" - αντιστοιχεί σε ένα κενό κελί, εάν ένας παίκτης μετακινηθεί στο κελί, δηλαδή "X", η τιμή "1" καταγράφεται και εάν ο υπολογιστής έκανε μια κίνηση, δηλαδή "O", η τιμή είναι «2». Αρχικά, όλα τα στοιχεία του πίνακα είναι ίσα με "0". Είναι απαραίτητο να ρυθμίσετε τη στατική μεταβλητή lvl, η οποία αποθηκεύει δεδομένα επιπέδου. Υπάρχουν συνολικά 3 επίπεδα σε αυτό το παιχνίδι: το lvl παίρνει την τιμή "1" εάν ο χρήστης έχει επιλέξει τον τύπο παιχνιδιού "X vs O", την τιμή "2" εάν "1ο επίπεδο με υπολογιστή" και την τιμή "3 "αν "2ο επίπεδο με υπολογιστή" " Η μεταβλητή του προγράμματος αναπαραγωγής αποθηκεύει τη σειρά στροφών («true» είναι η σειρά του παίκτη, «false» είναι η σειρά του υπολογιστή). Εφόσον το δικαίωμα να κάνει την πρώτη κίνηση δίνεται στον χρήστη, στην αρχή του παιχνιδιού παίκτης = true. Η στατική μεταβλητή σημαίας αποθηκεύει πληροφορίες σχετικά με το εάν υπάρχουν κενά κελιά στον αγωνιστικό χώρο ή όχι: εάν flag = true - δηλαδή false - δεν υπάρχουν κενά κελιά. Ο αλγόριθμος επαλήθευσης πρέπει να περιέχει μια επανάληψη των παραμέτρων του πίνακα x και να προτείνει τη δική του λύση, η οποία θα είναι η βέλτιστη για περαιτέρω αναπαραγωγή. Αυτό το πρόγραμμα διαθέτει 2 επίπεδα παιχνιδιού με υπολογιστή. Στο επίπεδο 1, η αποστολή του υπολογιστή δεν είναι να νικήσει τον αντίπαλο. Να γιατί αυτή τη λειτουργίαεπιστρέφει μια τυχαία τιμή του κελιού όπου θα πάει ο υπολογιστής. Ο κώδικας για αυτόν τον αλγόριθμο παρουσιάζεται στο [Παράρτημα 1]. Το σχήμα 2.4 δείχνει το μπλοκ διάγραμμα της υλοποίησης του κώδικα.

Η πιο κερδοφόρα κίνηση στην αρχή του παιχνιδιού είναι να μετακινηθείτε στο κέντρο του γηπέδου. Στη συνάρτηση dif_level(), ελέγχεται μια συνθήκη στην αρχή: αν ο παίκτης δεν πήγε στο κεντρικό πεδίο, τότε ο υπολογιστής πηγαίνει εκεί. Διαφορετικά, εάν ο παίκτης πήγε στο κέντρο, τότε καλείται η συνάρτηση check(2) για να ελέγξει τον συνδυασμό του υπολογιστή και, εάν υπάρχει ευκαιρία να κερδίσει, τότε επιστρέψτε τον αριθμό του κελιού. Εάν ο υπολογιστής δεν μπορεί να κερδίσει στην επόμενη κίνηση, τότε καλείται η συνάρτηση check(1): έλεγχος του συνδυασμού του παίκτη. Επιστρέφεται ο αριθμός του κελιού στο οποίο ο παίκτης θα κέρδιζε αν ποντάρει. Εάν δεν υπάρχει τέτοιος συνδυασμός, τότε καλείται η συνάρτηση low_level().

Εικ.2.4. - Μπλοκ διάγραμμα

Εικ.2.5. - Μπλοκ διάγραμμα

3. ΥΛΟΠΟΙΗΣΗ ΤΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ ΣΕ ΓΛΩΣΣΑ C++

.1 Αρχιτεκτονική προγράμματος

Αυτό το πρόγραμμα υλοποιεί 3 φόρμες: το κύριο μενού (Εικ. 2.1.), τον αγωνιστικό χώρο (Εικ. 2.2) και το πεδίο βοήθειας (κανόνες παιχνιδιού). 12 πάνελ, 9 από τα οποία είναι κύρια. Επίσης, στο τέλος του παιχνιδιού εμφανίζεται ένα pictureBox με το αποτέλεσμα, είναι 5 συνολικά (Εικόνα 2.3).

Μπορείτε να χρησιμοποιήσετε τους χειριστές κλικ πάνελ ως βάση, από τους οποίους υπάρχουν ακριβώς 9 στον αγωνιστικό χώρο. Κάθε χειριστής καλεί πολλές λειτουργίες. Στην αρχή υπάρχει μια προϋπόθεση, εάν ο χρήστης επιλέξει τον τύπο παιχνιδιού "X έναντι 0", τα κελιά απλά γεμίζουν με τις τιμές 1 ή 2 (σταυρός ή μηδέν). Ακολουθούν οι συναρτήσεις: ένδειξη προόδου (CrossZero()), που αλλάζει το σταυρό στο μηδέν και αντίστροφα, μπλοκάρει τα κατειλημμένα κελιά checkingArray(), βρίσκοντας τον νικητή (νικητή). Η συνάρτηση winner() εξετάζει όλες τις πιθανές επιλογές νίκης, οπότε αν ένας από τους παίκτες παρατάξει 3 από τα κομμάτια του (ένα σταυρό ή ένα μηδέν) κάθετα, οριζόντια ή διαγώνια, θα κερδίσει. Διαφορετικά, εάν το γήπεδο είναι γεμάτο, αλλά κανένας από τους παίκτες δεν έχει παραταχθεί, τότε καλείται η συνάρτηση ελέγχου ισοπαλίας (_friend()), η οποία ελέγχει αν έχουν απομείνει ελεύθερα κελιά στο γήπεδο ή όχι. Εάν fr = true, τότε δεν υπάρχουν ελεύθερα κελιά στο πεδίο. Εάν η τιμή έχει αλλάξει, σημαίνει ότι υπάρχει ένα ελεύθερο κελί στο πεδίο.

Η δεύτερη συνθήκη λειτουργεί εάν έχει επιλεγεί ο δεύτερος ή ο τρίτος τύπος παιχνιδιού. Τότε η συνάρτηση στην οποία έγινε η κίνηση του υπολογιστή ονομάζεται: move(int n). Μεταδίδει τον αριθμό του κελιού στο οποίο έκανε κλικ η συσκευή αναπαραγωγής. Ακολουθούν οι συναρτήσεις: ένδειξη προόδου (CrossZero()), αποκλεισμός κατειλημμένων κελιών checkingArray(). Τότε καλείται η συνάρτηση winner(), η οποία ελέγχει αν ο παίκτης κέρδισε με αυτή την κίνηση ή όχι. Εάν όχι, τότε ελέγχεται η παρουσία ελεύθερων κυττάρων. Εάν υπάρχουν ελεύθερα κελιά, τότε ο υπολογιστής μετακινείται. Στη συνέχεια, ανάλογα με το επίπεδο που έχει επιλέξει ο παίκτης «1» ή «2», καλούνται οι ακόλουθες συναρτήσεις: low_level(), dif_level(). Η συνάρτηση low_level() επιλέγει πού θα τοποθετήσει το μηδέν τυχαία και η συνάρτηση dif_level() παρουσιάζει έναν ειδικό αλγόριθμο για να κερδίσει ο υπολογιστής. Ακολουθούν οι συναρτήσεις: ένδειξη προόδου (CrossZero()), αποκλεισμός κατειλημμένων κελιών checkingArray(). Στη συνέχεια καλείται η συνάρτηση winner(), η οποία ελέγχει αν ο υπολογιστής κέρδισε με αυτή την κίνηση ή όχι. Εάν όχι, τότε ελέγχεται η παρουσία ελεύθερων κυττάρων. Εάν υπάρχουν ελεύθερα κελιά, τότε ο παίκτης μετακινείται.

.2 Επιλογή τυπικών οπτικών και μη οπτικών στοιχείων

Για την υλοποίηση αυτής της εργασίας επιλέχθηκαν τα ακόλουθα στοιχεία:

1) Έντυπο1, με δεδομένων παραμέτρων Text=Tic-Tac-Toe, ControlBox=False

2) f2, με τις καθορισμένες παραμέτρους BackColor, Text=Game

) comboBox1 με τις καθορισμένες παραμέτρους Items:

X εναντίον 0

1ο επίπεδο με υπολογιστή

Επίπεδο 2 με υπολογιστή

4) πίνακας, με καθορισμένες παραμέτρους BackColor και διαφορετικές τιμές για τις παραμέτρους Visible και Enabled. Για ορισμένα πλαίσια, γράφτηκαν συμβάντα όπως το κλικ.

5) κουμπί, με τις καθορισμένες παραμέτρους Font, Fore Color, BackColor, Text, για όλα τα κουμπιά γράφτηκαν συμβάντα όπως Κλικ.

6) ετικέτα, με τις καθορισμένες παραμέτρους BackColor, Font, Fore Color, Text.

) pictureBox, με καθορισμένες παραμέτρους Image, SizeMode= StretchImage.

) textBox, με τις καθορισμένες παραμέτρους BackColor, Font, Fore Color, Text=” ”.

4. ΑΠΟΤΕΛΕΣΜΑΤΑ ΔΟΚΙΜΗΣ

Ας δοκιμάσουμε το πρόγραμμα περνώντας από 3 τύπους παιχνιδιών.

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

Εικ.4.1.

Ας επιλέξουμε 1 τύπο παιχνιδιού - "Χ έναντι 0", π.χ. χρήστης εναντίον χρήστη. Σε αυτό το στάδιο του παιχνιδιού, ο χρήστης μπορεί να παίξει και με τον εαυτό του. (Εικ.4.2)

Εικ.4.2.

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

Εικ.4.3.

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

Εικ.4.4.

Το πρόγραμμα εκτελείται με επιτυχία σε όλες τις δοκιμαστικές παραλλαγές, χωρίς σφάλματα.

ΣΥΜΠΕΡΑΣΜΑ

Μπορούμε να πούμε με σιγουριά ότι η εργασία που τέθηκε στην αρχή της εργασίας έχει ολοκληρωθεί. Κατά τη διάρκεια της ανάπτυξης, σχεδιάστηκε και αναπτύχθηκε ένα έργο για ένα remix του διάσημου παιχνιδιού "Tic Tac Toe". Το παιχνίδι πληροί τις καθορισμένες απαιτήσεις και εκπληρώνει τις λειτουργίες του. Εφαρμόστηκε στην εργασία Διάφοροι τύποιπαιχνίδια και επίπεδα δυσκολίας.

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

Παρά τη φαινομενική απλότητα αυτού του προγράμματος, είναι γεμάτο με μια σειρά από δυσκολίες που υλοποιούνται χρησιμοποιώντας όλες τις βασικές τεχνικές της Visual C++.

Τα χαρακτηριστικά αυτού του προγράμματος είναι:

Σαφώς κατασκευασμένος αλγόριθμος.

Διαισθητική διεπαφή.

Εύχρηστος;

Πολύ σαφές εγχειρίδιο χρήσης.

Χωρίς περιττά πρόσθετα.

ΒΙΒΛΙΟΓΡΑΦΙΑ

1. http://www.pravilaigr.ru/xo.php

2. http://2igroka.com/stuff/sportivnye/krestiki_noliki_3d/15-1-0-14

3. https://www.draw.io/

Http://pol-video.ru/QPW9QHEO2GU/uroki_s_krestiki-noliki_ch1.html

ΠΑΡΑΡΤΗΜΑ 1

private: int low_level())(// διαδικασία για έναν ελαφρύ αντίπαλο;::Random^ rand = gcnew System::Random();(= rand->Next(0,8);

) while (x[r] != 0);r;

ΠΑΡΑΡΤΗΜΑ 2

private: bool check(int n)(k = -1;// ελέγχει όλους τους συνδυασμούς και επιστρέφει τη σωστή κίνηση(x == n) (((x == n)&&(x == 0)) k =2; ((x == n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =6;((x == n)&&(x == 0)) k =3;((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =7;((x == = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =4;((x == n)&&(x == 0)) k =6;((x == = n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =5;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =5;((x = = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =3;((x == = n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =7;

)(x == n) (((x == n)&&(x == 0)) k =6;

)(k!=-1) επιστροφή true;άλλο επιστροφή false;

ΠΑΡΑΡΤΗΜΑ 3

ιδιωτικό: int dif_level())(//δύσκολος εχθρός

//επιστροφή επιταγή(2);(x == 0) return (4);(check(2)) return k; else (check(1)) επιστροφή k; else low_level();

ΕΦΑΡΜΟΓΗ 4

private: void CrossZero())(// αλλάζει το σταυρό σε μηδέν (δείκτης προόδου)(player) (->Visible = true;->Visible = false;

) else (-> Visible = true;-> Visible = false;

): void checkingArray())(// συνάρτηση ελέγχου εάν υπάρχει κάτι σε ένα κελί, εάν υπάρχει, τότε δεν μπορείτε πλέον να κάνετε κλικ σε αυτό το κελί.(x == 1) (panel1->BackgroundImage = panel11->BackgroundImage ;panel1- >Enabled = false;)(x == 2) (panel1->BackgroundImage = panel10->BackgroundImage;panel1->Enabled = false;)(x == 1) (panel2->BackgroundImage = panel11->BackgroundImage ;panel2- >Enabled = false;)(x == 2) (panel2->BackgroundImage = panel10->BackgroundImage;panel2->Enabled = false;)(x == 1) (panel3->BackgroundImage = panel11->BackgroundImage ;panel3- >Enabled = false;)(x == 2) (panel3->BackgroundImage = panel10->BackgroundImage;panel3->Enabled = false;)(x == 1) (panel4->BackgroundImage = panel11->BackgroundImage ;panel4- >Enabled = false;)(x == 2) (panel4->BackgroundImage = panel10->BackgroundImage;panel4->Enabled = false;)(x == 1) (panel5->BackgroundImage = panel11->BackgroundImage ;panel5- >Enabled = false;)(x == 2) (panel5->BackgroundImage = panel10->BackgroundImage;panel5->Enabled = false;)(x == 1) (panel6->BackgroundImage = panel11->BackgroundImage ;panel6- >Enabled = false;)(x == 2) (panel6->BackgroundImage = panel10->BackgroundImage;panel6->Enabled = false;)(x == 1) (panel7->BackgroundImage = panel11->BackgroundImage ;panel7- >Enabled = false;)(x == 2) (panel7->BackgroundImage = panel10->BackgroundImage;panel7->Enabled = false;)(x == 1) (panel8->BackgroundImage = panel11->BackgroundImage ;panel8- >Enabled = false;)(x == 2) (panel8->BackgroundImage = panel10->BackgroundImage;panel8->Enabled = false;)(x == 1) (panel9->BackgroundImage = panel11->BackgroundImage ;panel9- >Enabled = false;)(x == 2) (panel9->BackgroundImage = panel10->BackgroundImage;panel9->Enabled = false;)

): bool winner())(// έλεγχος του νικητή και αποκλεισμός όλων των υπόλοιπων κελιών.

//σημαία bool = false;(((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x = = 2)) ||| ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2 )) ||| ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)))( (lvl==1) ( picturePo->Ορατό = true;)(picturePr->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;true;

)(((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || (( x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x = = x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)))((lvl==1) ( picturePx->Ορατό = true;)(picturePobeda->Ορατό = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;true;

): void _friend())(fr = true;(int i = 0; i< 9; i++) if (x[i] == 0) {fr = false; break;}(fr) { pictureN->Ορατό = αληθινό;)

): void move(int n)(// computer move function= false;[n] = 1;= !player;();();(winner()) () ((int i = 0; i< 9; i++) if (x[i] == 0) flag = true;(flag){(lvl == 2) = 2; = 2;= !player;();();();

): Σύστημα::Κενό κουμπί1_Κάντε κλικ(Σύστημα::Αντικείμενο^ αποστολέας, Σύστημα::EventArgs^ ε) (// νέο παιχνίδι>Ορατό = ψευδές;>Ορατό = ψευδές;>Ορατό = ψευδές; >Ορατό = ψευδές; >Ορατό = false; = comboBox1->Text;(typeGame == "")(::Show("Επιλέξτε πρώτα τον τύπο του παιχνιδιού σας!");

) else ((typeGame == "X έναντι 0") lvl = 1;(typeGame == "1ο επίπεδο με υπολογιστή") lvl = 2;(typeGame == "2ο επίπεδο με υπολογιστή") lvl = 3;( ); = αληθές; (int i = 0; i< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage =panelImaggroundI->BackgroundImage =panelImageground->BackgroundImage = panelImage->BackgroundImage = panel12->BackgroundImage BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->Enabled = true;->Enabled = true;->Enabled = true;->EnabledEnable> true; = true;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;

): System::Void panel1_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 0;(lvl == 1)((player)( = 1;

)= !player;();();();

): System::Void panel2_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 1;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel3_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 2;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel4_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 3;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel5_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 4;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel6_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 5;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel7_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 6;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel8_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 7;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel9_MouseClick(System::Object^ αποστολέας, System::Windows::Forms::MouseEventArgs^ e) (n = 8;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): Σύστημα::Κενό κουμπί2_Κάντε κλικ(Σύστημα::Αντικείμενο^ αποστολέας, Σύστημα::EventArgs^ e) (();

): System::Void picturePx_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void picturePo_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void picturePobeda_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void picturePr_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void pictureN_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

Προσοχή! Αυτή είναι μια εισαγωγική έκδοση του μαθήματος, τα υλικά του οποίου μπορεί να είναι ελλιπή.

Συνδεθείτε στον ιστότοπο ως φοιτητής

Συνδεθείτε ως μαθητής για πρόσβαση στο σχολικό υλικό

Δημιουργία διαμορφώσεων 1C: γράφοντας «Tic Tac Toe» μέρος 1/3

Θα μάθουμε μέσα από το παιχνίδι, και ως εκ τούτου το πρώτο μας έργο θα είναι να δημιουργήσουμε για όλους
ένα παιχνίδι γνωστό από την παιδική ηλικία - "Tic Tac Toe".

Ίσως ρωτήσετε, τι σχέση έχουν τα παιχνίδια με το 1C, τη λογιστική και τις συναλλαγές; Σχεδόν κανένας. Πρέπει όμως να ξεκινήσουμε σταδιακά και με τον καιρό θα φτάσουμε στον αυτοματισμό των αποθηκών. Προς το παρόν, ας ξεκινήσουμε από μικρά.

Πριν ξεκινήσουμε τον προγραμματισμό του παιχνιδιού Tic-Tac-Toe, ας το σκεφτούμε.

Γνωρίζουμε ήδη ότι η φόρμα έχει Στοιχεία, ένα από τα οποία είναι το Κουμπί. Τα κουμπιά είναι ικανά να εκτελούν εντολές και, ταυτόχρονα, έχουν ιδιότητες που σας επιτρέπουν να ελέγχετε την εμφάνισή τους στη φόρμα (για παράδειγμα, έναν τίτλο).

Για παράδειγμα, μπορείτε να χρησιμοποιήσετε ένα κουμπί για να δημιουργήσετε ένα πεδίο με εννέα ενεργές περιοχές (τα κελιά στα οποία κάνουμε κλικ και καταγράφουμε την ενέργεια, ενώ ταυτόχρονα εμφανίζουμε επιγραφές με τη μορφή "O" και "X"). Το κουμπί είναι κάτι παραπάνω από κατάλληλο για αυτό.

Τι χρειαζόμαστε? Προφανώς, θα χρειαστεί να θυμόμαστε την κίνησή μας και να θυμόμαστε την κίνηση του υπολογιστή. Θα χρειαστεί επίσης να αλλάξουμε τους τίτλους των κουμπιών: όταν κάνουμε κλικ, ο τίτλος του κουμπιού είναι πάντα "O", όταν ο υπολογιστής κινείται, είναι "X".

Αρχικά, θα χρειαστεί να δημιουργήσουμε μια νέα βάση δεδομένων στην οποία θα δημιουργήσουμε το παιχνίδι μας. Ας το κάνουμε.

Βήμα #1: δημιουργία κενού βάσης δεδομένων

Ας δημιουργήσουμε μια κενή βάση δεδομένων Tic-Tac-Toe.

Αναλυτικές οδηγίες

Ας ξεκινήσουμεΣυντόμευση 1C για το άνοιγμα μιας λίστας βάσεων πληροφοριών που είναι διαθέσιμες στον υπολογιστή. Διαβάζετε μια δοκιμαστική έκδοση του μαθήματος, είναι διαθέσιμα πλήρη μαθήματα. Χρειαζόμαστε δημιουργία νέα βάση, οπότε πατήστε το κουμπί " Προσθήκη":

Θα ανοίξει το παράθυρο προσθήκης βάση πληροφοριών, στο οποίο πρέπει να επιλέξετε το πρώτο στοιχείο " Δημιουργία βάσης πληροφοριών" και κάντε κλικ στο κουμπί "Επόμενο":

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

Στο επόμενο παράθυρο μας ζητείται να εισάγουμε το όνομα της νέας βάσης δεδομένων, κάτω από το οποίο θα εμφανίζεται στη λίστα των βάσεων δεδομένων. Ας μπούμε" Τρίλιζα" και κάντε κλικ στο κουμπί "Επόμενο":

Στο επόμενο παράθυρο πρέπει να καθορίσετε τη διαδρομή προς τον κενό φάκελο στον οποίο θα αποθηκευτεί η βάση δεδομένων μας. Σε αυτήν την περίπτωση, δημιούργησα το φάκελο " Τρίλιζα" στο φάκελο "1C Databases" στη μονάδα δίσκου D:

Στο επόμενο παράθυρο, αφήστε όλες τις ρυθμίσεις ως προεπιλεγμένες και κάντε κλικ στο " Ετοιμος":

Μετά από μια μικρή παύση, η βάση δεδομένων δημιουργήθηκε και προστέθηκε στη λίστα. Υπάρχουν δύο κύριοι τρόποι εργασίας με τη βάση δεδομένων: 1C: ΕπιχείρησηΚαι Διαμορφωτής:

Στη λειτουργία διαμόρφωσης διαμορφώνουμε και προγραμματίζουμε τη βάση δεδομένων, στη λειτουργία 1C: Enterprise βλέπουμε τι προκύπτει από αυτό.

Βήμα #2: ανοίξτε το διαμορφωτή

Ας πατήσουμε το κουμπί " Διαμορφωτής" για να μπείτε στη λειτουργία διαμόρφωσης:

Βήμα #3: ανοίξτε το δέντρο διαμόρφωσης

Εκτελέστε την εντολή μενού " Διαμόρφωση"->"Ανοίξτε τη διαμόρφωση":

Ένα δέντρο διαμόρφωσης άνοιξε μπροστά μας, το οποίο περιέχει διάφορες ενότητες διαμόρφωσης. Επειδή δεν έχουμε δημιουργήσει τίποτα ακόμα, αυτές οι ενότητες είναι κενές:

Βήμα #4: προσθήκη επεξεργασίας

Για να τοποθετήσουμε τη λογική του παιχνιδιού μας, θα χρησιμοποιήσουμε την ενότητα «Επεξεργασία». Ας κάνουμε κλικ κάντε δεξί κλικστην ενότητα " Θεραπείες" και επιλέξτε την εντολή "Προσθήκη":

Ένα παράθυρο για τη δημιουργία μιας νέας επεξεργασίας έχει ανοίξει μπροστά μας. Ας βάλουμε το όνομα" Τρίλιζα". Το συνώνυμο θα εισαχθεί από μόνο του. Αυτό είναι αρκετό για να αποθηκεύσουμε την επεξεργασία μας (ακόμα κενή) στη βάση δεδομένων. Κάντε κλικ στο κουμπί "Κλείσιμο":

Βήμα Νο. 5: πρώτος εντοπισμός σφαλμάτων του προγράμματος

Μπορείτε να ελέγξετε τι συνέβη από τη λειτουργία χρήστη ( 1C: Επιχείρηση). Για να μπείτε σε αυτό απευθείας από τον διαμορφωτή, εκτελέστε την εντολή μενού " Εντοπισμός σφαλμάτων"->"Ξεκινήστε τον εντοπισμό σφαλμάτων":

Δεδομένου ότι έχουμε κάνει μια αλλαγή στη βάση δεδομένων, μας ζητείται αν συμφωνούμε να αποδεχθούμε αυτήν την αλλαγή. Αυτή η ερώτηση θα μας τίθεται συνεχώς κατά τη διαδικασία ανάπτυξης. Συμφωνούμε (κουμπί " Ναί"):

Η βάση δεδομένων ξεκίνησε σε λειτουργία "1C:Enterprise". Διαβάζετε μια δοκιμαστική έκδοση του μαθήματος, είναι διαθέσιμα πλήρη μαθήματα. Αλλά όπως βλέπουμε, η εργασία με αυτό είναι ακόμα δύσκολη - απλά δεν υπάρχει τίποτα να διαλέξετε. Είναι περίεργο, γιατί έχουμε ήδη δημιουργήσει την επεξεργασία και, θεωρητικά, θα πρέπει να εμφανίζεται στον κίτρινο πίνακα.




Μπλουζα