Dagaz: Horde

image Vous êtes des millions. Nous - l'obscurité et l'obscurité et l'obscurité.
Essayez-le, combattez-nous!
Oui, les Scythes - nous le sommes! Oui, les Asiatiques - nous ...

Alexander Block " Scythians "

Dans un article précédent , j'ai beaucoup parlé de mes découvertes dans le domaine de la conception et de l'interface utilisateur des jeux de société, mais j'ai dû interrompre cette histoire, vous pouvez dire au milieu, en partie à cause du volume important de l'article, en partie simplement parce qu'à ce moment-là je n'étais pas prêt à continuer suivant. Depuis lors, beaucoup de choses ont changé. De nouveaux problèmes intéressants ont été résolus et les jeux qui les ont générés (non moins intéressants) ont été ajoutés à la version . Je veux en parler aujourd'hui.


Si quelqu'un se souvient, il s'agissait du jeu " Abalon ", développé par Michel Lale et Laurent Levy en 1988. Son essence est de pousser les balles ennemies hors du terrain. Deux balles peuvent pousser une et trois balles - une paire de balles de couleur différente. Le joueur peut déplacer ses balles sur le plateau, une à la fois, ou en groupe, deux ou trois balles chacune (en plus, trois balles devraient constituer une «rangée»). Qu'est-ce qui m'a empêché de faire ce jeu la dernière fois?

Évidemment pas le mouvement de groupe lui-même. Le mouvement simultané de plusieurs pièces, en un seul mouvement, se fait même aux échecs ( roque ). Et les puzzles " Sliding puzzles " sont simplement construits pour garantir que ce mouvement se produit de manière synchrone et en douceur. Regardons un jeu développé par Robert Abbott en 1975:


Il ressemble à un Abalon. La seule différence est que la "rangée" ne "pousse" pas la pièce de l'adversaire de sa place, mais la retire simplement du plateau en utilisant une capture "d'échecs". La victoire est attribuée à l'un des joueurs qui a réussi à tirer plus sur la dernière rangée du plateau de ses pièces que son adversaire n'a réussi à le faire à ce moment-là. L'ensemble du jeu est construit sur des "lignes" mobiles. Il est peu probable qu'il réussisse à gagner uniquement des pièces solitaires. Voilà à quoi ressemble un simple mouvement de poussée.

Zrf
(define push-1 ( $1 (verify friend?) (while friend? cascade $1 ) (verify not-friend?) add )) 

Il s'agit de la cascade de mots magiques - elle oblige l'interprète à "libérer" la figure déplacée vers le champ actuel, en prenant "dans la main" une autre figure (ce n'est pas important pour elle-même ou pour l'adversaire) et continue de bouger, déjà avec la nouvelle figure "en main". En une seule opération, une telle opération peut être effectuée de manière répétée, déplaçant ainsi un nombre illimité de pièces à la fois. De tels cas (et un peu plus complexes) se retrouvent également dans d'autres jeux - " Guns ", " Dameo ", " Leutwayite Game ", ...


