ASP.NET
  Home arrow ASP.NET arrow Page 9 - .Netterpillars: Artificial Intelligence an...
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Mobile Linux 
App Generation ROI 
Windows Web Hosting
 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
ASP.NET

.Netterpillars: Artificial Intelligence and Sprites, Part 2
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 4
    2005-01-11

    Table of Contents:
  • .Netterpillars: Artificial Intelligence and Sprites, Part 2
  • The Branch Class
  • Main Program and GameEngine Class
  • Second Draft: Coding the Player Character
  • Main Program and GameEngine Class
  • Third Draft: Coding the Game Engine and Collision Detection
  • Fourth Draft: Coding the Config Screen and Game Over
  • Coding for the Introduction Screen
  • Final Version: Coding the Netterpillars AI
  • The Main Program: Final Version
  • Further Improvements

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    .Netterpillars: Artificial Intelligence and Sprites, Part 2 - Final Version: Coding the Netterpillars AI


    (Page 9 of 11 )

    To finish your game, you need to code the NetterpillarAI class and make the final adjustments in the Main procedure, as shown in the next sections.

    The Netterpillar AI Class

    As you decided in the game proposal and in the game project, you only need to use a simple form of artificial intelligence. Just avoid walls and eat mushrooms if they are near, that’s all.

    public class AINetterpillar : GameEngine {
      private int RandomPercent = 5;
      public Sprite.CompassDirections
        ChooseNetterpillarDirection
         
    (Point CurrentLocation, Sprite.CompassDirections
           CurrentDirection) {…}
      public Sprite.CompassDirections
        RandomDirection (Point CurrentLocation,
          Sprite.CompassDirections ChoosCompassDirections){…}
    }

    Let’s review what the game objects are.

    protected enum GameObjects {
      Mushroom = 0,
      Empty = 1,
      Branch = 2,
      Netterpillar = 3
    };

    Not by accident, when you define this enumeration, you put the game objects in ascending order of collision preference. When you check the objects around you, the lowest value is the preferred one: A mushroom is better than empty space, and both are preferable to a collision resulting in death. You can use this to your advantage, to ease the choice of the best object by checking the lowest value (with the min function) from the positions around the current position of the netterpillar’s head.

    BestObject = (GameObjects)Math.Min(Math.Min(Math.Min(
    (int)GameField[CurrentLocation.X+1, CurrentLocation.Y],
    (int)GameField[CurrentLocation.X-1, CurrentLocation.Y]), (int)GameField[CurrentLocation.X, CurrentLocation.Y+1]), (int)GameField[CurrentLocation.X, CurrentLocation.Y-1]);

    Once the best object has been chosen, you can check it against the next object in the current direction; and if they are the same (there can be two or more optimal objects), you choose to stay in the current direction to make the netterpillar’s movement less erratic.

    One last step is to add some random behavior to make the movement less predictable and less prone to getting stuck in an infinite loop; for example, the netterpillar could move in circles around the game field forever if there’s no aleatory component. In your tests, anything greater than 10 percent randomness can lead to erratic behavior (remember, you choose a new direction many times a second); a value between 0 and 5 generates good results.

    public Sprite.CompassDirections ChooseNetterpillarDirection
      (Point CurrentLocation, Sprite.CompassDirections
          CurrentDirection) {
      Sprite.CompassDirections
          ChooseNetterpillarDirection_result =
        (Sprite.CompassDirections)0;
      GameObjects BestObject;
      GameObjects NextObject = (GameObjects)0;

      switch(CurrentDirection) {
        case Sprite.CompassDirections.East:
          NextObject = GameField[CurrentLocation.X+1, 
            CurrentLocation.Y];
          break;
        case Sprite.CompassDirections.West:
          NextObject = GameField[CurrentLocation.X-1,
            CurrentLocation.Y];
          break;
        case Sprite.CompassDirections.South:
          NextObject = GameField[CurrentLocation.X,
            CurrentLocation.Y+1];
          break;
        case Sprite.CompassDirections.North:
          NextObject = GameField[CurrentLocation.X,
            CurrentLocation.Y-1];
          break;
      }

      //Pick the lowest value - Mushroom or empty.
      BestObject = (GameObjects)Math.Min(Math.Min(Math.Min(
      (int)GameField[CurrentLocation.X+1, CurrentLocation.Y],
      (int)GameField[CurrentLocation.X-1, CurrentLocation.Y]),
      (int)GameField[CurrentLocation.X, CurrentLocation.Y+1]),
      (int)GameField[CurrentLocation.X, CurrentLocation.Y-1]);

      // If the current direction is the best direction, stay
         in current direction.
      if (NextObject==BestObject) {
        ChooseNetterpillarDirection_result = CurrentDirection;
      }
      else {
        // Select the direction of the best object.
        if (BestObject == GameField[CurrentLocation.X+1, 
            CurrentLocation.Y]) {
          ChooseNetterpillarDirection_result =
            Sprite.CompassDirections.East;
        }
        else if (BestObject == GameField[CurrentLocation.X-1,
                 CurrentLocation.Y]){
          ChooseNetterpillarDirection_result =
            Sprite.CompassDirections.West;
        }
        else if (BestObject == GameField[CurrentLocation.X,
                 CurrentLocation.Y+1]){
          ChooseNetterpillarDirection_result =
            Sprite.CompassDirections.South;
        }
        else if (BestObject == GameField[CurrentLocation.X,
                 CurrentLocation.Y-1]){
          ChooseNetterpillarDirection_result =
            Sprite.CompassDirections.North;
       }
      }

      ChooseNetterpillarDirection_result = RandomDirection
        (CurrentLocation, ChooseNetterpillarDirection_result);
      return ChooseNetterpillarDirection_result;
    }



    To code the RandomDirection method, called in the last line of the preceding code, you’ll simply pick a random number from 0 to 100, and if it’s less than the RandomPercent property, choose a new movement direction for the netterpillar. The next code sample presents the full code for this method.



    private static Random rand = new Random();
    public Sprite.CompassDirections RandomDirection
      (Point CurrentLocation, Sprite.CompassDirections
       ChoosCompassDirections) {
      Sprite.CompassDirections RandomDirection_result;
      int x = rand.Next(0, 100);

      RandomDirection_result = ChoosCompassDirections;
      if (x<RandomPercent) {
        switch(ChoosCompassDirections) {
          case Sprite.CompassDirections.East:
            // Try the other directions.
            if (GameField[CurrentLocation.X,
                CurrentLocation.Y+1]<=GameObjects.Empty) {
              RandomDirection_result =
                Sprite.CompassDirections.South;
            }
            else if(GameField[CurrentLocation.X,
                    CurrentLocation.Y-1]<=GameObjects.Empty) {
                   RandomDirection_result =
                     Sprite.CompassDirections.North;
            }
            else if(GameField[CurrentLocation.X-1,
                    CurrentLocation.Y]<=GameObjects.Empty) {
                   RandomDirection_result =
                     Sprite.CompassDirections.West;
            }
            break;
          case Sprite.CompassDirections.West:
            // Try the other directions.
            if (GameField[CurrentLocation.X,
                CurrentLocation.Y+1]<=GameObjects.Empty) {
              RandomDirection_result =
                Sprite.CompassDirections.South;
            }
            else if(GameField[CurrentLocation.X,
                    CurrentLocation.Y-1]<=GameObjects.Empty) {
                   RandomDirection_result =
                     Sprite.CompassDirections.North;
            }
            else if(GameField[CurrentLocation.X+1,
                   
    CurrentLocation.Y]<=GameObjects.Empty) {
                   RandomDirection_result =
                     Sprite.CompassDirections.East;
            }
            break;
          case Sprite.CompassDirections.North:
            // Try the other directions.
            if (GameField[CurrentLocation.X,
                CurrentLocation.Y+1]<=GameObjects.Empty) {
              RandomDirection_result =
                Sprite.CompassDirections.South;
            }
            else if(GameField[CurrentLocation.X+1,
                    CurrentLocation.Y]<=GameObjects.Empty) {
                   RandomDirection_result =
                     Sprite.CompassDirections.East;
            }
            else if(GameField[CurrentLocation.X-1,
                    CurrentLocation.Y]<=GameObjects.Empty) {
                   RandomDirection_result =
                     Sprite.CompassDirections.West;
            }
            break;
          case Sprite.CompassDirections.South:
            // Try the other directions.
            if (GameField[CurrentLocation.X,
                CurrentLocation.Y-1]<=GameObjects.Empty) {
              RandomDirection_result =
                Sprite.CompassDirections.North;
            }
            else if(GameField[CurrentLocation.X+1,
                    CurrentLocation.Y]<=GameObjects.Empty) {
                   RandomDirection_result =
                     Sprite.CompassDirections.East;
            }
            else if(GameField[CurrentLocation.X-1,
                    CurrentLocation.Y]<=GameObjects.Empty) {
                   RandomDirection_result = 
                     Sprite.CompassDirections.West;
            }
            break;
        }
      }
      return RandomDirection_result;
    }

    Since the code in the GameEngine is intended to take care of the game’s physics (for example, it moves the netterpillars, regardless of whether one is changing direction), you’ll have to put the code for moving the netterpillars based on the AI outside the game engine object; your Main procedure is the best option.

    Another valid approach would be to include the AI code inside the Netterpillar object—it’s just a matter of choice: a small number of bigger classes or many smaller ones.

    This chapter is from Beginning .NET Game Programming in C# by Ellen Hatton et al. (Apress, 2004, ISBN: 1590593197). Check it out at your favorite bookstore today. Buy this book now.

    More ASP.NET Articles
    More By Apress Publishing


     

    ASP.NET ARTICLES

    - Developing a Mini ASP.NET AJAX Server Centri...
    - Disadvantages of the ASP.NET MVC Framework
    - Advantages of the ASP.NET MVC Approach
    - ASP.NET Web Forms Weaknesses
    - ASP.NET Web Forms Meets ASP.NET MVC
    - Source Code for Saving and Retrieving Data w...
    - Using GridView to Save and Retrieve Data wit...
    - Handling Dynamic Images in ASP.NET 3.5 AJAX ...
    - Retrieving Data with AJAX and the GridView C...
    - Playing with Images in ASP.NET 3.5 AJAX Appl...
    - Saving and Retrieving Data with AJAX
    - Enhancing PHP Via the ASP.NET AJAX Framework...
    - Enhancing PHP Programming with the ASP.NET A...
    - Classes and ASP.NET AJAX
    - Using ASP.NET AJAX

     
    Best Practices for Windows Vista Migration Presentation
    Dell and Microsoft recently held a series of face-to-face seminars entitled, &qu....

     
    Creating a Culture for Code Reuse
    If you oversee development teams you know that like it or not proprietary and ex....

     
    Keys to Web Application Acceleration: Advances in Delivery Systems
    Accelerate Web apps by up to 5x. Ensure significantly faster access to the Web a....

     
    Optimizing Application Monitoring
    Tired of finding out from your customers that you're offline? This white paper e....

     
    Solaris to Solaris Migration -- Migrating applications from Sun SPARC to Dell PowerEdge R900
    This comprehensive Migration Guide reviews the approach that Principled Technolo....

     




    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway
    Stay green...Green IT