Selecione o item desconhecido do array multi-dimensional usando LINQ
-
06-07-2019 - |
Pergunta
Para a minha própria diversão pessoal, eu estou escrevendo o que eu espero que seja a base de um jogo para vir mais tarde. Na atual, eu estou trabalhando no "board" do jogo. Por favor, considere o seguinte:
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);
}
}
E esta:
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;
}
}
Eu sei que isso é tão errado provavelmente não é mesmo engraçado, mas este é o mais áspero de cortes irregulares.
Eu estou tentando obter GetLocation
para retornar o índice específico do Cube
em que o Person
está localizado. De modo que se a pessoa está em Board.GameBoard[1, 2, 10]
eu vou ser capaz de recuperar esse local (provavelmente como um int[]
conforme listado acima). No entanto, a atual, eu sou incapaz de compilar devido ao seguinte erro:
Could not find an implementation of the query pattern for source type 'Cubes.Cube[*,*,*]'. 'Where' not found.'
Eu tinha certeza de que LINQ deve ser capaz de consulta arrays multi-dimensionais, mas eu não encontrei qualquer documentação sobre como fazê-lo.
Todas as sugestões, ou estou no caminho completamente errado aqui?
Solução
LINQ não vê matrizes multidimential como você quer que ele porque não implementar IEnumerable<T>
(embora únicas matrizes índice fazer, que é o que surpreende as pessoas). Existem várias soluções alternativas: você pode evitar LINQ para procurar o cubo ou você pode escrever um método de extensão do seu próprio que faz os passeios mais tradicionais
Este é um caso em que eu não usaria LINQ fazer para a busca, mas mais do que eu provavelmente iria manter algumas referências para as várias peças do jogo em uma estrutura simples (provavelmente um dicionário), que é mais fácil de atualizar e gerenciar . Como uma idéia, o seu objeto parte saberia , onde é na própria placa e pode atualizar o cubo enquanto se movia, removendo-se de uma célula e adicionando-se a outro.
Seria importante saber se uma única célula pode conter mais de uma peça: em caso afirmativo, cada célula terá de ser uma lista de algum tipo assim (parece que forma em seu código). E uma vez que você chegar a este ponto, se há muito menos peças de jogo do que as células, eu provavelmente nunca realmente criar o "cubo"-se como uma estrutura de dados. Seria ser desenhado e os pedaços exibida através de algum algoritmo desenho ordem Z que puxado directamente a partir da lista de peças, em vez de uma matriz. Isso vai depender do estilo de jogo, porém: se as peças têm atributos e são pequenos em número que isso iria funcionar. Se o jogo é mais parecido com 3D Go ou similar, então o seu cubo original poderia fazer sentido ... ele realmente depende de quanta "personalidade" (e, portanto, de dados) suas peças têm.
Outras dicas
Faz muito mais sentido para mim para mover a declaração CurrentLocation int [] para o nível superior dentro de sua classe Person, e fornecer métodos getter / setter. Em seguida, cada pessoa armazena sua própria localização.
Para o custo de memória de 3 ints, você economiza-se de ter a consulta 1000 entradas de banco de dados cada vez que você deseja recuperar localização da pessoa.
Eu acho que a pessoa deve dizer a placa onde ele está, não peça do tabuleiro. Em outras palavras, eu iria criar uma classe Location3D (x, y, z), o uso que em uma classe GamePiece que todas as outras coisas no herdar bordo de. Que armazena localização, em seguida, cada pedaço sabe a sua localização.
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));
}
}