Du point de vue de l'interface utilisateur, les mouvements de «poussée» sont également mis en œuvre de manière assez triviale. L'étiquette familière du champ cible (cercle vert) apparaît sur la figure. Si (selon les règles du jeu) nous pouvons manger ce morceau - nous mangeons (capture d'échecs), sinon - nous poussons. Vous pouvez pousser une rangée et plus d'un champ en avant (comme dans le jeu Epaminondas). Bien sûr, coder un tel mouvement sera un peu plus compliqué:

Zrf
 (define push-2 ( $1 (verify friend?) (while friend? mark $1 (verify not-enemy?) to back cascade $1 ) $1 (verify not-friend?) add )) 

Le mot clé to (et son appariement à partir de ) agit en conjonction avec cascade . Cela signifie que le chiffre «hors de la main» doit être mis sur le plateau maintenant, et le nouveau chiffre «prendre dans la main» un peu plus tard, après avoir navigué vers un autre champ. En général, «pousser» les mouvements est simple, mais il existe un autre type de mouvement de groupe vers Abalon:


Je les appelle des mouvements "transversaux". Du point de vue du codage ZRF, il n'y a rien de compliqué en eux. Le problème est dans l'interface utilisateur. Comment «dire» au programme que le joueur veut déplacer non pas une balle, mais un groupe, si les deux mouvements sont autorisés par les règles? J'utilise le même «clignotement», qui m'a été si utile dans les dames, pour marquer le chiffre «actuel». Seulement maintenant, il y a plusieurs chiffres «actuels» dans l'ensemble.

Un clic sur une figure «libre» l'ajoute au groupe s'il y a un mouvement dans lequel toutes les figures ajoutées au groupe sont impliquées (il est encore plus facile de ne pas relâcher le bouton, mettant en surbrillance l'ensemble du groupe en un clic de souris). S'il n'y a pas de tels mouvements, seul un nouveau groupe est créé, composé jusqu'à présent d'une seule pièce. Les cercles verts sont toujours affichés pour le dernier chiffre ajouté (cela peut ne pas être très évident, mais vous pouvez vous y habituer). Un clic répété sur une figure «aveuglante» réinitialise immédiatement l'ensemble du groupe.

Au fait
Les cercles verts n'apparaîtront pas nécessairement simplement en présence de personnages «aveuglants». Dans certains cas, une situation est possible dans laquelle toutes les pièces sélectionnées sont incluses dans un mouvement valide, mais il n'y a pas de mouvement valide, limité à déplacer uniquement ces formes sélectionnées. Cela semble un peu déroutant, mais voici une illustration:


Dans ce jeu, seuls les mouvements simultanés de groupes de trois pièces sont autorisés (s'il reste moins de pièces, tout le monde devrait bouger). Toutes les figures sélectionnées se déplacent d'un pas et dans la même direction. Capture d'échecs, ses pièces interfèrent avec le mouvement. Pour gagner, vous devez tenir au moins une de vos pièces sur la dernière ligne, jusqu'au camp ennemi.

Le jeu lui-même, à mon avis, n'est pas très intéressant, mais, du point de vue du codage, c'est une vraie folie. Toute tentative de générer «honnêtement» tous les mouvements possibles de groupes de trois figures conduit à une explosion combinatoire. Vous devez tromper (l'avantage de Dagaz le permet). Pour commencer, nous générons tous les mouvements valides de pièces uniques. C'est simple:

 (define step ( $1 add )) 

Jusqu'à ce que vous puissiez même vérifier le combat possible de votre propre figure, tout cela plus tard! Nous allons simplement dans toutes les directions, dans la mesure du possible. Ensuite, activez la « magie ». Nous combinons simplement toutes les combinaisons possibles de trois mouvements de différentes pièces dans une seule direction, créant un produit cartésien. Après cela, nous rejetons les mouvements qui tombent sur nos propres pièces.

Pourquoi ne pas les déposer tout de suite? Pour une raison très simple - une pièce a le droit de se déplacer vers un champ occupé si elle est libérée dans le cadre du même mouvement de groupe, et au moment de générer les mouvements "élémentaires", il n'y a aucune information sur la composition des groupes déplacés! C'est pourquoi j'aime tellement ce projet. Lui, de temps en temps, jette des puzzles si intéressants ici!

Le déménagement ne doit pas avoir lieu sur un seul domaine, comme dans Abalone. Dans le jeu Ordo (et surtout dans Ordo X ), inventé par Dieter Stein en 2009, des groupes de personnages peuvent parcourir des distances bien plus grandes. La seule condition est que les pièces de leur couleur, à la fin du tour, ne soient pas séparées (c'est le même invariant du jeu que la nécessité pour le roi de laisser la menace aux échecs). Le joueur qui remporte la première ligne du plateau gagne.


Dans ce jeu, il y a des mouvements à la fois longitudinaux et transversaux des «rangées» de pièces de toute taille et à n'importe quelle distance (au sein du plateau, bien sûr). Il y a tellement de modèles utilisés pour générer des mouvements qu'il faut plus de 5 minutes pour traiter un fichier ZRF développé par moi avec un convertisseur (la plupart des jeux sont traités en quelques secondes)! On pourrait supposer que cela entraînerait des problèmes au stade de la génération des mouvements, mais ce n'est pas le cas. La grande majorité des coups est coupée par l' invariant du jeu.

Une autre tâche de réflexion sur le cerveau est apparue ici
Le fait est que le mécanisme d'alternance de la sélection des figures que j'ai développé pour effectuer un mouvement de groupe, d'une manière générale, est incompatible avec l'interface de «push» des mouvements, implémentée par les anciennes versions du contrôleur. C'est simple - pour faire un mouvement "poussant", vous devez sélectionner une figure qui a la capacité d'aller sur le terrain, occupée jusqu'à présent par une autre figure du groupe déplacé. Mais nous ne pouvons pas afficher son champ cible, car la formation du groupe n'est pas terminée, et le déplacement d'une seule figure vers le champ occupé est très probablement interdit par les règles du jeu.

En général, si tout se fait «selon les règles», il faut cliquer sur toutes les figures du groupe déplacé un par un et seulement après que l'interface affichera les champs cibles pour la dernière figure ajoutée. Même à Abalon, avec ses groupes de trois personnages maximum, c'est un peu fatiguant, mais à Ordo c'est généralement impensable! J'ai dû trouver une méthode spéciale qui «élargit» automatiquement le groupe lorsqu'il détecte les conflits décrits ci-dessus.

Voici à quoi ça ressemble pour l'ormeau
 Dagaz.Model.closure = function(board, move, group) { var r = []; _.each(group, function(pos) { r.push(pos); }); for (var i = 0; i < r.length; i++) { var pos = r[i]; _.each(move.actions, function(a) { if ((a[0] !== null) && (a[1] !== null) && (a[0][0] == pos)) { var p = a[1][0]; var piece = board.getPiece(p); if ((piece !== null) && (piece.player == board.player) && (_.indexOf(r, p) < 0)) { r.push(p); } } }); } return r; } 

Mais de longs mouvements de «poussée» sont autorisés dans Ordo et cet algorithme ne fonctionne pas! Peu importe - toutes les fonctions définies dans Dagaz.Model peuvent être redéfinies.

De cette façon
 Dagaz.Model.closure = function(board, move, group) { var design = board.game.design; var r = []; _.each(group, function(pos) { r.push(pos); }); for (var i = 0; i < r.length; i++) { var pos = r[i]; _.each(move.actions, function(a) { if ((a[0] !== null) && (a[1] !== null) && (a[0][0] == pos)) { var target = a[1][0]; var x = Dagaz.Model.getX(pos); var y = Dagaz.Model.getY(pos); var dx = sign(Dagaz.Model.getX(target) - x); var dy = sign(Dagaz.Model.getY(target) - y); var dir = design.findDirection(pos, pos + (dy * Dagaz.Model.WIDTH) + dx); if (dir !== null) { while ((pos !== null) && (pos != target)) { var piece = board.getPiece(pos); if ((piece === null) || (piece.player != board.player)) break; if (_.indexOf(r, pos) < 0) { r.push(pos); } pos = design.navigate(board.player, pos, dir); } } } }); } return r; } 

Cette surcharge est plus facile pour Takoka . Puisqu'il n'y a pas de mouvements "push" (il est toujours nécessaire de mettre clairement en évidence toutes les pièces incluses dans le groupe), il suffit de bloquer cette fonctionnalité, c'est-à-dire de ne pas étendre le groupe:

 Dagaz.Model.closure = function(board, move, group) { return group; } 

Je m'excuse pour le nom de la fonction qui ne dit rien à personne. Je ne pouvais tout simplement pas trouver un meilleur nom pour l'action.


Ce jeu implémente également le mouvement de groupe, mais ses mécanismes sont complètement différents! Ici, les chiffres se déplacent en groupes 3x3, de plus, les champs vides du groupe font également partie du «motif» déplacé. La présence de chiffres sur l'un des huit champs externes montre les directions dans lesquelles vous pouvez vous déplacer, et le remplissage du champ central détermine si vous pouvez déplacer le "motif" sur une distance arbitraire ou seulement courte, pas plus de 3 étapes. Pour gagner, il faut détruire "l'anneau" de l'ennemi - un analogue de la figure royale (c'est un champ vide, entouré de tous côtés par huit rempli). Vous devez faire très attention à ne pas détruire votre bague aussi.

GESS s'est avéré être un véritable cauchemar, à la fois en termes de " magie " et en termes de prototype lui-même - le squelette du jeu. Il suffit de dire que la carte (20x20, en tenant compte d'un certain nombre de champs en dehors de la carte) se compose de deux couches. La couche supérieure entière est entièrement remplie de formes invisibles qui contrôlent le mouvement. Le mouvement des pierres qui composent les «motifs» des joueurs ne sont que des effets secondaires de ces mouvements. Malheureusement, je n'ai pas encore réussi à développer un bot pour ce jeu.


À la fin de l'article, je veux vous présenter quelque chose d'autre qui n'est pas directement lié au sujet du mouvement de groupe des personnages. Ce jeu m'a demandé de faire l'un des abonnés à ma page de projet - Sultan Ratrout. En général, ce sont des dames de pilier ordinaires sur une planche hexagonale. Même sans les dames. Le concept de révolution est différent! Le terrain de jeu lui-même est transformable! Profitez-en.

Je pars en vacances ...

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


All Articles