Programmation d'un jeu Tic Tac Toe

La programmation de jeux informatiques peut être le travail le plus difficile techniquement (et peut-être le mieux rémunéré) qu'un programmeur puisse avoir. Les jeux de haut niveau nécessitent le meilleur des programmeurs et des ordinateurs.

Visual Basic 6 a maintenant été complètement ignoré en tant que plate-forme de programmation de jeux. (Il n'en a jamais vraiment été un. Même dans les «bons vieux jours», les programmeurs de jeux sérieux n'utilisaient jamais un langage de haut niveau comme VB 6 car vous ne pouviez tout simplement pas obtenir les performances de pointe requises par la plupart des jeux.) Mais le le simple jeu "Tic Tac Toe" est une excellente introduction à la programmation qui est un peu plus avancée que "Hello World!"

Il s'agit d'une excellente introduction à de nombreux concepts fondamentaux de la programmation, car elle combine des techniques, notamment:

  • L'utilisation de tableaux. Les marqueurs X et O sont conservés dans des tableaux séparés et les tableaux entiers sont passés entre les fonctions pour suivre la progression du jeu.
  • Utilisation de graphiques de niveau VB 6: VB 6 n'offre pas de grandes capacités graphiques, mais le jeu est une bonne introduction à ce qui est disponible. Une grande partie du reste de cette série est une exploration de la façon dont GDI +, la prochaine génération de graphiques Microsoft, remplace les graphiques de niveau VB 6.
  • Utilisation de calculs mathématiques pour le contrôle du programme: le programme utilise des calculs intelligents de modulo (Mod) et de division d'entiers en utilisant les tableaux de marqueurs à deux jeux pour déterminer quand une "victoire" à trois éléments s'est produite.

La classe de programmation dans cet article est peut-être juste un peu au-delà du niveau de début mais elle devrait être bonne pour les programmeurs "intermédiaires". Mais commençons à un niveau élémentaire pour illustrer certains des concepts et vous lancer dans votre carrière de programmeur de jeux Visual Basic. Même les élèves plus avancés que cela peuvent trouver qu'il est un peu difficile d'obtenir les objets sous la forme juste.

Comment jouer au Tic Tac Toe

Si vous n'avez jamais joué au Tic Tac Toe, voici les règles. Deux joueurs alternent pour placer les X et les O sur un terrain de jeu de 3 x 3.

Avant le début du jeu, les deux joueurs doivent se mettre d'accord sur qui ira en premier et qui marquera ses mouvements avec quel symbole. Après le premier coup, les joueurs placent alternativement leurs marques dans n'importe quelle cellule vide. Le but du jeu est d'être le premier joueur avec trois marques sur une ligne horizontale, diagonale ou verticale. S'il n'y a pas de cellules vides et qu'aucun des joueurs n'a de combinaison gagnante, le jeu est un match nul.

Démarrage du programme

Avant de commencer un codage réel, il est toujours judicieux de modifier les noms des composants que vous utilisez. Une fois que vous commencez à coder, le nom sera utilisé automatiquement par Visual Basic, vous voulez donc que ce soit le bon nom. Nous utiliserons le nom du formulaire frmTicTacToe et nous changerons également la légende en "À propos de Tic Tac Toe".

Une fois le formulaire établi, utilisez le contrôle de boîte à outils ligne pour dessiner une grille 3 x 3. Cliquez sur l'outil Ligne, puis tracez une ligne à l'endroit souhaité. Vous devrez créer quatre lignes de cette façon et ajuster leur longueur et leur position pour qu'elles aient l'air bien. Visual Basic a également quelques outils pratiques sous le menu Format qui vous aideront. C'est une excellente occasion de pratiquer avec eux.

En plus de la grille de jeu, nous aurons besoin de certains objets pour les symboles X et O qui seront placés sur la grille. Puisqu'il y a neuf espaces dans la grille, nous allons créer un tableau d'objets avec neuf espaces, appelés éléments dans Visual Basic.

Il existe plusieurs façons de faire à peu près tout dans l'environnement de développement Visual Basic, et la création de tableaux de contrôle ne fait pas exception. La façon la plus simple est probablement de créer la première étiquette (cliquer et dessiner comme l'outil Ligne), de la nommer, de définir tous les attributs (tels que Font et ForeColor), puis d'en faire des copies. VB 6 vous demandera si vous souhaitez créer un tableau de contrôle. Utilisez le nom lblPlayGround pour la première étiquette.

