Hello!
This is my first thread here, so douzo yoroshiku
I have started to learn programming and game design as a hobby not long ago, and I’m working on my first ever puzzle game using Monogame. The game logic is fairly simple:
- The game consists of a 5x7 board.
- At the start of the game, a setpiece is added on each of the 35 board tiles.
- All of the setpieces a “type” randomly assigned from these five:
fire,
water,
nature,
stone,
gem (currently represented by a star, don’t ask me why). - The player can move any of the pieces from its current tile to one of the four directly neighbouring tiles (above, below, left, right). The moved setpiece is then swapped with the setpiece from that tile.
- If moving the pieces creates a chain of 5 or more neighbouring pieces of the same type, these pieces will be “replaced” with pieces of a new type (in fact the chained pieces are simply assigned a new type, bc. I did not want to create too much garbage).
- The player receives points and extra time for each of the “replaced” pieces.
The gameboard looks like this:
My current problem is with point 5 of the game logic, that is properly counting and clearing the chained pieces. At the moment, when a setpiece is dropped on the board, I call a function like this:
public void CountChain()
{
/// <summary>
/// Checks how many pieces of the same type are in a chain (situated next to each other)
/// </summary>
int currentChain = 0;
int iterations = 23;
// Checks the dropped piece for the neigbouring pieces.
AddNeighbouringPieces(addToChain);
while (iterations > 0)
{
// Checks each of the chained pieces for more neighbouring pieces.
foreach (SetPiece s in chainedPieces)
{
s.AddNeighbouringPieces(addToChain);
}
// Adds pieces from the addToChain list to the chainedPieces list, if it does not already contain these pieces.
foreach(SetPiece s in addToChain)
{
if(!chainedPieces.Contains(s))
{
chainedPieces.Add(s);
}
}
iterations -= 1;
}
// If iterations complete, counts the chained pieces.
if(iterations == 0)
{
currentChain = chainedPieces.Count();
// If chain longer than the minimum required, calls ReplacePieces for all the chained pieces.
if (currentChain >= minChain)
{
Debug.WriteLine("cleared pieces = " + currentChain + " of type:" + type.ToString());
ReplacePieces(chainedPieces, currentChain);
}
addToChain.Clear();
chainedPieces.Clear();
}
}
public void AddNeighbouringPieces(List<SetPiece> addToChain)
{
// Adds neighbouring pieces to the addToChain list, from which they are later added to the chainedPieces list.
foreach (SetPiece s in content.board.setPieces)
{
if (isNeighboring(currentTile, s.currentTile) && s.type == type && !addToChain.Contains(s))
{
addToChain.Add(s);
}
}
}
As you can see I am using two different lists here - chainedPieces to store all the pieces in the chain, and addToChain, to store the neighbouring pieces of the given piece, which are later added to the chainedPieces list. I did this because obviously I cannot add pieces directly to the chainedPieces list while looping through that list in the foreach loop. However, this seems to me like a very roundabout way to do something simple? Is there a less convoluted way to do something like this?
Also, I think am getting some corner issues, with pieces being replaced when they should not actually be replaced, since they are not part of a 5+ chain. It’s hard for me to pinpoint exactly when the issue occurs, I think I will need to record a couple of playthroughs of the game to detect that, but I suppose if anything, the issue stems from my mistake in the function above. I’m just not sure what it is.
Help?