Java - Why don't my mice move correctly?

时间:2015-07-28 22:18:54

标签: java methods interface abstract-class

I am currently working on a program that shows the movements of a critter in a field. The critters are marked by a char (example: 'M' for mouse) and each have their own way of movement. The method that I am having trouble with is a method that should make my Mouse critter move.

  • They should be moving in diagonals (NORTH then EAST or WEST. EAST, then NORTH or SOUTH) a certain amount of times and then changes diagonal directions.
    • The amount of times the mice move diagonally is controlled by myCount. if myCount is less than myTarget, then the mice should move diagonally. The mice change direction when myCount is equal to myTarget. Then myCount is set back to 0. I want my mice to move in a diagonal 8 times before changing diagonal directions.
  • However, instead my mice sometimes go diagonally for a little bit, but they always end up moving up then down or left then right over and over about 5 times.

Here is what my program's output looks like. (The S are stones that don't move, they are considered another critter in this case).

The interface:

public interface Critter
{
   public static final int NORTH = 0;
   public static final int WEST = 1;
   public static final int SOUTH = 2;
   public static final int EAST = 3;
   public static final int CENTER = 4;

   public char getChar();
   public int getMove(CritterInfo theInfo);
}

The abstract class:

public abstract class AbstractCritter implements Critter
{
   private char myCritterName;

   public AbstractCritter(final char theChar)
   {
      myCritterName = theChar;
   }
   public char getChar()
   {
      return myCritterName;
   }
}

The method I am having issues with:

import java.util.*;
public class Mouse extends AbstractCritter
{
   private int myDirection;
   private int myCount;
   private boolean myFirst;
   private int myTarget;
   private Random myRand;
   private int myCheck;

   public Mouse()
   {
      super('M');
      myRand = new Random();
      myDirection = myRand.nextInt(4);
      myCount = 0;
      myFirst = false;
      myTarget = 16;
      myCheck = 0;
   }
   public int getMove(CritterInfo theInfo)
   {
      if (myCount == myTarget)
      {
         myCount = 0;
         int direction = myRand.nextInt(4);
         myFirst = false;

      }
      int direction = myDirection;
      int direction2 = myRand.nextInt(4);
      myCount++;

      if (!myFirst)
      {

         myCheck = myRand.nextInt(2);
         if (myDirection == NORTH || myDirection == SOUTH)
         {
            if (myCheck == 0)
            {
               direction2 = EAST;
            }
            else
            {
               direction2 = WEST;
            }
         }
         else if (myDirection == EAST || myDirection == WEST)
         {
            if (myCheck == 0)
               {
                  direction2 = NORTH;
               }
               else
               {
                  direction2 = SOUTH;
               }
         }
         myFirst = true;
      }

      if (myCount % 2 == 0)
      {
         return direction;
      }
      else
      {
         return direction2;
      }
   }
}

1 个答案:

答案 0 :(得分:1)

If you create an enum to hold the two different states your mice can be in, it becomes much, much less confusing. Switch between the two states every 8 moves, and then use the enum itself to tell you which movement rules you should be using.

The key part of the logic is this line here:

int offset = 2 - ((index / 2) * 2);

Index will be 0,1 if the direction is NORTH, SOUTH, and it will be 2,3 if the direction is EAST, WEST. Dividing and then multiplying by two makes it be 0 for NORTH, SOUTH, and makes it be 2 for EAST, WEST. Then we use 2 - that value to flip it around, and then we add 1 randomly to choose an orthogonal direction again.

Here's the code:

import java.util.*;
public class Mouse extends AbstractCritter {
  private static final int[] allDirections = { NORTH, SOUTH, EAST, WEST };
  private static final Random myRand = new Random();

  private final int myTarget = 16;
  private int myCount = 0;
  private int firstDirection;
  private int secondDirection;

  public Mouse() {
    super('M');
    randomizeDirection();
  }

  public int getMove(CritterInfo info)
  { 
    myCount++;
    if(myCount == myTarget) {
      randomizeDirection();
      myCount = 0;
    }
    return myCount % 2 == 0 ? firstDirection : secondDirection;
  }

  private void randomizeDirection() {
    int index = myRand.nextInt(4);
    firstDirection = allDirections[index];
    int offset = 2 - ((index / 2) * 2); // this turns 0, 1 -> 2; 2, 3 -> 0
    secondDirection = allDirections[offset + myRand.nextInt(2)];
  } 
}