Pour créer les huit autres éléments de la grille, sélectionnez le premier objet d'étiquette, définissez la propriété Index sur zéro et appuyez sur CTRL + C (copie). Vous pouvez maintenant appuyer sur CTRL + V (coller) pour créer un autre objet d'étiquette. Lorsque vous copiez des objets comme celui-ci, chaque copie hérite de toutes les propriétés, à l'exception de l'index de la première. L'index augmentera d'une unité pour chaque copie. Il s'agit d'un tableau de contrôle car ils ont tous le même nom, mais des valeurs d'index différentes.

Si vous créez le tableau de cette façon, toutes les copies seront empilées les unes sur les autres dans le coin supérieur gauche du formulaire. Faites glisser chaque étiquette vers l'une des positions de la grille de lecture. Assurez-vous que les valeurs d'index sont séquentielles dans la grille. La logique du programme en dépend. L'objet étiquette avec la valeur d'index 0 doit être dans le coin supérieur gauche et l'étiquette en bas à droite doit avoir l'index 8. Si les étiquettes couvrent la grille de lecture, sélectionnez chaque étiquette, cliquez avec le bouton droit et sélectionnez Envoyer vers l'arrière.

Puisqu'il y a huit façons possibles de gagner le jeu, nous aurons besoin de huit lignes différentes pour afficher la victoire sur la grille de jeu. Vous utiliserez la même technique pour créer un autre tableau de contrôle. Tout d'abord, tracez la ligne, nommez-la linWin et définissez la propriété Index sur zéro. Utilisez ensuite la technique du copier-coller pour produire sept lignes supplémentaires. L'illustration suivante montre comment définir correctement les numéros d'index.

En plus des objets d'étiquette et de ligne, vous avez besoin de quelques boutons de commande pour jouer au jeu et d'autres étiquettes pour conserver le score. Les étapes pour les créer ne sont pas détaillées ici, mais ce sont les objets dont vous avez besoin.

Deux objets bouton:

  • cmdNewGame
  • cmdResetScore

Objet Frame fraPlayFirst contenant deux cases d'option:

  • optXPlayer
  • optOPlayer

Objet Frame fraScoreBoard contenant six étiquettes. Seuls lblXScore et lblOScore sont modifiés dans le code du programme.

  • lblX
  • lblXScore
  • lblO
  • lblOScore
  • lblMinus
  • lblColon

Enfin, vous avez également besoin de l'objet d'étiquette lblStartMsg pour «masquer» le bouton cmdNewGame lorsqu'il ne doit pas être cliqué. Cela n'est pas visible dans l'illustration ci-dessous car il occupe le même espace dans le formulaire que le bouton de commande. Vous devrez peut-être déplacer temporairement le bouton de commande pour dessiner cette étiquette sur le formulaire.

Jusqu'à présent, aucun codage VB n'a été fait, mais nous sommes enfin prêts à le faire.

Initialisation

Maintenant, vous pouvez enfin commencer à coder le programme. Si vous ne l'avez pas déjà fait, vous voudrez peut-être télécharger le code source à suivre pendant que le fonctionnement du programme est expliqué.

L'une des premières décisions de conception à prendre est de savoir comment suivre l'état actuel du jeu. En d'autres termes, quels sont les X et Os actuels sur la grille de jeu et qui bouge ensuite. Le concept d '«état» est essentiel dans de nombreuses programmations, et en particulier, il est important dans la programmation d'ASP et d'ASP.NET pour le Web

Il existe plusieurs façons de procéder, c'est donc une étape critique de l'analyse. Si vous résolviez ce problème par vous-même, vous souhaiterez peut-être dessiner un organigramme et essayer différentes options avec du papier à gratter avant de commencer tout codage..

Variables

Notre solution utilise deux "tableaux bidimensionnels" car cela permet de garder une trace de "l'état" en changeant simplement les index des tableaux dans les boucles de programme. L'état du coin supérieur gauche sera dans l'élément de tableau avec l'index (1, 1), le coin supérieur droit sera dans (1, 3), le coin inférieur droit dans (3,3), etc. . Les deux tableaux qui font cela sont:

iXPos (x, y)

et

iOPos (x, y)

Il existe de nombreuses façons différentes de le faire et la solution VB.NET finale de cette série vous montre comment le faire avec un seul tableau unidimensionnel.

La programmation pour traduire ces tableaux en décisions de gain des joueurs et les affichages visibles dans le formulaire sont sur la page suivante.

Vous avez également besoin de quelques variables globales comme suit. Notez que ceux-ci se trouvent dans le code Général et Déclarations du formulaire. Cela en fait des variables de "niveau module" qui peuvent être référencées n'importe où dans le code de ce formulaire. Pour plus d'informations, consultez Comprendre l'étendue des variables dans l'aide de Visual Basic.

Il y a deux domaines où les variables sont initialisées dans notre programme. Tout d'abord, quelques variables sont initialisées pendant le chargement du formulaire frmTicTacToe.

Sous-formulaire privé_Load ()

Deuxièmement, avant chaque nouveau jeu, toutes les variables qui doivent être réinitialisées aux valeurs de départ sont affectées dans un sous-programme d'initialisation.

Sub InitPlayGround ()

Notez que l'initialisation de la charge de formulaire appelle également l'initialisation de l'aire de jeux.

L'une des compétences essentielles d'un programmeur est la capacité d'utiliser les fonctionnalités de débogage pour comprendre ce que fait le code. Vous pouvez utiliser ce programme pour essayer:

  • Parcourir le code avec la touche F8
  • Définition d'une surveillance sur des variables clés, telles que sPlaySign ou iMove
    Définition d'un point d'arrêt et interrogation de la valeur des variables. Par exemple, dans la boucle interne de l'initialisation:
lblPlayGround ((i - 1) * 3 + j - 1) .Caption = ""

Notez que ce programme montre clairement pourquoi c'est une bonne pratique de programmation de conserver les données dans des tableaux autant que possible. Si vous n'aviez pas de tableaux dans ce programme, vous devriez écrire du code comme ceci:

Ligne0.Visible = Faux
Line1.Visible = False
Line2.Visible = False
Ligne3.Visible = Faux
Line4.Visible = False
Line5.Visible = False
Line6.Visible = False
Line7.Visible = False

au lieu de cela:

Pour i = 0 à 7
linWin (i) .Visible = False
Ensuite je

Faire un pas

Si une partie du système peut être considérée comme «le cœur», c'est le sous-programme lblPlayGround_Click. Ce sous-programme est appelé chaque fois qu'un joueur clique sur la grille de jeu. (Les clics doivent être à l'intérieur de l'un des neuf éléments lblPlayGround.) Notez que ce sous-programme a un argument: (Index As Integer). La plupart des autres «sous-routines d'événements», comme cmdNewGame_Click (), ne le font pas. L'index indique quel objet d'étiquette a été cliqué. Par exemple, l'index contiendrait la valeur zéro pour le coin supérieur gauche de la grille et la valeur huit pour le coin inférieur droit.

Après qu'un joueur a cliqué sur un carré de la grille de jeu, le bouton de commande pour démarrer un autre jeu, cmdNewGame, est "activé" en le rendant visible. L'état de ce bouton de commande est double car il est également utilisé comme variable de décision booléenne plus tard. dans le programme. L'utilisation d'une valeur de propriété comme variable de décision est généralement déconseillée car s'il devient nécessaire de modifier le programme (par exemple, pour rendre le bouton de commande cmdNewGame visible en permanence), le programme échouera de manière inattendue car vous ne vous souvenez peut-être pas qu'il est également utilisé dans le cadre de la logique du programme. Pour cette raison, il est toujours judicieux de parcourir le code du programme et de vérifier l'utilisation de tout ce que vous modifiez lors de la maintenance du programme, même les valeurs des propriétés. Ce programme viole la règle en partie pour faire valoir ce point et en partie parce que c'est un morceau de code relativement simple où il est plus facile de voir ce qui est fait et d'éviter les problèmes plus tard.

Une sélection de joueur d'une case de jeu est traitée en appelant le sous-programme GamePlay avec Index comme argument.

Traitement du déménagement

Tout d'abord, vous vérifiez si un carré inoccupé a été cliqué.

Si lblPlayGround (xo_Move) .Caption = "" Alors

Une fois que nous sommes sûrs qu'il s'agit d'un mouvement légitime, le compteur de mouvements (iMove) est incrémenté. Les deux lignes suivantes sont très intéressantes car elles traduisent les coordonnées du tableau de composants If lblPlayGround unidimensionnel en index bidimensionnels que vous pouvez utiliser dans iXPos ou iOPos. Mod et division entière (la `` barre oblique inverse '') sont des opérations mathématiques que vous n'utilisez pas tous les jours, mais voici un excellent exemple montrant comment elles peuvent être très utiles.

 Si lblPlayGround (xo_Move) .Caption = "" Alors
