Je débrouge actuellement ma table de transposition pour un moteur de variante d'échecs Veuillez ne pas suggérer que je devrais stocker par carte centrée au lieu de la pièce centrée sur la carte / fort>. Je dois stocker la liste des pièces en raison de la nature unique des pièces plafonnées et capturées. Les pièces de ces états sont comme si elles occupent une localisation de chevauchement et de position. S'il vous plaît regarder la description de la manière dont les pièces sont stockées forts>. p> une transposition Ce qui suit est un algorithme général bool operator==(const Position &b)
{
for (int i = 0; i < 32; i++)
if (piece[i] != b.piece[i])
return false;
return true;
}
7 Réponses :
Pourquoi ne pas conserver une chaîne de 64 octets dans votre base de données correspondant à la disposition de l'échiquier? Chaque type de pièce, y compris «Pas de pièce», représente une lettre (différentes capsules pour les deux couleurs, c'est-à-dire ABC pour Black, ABC pour blanc). La comparaison de la carte se résume à une comparaison de chaîne simple. p>
En général, la comparaison de la perspective de l'échiquier, au lieu du point de vue de la pièce, se débarrassera de votre problème de transposition! p>
Cela fonctionnerait pour les échecs traditionnels. Mais dans la variante des échecs que j'écris, pièces peut également être placable b>. Ce qui signifie que la solution de perspective de votre conseil ne fonctionnerait pas comme des pièces à placer ou qui étaient mortes ne serait pas répertoriée dans la chaîne de 64 octets. Le tableau ne contient pas toutes les données et mon problème est que la liste des pièces est plus difficile à détecter les transpositions b>.
Hm, dommage. Il y aurait toujours un moyen de contourner cela en ajoutant les 64 caractères de la Commission par une liste ordonnée de toutes les pièces mortes (c'est-à-dire AABAC). Mais peut-être que ça commence à devenir peu pratique? C'est un problème classique de Time de stockage VS Tradeoff.
Justin. Développez simplement la carte stockée pour permettre une zone de pièces «non placées» à l'extérieur du tableau.
@Esben: Cela ne fonctionnerait pas, sauf trier comme je l'ai mentionné, car cette zone non passée ressemble davantage à une piscine sans position.
Jochem. Définissez ensuite certains commandes standard. Ou juste les trier
Dans la perspective de la pièce, vous pouvez le faire:
for each color: for each piece type: start new list for board A for each piece of this piece type on board A add piece position to the list start new list for board B for each piece of this piece type on board B add piece position to the list order both lists and compare them
Encore une fois, cela ne fonctionnerait pas pour ma variante. Les morceaux sur la planche sont uniques, mais les pièces placables / capturées ne sont pas. Par exemple, le début du jeu commence avec toutes les valeurs "-2" (placement). Vous perdez les informations de type pièce des groupements d'index. Sans que la perte de 2 pions serait la même que la perte de 2 tevokes. De plus, l'idée de somme ne fonctionnera pas Voir ce .
L'idée de somme n'est pas d'exclure rapidement certaines commissions (comme on pouvait s'y attendre serait la case la plus courante). Parce que pour être égal, la somme devrait au moins être égale. Je pense que cela fonctionnerait, placable n'est qu'un autre index. Si vous avez un pion sur B2, la liste ordonnée rendra toujours -2, -2, -2, -2, -2, -2, -2, x (x étant l'indice B2). Dans votre question, vous avez dit -1 était placé mais d'accord.
Oui, les positions égales ont des sommes égales, mais l'inverse n'est pas vrai. De plus, ma solution simple peut déjà détecter des positions égales dans lesquelles les pièces ne sont pas transposées. Mais une transposition ne peut être détectée, et c'est ce dont j'ai besoin.
Donc, essentiellement une copie par morceaux, trier et comparer. Cela fonctionnerait, mais je cherche une solution sans copie / tri. Le coût unique pour cela n'est rien, mais plus de 100 000 personnes s'ajoute.
et une troisième option (j'espère vraiment que poster 3 réponses à une question est correcte, Stackoverflow-wise;)): P>
Gardez toujours vos morceaux du même type dans l'ordre d'index, c'est-à-dire que le premier pion dans la liste doit toujours avoir l'index le plus bas. Si un mouvement a lieu qui enfreint cela, passez simplement les positions de pions dans la liste. L'utilisation ne verra pas la différence, un pion est un pion. P>
Maintenant, lorsque vous comparez des positions, vous pouvez être sûr qu'il n'y a pas de problème de transposition et vous pouvez simplement utiliser votre boucle proposée. P>
Je ne pense pas que cela fonctionnerait car ma fonction de recherche est récursive et ne serait probablement pas en mesure de défaire le déménagement si je continue à échanger les morceaux. L'objet de déplacement utilise l'index pour faire / éteindre les mouvements. Vous ne faites que d'ajouter plus de frais généraux.
C'est une très bonne approche de la question comme demandé: plus généralement, lors de la comparaison des objets (tels que des positions du conseil) où il y a plus d'une représentation valide pour le même objet (en raison de la transposition, etc.), une stratégie puissante consiste à essayer de trouver Un représentant "canonique" - c'est-à-dire pour chaque position de la carte qui peut avoir de nombreuses représentations, en choisir un comme "droit", puis en comparant deux positions (ou à l'avance), transformez-les dans ce "droit" ("canonique") Représentation - De cette façon, s'ils ne comparent pas égaux, vous pouvez être certains sont des positions différentes.
BTW La récursion ne devrait pas être un problème (il suffit d'avoir une fonction qui déplace une pièce et met à jour la représentation, puis appelez-la une fois sur le chemin de déplacement d'une pièce, et de nouveau sur le point de passer pour le déplacer). Et dans la grande majorité des cas, la mise à jour est triviale - au plus échanger deux entrées - de sorte que les cas «durs» doivent être suffisamment rares pour en faire une victoire globale. Mais si vous êtes prêt à changer de représentation de votre conseil d'administration, la solution d'Amoss est meilleure et Mathieu PAGÉ explique comment utiliser le hachage pour la rendre encore plus efficace ...
@Justin: Alors, essayez de le faire fonctionner. Par exemple, chaque fois que vous construisez une nouvelle position (évoluant ou en arrière), vous pouvez vous assurer qu'il est en ordre canonique. Et, sérieusement, arrêtez de pleurer - vous consacrez plus de texte pour vous plaindre de la manière dont les idées de tout le monde ne pouvaient pas fonctionner pour vous que vous ne devez poser la question.
Compte tenu de votre choix de représentation de l'état du jeu, vous devez trier les indices des pions noirs, les indices de pions blancs, etc., d'une manière ou d'une autre. Si vous ne le faites pas au cours de la création d'un nouvel état de jeu, vous devrez le faire à la comparaison. Parce que vous n'avez besoin que de trier un maximum de 8 éléments, cela peut être fait assez vite. P>
Il y a quelques alternatives pour représenter vos états de jeu: P>
ou p>
Ces deux alternatives n'auraient pas de problème de transposition. P>
Quoi qu'il en soit, j'ai l'impression que vous tremblez avec des micro-optimisations lorsque vous devriez d'abord le faire fonctionner. P>
"Ne suggère pas que je devrais stocker par carte centrale au lieu de la pièce centrée sur la pièce". p>
Vous êtes si concentré sur ne pas le faire, que vous manquiez la solution évidente. comparer em> spécifique au tableau. Pour comparer deux listes de position Si après avoir retiré tous les éléments de Une optimisation consiste à vérifier les longueurs de l1 code> et
l2 code>, placez tous les éléments de
l1 code> sur une carte (temporaire). Ensuite, pour chaque élément de
L2 code>, vérifiez s'il est présent sur le tableau temporaire. Si un élément de L2 n'est pas présent sur la planche (et donc dans
l1 code>), renvoie inégal. p>
L2 code>, il reste des pièces à gauche sur la carte, puis
l1 code> doit avoir eu des éléments non présents dans
l2 code > et les listes sont égales.
l1 code> et
l2 code> ne sont égaux que lorsque la carte temporaire est vide par la suite. P>
l1 code> et
l2 code> premier. Non seulement cela va-t-il prendre de nombreuses divergences rapidement, il élimine également la nécessité de supprimer les elemetns de
L2 code> de la BAORD et du chèque "vide vide" à la fin. Cela n'est nécessaire que pour attraper le cas où
l1 code> est un véritable superset de
l2 code>. Si
l1 code> et
l2 code> ont la même taille, et
l2 code> est un sous-ensemble de
l1 code>, puis
l1 code> et
l2 code> doit être égal. p>
Cette réponse ne résout pas complètement le problème. (Je pense que cela peut être étendu à le faire sans trop de problèmes, mais à l'heure actuelle, il ne tient pas compte de la différence entre les pièces qui sont "placables" par rapport aux pièces "mortes" ...)
Il y a beaucoup de recherches effectuées sur les échecs informatiques et la manière de créer un hasch unique pour une position est un problème bien connu avec une solution universelle utilisée par pratiquement tous les moteurs d'échecs.
Ce que vous devez faire est d'utiliser hachage zobriste pour créer un unique (pas vraiment unique, mais nous verrons plus tard pourquoi ce n'est pas un problème en pratique) clé pour chaque position différente. algorithme appliqué aux échecs est expliqué ici . P>
lorsque vous démarrez votre programme Vous créez ce que nous appelons Zobrist Keys. Ce sont des entiers aléatoires de 64 bits pour chaque pièce / paires carrées. Dans C, vous auriez une matrice de 2 dimensions comme ceci: p>
// remove one pawn from the off-the-board boardHash = boardHash ^ offTheBoardZobKeys[WHITE_PAWN][numberOfWhitePawsOffTheBoard]; // Put a pawn on a2 boardHash = boardHash ^ zobKeys[WHITE_PAWN][A2];
J'utilise déjà une variante de hachage de Zobrist. Mais j'utilise Ajout / Sub à cause des pièces placables.
Je ne sais pas comment vous utilisez ajout / sous ... à la place de Xor? Mais vous avez simplement besoin de trouver un moyen de retrouver le statut des pièces «hors du conseil». Cela peut être fait avec l'algorithme habituel, j'ai expliqué une façon de le faire dans mon édition.
Votre principale objection à stocker les états sage est que vous avez un sac de pièces moins de position. Pourquoi ne pas maintenir un tableau + un vecteur de morceaux? Cela répondrait à vos besoins et il présente l'avantage de représenter une représentation canonique pour vos États. Par conséquent, vous n'avez pas besoin de tri et utilisez cette représentation en interne ou convertiez-la lorsque vous devez comparer:
Piece-type in A1 ... 63 more squares Number of white pawns off-board Number of black pawns off-board ... other piece types