Tic-Tac-Toe
GW-Basic, utilisé par PC-Basic
Programme avec Texte Seulement
L'écriture d'un programme tic-tac-toe est un élément essentiel des cours de programmation depuis des décennies ; les programmeurs naissants ont codé des versions du jeu pour renforcer leurs compétences.
Le tic-tac-toe, vieux de plusieurs milliers d'années, a également été proposé presque depuis la création de BASIC.
Pour preuve de cela, ne cherchez pas plus loin que le chapitre intitulé "TIC-TAC-TOE" dans l'un des livres de BASIC originaux, 101 BASIC Computer Games (1973) de David H. Ahl.
TIC.BAS, listé ci-dessous, vous offre un jeu de tic-tac-toe relativement simple : choisissez si vous ou l'ordinateur devez commencer ; ensuite, saisissez la ligne et la colonne de votre coup (vous êtes X, l'ordinateur est O) jusqu'à ce que vous ou l'ordinateur décrochez trois lettres identiques d'affilée, ou que les neuf cases du plateau de jeu soient remplies, ce qui entraîne un match nul.
Il existe un certain nombre de sous-programmes dans le programme et un ensemble de tableaux est utilisé pour suivre les mouvements. En raison de la complexité de TIC.BAS, c'est mieux si on s'y attaque un morceau à la fois.
Chaque cellule (ou point) du tableau de tic-tac-toe classique sera indexée par un entier compris entre 1 et 9 :
Le chiffre 1 sera utilisé pour représenter un X placé dans l'un des neuf emplacements du plateau de jeu, tandis que le chiffre 10 sera utilisé pour représenter un O. (Rappelons que le joueur est X, et l'ordinateur est O.)
Par exemple, un plateau de jeu ainsi rempli en milieu de partie
se traduit par le programme esquissant numériquement le plateau de jeu comme ceci :
À partir de là, nous pouvons trouver les sommes des trois rangées (de haut en bas), des trois colonnes (de gauche à droite) et des deux diagonales (de gauche à droite d'abord, puis de gauche à droite) ; c'est un total de huit sommes à calculer.
Les indices de ces lignes, colonnes et diagonales, ainsi que leurs sommes respectives, comme indiqué dans le tableau de jeu rempli ci-dessus, sont les suivants :
Somme 1 : somme de la ligne 1
(indices : 1, 2, 3) : 20
Somme 2 : somme de la ligne 2 (indices : 4, 5, 6) :
11
Somme 3 : somme de la ligne 3 (indices : 7, 8, 9) : 2
Somme 4 : somme
de la colonne 1 (indices 1, 4, 7) : 10
Somme 5 : somme de la colonne 2
(indices 2, 5, 8) : 12
Somme 6 : somme de la colonne 3 (indices 3, 6, 9) :
11
Somme 7 : somme de la diagonale 1 (indices 1, 5, 9) : 12
Somme 8 :
somme de la diagonale 2 (indices 3, 5, 7) : 1
Vous trouverez ci-dessous le code pour démarrer le programme et configurer plusieurs tableaux.
5 REM TIC.BAS
10 KEY OFF
15 RANDOMIZE TIMER:I=INT(1+9*RND(1))
20 COLOR 15,1:CLS
30 DIM SUMARRAY(8)
35 DIM POSARRAY(9)
36 DIM INDEXARRAY(24)
37 INDEXARRAY(1)=1:INDEXARRAY(2)=2:INDEXARRAY(3)=3
:INDEXARRAY(4)=4:INDEXARRAY(5)=5:INDEXARRAY(6)=6 :INDEXARRAY(7)=7:INDEXARRAY(8)=8:INDEXARRAY(9)
=9
38 INDEXARRAY(10)=1:INDEXARRAY(11)=4:INDEXARRAY(12
)=7:INDEXARRAY(13)=2:INDEXARRAY(14)=5:INDEXARRAY(15)=8:INDEXARRAY(16)=3:INDEXARRAY(17)=6:INDEXARRAY(18)=9
39 INDEXARRAY(19)=1:INDEXARRAY(20)=5:INDEXARRAY(21)=9:INDEXARRAY(22)=3:INDEXARRAY(23)=5:INDEXARRAY(24)=7
40 FOR X=1 TO 8
50 SUMARRAY(X)=0
55 POSARRAY(X)=0
60 NEXT X
65
POSARRAY(9)=0
Aux lignes 30 et 35, nous avons déclaré deux tableaux : le SUMARRAY, qui trouve les sommes des trois lignes, trois colonnes et deux diagonales ; et le POSARRAY (pour tableau de position), qui capture la valeur à l'intérieur de chacune des neuf cellules (ou points) du plateau de jeu ; la valeur peut être 0 (pas de lettre), 1 (un X) ou 10 (un O).
Les lignes 36 à 39 initialisent et déclarent des valeurs pour INDEXARRAY, qui ressemble exactement à ce que cela ressemble : un tableau des valeurs d'index des lignes, des colonnes et des diagonales.
La ligne 15 définit une graine aléatoire initiale basée sur l'horloge interne de l'ordinateur, puis choisit un nombre aléatoire entre 1 et 9, stockant la valeur dans la variable I - qui servira de cellule aléatoire pour que l'ordinateur place un O uniquement si l'ordinateur se déplace en premier.
Nous devons inviter l'utilisateur à voir s'il souhaite se déplacer en premier :
70 PRINT" --- TIC TAC TOE ---"
80 PRINT "Vous serez X, et l'ordinateur sera O."
90 PRINT:INPUT "Tapez 1 si
vous souhaitez passer en premier ; tapez 2 si vous souhaitez passer en
second";GO
95 IF G0=2 THEN POSARRAY(I)=10
Si l'utilisateur choisit de s'en remettre à l'ordinateur, le premier coup de l'ordinateur est randomisé en utilisant la valeur stockée dans la variable I.
Ensuite, installons le plateau de jeu sur l'écran.
100 'Mise en place le plateau
de jeu
105 CLS
106 X=1
110 LOCATE 1,5:PRINT "--- TIC TAC TOE ---"
115 FOR A=5 TO 9 STEP 2
117 FOR B=12 TO 16 STEP 2
120 LOCATE A,B
130
GOSUB 1000
132 X=X+1
140 NEXT B
150 NEXT A
155 X=0
157 COLOR 14
160 LOCATE 4,12:PRINT "1":LOCATE 4,14:PRINT "2":LOCATE 4,16:PRINT "3"
170
LOCATE 5,10:PRINT "1":LOCATE 7,10:PRINT "2":LOCATE 9,10:PRINT "3"
175 COLOR
15
300 GOSUB 2000
400 GOSUB 4000
500 GOSUB 3000
999 GOTO 100
'Redessine le plateau de jeu
Nous devons également interroger l'utilisateur pour son prochain mouvement. Celui-ci sera composé de deux entrées : une ligne et une colonne.
200 'Interroge l'utilisateur
pour son mouvement
210 LOCATE 14,1:INPUT "Entrez la ligne de votre prochain
coup (1 to 3)";ROW
220 LOCATE 15,1:INPUT "Entrez la colonne de votre prochain
coup (1 to 3)";COL
230 IF ROW<1 OR ROW>3 THEN 210
240 IF COL<1 OR COL>3
THEN 220
250 IF ROW=1 THEN ELEMENT=COL
260 IF ROW=2 THEN ELEMENT=COL+3
270 IF ROW=3 THEN ELEMENT=COL+6
280 IF POSARRAY(ELEMENT)=0 THEN POSARRAY(ELEMENT)=1
Ensuite, un sous-programme doit être écrit pour déterminer où afficher précisément les X et les O à l'écran.
C'est ici:
1000 'Sous-programme pour
déterminer s'il faut sortir un X, un O ou rien
1010 IF POSARRAY(X)=0 THEN
PRINT "_";:RETURN
1020 IF POSARRAY(X)=1 THEN PRINT "X";:RETURN
1030 IF
POSARRAY(X)=10 THEN PRINT "O";:RETURN
Encore une autre sous-routine est nécessaire, cette fois pour calculer toutes les sommes des lignes, des colonnes et des diagonales. Notez que les sommes des lignes, des colonnes et des diagonales impliquent ce qui suit :
Somme de 0 : il n'y a pas de O
ou de X sur r, c ou d.
Somme de 1 : il y a un X sur r, c ou d.
Somme de 2
: il y a deux X sur r, c ou d.
Somme de 3 : il y a trois X sur le jeu r, c ou
d : jeu terminé : le joueur humain a gagné.
Somme de 10 : il y a un O sur r,
c ou d.
Somme de 20 : il y a deux O sur r, c ou d.
Somme de 30 : Il y a
trois O sur le r, c, d ; jeu terminé : l'ordinateur a gagné.
Somme de 11 : Il
y a un X et un O sur le r, c ou d.
Somme de 12 : Il y a deux X et un O sur le
r, c, ou d.
Somme de 21 : Il y a un X et deux O sur le r, c ou d.
2000 'Sous-programme pour
calculer toutes les sommes des lignes, des colonnes et des diagonales
2010
'Sommes des lignes
2020 SUMARRAY(1)=POSARRAY(1)+POSARRAY(2)+POSARRAY(3)
2030 SUMARRAY(2)=POSARRAY(4)+POSARRAY(5)+POSARRAY(6)
2040 SUMARRAY(3)=POSARRAY(7)+POSARRAY(8)+POSARRAY(9)
2050 'Sommes des colonnes
2060 SUMARRAY(4)=POSARRAY(1)+POSARRAY(4)+POSARRAY(7)
2070 SUMARRAY(5)=POSARRAY(2)+POSARRAY(5)+POSARRAY(8)
2080 SUMARRAY(6)=POSARRAY(3)+POSARRAY(6)+POSARRAY(9)
2090 'Sommes des diagonales
2100 SUMARRAY(7)=POSARRAY(1)+P0SARRAY(5)+POSARRAY(9)
2110 SUMARRAY(8)=POSARRAY(3)+POSARRAY(5)+POSARRAY(7)
2120 RETURN
Nous devons vérifier à plusieurs reprises si quelqu'un a gagné la partie ou s'il y a eu match nul. Voici le code :
3000 'Sous-programme pour
vérifier s'il y a un gagnant
3010 WINNER=0
3020 FOR X=1 TO 8
3030 IF
SUMARRAY(X)=3 THEN WINNER=1
3040 IF SUMARRAY(X)=30 THEN WINNER=2
3050
NEXT X
3060 RETURN
5000 'Sous-programme pour
vérifier s'il y a une égalité
5020 FOR X=1 TO 9
5030 IF POSARRAY(X)=0 THEN
RETURN
5040 NEXT X
5050 PRINT "C'est l'égalité!"
5060 END
180 IF WINNER=1 THEN
PRINT:PRINT "VOUS AVEZ GAGNÉ LE JEU!!!":END
190 IF WINNER=2 THEN
PRINT:PRINT"Vous avez perdu le jeu. Désolé.":END
195 GOSUB 5000
La partie de TIC.BAS la plus complexe à coder est l'IA de l'ordinateur. Nonobstant le placement aléatoire d'un premier coup O, l'ordinateur effectue des coups basés sur la hiérarchie de sommes suivante (par ordre de priorité) :
1. Si une ligne, une colonne ou une somme diagonale est égale à 20, alors un O dans l'emplacement vide gagnera la partie - alors déplacez-vous là.
2. Si la somme d'une ligne, d'une colonne ou d'une diagonale est égale à 2, alors un O empêchera le joueur humain de gagner la partie, alors déplacez-vous là.
3. Si une ligne, une colonne ou une somme diagonale est égale à 10, l'insertion d'un O laissera une cellule ouverte avec deux O - alors déplacez-vous là.
4. Si une ligne, une colonne ou une somme diagonale est égale à 0, alors l'insertion d'un O marquera un territoire - alors déplacez-vous là.
5. Si aucune des conditions précédentes n'est satisfaite, placez un O à l'intérieur de la prochaine cellule ouverte disponible.
Voici le sous-programme qui code dans la hiérarchie déterminant le prochain coup de l'ordinateur :
4000 'Sous-programme permettant
à l'ordinateur d'effectuer son mouvement
4010 'Tout d'abord, l'ordinateur
doit se déplacer vers une ligne, col, diag il pourrait immédiatement gagner avec
4020 FOR Y=1 TO 24 STEP 3
4030 TEMPSUM=-1:MOVE=0
4040 TEMPSUM=POSARRAY(INDEXARRAY(Y))+POSARRAY(INDEXARRAY(Y+1))+POSARRAY(INDEXARRAY(Y+2))
4050 IF TEMPSUM=20 THEN MOVE=1
4060 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y))=0
THEN POSARRAY{INDEXARRAY(Y))=10:RETURN
4070 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+1))=0
THEN POSARRAY(INOEXARRAY(Y+1))=10:RETURN
4080 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+2))=0
THEN POSARRAY(INDEXARRAY(Y+2))=10:RETURN
4090 NEXT Y
4100 'Next,
computer must defend a row, col, or diag--if necessary
4120 FOR Y=1 TO 24
STEP 3
4130 TEMPSUM=-1:MOVE=0
4140 TEMPSUM=POSARRAY(INDEXARRAY(Y) )+POSARRAY(INDEXARRAY(Y+1))+P0SARRAY(INDEXARRAY(Y+2))
4150 IF TEMPSUM=2 THEN MOVE=1
4160 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y))=0
THEN POSARRAY(INDEXARRAY(Y))=10:RETURN
4170 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+1))=0
THEN POSARRAY(INDEXARRAY(Y+1))=10:RETURN
4180 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+2))=0
THEN POSARRAY(INDEXARRAY(Y+2))=10:RETURN
4190 NEXT Y
4200 'Ensuite,
l'ordinateur doit se déplacer vers une ligne, col, diag où il y en a un 0
4220 FOR Y=1 TO 24 STEP 3
4230 TEMPSUM=-1:MOVE=0
4240 TEMPSUM=POSARRAY(INDEXARRAY(Y))+POSARRAY(INDEXARRAY(Y+1))+POSARRAY(INDEXARRAY(Y+2))
4250 IF TEMPSUM=10 THEN MOVE=1
4260 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y))=0
THEN POSARRAY(INDEXARRAY(Y))=10:RETURN
4270 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+1))=0
THEN POSARRAY(INDEXARRAY(Y+1))=10:RETURN
4280 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+2))=0
THEN POSARRAY(INDEXARRAY(Y+2))=10:RETURN
4290 NEXT Y
4300 'L'ordinateur
doit passer à une ligne vide, col, diag suivant
4320 FOR Y=1 TO 24 STEP 3
4330 TEMPSUM=-1:MOVE=0
4340 TEMPSUM=POSARRAY(INDEXARRAY(Y))+POSARRAY(INDEXARRAY(Y+1))+POSARRAY(INDEXARRAY(Y+2))
4350 IF TEMPSUM=0 THEN MOVE=1
4360 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y))=0
THEN POSARRAY(INDEXARRAY(Y))=10:RETURN
4370 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+1))=0
THEN POSARRAY(INDEXARRAY(Y+1))=10:RETURN
4380 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+2))=0
THEN POSARRAY(INDEXARRAY(Y+2))=10:RETURN
4390 NEXT Y
4400 'Enfin,
l'ordinateur doit se déplacer là où il reste à aller
4420 FOR Y=1 TO 24 STEP
3
4430 TEMPSUM=-1:MOVE=0
4440 TEMPSUM=POSARRAY(INDEXARRAY(Y))+POSARRAY(INDEXARRAY(Y+1))+P0SARRAY(INDEXARRAY(Y+2))
4450 IF (TEMPSUM=1 OR TEMPSUM=11) THEN MOVE=1
4460 IF MOVE=1 AND
POSARRAY(INDEXARRAY(Y))=0 THEN POSARRAY(INDEXARRAY(Y))=10:RETURN
4470 IF
MOVE=1 AND POSARRAY(INDEXARRAY(Y+1))=0 THEN POSARRAY(INDEXARRAY(Y+1))=10:RETURN
4480 IF MOVE=1 AND POSARRAY(INDEXARRAY(Y+2))=0 THEN POSARRAY(INDEXARRAY(Y+2))=10:RETURN
4490 NEXT Y
L'ordinateur mène un combat décent dans TIC.BAS, mais une IA encore plus robuste est sûrement possible en programmant des heuristiques supplémentaires de tic-tac-toe. (En d'autres termes, l'ordinateur ne joue pas parfaitement le jeu ; c'est à vous de lui apporter un remède.)
En outre, d'autres variantes populaires du tic-tac-toe, telles que le tic-tac-toe tridimensionnel, sont mûres pour être traduites en code GW-BASIC.
L'amélioration du tic-tac-toe numérique avec certains graphiques rendrait également les choses plus agréables pour les utilisateurs.
Enfin, vous pouvez envisager d'optimiser un peu le code en utilisant les instructions DATA et READ pour charger les valeurs initiales dans des tableaux, par exemple.
Vous avez du pain sur la planche!.