IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[défi n°9] Si ça vous gratte...


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    houla, effectivement! ça sent la confusion de versions (j'ai 3 pages de tests différentes)

    bon, voyons voir...

  2. #2
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    à retester

    le code n'est pas du tout économique mais bon, après tout, j'apprends à jouer hein

  3. #3
    Invité
    Invité(e)
    Par défaut
    Celui de JT, quand on gagne c'est lui qui gagne les points...
    Des fois c'est à lui de jouer, mais il joue pas...
    L'autre de "je-sais-plus-qui" il fait une erreur très bête.
    Il ne faut surtout pas qu'il joue ni en 1, ni en 2 ! Sinon moi je joue soit en 1 ou en 2, et la c'est finit pour lui !

  4. #4
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    JT y'a encore un bug dans ton AI : quand on joue sur les cases 0, 5 ou 0, 7 ou 6, 5 l'ordinateur ne joue pas.
    Une des parties gagnantes avec ton AI est : 0, 6, 5, 3.

    Moi mon code avance, mais il s'annonce monstrueux. 140 lignes juste pour le constructeur et les méthodes du morpion, (sans le html) et j'ai pas encore commencé à programmer l'AI.

  5. #5
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    JT y'a encore un bug dans ton AI : quand on joue sur les cases 0, 5 ou 0, 7 ou 6, 5 l'ordinateur ne joue pas.
    Une des parties gagnantes avec ton AI est : 0, 6, 5, 3.

    Moi mon code avance, mais il s'annonce monstrueux. 140 lignes juste pour le constructeur et les méthodes du morpion, (sans le html) et j'ai pas encore commencé à programmer l'AI.



    Au passage zebuman j'aime bien dans ton code la façon de représenter les grilles par des nombres. Je vais faire mon morpion+AI, après je l'optimiserais sûrement avec ça.

  6. #6
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684

  7. #7
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    Bon voilà mon premier code. Du bien lourd pour une AI déplorable (se contente de gagner ou ne pas perdre).
    Il ne me reste plus "que" à ne pas jouer au hasard dans le cas par défaut.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
      <head>
        <title>Morbac</title>
        <style type="text/css">
        #morbac {
          table-layout: fixed;
          border-spacing: 1px;
          empty-cells: show;
          border: 3px outset #000;
          font-weight: bold;
        }
        #morbac td {
          width: 30px;
          height: 30px;
          border: 2px inset #000;
          text-align: center;
        }
        </style>
        <script type="text/javascript">
        function mor_joue (place) {
          if (this.lock) {
            alert("Impossible de jouer\n plus aucune partie n'est en cours");
            return false;
          }
          if (place < 0 || place > this.cases.length || this.grille[place]) {
            alert("Cette case est déjà prise");
            return false;
          }
          this.grille[place] = this.qui;
          this.cases[place].data = (this.qui == 1) ? 'X' : 'O';
          if (this.testFin()) {
            this.newPartie();
            return false;
          }
     
          if (this.qui == 1 && this.onplay1) {
            if (typeof this.onplay1 == 'function') this.onplay1(place);
            else if (typeof this.onplay1[0][this.onplay1[1]] == 'function') this.onplay1[0][this.onplay1[1]](place);
          } else if (this.qui == -1 && this.onplay2) {
            if (typeof this.onplay2 == 'function') this.onplay2(place);
            else if (typeof this.onplay2[0][this.onplay2[1]] == 'function') this.onplay2[0][this.onplay2[1]](place);
          }
          this.qui = -this.qui;
          if (this.qui == 1 && this.joueur1) {
            if (typeof this.joueur1 == 'function') this.joueur1(place);
            else if (typeof this.joueur1[0][this.joueur1[1]] == 'function') this.joueur1[0][this.joueur1[1]](place);
          } else if (this.qui == -1 && this.joueur2) {
            if (typeof this.joueur2 == 'function') this.joueur2(place);
            else if (typeof this.joueur2[0][this.joueur2[1]] == 'function') this.joueur2[0][this.joueur2[1]](place);
          }
          return true;
        }
     
        function mor_testGagne () {
          //parcours du tableau horizontalement
          for (var i=0; i<this.grille.length; i++) {
            if (i%this.taille == 0) var temp = 0;
            temp += this.grille[i];
     
            if ((i+1)%this.taille == 0 && temp == this.taille) {
              return 1;
            } else if ((i+1)%this.taille == 0 && temp == -this.taille) {
              return -1;
            }
          }
     
     
          //verticalement (double boucle à optimiser)
          for (var i=0; i<this.taille; i++) {
            var temp = 0;
            for (var j=0; j<this.taille; j++) {
              temp += this.grille[j*this.taille+i];
            }
     
            if (temp == this.taille) {
              return 1;
            } else if (temp == -this.taille) {
              return -1;
            }
          }
     
          var temp = 0, temp2 = 0;
     
          //en diagonal (les 2 en même temps)
          for (var i=0; i<this.taille; i++) {
            temp += this.grille[i*this.taille+i];
            temp2 += this.grille[(i+1)*this.taille-(i+1)];
          }
          if (temp == this.taille || temp2 == this.taille) {
            return 1;
          } else if (temp == -this.taille || temp2 == -this.taille) {
            return -1;
          }
          return 0;
        }
     
        function mor_testFin() {
          var win = this.testGagne();
     
          if (win) {
            this.total.data++;
            this.lock = true;
          }
     
          if (win == 1) {
            this.gagne1.data++;
            alert("Le joueur 1 à gagné");
          } else if (win == -1) {
            this.gagne2.data++;
            alert("Le joueur 2 a gagné");
          } else {
            //si personne n'a gagné c'est un match null ou un match pas terminé
            for (var i=0; i<this.grille.length; i++) {
              if (!this.grille[i]) return false;
            }
     
            //si la boucle se fini il n'y a plus de cases libres
            this.nuls.data++;
            this.total.data++;
            this.lock = true;
            alert("Match nul");
          }
          return true;
        }
     
        function mor_newPartie () {
          this.grille = new Array(this.taille*this.taille); //on ne fait que des grilles carrés
          for (var i=0; i<this.grille.length; i++) {
            this.grille[i] = 0; //undefined pose des problèmes
            this.cases[i].data = ' ';
          }
     
          this.qui = (this.total.data%2) ? -1 : 1;
          this.lock = false;
     
          if (typeof this.onnew == 'function') this.onnew();
          else if (typeof this.onnew[0][this.onnew[1]] == 'function') this.onnew[0][this.onnew[1]]();
     
          if (this.qui == 1 && this.joueur1) {
            if (typeof this.joueur1 == 'function') this.joueur1();
            else if (typeof this.joueur1[0][this.joueur1[1]] == 'function') this.joueur1[0][this.joueur1[1]]();
          } else if (this.qui == -1 && this.joueur2) {
            if (typeof this.joueur2 == 'function') this.joueur2();
            else if (typeof this.joueur2[0][this.joueur2[1]] == 'function') this.joueur2[0][this.joueur2[1]]();
          }
        }
     
        function mor_reset() {
          this.total.data = 0;
          this.gagne1.data = 0;
          this.gagne2.data = 0;
          this.nuls.data = 0;
          this.grille = new Array(this.taille^2);
          this.cases = new Array();
          for (var i=0; i<this.grille.length; i++) {
            this.cases[i].data = ' ';
          }
          this.lock = false;
        }
     
        function morpion_grille(taille, tablo, total, gagne1, gagne2, nuls) {
          this.lock = false;
          this.taille = taille;
          this.total = total.firstChild;
          this.gagne1 = gagne1.firstChild;
          this.gagne2 = gagne2.firstChild;
          this.nuls = nuls.firstChild;
          this.cases = new Array();
     
          var elts = tablo.getElementsByTagName('td');
          for (var i=0; i<elts.length; i++) {
            this.cases[i] = elts[i].firstChild;
          }
     
          this.joue = mor_joue;
          this.testGagne = mor_testGagne;
          this.testFin = mor_testFin;
          this.newPartie = mor_newPartie;
          this.reset = mor_reset;
        }
     
     
    	/***************/
    	/*Début de l'AI*/
    	/***************/
     
        function AI_played(place) {
          this.grille[place] = -1;
        }
     
        function AI_joue() {
          var prochain = this.bestChoice();
          if (prochain == -1) {
            do {
              prochain = parseInt(Math.random()*this.grille.length);
            } while (this.grille[prochain]);
          }
          this.grille[prochain] = 1;
          if (typeof this.doPlay == 'function') this.doPlay(prochain);
          else if (typeof this.doPlay[0][this.doPlay[1]] == 'function') this.doPlay[0][this.doPlay[1]](prochain);
          return prochain;
        }
     
        function AI_meilleur () {
          var placeVideDiag1, placeVideDiag2, nextWin = -1, nextNotLose = -1, nbVideDiag1 = 0, nbVideDiag2 = 0, addDiag1 = 0, addDiag2 = 0;
          //win the yes, need the know to win, against the no !
          for (var i=0; i<3; i++) {
            var placeVideLigne, placeVideColone, nbVideLigne = 0, nbVideColone = 0, addLigne = 0, addColone = 0;
            for (var j=0; j<3; j++) {
              if (this.grille[i*3+j]) {
                addLigne += this.grille[i*3+j];
              } else {
                nbVideLigne++;
                placeVideLigne = i*3+j;
              }
              if (this.grille[j*3+i]) {
                addColone += this.grille[j*3+i];
              } else {
                nbVideColone++;
                placeVideColone = j*3+i;
              }
            }
     
            if (this.grille[i*3+i]) {
              addDiag1 += this.grille[i*3+i];
            } else {
              nbVideDiag1++;
              placeVideDiag1 = i*3+i;
            }
            if (this.grille[i*3+(2-i)]) {
              addDiag2 += this.grille[i*3+(2-i)];
            } else {
              nbVideDiag2++;
              placeVideDiag2 = i*3+(2-i);
            }
     
            if (nbVideLigne == 1 && addLigne == 2) {
              //on peut gagner :) (en faisant une ligne)
              nextWin = placeVideLigne;
            } else if (nbVideColone == 1 && addColone == 2) {
              //on peut gagner (en faisant une colone)
              nextWin = placeVideColone;
            }
     
            if (nbVideLigne == 1 && addLigne == -2) {
              nextNotLose = placeVideLigne;
            } else if (nbVideColone == 1 && addColone == -2) {
              nextNotLose = placeVideColone;
            }
          }
     
          //win diag
          if (nbVideDiag1 == 1 && addDiag1 == 2) {
            nextWin = placeVideDiag1;
          } else if (nbVideDiag2 == 1 && addDiag2 == 2) {
            nextWin = placeVideDiag2;
          }
          //not lose diag
          if (nbVideDiag1 == 1 && addDiag1 == -2) {
            nextNotLose = placeVideDiag1;
          } else if (nbVideDiag2 == 1 && addDiag2 == -2) {
            nextNotLose = placeVideDiag2;
          }
          return (nextWin != -1) ? nextWin : nextNotLose;
        }
     
        function AI_restart() {
          this.grille = new Array(9);
        }
     
        function AI_new(callPlay) {
          this.doPlay = callPlay;
          this.played = AI_played;
          this.joue = AI_joue;
          this.bestChoice = AI_meilleur;
          this.restart = AI_restart;
        }
     
        function init() {
          morpion = new morpion_grille(3, nodeGratte = document.getElementById('morbac'),
            document.getElementById('nbParties'),
            document.getElementById('nbGagne1'),
            document.getElementById('nbGagne2'),
            document.getElementById('nbNuls'));
          var cases = nodeGratte.getElementsByTagName('td');
          for (var i=0; i<cases.length; i++) {
            cases[i].onclick = new Function("morpion.joue("+i+")");
          }
     
          AI = new AI_new([morpion, 'joue']);
          morpion.onplay1 = [AI, 'played'];
          morpion.onnew = [AI, 'restart'];
          morpion.joueur2 = [AI, 'joue'];
          morpion.newPartie();
        }
        </script>
      </head>
      <body onload="init()">
        <div>Nombre de parties joués : <var id="nbParties">0</var></div>
        <div>Nombre de parties gagnés par <em>vous</em> : <var id="nbGagne1">0</var></div>
        <div>Nombre de parties gagnés par <em>l'autre</em> : <var id="nbGagne2">0</var></div>
        <div>Nombre de matchs nuls : <var id="nbNuls">0</var></div>
        <table id="morbac">
          <tr>
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
          <tr>
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
          <tr>
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
        </table>
      </body>
    </html>
    L'avantage d'avoir totalement séparé le jeu de morpion de l'AI c'est de pouvoir changer complètement l'un sans affecter l'autre.
    De plus je peux faire jouer l'AI contre elle-même.

  8. #8
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    ne pas perdre? à voir...

    ça y est j'ai trouvé un moyen de réduire mon mastodonte; après, tu trouveras sûrement des bugs

  9. #9
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    Ne pas perdre dans le sens où il va se mettre dans la case vide si tu en a deux d'alignés.
    En gros pour le moment il a un niveau gros débutant.

    ça y est j'ai trouvé un moyen de réduire mon mastodonte
    T'as vu la taille du mien ? :p

    Au passage, pour le moment quand je fais jouer mon AI contre elle-même, sur 100 parties j'obtiens 25 - 26 et 49 nuls. Avec une AI parfaite on devrait obtenir 0 - 0 et 100 nuls.

    JT y'aurait pas moyen que tu modifie un peu ton jeu pour faire jouer ton AI contre elle-même. (oublies pas de désactiver la petite animation )

  10. #10
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    ben c'est couru d'avance, si je fais ça j'aurai que des nuls!

  11. #11
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    démo

    et là tu vas voir qu'il n'y a pas 50 manières de gagner au morpion

  12. #12
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    bon alors! grattez-vous les méninges quoi! c'est un défi open hein, je le rappelle

  13. #13
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    Ne désespère pas je travaille encore sur mon AI.
    Par contre ça va pas être un champion de vitesse. :p

  14. #14
    Expert confirmé

    Avatar de denisC
    Profil pro
    Développeur Java
    Inscrit en
    Février 2005
    Messages
    4 050
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 4 050
    Par défaut
    C'est quoi le défi??? Faire un morpion qui ne perds jamais. C'est fait (pas super compliqué). Et donc, après, ou est le reste du défi???

  15. #15
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    Si tu trouves ça trop simple, fais ton AI de telle sorte à ce qu'elle puisse facilement évoluer et jouer sur une grille de 4*4 et n*n.

    Aille c'est moins marrant

    Après on pourrait peut-être faire s'affronter les différentes AI
    Au passage denisC tu pourrais peut-être nous poster ton code qui joue pas au hasard.

  16. #16
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    Citation Envoyé par Celelibi
    Au passage denisC tu pourrais peut-être nous poster ton code qui joue pas au hasard.
    tiens c'est vrai ça


    sinon, denis, je parlais pour les milliards de visiteurs quotidiens du forum, qui sont cordialement invités à faire péter toutes les logiques avec leurs inventions inédites


    ou alors j'aurais dû proposer un monopoly? ou un pacman


    en tout cas, si quelqu'un se sent prêt à lancer le défi "Puissance 4" c'est cool

  17. #17
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    Voilà, j'ai fini mon AI.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
      <head>
        <title>Morbac</title>
        <style type="text/css">
        #morbac {
          table-layout: fixed;
          border-spacing: 1px;
          empty-cells: show;
          border: 3px outset #000;
          font-weight: bold;
        }
        #morbac td {
          width: 30px;
          height: 30px;
          border: 2px inset #000;
          text-align: center;
        }
        </style>
        <script type="text/javascript">
        function melange () {
          this.sort(function () { return Math.random()*3-1 });
        }
        Array.prototype.shuffle = melange;
     
        function mor_joue (place) {
          if (this.lock) {
            alert("Impossible de jouer\n plus aucune partie n'est en cours");
            return false;
          }
          if (place < 0 || place > this.cases.length || (this.grille[0] | this.grille[1]) & (1 << place)) {
            alert("Cette case est déjà prise");
            return false;
          }
          this.grille[this.qui] |= 1 << place;
          this.cases[place].data = (this.qui == 1) ? 'X' : 'O';
          if (this.testFin()) {
            this.newPartie();
            return false;
          }
     
          if (this.qui == 1 && this.onplay1) {
            if (typeof this.onplay1 == 'function') this.onplay1(place);
            else if (typeof this.onplay1[0][this.onplay1[1]] == 'function') this.onplay1[0][this.onplay1[1]](place);
          } else if (this.qui == 0 && this.onplay2) {
            if (typeof this.onplay2 == 'function') this.onplay2(place);
            else if (typeof this.onplay2[0][this.onplay2[1]] == 'function') this.onplay2[0][this.onplay2[1]](place);
          }
          this.qui = 1 - this.qui; //comme ça on alterme entre 0 et 1
          if (this.qui == 1 && this.joueur1) {
            if (typeof this.joueur1 == 'function') this.joueur1();
            else if (typeof this.joueur1[0][this.joueur1[1]] == 'function') this.joueur1[0][this.joueur1[1]]();
          } else if (this.qui == 0 && this.joueur2) {
            if (typeof this.joueur2 == 'function') this.joueur2();
            else if (typeof this.joueur2[0][this.joueur2[1]] == 'function') this.joueur2[0][this.joueur2[1]]();
          }
          return true;
        }
     
        function mor_testGagne () {
          //motifs d'alignement horizontaux et verticaux
          var hzalign = (1 << this.taille) - 1; // 111b
          var vzalign = 0;
          for (var i=0; i<this.taille; i++) vzalign |= (1 << i*this.taille); // 001'001'001b
     
          //parcours du tableau horizontalement et verticalement
          for (var i=0; i<this.taille; i++) {
            var horiz = hzalign << (i*this.taille);
            var vertz = vzalign << i; 
     
            if (((this.grille[0] & horiz) == horiz) || ((this.grille[0] & vertz) == vertz)) {
              return -1;
            } else if (((this.grille[1] & horiz) == horiz) || ((this.grille[1] & vertz) == vertz)) {
              return 1;
            }
          }
     
          var diag1 = 0, diag2 = 0;
          //en diagonal
          for (var i=0; i<this.taille; i++) {
            diag1 |= 1 << (i*this.taille + i);
            diag2 |= 1 << ((i+1)*this.taille - (i+1));
          }
          if (((this.grille[0] & diag1) == diag1) || ((this.grille[0] & diag2) == diag2)) {
            return -1;
          } else if (((this.grille[1] & diag1) == diag1) || ((this.grille[1] & diag2) == diag2)) {
            return 1;
          }
          return 0;
        }
     
        function mor_testFin() {
          var win = this.testGagne();
     
          if (win) {
            this.total.data++;
            this.lock = true;
          }
     
          if (win == 1) {
            this.gagne1.data++;
            alert("Le joueur 1 à gagné");
          } else if (win == -1) {
            this.gagne2.data++;
            alert("Le joueur 2 a gagné");
          } else {
            //si personne n'a gagné c'est un match null ou un match pas terminé
            //si il reste une case vide c'est pas fini
            if ((this.grille[0] | this.grille[1]) < 511) return false;
     
     
            //si la boucle se fini il n'y a plus de cases libres
            this.nuls.data++;
            this.total.data++;
            this.lock = true;
            alert("Match nul");
          }
          return true;
        }
     
        function mor_newPartie () {
          this.grille = new Array(0, 0); //on ne fait que des grilles carrés
          for (var i=0; i<this.cases.length; i++) {
            this.cases[i].data = ' ';
          }
     
          this.qui = (~this.total.data) & 1;
          this.lock = false;
     
          if (this.onnew) {
            if (typeof this.onnew == 'function') this.onnew();
            else if (typeof this.onnew[0][this.onnew[1]] == 'function') this.onnew[0][this.onnew[1]]();
          }
     
          if (this.qui == 1 && this.joueur1) {
            if (typeof this.joueur1 == 'function') this.joueur1();
            else if (typeof this.joueur1[0][this.joueur1[1]] == 'function') this.joueur1[0][this.joueur1[1]]();
          } else if (this.qui == 0 && this.joueur2) {
            if (typeof this.joueur2 == 'function') this.joueur2();
            else if (typeof this.joueur2[0][this.joueur2[1]] == 'function') this.joueur2[0][this.joueur2[1]]();
          }
        }
     
        function mor_reset() {
          this.total.data = 0;
          this.gagne1.data = 0;
          this.gagne2.data = 0;
          this.nuls.data = 0;
          this.grille = new Array(0, 0);
          this.cases = new Array();
          for (var i=0; i<this.cases.length; i++) {
            this.cases[i].data = ' ';
          }
          this.lock = false;
        }
     
        function morpion_grille(taille, tablo, total, gagne1, gagne2, nuls) {
          this.lock = false;
          this.taille = taille;
          this.total = total.firstChild;
          this.gagne1 = gagne1.firstChild;
          this.gagne2 = gagne2.firstChild;
          this.nuls = nuls.firstChild;
          this.cases = new Array();
     
          var elts = tablo.getElementsByTagName('td');
          for (var i=0; i<elts.length; i++) {
            this.cases[i] = elts[i].firstChild;
          }
     
          this.joue = mor_joue;
          this.testGagne = mor_testGagne;
          this.testFin = mor_testFin;
          this.newPartie = mor_newPartie;
          this.reset = mor_reset;
        }
     
     
    	/***************/
    	/*Début de l'AI*/
    	/***************/
     
        function AI_played(place) {
          this.grille[0] |= 1 << place;
        }
     
        function AI_joue() {
          var scoreCases = new Array();
          for (var i=0; i<9; i++) {
            if ((this.grille[0] | this.grille[1]) & (1 << i)) continue;
            //elle est bien cette case ?
            scoreCases.push([i, this.bienLaCase(i, 1)]);
          }
          scoreCases.sort(function (a, b) {return b[1]-a[1];});
          while (scoreCases.length > 1) {
            if (scoreCases[0][1] > scoreCases[scoreCases.length-1][1]) scoreCases.pop();
            else break;
          }
          scoreCases.shuffle();
          var prochain = scoreCases[0][0];
          this.grille[1] |= 1 << prochain;
          if (typeof this.doPlay == 'function') this.doPlay(prochain);
          else if (typeof this.doPlay[0][this.doPlay[1]] == 'function') this.doPlay[0][this.doPlay[1]](prochain);
          return prochain;
        }
     
        function AI_bien (place, qui) {
          //juste un accélérateur, l'algo donnerait le même résultat
          //toutes les cases donne un score de 0 si on joue le premier
          if ((this.grille[0] | this.grille[1]) == 0) return 0;
     
          this.grille[qui] |= 1 << place;
          //win the yes, need the know to win... against the no !
          for (var i=0; i<this.winCombi.length; i++) {
            if ((this.grille[qui] & this.winCombi[i]) == this.winCombi[i]) {
              //si je peux gagner il FAUT jouer là
              //si ça lui permet de gagner il NE FAUT PAS jouer là
              this.grille[qui] &= ~(1 << place);
              return (qui == 1) ? 1 : -1;
            }
          }
          //si je ne peux ni gagner ni empêcher de gagner on regarde le coup suivant
          var scoreNext = new Array();
          for (var i=0; i<9; i++) {
            if ((this.grille[0] | this.grille[1]) & (1 << i)) continue;
            scoreNext.push([i, this.bienLaCase(i, 1-qui)]);
          }
          this.grille[qui] &= ~(1 << place);
          if (scoreNext.length == 0) return 0;
          scoreNext.sort(function (a, b) {return b[1]-a[1];});
          if (qui == 1) scoreNext.reverse();
          return scoreNext[0][1];
        }
     
        function AI_restart() {
          this.grille = new Array(0, 0);
        }
     
        function AI_new(callPlay) {
          this.winCombi = new Array();
          this.doPlay = callPlay;
          this.played = AI_played;
          this.joue = AI_joue;
          this.bienLaCase = AI_bien;
          this.restart = AI_restart;
     
          this.winCombi.push(7, 7 << 3, 7 << 6, 73, 73 << 1, 73 << 2, 273, 84);
        }
     
        function init() {
          morpion = new morpion_grille(3, nodeGratte = document.getElementById('morbac'),
            document.getElementById('nbParties'),
            document.getElementById('nbGagne1'),
            document.getElementById('nbGagne2'),
            document.getElementById('nbNuls'));
          var cases = nodeGratte.getElementsByTagName('td');
          for (var i=0; i<cases.length; i++) {
            cases[i].onclick = new Function("morpion.joue("+i+")");
          }
     
          AI = new AI_new([morpion, 'joue']);
          //AI2 = new AI_new([morpion, 'joue']);
          morpion.onplay1 = [AI, 'played'];
          //morpion.onplay2 = [AI2, 'played'];
          morpion.onnew = [AI, 'restart'];
          //morpion.onnew = function () { AI.restart(); AI2.restart();};
          morpion.joueur2 = [AI, 'joue'];
          //morpion.joueur1 = [AI2, 'joue'];
          morpion.newPartie();
        }
        </script>
      </head>
      <body onload="init()">
        <div>Nombre de parties joués : <var id="nbParties">0</var></div>
        <div>Nombre de parties gagnés par <em>vous</em> : <var id="nbGagne1">0</var></div>
        <div>Nombre de parties gagnés par <em>l'autre</em> : <var id="nbGagne2">0</var></div>
        <div>Nombre de matchs nuls : <var id="nbNuls">0</var></div>
        <table id="morbac">
          <tr>
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
          <tr>
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
          <tr>
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
        </table>
      </body>
    </html>
    Celui là est théoriquement imbattable.
    De plus il est facilement adaptable pour une grille plus grande.
    (Le constructeur grille lui il suffit de lui passer les bons paramètres pour qu'il s'adapte tout seul)

    Après quelques recherches il semblerait que j'ai réinventé l'algo du MinMax.
    Moi qui voulais juste attribuer un score à chaque coup jouable voilà qu'on me parle d'heuristique...

    Je vais essayer d'accélérer la recherche avec le MinMax2 http://bertoul.com/index.php?link=minmax

  18. #18
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    Tien JT un autre bug dans ton AI.
    Quand c'est ton AI qui commence et que je joue la séquence suivante (0 = première case) : 7, 2, 3, 6. L'AI gagne, mais dit "match nul".

    Je suis en train de faire jouer mon AI contre la tienne. (2 onglets d'ouvert et je joue sur l'un ce que l'AI à joué sur l'autre). Mon AI viens de gagner une partie.

  19. #19
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    ça m'étonnerait!

    quand je joue 7-2-3, l'ordi gagne et ça s'arrête là!

    mais aujourd'hui t'as raison, il m'a semblé avoir un message aberrant de ce genre

    jolie ton AI 8)

  20. #20
    Membre émérite
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Par défaut
    Tu as raison ça commence pas par 7 mais 8, la partie qui fait buger est donc 8, 2, 3, 6.


    jolie ton AI 8)
    Au niveau du code, de l'algo ou au niveau de la façon dont elle joue ?

    La prochaine fois que tu donnes un défis de ce genre il faudrai que tu code avant une interface de jeu pour que tout le monde parte sur les mêmes bases et pouvoir ensuite faire s'affronter les AI.
    Mon constructeur grille par exemple est totalement indépendant de l'AI.
    Il va appeller une fonction ou une méthode défini par l'utilisateur à chaque fois que l'autre joueur a joué un coup ou quand on lui demande de jouer.
    Et aussi pour quand on doit réinitialiser la partie.
    (méthodes onplay, onnew et joueur2)

    Je vais essayer d'intégrer mon AI dans ton jeu pour les faire jouer ensemble automatiquement. Ça m'a l'air plus simple que de faire le contraire.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 4 PremièrePremière 1234 DernièreDernière

Discussions similaires

  1. Défi : La chanson qui vous reste en tête !
    Par Hikage dans le forum La taverne du Club : Humour et divers
    Réponses: 527
    Dernier message: 27/02/2014, 22h35
  2. Le grand mode d'emploi du forum, à lire si vous souhaitez tout savoir !
    Par Anomaly dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 2
    Dernier message: 03/06/2013, 17h36
  3. Que pensez vous des défis ?
    Par ram-0000 dans le forum Défis C
    Réponses: 12
    Dernier message: 05/10/2009, 08h40
  4. [défi n°2] "Etes-vous String?"
    Par javatwister dans le forum Général JavaScript
    Réponses: 20
    Dernier message: 20/08/2005, 15h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo