2009-06-17 8 views
3

Pour mon plaisir personnel, j'écris ce qui, je l'espère, constituera la base d'un jeu à venir plus tard. Au courant, je travaille sur le jeu "board". S'il vous plaît considérer les points suivants:Sélectionnez l'élément inconnu du tableau multidimensionnel à l'aide de LINQ

class Board 
{ 
    private Cube[,,] gameBoard; 
    public Cube[, ,] GameBoard { get; } 
    private Random rnd; 
    private Person person; 
    public Person _Person { get; } 

    //default constructor 
    public Board() 
    { 
     person = new Person(this); 
     rnd = new Random(); 
     gameBoard = new Cube[10, 10, 10]; 
     gameBoard.Initialize(); 
     int xAxis = rnd.Next(11); 
     int yAxis = rnd.Next(11); 
     int zAxis = rnd.Next(11); 

     gameBoard[xAxis, yAxis, zAxis].AddContents(person); 
    } 
} 

Et ceci:

class Person : IObject 
{ 
    public Board GameBoard {get; set;} 
    public int Size { get; set; } 
    public void Move() 
    { 
     throw new NotImplementedException(); 
    } 

    public void Move(Cube startLocation, Cube endLocation) 
    { 
     startLocation.RemoveContents(this); 
     endLocation.AddContents(this); 
    } 

    public Person(Board gameBoard) 
    { 
     Size = 1; 
     GameBoard = gameBoard; 
    } 

    public int[] GetLocation() 
    { 
     int[] currentLocation; 
     var location = 
      from cubes in GameBoard.GameBoard 
      where cubes.GetContents.Contains(this) 
      select cubes; 
    } 
} 

Je sais que ce qui est si mal il est probablement même pas drôle, mais c'est le plus rugueux des coupes grossières.

J'essaie d'obtenir GetLocation pour retourner l'index spécifique du Cube dans lequel se trouve le Person. Donc, si la personne est dans Board.GameBoard[1, 2, 10], je serai en mesure de récupérer cet emplacement (probablement comme int[] comme indiqué ci-dessus). Cependant, au cours, je suis incapable de compiler en raison de l'erreur suivante:

Could not find an implementation of the query pattern for source type 'Cubes.Cube[*,*,*]'. 'Where' not found.' 

Je me doutais bien que LINQ devrait pouvoir interroger des tableaux multidimensionnels, mais je ne l'ai pas trouvé aucune documentation sur la façon pour le faire.

Des suggestions, ou suis-je sur la piste complètement faux ici?

Répondre

8

LINQ ne voit pas les tableaux multidimentiels comme vous le souhaitez car ils n'implémentent pas IEnumerable<T> (bien que les tableaux à index unique le fassent, ce qui surprend les gens). Il existe plusieurs solutions de contournement: vous pouvez éviter LINQ pour la recherche dans le cube ou vous pouvez écrire votre propre méthode d'extension qui fait les promenades plus traditionnelles.

C'est un cas où je n'utiliserais pas LINQ faire pour la recherche, mais plus que cela je garderais probablement quelques références aux différentes pièces dans une structure simple (probablement un dictionnaire) qui est plus facile à mettre à jour et gérer. À titre d'idée, votre objet pièce connaîtrait il se trouverait sur le tableau lui-même et pourrait mettre à jour le cube lorsqu'il se déplacerait en se retirant d'une cellule et en s'ajoutant à une autre.

Il serait important de savoir si une seule cellule peut contenir plus d'une pièce: si c'est le cas, chaque cellule devrait également être une liste d'un certain type (cela apparaît ainsi dans votre code). Et une fois que vous en êtes arrivé là, s'il y a beaucoup moins de pièces de jeu que de cellules, je ne créerais probablement jamais le "cube" lui-même en tant que structure de données. Il serait dessiné et les pièces affichées via un algorithme de dessin d'ordre Z qui tirait directement de la liste des pièces, plutôt que d'un tableau. Cela dépendra du style de jeu: si les pièces ont des attributs et sont en petit nombre, cela fonctionnera. Si le jeu ressemble plus à 3D Go ou similaire, alors votre cube d'origine aurait du sens ... cela dépend vraiment de la «personnalité» (et donc des données) de vos pièces.

+1

Merci ... J'avais peur de ça. Et puis je trouve que j'ai seulement posé une partie de la question à laquelle j'ai besoin de la réponse. Oups. – AllenG

0

Il me semble beaucoup plus logique de déplacer la déclaration int [] currentLocation au niveau supérieur dans votre classe Person, et de fournir des méthodes getter/setter. Ensuite, chaque personne stocke son propre emplacement.

Pour le coût en mémoire de 3 ints, vous évitez d'avoir à interroger 1000 entrées de base de données chaque fois que vous souhaitez récupérer l'emplacement de la personne.

0

Je pense que la personne devrait dire au conseil où il est, ne pas demander au conseil. En d'autres termes, je voudrais créer une classe Location3D (x, y, z), l'utiliser dans une classe GamePiece dont toutes les autres choses sur la carte héritent. Cela stocke l'emplacement, puis chaque peece sait que c'est l'emplacement.

public class Location3D 
{ 
    public Location3D(int x, int y, int z) { X = x; Y = y; Z = z; } 
    public int X { get; set; } 
    public int Y { get; set; } 
    public int Z { get; set; } 
} 

public abstract GamePiece 
{ 
    public Location3d { get; set; } 

public class Person: GamePiece // inherit GamePiece 
{ 
    // everything else about Person 
} 

public class Board 
{ 
    public Board() 
    { 
    person = new Person(this); 
    rnd = new Random(); 
    gameBoard = new Cube[10, 10, 10]; 
    gameBoard.Initialize(); 
    int xAxis = rnd.Next(11); 
    int yAxis = rnd.Next(11); 
    int zAxis = rnd.Next(11); 

    var location = new Location3D(xAxis, yAxis, zAxis); 
    person.Location = location; 

    GetCubeAt(location).AddContents(person); 
    } 

    public Cube GetCubeAt(Location3D location) 
    { 
    return gameBoard[location.X, location.Y, location.Z]; 
    } 

    public Cube GetCubeAt(int x, int y, int z) 
    { 
    return GetCubeAt(new Location3D(x,y,z)); 
    } 
}