Vendredi JS: jeu JS et CSS en ligne

Beaucoup d'anciens se souviendront peut-être d'une épidémie d'articles avec des titres comme "% quelque chose% dans 30 lignes de JS". Et aussi le post épique " Jeu en 0 lignes de code sur JS pur " qui a suivi, après quoi l'épidémie a brusquement décliné. Conscient que je ne dépasserais jamais ce chef-d'œuvre, j'ai néanmoins décidé cinq ans plus tard de terminer mes cinq cents.

Mesdames et Messieurs, nous vous proposons le jeu «Tic-Tac-Toe» à zéro lignes de JS, et aussi, contrairement au jeu mentionné ci-dessus, à zéro lignes de CSS (y compris les styles en ligne). Uniquement du HTML pur, du hardcore.


Lien vers le jeu

Cela a l'air moche, mais cela fonctionnera dans n'importe quel navigateur. Sous la coupe, je vais vous dire pourquoi le jeu sans JS était dans la section "Vendredi JS", ainsi que d'autres détails sales. Cependant, je n'ouvrirai l'Amérique à personne, si vous êtes un codeur expérimenté, vous ne pouvez même pas passer sous la coupe

En fait, tout est très stupide. Le jeu se compose de près de 6 000 pages de code HTML statique, reliant les uns aux autres. Lorsque vous piquez sur une cellule du terrain de jeu, vous accédez à la page où le déplacement vers cette cellule a déjà été effectué. Évidemment, écrire des pages de 6k avec vos mains est un plaisir en dessous de la moyenne. Par conséquent (surprise!) Les pages sont générées par des scripts JS utilisant NodeJS.

Digression lyrique
Après avoir écrit la ligne précédente, je me suis soudainement demandé si l'expression «JS-script» n'était pas une tautologie, comme «CD-ROM» ou «VIP-person». D'une part, cela semble l'être. D'un autre côté, JS n'est toujours pas une abréviation, mais une abréviation de nature légèrement différente. Cependant, le poste n'est toujours pas sur la philologie, car la digression lyrique se termine et l'attaque lyrique commence.

Tout d'abord, nous construisons le soi-disant arbre de jeu - la totalité de tous les états de jeu possibles et les transitions entre eux. L'état initial du jeu dans mon code est le suivant:

const initialState = { player: PLAYER_X, field: Array.from(Array(9)).map(() => EMPTY_CELL), moves: {} } 

Il contient des informations sur qui est maintenant le tour et quel est l'état du terrain de jeu. À l'avenir, il contiendra également des informations sur les mouvements qui peuvent être effectués et les états dans lesquels ils aboutiront, ainsi que d'autres choses agréables.

Ensuite, nous commençons, je m'excuse pour la tautologie, à partir de l'état initial et faisons ce qui suit:

  1. On vérifie si l'état est terminal (victoire des croix, victoire des jetons, nul).
  2. Si tel est le cas, ajoutez des informations à ce sujet à l'objet d'état et terminez.
  3. Sinon, parcourez toutes les cellules du champ.
  4. Pour chaque cellule vide du champ, créez un nouvel état de jeu dans lequel le joueur actuel a effectué un mouvement vers cette cellule et le mouvement a été transmis au joueur suivant.
  5. Dans le champ des moves de l'état actuel, ajoutez un enregistrement d'un mouvement possible. La clé de cette entrée est l'index de cellule et la valeur est le lien vers le nouvel état.
  6. Nous répétons cet algorithme récursivement pour tous les nouveaux états apparus.

En fait, mon code est un peu plus compliqué, j'ai par habitude déplié la récursivité dans une boucle, et au lieu de références à d'autres états lors des moves leurs clés de chaîne sont stockées dans un certain tableau associatif. Mais ce sont tous les détails.

Ensuite, à partir de chaque objet d'état du jeu, nous générons une page HTML. En parcourant l'objet de moves , nous remplissons les cellules vides du champ avec des liens vers les pages correspondant aux mouvements effectués dans ces cellules. Ensuite, nous transformons le tableau unidimensionnel du champ en un tableau HTML bidimensionnel. Nous ajoutons toutes sortes de choses agréables comme des instructions sur lesquelles le joueur marche et des liens vers la page d'accueil - et le tour est joué!

En plus du mode, lorsque les croix et les zéros sont placés par une personne, dans mon hit méga-indie, il y a aussi la possibilité de jouer contre le cerveau de fer. Ceci est réalisé comme suit:

  1. Premièrement, récursivement (en fait pas) pour chaque état de jeu, le résultat attendu du jeu est calculé - celui qui sera atteint si les deux parties jouent parfaitement.
  2. Ensuite, l'arbre de jeu est modifié comme suit: au lieu du coup du joueur, nous faisons maintenant deux coups à la fois. Le deuxième mouvement est le mouvement de l'intelligence artificielle. De plus, parmi toutes les réponses possibles au coup du joueur, celle avec le meilleur résultat attendu est sélectionnée. Ainsi, après avoir piqué sur une cage vide, le joueur se rend immédiatement à la position où une croix (ou zéro) est apparue dans cette cellule, et un zéro (ou croix) est apparu dans une autre cellule.
  3. Toutes les positions de jeu correspondant à des mouvements que l'IA ne fait pas sont rejetées sans pitié.
  4. Ensuite, le code HTML est généré à partir des positions restantes dans un dossier séparé - exactement le même que pour le cas de deux joueurs.

Par des principes similaires, vous pouvez implémenter n'importe quel jeu avec un arbre pas très grand. Cependant, si je veux faire des échecs de cette manière, il me semble que le github refusera d'héberger ceci =)

En parlant de github: vous pouvez y voir l'intégralité du code (le lien se trouve sur la page principale du jeu). Sur ce point, en général, c'est tout. Au revoir, filles et garçons. A bientôt.

PS Le remplacement des sauts de ligne du style Windows au style Unix est très long lorsqu'il s'agit de 6 000 fichiers. J'ai regretté de ne pas avoir pris soin de cela au stade de l'écriture du code, mais j'ai quand même courageusement enduré git add à la fin.

Source: https://habr.com/ru/post/fr419135/


All Articles