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  
Silverlight  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
ASP Web Hosting  
ASP.NET Web Hosting 
Windows Web Hosting
 
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

    - Develop Your First ASP.NET Website with Visu...
    - Run ASP.NET in Windows XP Home with Cassini ...
    - How to Test a Web Application
    - How to Add Code and Validation Controls to a...
    - Working in Source and Split Views to Build a...
    - How to Build a Web Form for a One-Page Web A...
    - How to Develop a One-Page Web Application
    - An ASP.NET Web Application in Action
    - Developing ASP.NET Web Applications
    - An Introduction to ASP.NET Web Programming
    - Introduction to the ADO.NET Entity Framework...
    - Completing an In-Text Advertising System und...
    - Programming an In-Text Advertising System un...
    - Building an In-Text Advertising System Under...
    - Developing a Mini ASP.NET AJAX Server Centri...





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