Question

For my own personal amusement, I'm writing what I hope will be the foundation of a game to come later. At current, I'm working on the game "board". Please consider the following:

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);
    }
}

And this:

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;
    }
}

I know this is so wrong it's probably not even funny, but this is the roughest of rough cuts.

I'm trying to get GetLocation to return the specific index of the Cube in which the Person is located. So that if the person is in Board.GameBoard[1, 2, 10] I'll be able to retrieve that location (probably as an int[] as listed above). However, at current, I'm unable to compile due to the following error:

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

I was pretty sure that LINQ should be able to query multi-dimensional arrays, but I haven't found any documentation on how to do it.

Any suggestions, or am I on the completly wrong track here?

Was it helpful?

Solution

LINQ does not see multidimential arrays as you want it to because they do not implement IEnumerable<T> (although single index arrays do, which is what surprises people). There are several workarounds: you can avoid LINQ for searching the cube or you can write an extension method of your own that does the more traditional walks.

This is a case where I wouldn't use LINQ do to the search, but more than that I probably would keep some references to the various playing pieces in a simple structure (probably a dictionary) that is easier to update and manage. As an idea, your piece object would know where it is on the board itself and could update the cube as it moved by removing itself from one cell and adding itself to another.

It would be important to know if a single cell can contain more than one piece: if so, each cell would need to be a list of some type as well (it appears that way in your code). And once you get to this point, if there are vastly fewer playing pieces than cells, I probably would never actually create the "cube" itself as a datastructure. It would be drawn and the pieces displayed via some Z order drawing algorithm that pulled directly from the piece list, rather than an array. This would depend on the style of game though: if the pieces have attributes and are small in number this would work. If the game is more like 3D Go or similar, then your original cube would make sense... it really depends on how much "personality" (and thus data) your pieces have.

OTHER TIPS

Makes a lot more sense to me to move the int[] currentLocation declaration to the top level inside your Person class, and provide getter/setter methods. Then each Person stores its own location.

For the memory cost of 3 ints, you save yourself from having to query 1000 database entries every time you want to retrieve the person's location.

I think the Person should tell the board where he is, not ask the board. In otherwords, I would create a Location3D class (x,y,z), use that in a GamePiece class that all other things on the board inherit from. That stores location, then each peice knows it's location.

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));
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top