[comp.ai.neural-nets] Starting in AI

rs965275@longs.LANCE.ColoState.EDU (Robert Simmons) (11/15/90)

Hello,

this is my first attempt at an AI program.  I started this with only a 
chapter of reading in an CS book that had some AI explanations in it.
Since this school has limited resources in ai stuff, I have posted this
with a request that those who read it will mail me coments on this, my first 
attempt, program.  If there are any pfessors out there reading this I would
like some coments on some good ai schools (anywhere in the world!!) and some 
admission info.  I have been programing since I was youns and am very
interested
in the schools that offer good ai programs. I would like to hear about these
professors' schools.

Sincerely
Robert E. Simmons jr.

P.S. Even coments such as "this is an excelent start are solicited". also 
if anyone has modifications for the program, Please feel free to make them and
e-mail me the revised code!!

{
***************************************************************************
                          Program Puzzle Solver
***************************************************************************
}

{
***************************************************************************
                Hueristic Problem Solving Demonstration
                         by Robert Simmons jr.
***************************************************************************
     
     Problem Statement:   This Program will implement a heristic 
			  algorithm to solve a 10 x 10 tile puzzle.
			  The algorithm conststs of evaluating the
			  possible plays and choosing the best option.
			  Then the plays are added to the stack so the 
			  puzzle can be backed up and routed on another
			  option af equal value.

			  The search tree for the implementation of this
			  problem without heuristics would be on the 
			  average of 3^n nodes with n being the number 
			  of moves required to solve the puzzle while 
			  this heuristic method employs only one of the 
			  search paths.

			  The search tree imagined for the prob without 
			  heuristics might be represented as a triangle 
			  as follows:

					       *
                                             *****
                                           *********
                                         *************
                                       *****************
                                     *********************
                                  **************************
                                ******************************

                           when expanded out for the problem at hand the
			   triangle is bound to get big fast.  This 
			   program's heuristic cuts the triangle to the 
			   following:

                                               *
                                             -****
                                           ---******
                                         ----*********
                                       --------*********
                                     ---------------******
                                  ---------------------*****
                                ----------------------------**
                           
			   where - is a node not necessary to the solution.
			   One can rapidly see the advantage of fig2 
			   over fig1.

***************************************************************************

Diagnostics:   The program must be given valid input.  Since it was not 
	       designed with the general user in mind, it will not accept
	       bad data and will simply crash.

***************************************************************************









			    Variable Dictionary
                            -------------------
			       Main Program
			       ==== =======

      Variable                                        Definition
      --------                                        ----------

      Datapoint                              Type Pointer for the move stack. 
      Stack                                  Stack containing previous moves
					       and the flags for when the 
					       options are equally good.
      move                                   Field in Stack containing the 
					       previous moves.
      flag                                   Flag fo equal options.
      next                                   Link in list.
      Mattype                                Puzzle config. matrix. 
      Top                                    Pointer for the top of the stack.
      Last                                   Pointer to the next highest nod in
					       the stack.
      Firstmove                              Id to not allow exclusion of 
					       previous move.
      Upmv                                   Boolean for whether the move 
					       should be executed.
      Dwnmv                                  Boolean for whether the move
					       should be executed.
      Lftmv                                  Boolean for whether the move
					       should be executed.
      Rhtmv                                  Boolean for whether the move
					       should be executed.
      Upmove                                 Boolen for whether the move
                                               was excecuted.
      Dwnmove                                Boolean for whether the move
					       was be executed.
      Lftmove                                Boolean for whether the move
					       was be executed.
      Negup                                  Side, corner delimiter.
      Negdown                                Side, corner delimiter.
      Negleft                                Side, corner delimiter.
      Negright                               Side, corner delimiter.
      Setflag                                Flag for equal options.
      Perifery                               Boolean, for sides.
      Corner                                 Boolean for corners.
      Rhtmove                                Boolean for whether the move
				    	       was be executed.
      Upval                                  Entropy of Option matrix.
      Dwnval                                 Entropy of Option matrix.
      Lftval                                 Entropy of Option matrix.
      Rhtval                                 Entropy of Option matrix.
      Prmove                                 Inverse of previous move 
					       excecuted.
      Curstate                               Cuurent array Entropy.
      Cblx                                   X cord. for the blank.
      Count                                  Generic counter.
      Count2                                 Generic Counter #2.
      Cbly                                   Y cord. for the blank.
      Curpuzzle                              Current puzzle format.
      Uppuzzle                               Option puzzle format.
      Dwnpuzzle                              Option puzzle format.
      Lftpuzzle                              Option puzzle format.
      Rhtpuzzle                              Option puzzle format.

***************************************************************************
}
program puzsolve (input,output);

  type  Datapoint = ^Stack;                 { type declaration Block }
	Stack = record
	          move : integer;
	          flag : boolean; 
		  next : Datapoint;
                end; { Record Definition }
        Mattype = array [1..10,1..10] of integer; 
  
  var Top,
      Last                                 : Datapoint;
      Firstmove,
      Upmv,
      Dwnmv,
      Lftmv,
      Rhtmv,
      Upmove,
      Dwnmove,
      Lftmove,
      Negup,
      Negdown,
      Negleft,
      Negright,
      Setflag,
      Perifery,
      Corner,
      Rhtmove                               : boolean;
      Upval,
      Dwnval,
      Lftval,
      Rhtval,
      Prmove,
      Curstate,
      Cblx,
      Count,
      Count2,
      Cbly                                  : integer;
      Curpuzzle,
      Uppuzzle,
      Dwnpuzzle,
      Lftpuzzle,
      Rhtpuzzle                             : Mattype;
  
  
  {
  *************************************************************************
         Function to Evaluate the Entropy of an Input Matrix
  *************************************************************************
  }
  function enval ( Current : Mattype): integer;
    
    var Ycor,
	Xcor,
	Xloc,
	Yloc,
	Hold,
	Homeloc : integer;
    
    {
    **********************************************************************
          Function to Calculate the Absolute Value of a Number 
    **********************************************************************
    }
    function absolute (Argument : integer):integer;
      
      begin { Function }
	
        if Argument < 0 
	  then 
	    absolute := 0 - Argument
          else 
	    absolute := Argument;
      
      end; { Function }

    {
    **********************************************************************
                              Resume enval
    **********************************************************************
    }
    {
    This function calculates the entropy of an input matrix by incrementing
    the entropy value for how far each tile is out of position. 
    }
    begin 
      
      Hold := 0;
      for Ycor := 1 to 10 do
	begin
	  
	  for Xcor := 1 to 10 do
	    begin { For }
	      
	      Homeloc := Current[Ycor,Xcor];
	      Xloc := Homeloc mod 10;
	      if Xloc = 0
	        then 
		  Xloc := 10;
	      Yloc := Homeloc div 10 + 1; 
	      if Yloc = 0 
		then
		  Yloc := 1;
              if ((Homeloc mod 10) = 0)		
		then 
		  Yloc := Yloc - 1;
              if Homeloc = 0 
		then 
		  begin
		    
		    Xloc := Xcor;
		    Yloc := Ycor;
                  
		  end;

	      Hold := Hold + (absolute((Xcor-Xloc)) + absolute(Ycor - Yloc));
	    
	    end; { For }
        
	end; { For }
       
       enval := Hold;

    end;  { Procedure }

 

  {
  ************************************************************************
                         Procedure To Move the Tile
  ************************************************************************
  }
  procedure tilemove (var Tempmat : Mattype; Xblank, Yblank, Comand : integer);
    
     
    begin
      
      case Comand of
          
	  1 : begin {move tile under the blank up}
		
		Tempmat[Yblank,Xblank] := Tempmat[(Yblank + 1),Xblank];
		Tempmat[(Yblank + 1),Xblank] := 0;
                Yblank := Yblank + 1;

	      end;
          
	  2 : begin {move tile over the blank down}

		Tempmat[Yblank,Xblank] := Tempmat[(Yblank - 1),Xblank];
		Tempmat[(Yblank - 1),Xblank] := 0;
		Yblank := Yblank - 1;

	      end;
          
	  3 : begin {move tile to the left of the blank right}

		Tempmat[Yblank,Xblank] := Tempmat[Yblank,(Xblank - 1)];
		Tempmat[Yblank,(Xblank - 1)] := 0;
		Xblank := Xblank - 1;

	      end;
          
	  4 : begin {move tile to the right of the blank left}

		Tempmat[Yblank,Xblank] := Tempmat[Yblank,(Xblank + 1)];
		Tempmat[Yblank,(Xblank + 1)] := 0;
		Xblank := Xblank + 1;

              end
        
	end; { Case }

    end; { Procedure }

  {
  *************************************************************************
  Procedure to Backup Matrix to Last Flag
  *************************************************************************
  }
  procedure backtrack (var Newpuzzle:Mattype; Pop : Datapoint;
		       Xcord, Ycord : integer);
   
    var Previous : Datapoint;
        Prmove : integer; 
    begin 
      
       if (not (Pop^.flag)) 
	 then
	   begin
             
	     Prmove := Pop^.move;
             tilemove(Newpuzzle,Xcord,Ycord,Prmove);
             Previous := Pop^.next;
             Pop := Previous;
	     backtrack(Newpuzzle, Pop, Xcord, Ycord);
           
	   end
         else {execute 1 more time to get position before the flag}
	   begin
	     Prmove := Pop^.move;
	     tilemove(Newpuzzle,Xcord,Ycord,Prmove);
	     Previous := Pop^.next;
	     Pop := Previous;
           end;

     end;

  
  {
  ************************************************************************
  Procedure to Determine X and Y Coordinates of the Blank
  ************************************************************************
  }
  procedure determine (var Xloc, Yloc : integer; Newarray : Mattype);

    begin
      
      Xloc := 1;
      Yloc := 1;
       
      while (Newarray[Yloc,Xloc] <> 0) do
        begin
	  
	  Xloc := Xloc + 1;
	  if (Xloc > 10) 
	    then 
	      begin
		
		Xloc := 1;
		Yloc := Yloc +1;
              
	      end;
        
	end; {while}
     
     end; {procedure}

  {
  *************************************************************************
                   Read in The Puzzle Configuration
  *************************************************************************
  }
  procedure matread (var Current : Mattype; Xcor, Ycor : integer);

    begin
      
      read (Current[Ycor,Xcor]);
      Xcor := Xcor + 1;
      if (Xcor > 10) 
	then 
	  begin
	   
	    Ycor := Ycor + 1;
	    Xcor := 1;
	    readln;
          
	  end; { Then }

      if (Ycor <= 10) 
	then 
	  matread (Current, Xcor, Ycor);
    

    end;

   {
   **********************************************************************
   Begin Main Loop
   **********************************************************************
   }
   begin { Program }
     
     new (Top);
     Top^.next := nil;
     Top^.move := 0;
     Top^.flag := true;
     new (Top);
     Top^.next := Last;
     Firstmove := true; 
     Prmove := 0;
     matread (Curpuzzle,1,1);
     Curstate := enval(Curpuzzle);
     determine (Cblx,Cbly,Curpuzzle);
     while (Curstate <> 0) do
       begin
         
	 Uppuzzle := Curpuzzle;
         Dwnpuzzle := Curpuzzle;
         Lftpuzzle := Curpuzzle;
         Rhtpuzzle := Curpuzzle;
         if ((Cblx = 1) or (Cblx = 10) or (Cbly = 1) or (Cbly = 10))
           then
	     begin
	       
	       Perifery := true;
	       if ((Cblx = 1) or (Cblx = 10) and (Cbly = 1) or (Cbly = 10))
	         then 
	           Corner := true
                 else 
	           Corner := false;
              
	      end
    
            else
	      begin
	        
	        Perifery := false;
	        Corner := false;
              
	      end;
         
         Upmv := false;
         Dwnmv := false;
         Lftmv := false;
         Rhtmv := false;
	 Negup := false;
	 Negdown := false;
	 Negleft := false;
	 Negright := false;
         
	 if (Perifery = true)
	   then 
	     begin
	       
	       if (Cblx = 1)
	         then 
		   begin
                     
		     Negleft := true;
		     if Corner = true 
		       then 
			 if Cbly = 10 
			   then 
			     Negup := true
                           else 
			     if Cbly = 1
			       then 
				 Negdown := true;
		   end;
             end;

         if (Perifery = true)
           then
             begin

               if (Cblx = 10)
	         then
	           begin
         
	             Negright := true;
	             if Corner = true
	               then
		         if Cbly = 10
		           then
		             Negup := true
                           else
		             if Cbly = 1
		               then
		                 Negdown := true;
                   end;
             end;
         
         
         if (Perifery = true)
           then
             begin
         
               if (Cbly = 1)
	         then
	           begin
         
	             Negdown := true;
	             if Corner = true
	               then
		         if Cblx = 1
		           then
		             Negleft := true
                           else
		             if Cblx = 10
		               then
		                 Negright := true;
                   end;
             end;
         
         
         if (Perifery = true)
           then
             begin
         
               if (Cbly = 10)
	         then
	           begin
         
	             Negup := true;
	             if Corner = true
	               then
		         if Cblx = 1
		           then
		             Negleft := true
                           else
		             if Cblx = 10
		               then
		                 Negright := true;
                   end;
             end;
         
         if (Prmove <> 1)
           then
             begin
               
	       if Negup <> true 
		 then
		   begin

                     Upmv := true;
                     tilemove(Uppuzzle,Cblx,Cbly,1);
                     Upval := enval(Uppuzzle);

                   end; 
             end;

         if (Prmove <> 2)
           then
             begin

               if Negdown <> true
		 then
		   begin
		     
		     Dwnmv := true;
                     tilemove(Dwnpuzzle,Cblx,Cbly,2);
                     Dwnval := enval(Dwnpuzzle);
                   
		   end;
             end;

         if (Prmove <> 3)
           then
             begin
         
               if Negleft <> true
		 then
		   begin
		   
		     Lftmv := true;
                     tilemove(Lftpuzzle,Cblx,Cbly,3);
                     Lftval := enval(Lftpuzzle);

                   end;
            end;		              

         if (Prmove <> 4)
           then
             begin
		                    
               if Negright <> true
		 then
		   begin
		     
		     Rhtmv := true;
                     tilemove(Rhtpuzzle,Cblx,Cbly,4);
                     Rhtval := enval(Rhtpuzzle);		      

                   end;
             end;

         Upmove := false;
         Dwnmove := false;
         Lftmove := false;
         Rhtmove := false;
         
         if (Firstmove = true)
           then 
	     Firstmove := false;
         
         if Upmv = true
           then 
     	     if Upval < Curstate
	       then 
	         Upmove := true 
               else 
	         Upmove := false;
         
	 if Dwnmv = true
           then
             if Dwnval < Curstate
               then 
                 Dwnmove := true
               else
		 Dwnmove := false;
           
	  if Lftmv = true
            then
              if Lftval < Curstate
                then 
	          Lftmove := true
                else 
	 	  Lftmove := false;
          
	  if Rhtmv = true
            then
              if Rhtval < Curstate
                then 
                  Rhtmove := true
                else
                  Rhtmove := false;;
          
	  if (((Upmove = true) or (Dwnmove = true) or
	     (Lftmove = true) or (Rhtmove = true)) and
	     ((Upmove = true) or (Dwnmove = true) or
	     (Lftmove = true) or (Rhtmove = true)))
            then 
	      Setflag := true;

          if Upmove = true 
	    then 
	      begin 
	        
	        { Add to stack }
                Top^.move := 2;
		if Setflag = true 
		  then 
		    Top^.flag := true
                  else 
		    Top^.flag := false;
	        Curpuzzle := Uppuzzle;
                Last := Top;
                new (Top);
		Prmove := 2;
                new (Top);
                Top^.next := Last;
                
	      end
            
	    else  
              if Dwnmove = true
                then
                  begin
                    
	            { Add to stack }
                    Top^.move := 1;
		    if Setflag = true
		      then
			Top^.flag := true
                      else
			Top^.flag := false;
                    Curpuzzle := Dwnpuzzle;
                    Last := Top;
                    Prmove := 1;
		    new (Top);
                    Top^.next := Last;
	
	           end
                 
		 else 
                   if Lftmove = true
                     then
                       begin
                         
	                 { Add to stack }
			 Top^.move := 4;
			 if Setflag = true
			   then
			     Top^.flag := true
                           else
			     Top^.flag := false;
                         Curpuzzle := Lftpuzzle;
                         Last := Top;
                         Prmove := 4;
			 new (Top);
                         Top^.next := Last;

	               end
                     else 
                       if Rhtmove = true
	                 then
	                   begin
	                     
	                     { Add to stack }
			     Top^.move := 3;
			     if Setflag = true
			       then
				 Top^.flag := true
			       else
				 Top^.flag := false;
			     Curpuzzle := Rhtpuzzle;
                             Last := Top;
                             Prmove := 3;
			     new (Top);
                             Top^.next := Last;

			   end

                         else  
			        { if all options fail then
		                backtrack to the Last flag }
                           backtrack(Curpuzzle,Top,Cblx,Cbly);
    
           determine (Cblx,Cbly,Curpuzzle);
	   Curstate := enval(Curpuzzle);

     end; { while loop }
     
     { Print Out the Final Matrix }
     
     for Count := 1 to 10 do
       begin
	 
	 for Count2 := 1 to 10 do
	     write (Curpuzzle[Count,Count2]:3);
         
	 writeln
       
       end;

end. { Program }