Construire un jeu de dominos-modélisation et mise en page


J'ai commencé à faire un jeu de domino simple. (celui où vous placez les tuiles avec les mêmes numéros les uns à côté des autres). J'ai commencé à le modéliser et je semble avoir atterri dans un endroit difficile maintenant. Im modélisant le domino réel (appelé "os"):

namespace DominoCore
{
    public enum BoneOrientation { Horizontal, Vertical }

    public interface IBone
    {
        int FirstValue { get; }
        int SecondValue { get; }
        BoneOrientation Orientation { get; set; }
    }
}

Après ce type, je dois les disposer sur le terrain de jeu. J'ai fait un terrain de jeu avec des tuiles carrées:

namespace DominoCore
{
    public interface IField
    {
        IPlayer FirstPlayer { get; }
        IPlayer SecondPlayer { get; }
        IBoneYard BoneYard { get; }
        List<ITile> Tiles { get; }

        void PlaceBone(IPlayer player, IBone bone, int startX);
    }
}

Le terrain de jeu a deux joueurs et un Boneyard (les dominos non donnés aux joueurs) puis une liste de plitkami.

namespace DominoCore
{
    public enum BoneExpandDirection { Up, Down, Right, Left }

    public interface ITile
    {
        int X { get; }
        int Y { get; }
        IBone Bone { get; set; }
        BoneExpandDirection ExpandDirection { get; set; }
    }
}

Maintenant vient mes problèmes:,

  1. Si j'obtiens un domino (Os) avec la valeur de (1,3) et que je veux le placer sur le champ, comment puis-je représenter l'emplacement de l'endroit où il a été placé (par exemple, une tuile avec la coordonnée 5,5)
  2. La tuile domino s'étend-elle ensuite vers la droite à partir de 5,5?
  3. Et si je le tourne de 90 degrés, alors l'orientation est vers le haut, tournez - le de 180 degrés puis c'est vers la gauche-et la valeur est maintenant (3,1).
  4. Comment puis-je faire cela distinction entre mise en page, domino et tuile?

Je suppose qu'à un moment donné, j'ai besoin de comprendre, quand un joueur place une tuile - pour calculer si c'est légal (recherchez dans le champ des tuiles/os). Les différents placements du même domino / os sont illustrés dans l'image ci-dessous.

Le problème suivant est la disposition des dominos/os, je pense à faire une grille, mais cela ne correspond pas à placer une tuile "à travers" (perpendiculaire) d'autres dominos/os. Lorsque vous placez une tuile je suis de retour à la première problème: comment faire pour valider son statut juridique? comment trouver le domino avec lequel il borde?

J'espère que cela a du sens - j'ai du mal à décrire la mise en page et le problème de validation auquel je suis confronté.

Divers scénarios de domino

MODIFIER Au démarrage du jeu, les os en jeu sont:

[6,6] [6,5] [6,4] [6,3] [6,2] [6,1] [6,0]
[5,5] [5,4] [5,3] [5,2] [5,1] [5,0]
[4,4] [4,3] [4,2] [4,1] [4,0] 
[3,3] [3,2] [3,1] [3,0]
[2,2] [2,1] [2,0]
[1,1] [1,0]
[0,0]

Chaque tuile peut être inversée cela signifie que la tuile [6,3] peut également être retournée à 180 degrés et utilisée comme [3,6]

Author: Brian Hvarregaard, 2012-01-30

3 answers

Il semble qu'une grille soit une approche raisonnable, mais c'est une grille logique, et ne correspond pas directement à la disposition physique des tuiles. En supposant que la grille est une structure bidimensionnelle, à peu près

(0,0),(0,1),(0,2),(0,3)
(1,0),(1,1),(1,2),(1,3)
(2,0),(2,1),(2,2),(2,3)
(3,0),(3,1),(3,2),(3,3)

Ensuite, vous devez garder une trace de la cellule dans laquelle se trouve une tuile et de son orientation (un octet ou une énumération fera l'affaire ici, car il n'y a que 4 valeurs possibles). la vérification de la légalité est assez facile-en supposant que l'orientation est une énumération:

public enum BoneOrientation {
    Horizontal = 0
    Vertical = 1
    Reversed = 2
}

Et vous avez de la classe BonePlacement:

public class BonePlacement {
    public int X { get; set; }
    public int Y { get; set; }
    public BoneOrientation Orientation { get; set; }
    public IBone Bone { get; set; } 
}

Enfin,

// Assuming you have some `List<BonePlacement>` called placements
public boolean ValidNextMove(BonePlacement placement) {
    if (placements.Count == 0) return true; // presumably the first move is always allowed
    if ((placement.Orientation && BoneOrientation.Horizontal) == BoneOrientation.Horizontal) {
        // The move being tested is a horizontal placement
        if ((placement.Orientation && BoneOrientation.Reversed) == BoneOrientation.Reversed) {
            // The tile is reversed
            // Check for a neighboring tile in an acceptable configuration
        } else {
            // The tile is not reversed
            // Check for a neighboring tile in an acceptable configuration
        }
    } else {
        // The move being tested is a vertical placement
        if ((placement.Orientation && BoneOrientation.Reversed) == BoneOrientation.Reversed) {
            // The tile is reversed
            // Check for a neighboring tile in an acceptable configuration
        } else {
            // The tile is not reversed
            // Check for a neighboring tile in an acceptable configuration
        }
    }
}
 0
Author: Chris Shain, 2012-01-30 19:09:41

Qu'en est-il de relier les os ensemble?

public interface IBone
{
    int FirstValue { get; }
    int SecondValue { get; }
    BoneOrientation Orientation { get; set; }
    IBone left { get; set; }
    IBone right { get; set; }
    IBone upper { get; set; }
    IBone lower { get; set; }
}

Afin de déterminer les coordonnées des os, vous auriez alors besoin d'un algorithme récursif afin de traverser cette structure arborescente.

 1
Author: Olivier Jacot-Descombes, 2012-01-30 19:05:35

Il semble que votre grille devrait avoir une résolution minimale de .5*(longueur du côté court), en supposant que la longueur du côté long de l'os est un multiple de la longueur du côté court. Cela permettra toutes sortes de configurations de formes différentes telles que le scénario C.

Pour le dire différemment, utilisez une grille carrée, puis superposez des os de taille 2x4 sur cette grille.

Ensuite, vous devriez trouver une convention pour marquer l'emplacement des os, comme la main supérieure gauche coin. Par exemple, un Os avec des coordonnées (3,3) et une orientation verticale pourrait faire référence à un os vertical 2x4 dont la tuile la plus en haut à gauche se trouve à (3,3) sur la grille de la carte. L'Os jusqu'à (4,3) sur le droit, et (3,6) et (4,6) sur le fond.

Vous devrez ensuite exécuter une validation après le placement du bloc pour vous assurer que l'Os ne dépasse pas les bords droit ou inférieur du plateau de jeu.

Je ne connais pas les règles du jeu, mais cela pourrait aider à garder un IsFlipped bool propriété qui afficherait (1,3) différemment (1 avant 3 ou vice-versa) sans changer la représentation interne des valeurs de l'Os.

En ce qui concerne la notation, vous pouvez conserver certaines informations sur les os qui sont liés à d'autres dans votre implémentation Bone, et utiliser ces informations pour conserver un décompte en cours des scores lorsque les blocs sont placés, ou avoir un autre objet ruleset qui peut consommer une liste d'os et calucler un score à tout moment.

 1
Author: Chris Trombley, 2012-01-30 20:27:51