Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Board game pawn movement algorithm

Tags:

c#

algorithm

wpf

I've been working on a board game with a friend of mine. We have managed to get most of it working. The game is called 'jeu de barricade'. Maybe you know it.

The whole board gets created using a Linked List so every field has a 'LinkNorth', 'LinkEast', 'LinkSouth' and 'LinkWest' variable.

Here is the board to give you an idea of how it looks like.

Board Screen
Now, there is one thing we just can't seem to figure out how to do. Currently, a pawn can be selected, and it can be moved to any field on the board. This of course is not good. What we need to do now, is write a method with some sort of algorithm that returns an array or list of the fields the pawn is able to move to. This way, we can check if the selected pawn is actually able to move to the field you clicked on, with the thrown dice number. (a random number from 1 till 6 is generated)
One more thing though. Every 'Field' class has a barricadePawn variable. When this variable contains a barricadePawn object. (barricadePawn != null) the pawn should not be able to move over it. The pawn should be allowed to move onto that field, but not any further. (when the player lands exactly on a barricade, he can move it. But we already implemented that, so don't worry about that)

So, in short.
- I want to create a method in our 'Pawn' class, which returns an array or list of all the fields that the pawn should be able to move to.
- The pawn should be able to move on barricades but NOT over them.
- The pawn has to move exactly the amount thrown by the dice. So, to get on the finish or on a barricade, you have to throw exactly the right amount.

We have these in our 'Pawn' class:
'currentLocation' contains the field that the selected pawn is currently standing on.

private Model.Field startLocation;
private Model.Field currentLocation; 

public List<Model.Field> getPossibleMoves(Model.Field curSpot, int remainingMoves, List<Model.Field> moveHistory)
    {
        List<Model.Field> retMoves = new List<Model.Field>();
        if( remainingMoves == 0 )
        {
            retMoves.Add(curSpot);
            return retMoves;
        }
        else
        {
            moveHistory.Add(curSpot);
            if( curSpot.LinkNorth != null && !moveHistory.Contains(curSpot.LinkNorth) )
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkNorth, remainingMoves - 1, moveHistory ));
            }

            if (curSpot.LinkEast != null && !moveHistory.Contains(curSpot.LinkEast))
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkEast, remainingMoves - 1, moveHistory ));
            }

            if (curSpot.LinkSouth != null && !moveHistory.Contains(curSpot.LinkSouth))
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkSouth, remainingMoves - 1, moveHistory ));
            }

            if (curSpot.LinkWest != null && !moveHistory.Contains(curSpot.LinkWest))
            {
                retMoves.AddRange( getPossibleMoves( curSpot.LinkWest, remainingMoves - 1, moveHistory ));
            }
        }
    }

And this is our 'Field' class:

public class Field
    {
        protected Field linkNorth, linkEast, linkSouth, linkWest;
        protected Controller.Pawn pawn;
        protected Model.BarricadePawn barricadePawn;
        protected int x, y;

        //Properties:
        public Field LinkNorth
        {
            get { return linkNorth; }
            set { linkNorth = value; }
        }
        public Field LinkEast
        {
            get { return linkEast; }
            set { linkEast = value; }
        }
        public Field LinkSouth
        {
            get { return linkSouth; }
            set { linkSouth = value; }
        }
        public Field LinkWest
        {
            get { return linkWest; }
            set { linkWest = value; }
        }
        public Controller.Pawn Pawn
        {
            get { return pawn; }
            set { pawn = value; }
        }
        public BarricadePawn Barricade
        {
            get { return barricadePawn; }
            set { barricadePawn = value; }
        }
        public int X
        {
            get { return x; }
            set { x = value; }
        }
        public int Y
        {
            get { return y; }
            set { y = value; }
        }
    }

If anyone could help us with this, it would be much appreciated. We haven't been able to come up with anything.

like image 442
Snowy007 Avatar asked Mar 14 '13 17:03

Snowy007


1 Answers

Try creating a recursive method.

List<Spot> CheckMoves(Spot curSpot, int remainingMoves, List<Spot> moveHistory)
{
    List<Spot> retMoves = new List<Spot>();
    if( remainingMoves == 0 )
    {
        retMoves.Add(curSpot);
        return retMoves;
    }
    else
    {
        moveHistory.Add(curSpot);
        if( !moveHistory.Contains(Spot.North) )
        {

            retMoves.AddRange( CheckMoves( Spot.North, remainingMoves - 1, moveHistory );
        }
        /* Repeat for E, W, S */
    }
}

This will return a List (where spot is the class that represents a position on the board) that contains all potential final positions. Of course you'll need to be a bit more thorough in making sure the Spot.North is a valid spot, but this is a basic idea for you.

The method above won't allow the user to move into the same spot twice in a single move, but doesn't look for barricades or other obstructions. It also doesn't handle any spots which halt movement or have no possible movement in a particular direction.

It should, however, give you an idea of how it should go.

like image 174
Jeff Avatar answered Oct 23 '22 23:10

Jeff