iMove = iMove + 1
x = Int (xo_Move / 3) + 1
y = (xo_Move Mod 3) + 1

La valeur xo_Move 0 sera traduite en (1, 1), 1 en (1, 2)… 3 en (2, 1)… 8 en (3, 3).

La valeur dans sPlaySign, une variable avec une portée de module, garde la trace du joueur qui a fait le déplacement. Une fois les tableaux de déplacement mis à jour, les composants d'étiquette dans la grille de lecture peuvent être mis à jour avec le signe approprié.

Si sPlaySign = "O" Alors
iOPos (x, y) = 1
iWin = CheckWin (iOPos ())
Autre
iXPos (x, y) = 1
iWin = CheckWin (iXPos ())
Fin si
lblPlayGround (xo_Move) .Caption = sPlaySign

Par exemple, lorsque le joueur X clique sur le coin supérieur gauche de la grille, les variables auront les valeurs suivantes:

L'écran utilisateur affiche uniquement un X dans la zone supérieure gauche, tandis que l'iXPos a un 1 dans la zone supérieure gauche et 0 dans tous les autres. L'iOPos a 0 dans chaque boîte.

Les valeurs changent lorsque le joueur O clique sur le carré central de la grille. Maintenant, l'iOPos affiche un 1 dans la zone centrale tandis que l'écran utilisateur affiche un X dans le coin supérieur gauche et un O dans la zone centrale. L'iXPos n'affiche que le 1 dans le coin supérieur gauche, avec 0 dans toutes les autres cases.

Maintenant que vous savez où un joueur a cliqué et quel joueur a fait le clic (en utilisant la valeur dans sPlaySign), tout ce que vous avez à faire est de savoir si quelqu'un a gagné une partie et de savoir comment le montrer à l'écran.

Trouver un gagnant

Après chaque déplacement, la fonction CheckWin recherche la combinaison gagnante. CheckWin fonctionne en ajoutant chaque ligne, à travers chaque colonne et à travers chaque diagonale. Le suivi des étapes via CheckWin à l'aide de la fonctionnalité de débogage de Visual Basic peut être très éducatif. Trouver une victoire est une question de premier, vérifier si trois 1 ont été trouvés dans chacun des contrôles individuels dans la variable iScore, puis renvoyer une valeur de "signature" unique dans Checkwin qui est utilisée comme index de tableau pour changer la propriété Visible de un élément dans le tableau de composants linWin. S'il n'y a pas de gagnant, CheckWin contiendra la valeur -1. S'il y a un gagnant, l'affichage est mis à jour, le tableau de bord est modifié, un message de félicitations s'affiche et le jeu redémarre.

Passons en revue l'une des vérifications en détail pour voir comment cela fonctionne. Les autres sont similaires.

'Vérifier les lignes pour 3
Pour i = 1 à 3
iScore = 0
CheckWin = CheckWin + 1
Pour j = 1 à 3
iScore = iScore + iPos (i, j)
Suivant j
Si iScore = 3 alors
Fonction de sortie
Fin si
Ensuite je

La première chose à noter est que le premier compteur d'index i décompte les lignes tandis que le second j compte à travers les colonnes. La boucle extérieure se déplace alors simplement d'une ligne à l'autre. La boucle intérieure compte les 1 de la ligne actuelle. S'il y en a trois, alors vous avez un gagnant.

Notez que vous gardez également une trace du nombre total de carrés testés dans la variable CheckWin, qui est la valeur renvoyée lorsque cette fonction se termine. Chaque combinaison gagnante se terminera par une valeur unique dans CheckWin de 0 à 7 qui est utilisée pour sélectionner l'un des éléments du tableau de composants linWin (). Cela rend l'ordre du code dans la fonction CheckWin aussi! Si vous avez déplacé l'un des blocs de code de boucle (comme celui ci-dessus), la mauvaise ligne sera tracée sur la grille de jeu lorsque quelqu'un gagne. Essayez-le et voyez!

Détails de finition

Le seul code non encore discuté est le sous-programme pour un nouveau jeu et le sous-programme qui réinitialisera le score. Le reste de la logique du système facilite leur création. Pour démarrer une nouvelle partie, il vous suffit d'appeler le sous-programme InitPlayGround. Pour plus de commodité pour les joueurs puisque le bouton peut être cliqué au milieu d'une partie, vous demandez une confirmation avant de continuer. Vous demandez également une confirmation avant de redémarrer le tableau de bord.