Δημιουργία ενός παιχνιδιού τικ-τακ. στάδιο: ελέγξτε αν ο παίκτης κέρδισε

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

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

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

Δημιουργία διαμορφώσεων 1C: εγγραφή "Tic-tac-toe" μέρος 1/3

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

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

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

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

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

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

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

Βήμα #1: Δημιουργήστε μια κενή βάση

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Βήμα #5: Πρώτα διόρθωση σφαλμάτων του προγράμματος

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

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

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

Πώς να γράψετε ένα ρομπότ που δεν μπορεί να νικηθεί στο 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" αντίστοιχα.

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

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

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

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

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

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

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

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

Εάν το 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. Για την ομάδα New Game, γράψτε
κώδικα προγράμματος στο μέλλον μέσω
μερικά βήματα.

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

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

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 \ Tic Tac Toe
Το 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
το παιχνίδι θα μηδενιστεί
όλα τα κελιά του πίνακα, αντικαθιστώντας όλα
"σταυροί" και "noughts" επάνω
άδεια κελιά. Επίσης έξοδος
γράμματα "Η κίνησή σου"

ΒΗΜΑ 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 ΒΕΛΤΙΩΣΗ "ΠΑΙΞΙΜΟΤΗΤΑΣ"

Για τη βελτίωση της δυνατότητας αναπαραγωγής
αντί για σειριακή έξοδο
στο πρώτο άδειο
κελιά των «μηδενικών», υλοποιούμε
έξοδος μέσω τυχαίας γεννήτριας
αριθμοί.
Για αυτό πρέπει να προσθέσετε
μία μεταβλητή boolean
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 είναι ένα πρόγραμμα που έχει σχεδιαστεί για να ψυχαγωγεί τον χρήστη, επομένως η διεπαφή του, σε αυτήν την εργασία μαθήματος, είναι φτιαγμένη σε στυλ παιχνιδιού με συνδυασμό θετικών χρωμάτων που επιδεινώνουν το συναισθηματικό μέρος του παιχνιδιού.

Υπάρχουν τρεις τύποι στο παιχνίδι: Χ έναντι 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". Γι' αυτό το επέλεξα για σύγκριση.

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

Ρύζι. 1.1

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

1.3 Θεωρητικά θεμέλια ανάπτυξης

Ανάλυση

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

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

Ένα μερικό δέντρο καταστάσεων παιχνιδιού φαίνεται στο Σχ. 1.2 για το παιχνίδι τικ-τακ. Το δέντρο των καταστάσεων παιχνιδιού για το παιχνίδι τικ-τάκ, όπου ο παίκτης για «τικ-τακ-τόι» πηγαίνει πρώτος και ενεργεί σύμφωνα με τον παραπάνω αλγόριθμο και ο παίκτης για «τακ-τάκ» μπορεί να κάνει ό,τι θέλει (επιπλέον, μια κορυφή δίνεται για μια ορθολογική και για μια παράλογη πράξη, δηλαδή οποιαδήποτε άλλη), αποτελείται από 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 - Παιχνίδι

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

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

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

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

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

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

Για να εφαρμόσετε τον αλγόριθμο σκέψης παιχνιδιού, πρέπει να καθορίσετε τον στατικό πίνακα gcnew array (9); στο οποίο θα αποθηκευτούν οι καταστάσεις του αγωνιστικού χώρου, όπου κάθε κελί του πίνακα αντιστοιχεί σε ένα κελί. "0" - αντιστοιχεί σε ένα κενό κελί, εάν ο παίκτης πήγε στο κελί, δηλαδή "Χ", η τιμή "1" καταγράφεται και εάν ο υπολογιστής έκανε την κίνηση, δηλαδή "O", η τιμή είναι "2". Αρχικά, όλα τα στοιχεία του πίνακα είναι ίσα με "0". Πρέπει να ορίσετε τη στατική μεταβλητή lvl, η οποία αποθηκεύει τα δεδομένα επιπέδου. Υπάρχουν συνολικά 3 επίπεδα σε αυτό το παιχνίδι: το lvl παίρνει την τιμή "1" εάν ο χρήστης έχει επιλέξει τον τύπο παιχνιδιού "X vs. O", την τιμή "2" εάν "1 επίπεδο με τον υπολογιστή" και την τιμή " 3" εάν "2 επίπεδα με τον υπολογιστή ". Το μεταβλητό πρόγραμμα αναπαραγωγής - αποθηκεύει τη σειρά της κίνησης ("true" - κίνηση του παίκτη, "false" - κίνηση του υπολογιστή). Εφόσον το δικαίωμα της πρώτης κίνησης παραχωρείται στον χρήστη, στην αρχή του παιχνιδιού παίκτης = true. Η στατική μεταβλητή flag αποθηκεύει πληροφορίες σχετικά με το εάν υπάρχουν κενά κελιά στον αγωνιστικό χώρο ή όχι: εάν 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 στον αγωνιστικό χώρο. Κάθε χειριστής καλεί πολλαπλές συναρτήσεις. Στην αρχή υπάρχει μια προϋπόθεση, εάν ο χρήστης επιλέξει τον τύπο παιχνιδιού "Χ έναντι 0", απλώς τα κελιά γεμίζουν με τις τιμές 1 ή 2 (σταυρός ή μηδέν). Στη συνέχεια ακολουθούν οι συναρτήσεις: ένδειξη της κίνησης (CrossZero()), που αλλάζει το σταυρό σε μηδέν και αντίστροφα, μπλοκάρει τα κατειλημμένα κελιά με checkingArray(), βρίσκοντας τον winner winner(). Στη συνάρτηση 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) Form1, με τις παραμέτρους που δίνονται Text=Tic-Tac-Toe, ControlBox=False

2) f2, με σετ BackColor, Text=Game

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

X έναντι 0

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

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

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

5) κουμπί, με τις καθορισμένες παραμέτρους Γραμματοσειρά, Μπροστινό Χρώμα, Πίσω Χρώμα, Κείμενο, για όλα τα κουμπιά γράφτηκαν συμβάντα όπως Κλικ.

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

) pictureBox, με καθορισμένες παραμέτρους εικόνας, 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

ιδιωτικό: 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) επιστροφή αληθής· αλλιώς επιστροφή ψευδής·

ΠΑΡΑΡΤΗΜΑ 3

ιδιωτικό: int dif_level()(//δύσκολος αντίπαλος

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

ΠΑΡΑΡΤΗΜΑ 4

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

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

): void checkingArray()(// συνάρτηση για να ελέγξετε αν υπάρχει κάτι στο κελί, εάν υπάρχει, τότε δεν μπορείτε πλέον να κάνετε κλικ σε αυτό το κελί. >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->B ackgroundImage = 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 vs 0") lvl = 1;(typeGame == "Επίπεδο υπολογιστή 1") lvl = 2;(typeGame == "Επίπεδο υπολογιστή 2") lvl = 3;(); = true ;(int i = 0; i< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage =panelImageground->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;();();();

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

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

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

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

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

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

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

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

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

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

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

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

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

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

) αλλιώς αν ((lvl == 2)||(lvl == 3))((n);

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

): Σύστημα::Κενή εικόναPx_Click(System::Object^ αποστολέας, System::EventArgs^ e) (>Ορατό = 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;

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

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

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

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

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

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

Λογικές

Δεν βρήκα πολύπλοκους (καθολικούς) αλγόριθμους για τον αγωνιστικό χώρο 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)); εάν (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) και ούτω καθεξής - σε γενικές γραμμές, εδώ εξαρτάται από εσάς.

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

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

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

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

Συνεχίζοντας το θέμα:
Διαδίκτυο

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