import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; 
/************************************************** * 类功能简介:游戏场景的实现 2004-03-05 * @author [email protected] * @version 1.01 **************************************************/ 
public class GamePlat extends Canvas //implements KeyListener {   public static final int BOARDNUM = 3;         //可以活动的元素   public static final int WIDACTION = 201;      //设置拼图游戏活动场景图片的宽度   public static final int HEIACTION = 201;      //设置拼图游戏活动场景图片的高度   public static final int WID = 281;            //设置整个GamePlat的宽度   public static final int HEI = 281;            //设置整个GamePlat的高度 
  private int [][] boardArray;                  //游戏里面的可以变换的数组 
  private final int [][] WINARRAY = {{0,1,2},   //设定游戏成功的条件                                      {3,4,5},                                      {6,7,8}};   private int stepNum = 0;                      //记录玩家走走过的步骤 
  private Random rand = null;   private Toolkit tk = null;   private Image spiriteImage = null;   private int x8 = BOARDNUM-1,y8 = x8; 
  /**************************************************   * 构造方法:构造整个游戏最重要的数据   ***************************************************/ 
  public GamePlat()   {     tk = getToolkit();     rand = new Random();     boardArray = new int[BOARDNUM][BOARDNUM];     try     {       spiriteImage = tk.createImage("photo.jpg");     }     catch (Exception ex)     {       System.out.println(ex.getMessage());     }     init();   } 
  /**************************************************   * 方法介绍:初始化记录步骤和并随机生成每个数组里面的值   * 输入参数:无   * 返回类型:无   ****************************************************/ 
  public void init()   {     stepNum = 0;     generateBoardNum();   } 
  /**************************************************   * 方法介绍:随机生成每个数组里面的值   * 输入参数:无   * 返回类型:无   ****************************************************/ 
  private void generateBoardNum()   {     int k=0;     for (int i = 0 ; i < 3 ; i++)       for (int j = 0 ; j < 3 ; j++)       {         boardArray[i][j] = k++;       }       for (int i = 0 ; i < 100 ; i++)       {         int x1,y2,x2,y1,temp;         x1=Math.abs(rand.nextInt()%3);         x2=Math.abs(rand.nextInt()%3);         y1=Math.abs(rand.nextInt()%3);         y2=Math.abs(rand.nextInt()%3);         temp = boardArray[x1][y1];         boardArray[x1][y1]=boardArray[x2][y2];         boardArray[x2][y2]=temp;       }       int x=0,y=0,temp;       for (int i = 0 ; i < 3 ; i++)         for(int j = 0 ; j < 3 ; j++)         {           if(boardArray[i][j]==8)           {             x=i;             y=j;             System.out.println("Now the X"+i+" & Y"+j+" & boardArrayVALUE is : X : "+x+" Y : "+y+" BV : "+boardArray[i][j]);             break;           }         }       System.out.println("Now the X2 & Y2 & boardArrayVALUE is : X : 2 Y : 2 BV : "+boardArray[2][2]);       if(x == 2 && y == 2)         return;       else       {         temp = boardArray[2][2];         boardArray[2][2]=8;         boardArray[x][y]=temp;       }       //cheat();       testArray(boardArray);     } 
    /**************************************************      * 方法介绍:作弊,用来测试人工智能      * 输入参数:无      * 返回类型:无      ****************************************************/     public void cheat()     {       System.out.println("CHEAT:)");       int k = 0;       for (int i = 0 ; i < BOARDNUM ; i++)       {         for (int j = 0; j < BOARDNUM; j++)         {           boardArray[i][j] = k++;         }       } 
      boardArray [0][2]=2;       boardArray [1][2]=8;       boardArray [2][2]=5;       for (int i = 0 ; i < BOARDNUM ; i++)       {         for (int j = 0; j < BOARDNUM; j++)         {           System.out.print(boardArray[i][j] + " ");         }         System.out.println();       } 
     } 
    /**************************************************     * 方法介绍:int [][]引用的数组中的值按一定格式输出     * 输入参数:int [][]     * 返回类型:无     ****************************************************/ 
   private void testArray(int [][] args)    {      System.out.println("TEST THE ARRAY");      for (int i = 0; i < BOARDNUM; i++)      {        for (int j = 0; j < BOARDNUM; j++)        {          System.out.print( args[i][j] +" ");        }        System.out.println();      }    }    /**************************************************     * 方法介绍:让存储8的元素和它下面的元素交换,这种方法完     * 成得方法效率可能稍差,但这是为了能够扩展人工智能而不     * 得不采取得方法,因为如果不知道8的位置,人工智能就不     * 能实现     * 输入参数:int [][]     * 返回类型:int [][]     ****************************************************/ 
   private int [][] updateDown(int [][] args)    {      int [][] tempArr = new int [BOARDNUM][BOARDNUM];      for (int i = 0 ; i < BOARDNUM ; i++)        for (int j = 0 ; j < BOARDNUM ; j++)        {          tempArr [i][j] = args[i][j];        }      int x8 =0,y8=0;      for (int i = 0 ; i < 3 ; i++)         for(int j = 0 ; j < 3 ; j++)         {           if(tempArr[i][j]==8)           {             x8=i;             y8=j;             //System.out.println("Now the X"+i+" & Y"+j+" & boardArrayVALUE is : X : "+x8+" Y : "+y8+" BV : "+tempArr[i][j]);             break;           }         } 
     if (x8 != 2)      {        int temp = tempArr[x8+1][y8];        tempArr[x8+1][y8] = tempArr[x8][y8];        tempArr[x8][y8] = temp;      }      return tempArr;    } 
   /**************************************************     * 方法介绍:让存储8的元素和它上面的元素交换,这种方法完     * 成得方法效率可能稍差,但这是为了能够扩展人工智能而不     * 得不采取得方法,因为如果不知道8的位置,人工智能就不     * 能实现     * 输入参数:int [][]     * 返回类型:int [][]     ****************************************************/ 
    private int [][] updateUp(int [][] args)    {      int [][] tempArr = new int [BOARDNUM][BOARDNUM];      for (int i = 0 ; i < BOARDNUM ; i++)        for (int j = 0 ; j < BOARDNUM ; j++)        {          tempArr [i][j] = args[i][j];        }      int x8 =0,y8=0;      for (int i = 0 ; i < 3 ; i++)         for(int j = 0 ; j < 3 ; j++)         {           if(tempArr[i][j]==8)           {             x8=i;             y8=j;            // System.out.println("Now the X"+i+" & Y"+j+" & boardArrayVALUE is : X : "+x8+" Y : "+y8+" BV : "+tempArr[i][j]);             break;           }         } 
      if (x8 != 0)       {         int temp = tempArr[x8-1][y8];         tempArr [x8-1][y8] = tempArr[x8][y8];         tempArr [x8][y8] = temp;       }       return tempArr; 
   } 
   /**************************************************     * 方法介绍:让存储8的元素和它右面的元素交换,这种方法完     * 成得方法效率可能稍差,但这是为了能够扩展人工智能而不     * 得不采取得方法,因为如果不知道8的位置,人工智能就不     * 能实现     * 输入参数:int [][]     * 返回类型:int [][]     ****************************************************/ 
   private int [][] updateRight(int [][] args)    {      int [][] tempArr = new int [BOARDNUM][BOARDNUM];      for (int i = 0 ; i < BOARDNUM ; i++)        for (int j = 0 ; j < BOARDNUM ; j++)        {          tempArr [i][j] = args[i][j];        }      int x8 =0,y8=0;      for (int i = 0 ; i < 3 ; i++)         for(int j = 0 ; j < 3 ; j++)         {           if(tempArr[i][j]==8)           {             x8=i;             y8=j;            // System.out.println("Now the X"+i+" & Y"+j+" & boardArrayVALUE is : X : "+x8+" Y : "+y8+" BV : "+tempArr[i][j]);             break;           }         } 
     if (y8 != 2)      {        int temp = tempArr [x8][y8+1];        tempArr [x8][y8+1] = tempArr [x8][y8];        tempArr [x8][y8] = temp;      }      return tempArr;    } 
   /**************************************************     * 方法介绍:让存储8的元素和它左面的元素交换,这种方法完     * 成得方法效率可能稍差,但这是为了能够扩展人工智能而不     * 得不采取得方法,因为如果不知道8的位置,人工智能就不     * 能实现     * 输入参数:int [][]     * 返回类型:int [][]     ****************************************************/ 
  
   private int [][] updateLeft(int [][] args)    {      int [][] tempArr = new int [BOARDNUM][BOARDNUM];      for (int i = 0 ; i < BOARDNUM ; i++)        for (int j = 0 ; j < BOARDNUM ; j++)        {          tempArr [i][j] = args[i][j];        }      int x8 =0,y8=0;      for (int i = 0 ; i < 3 ; i++)         for(int j = 0 ; j < 3 ; j++)         {           if(tempArr[i][j]==8)           {             x8=i;             y8=j;             //System.out.println("Now the X"+i+" & Y"+j+" & boardArrayVALUE is : X : "+x8+" Y : "+y8+" BV : "+tempArr[i][j]);             break;           }         } 
     if (y8 != 0)      {        int temp = tempArr [x8][y8-1];        tempArr [x8][y8-1] = tempArr [x8][y8];        tempArr [x8][y8] = temp;      }      return tempArr;    } 
   /**************************************************     * 方法介绍:程序调试时使用的接口,实现了数组的变换     * 输入参数:无     * 返回类型:无     **************************************************/ 
   public void mainCallLeft()    {      boardArray = updateLeft(boardArray);      testArray(boardArray);    } 
   /**************************************************     * 方法介绍:程序调试时使用的接口,实现了数组的变换     * 输入参数:无     * 返回类型:无     **************************************************/ 
   public void mainCallRight()    {      boardArray = updateRight(boardArray);      testArray(boardArray);    }    /**************************************************     * 方法介绍:程序调试时使用的接口,实现了数组的变换     * 输入参数:无     * 返回类型:无     **************************************************/ 
   public void mainCallUp()    {      boardArray = updateUp(boardArray);      testArray(boardArray);    } 
   /**************************************************     * 方法介绍:程序调试时使用的接口,实现了数组的变换     * 输入参数:无     * 返回类型:无     **************************************************/ 
   public void mainCallDown()    {      boardArray = updateDown(boardArray);      testArray(boardArray);    }    /**************************************************     * 方法介绍:判断是否已经排列正确     * 输入参数:int [][]     * 返回类型:boolean     **************************************************/ 
   private boolean isOrder(int [][] args)    {      for (int i = 0 ; i < BOARDNUM ; i++)          for (int j = 0 ; j < BOARDNUM ; j++)          {            if (args [i][j] != WINARRAY[i][j])              return false;          }       return true;    }    /**************************************************     * 方法介绍:程序调试时使用的接口,实现了人工智能变换     * 输入参数:无     * 返回类型:无     **************************************************/ 
   public void aI()    {      Vector [] binTree = new Vector [2];              //建立两颗二叉树存储数组状态      StringBuffer [] strDir = new StringBuffer [2];   //建立两颗二叉树存储搜索方向      for ( int i = 0 ; i < 2 ; i++)        for (int j = 0 ; j < 2 ; j++)        {          binTree [i] = new Vector(0,1);          strDir [i] =  new StringBuffer("");        }      if (isOrder(boardArray))      {        System.out.println("The Tree Not Construct , and the answer is OK");        return;      }      else      {        int [][] tempArr; 
       strDir [0].append("U");                         //方向树的根结点        tempArr = updateUp(boardArray);        //testArray(tempArr);        if(isOrder(tempArr))        {          System.out.println("The answer found at the first time use the direction tree");          System.out.println(strDir [0].toString());          return;        }        binTree [0].addElement(tempArr); 
        strDir[1].append("L");        tempArr = updateLeft(boardArray);        //testArray(tempArr);        if(isOrder(tempArr))        {          System.out.println("The answer found at the first time use the direction tree");          System.out.println(strDir [1].toString());          return;        }        binTree[1] . addElement(tempArr);        System.out.println("The tree become useful in searching the answer for every successful condidtion");        int stepRecord = 0;        for ( stepRecord = 0 ; ; stepRecord++)        {          System.out.println(stepRecord);          for (int i = 0 ; i < 2 ; i++)          {            int less = (int)(Math.pow(2,stepRecord)) - 1;            int large = (int)(Math.pow(2,stepRecord+1)) - 1;            for (int k = less ; k < large ; k++)            {              int [][] theCurrentState = (int [][])binTree [i].elementAt(k);              if (strDir [i].charAt(k) == 'L' || strDir [i].charAt(k) == 'R')              {                strDir[i].append("U");                tempArr = updateUp(theCurrentState);                //testArray(tempArr);                if(isOrder(tempArr))                {                  System.out.println("The answer found when constructing tree");                  System.out.println(strDir [i].toString());                  return;                }                binTree [i].addElement(tempArr);                strDir[i].append("D");                tempArr = updateDown(theCurrentState);                //testArray(tempArr);                if(isOrder(tempArr))                {                  System.out.println("The answer found when constructing tree");                  System.out.println(strDir [i].toString());                  return;                }                binTree [i].addElement(tempArr); 
              }              else              {                strDir[i].append("L");                tempArr = updateLeft(theCurrentState);                //testArray(tempArr);                if(isOrder(tempArr))                {                  System.out.println("The answer found when constructing tree");                  System.out.println(strDir [i].toString());                  return;                }                binTree [i].addElement(tempArr);                strDir[i].append("R");                tempArr = updateRight(theCurrentState);                //testArray(tempArr);                if(isOrder(tempArr))                {                  System.out.println("The answer found when constructing tree");                  System.out.println(strDir [i].toString());                  return;                }                binTree [i].addElement(tempArr); 
             }            }          }        }      }      //The AI has work well , but you will can't get the answer except:      //First you know have to make up a tree & how the use the last leave      //to find the root . The way like this : the N --->the least leave      //the step is : (N+1)/2 - 1 -> N      ///             (N+1)/2 - 1 -> N      ///               ...............      ///                        0 ->      and you will found the answer is      //correct may be not optimisted! copyright : [email protected]      //modified for the www.csdn.net         .    regards......      //The most importand method in this file .  2004-03-06.    } 
  
    /**************************************************     * 方法介绍:测试数据的正确与否     * 输入参数:String []     * 返回类型:无     ****************************************************/     public static void  main(String [] args) throws Exception     {       GamePlat gp = new GamePlat();       InputStreamReader reader = new InputStreamReader(System.in);       BufferedReader input = new BufferedReader(reader);       System.out.println("Now you can play the Game in console!");       System.out.println("Following are commands");       System.out.println("up");       System.out.println("down");       System.out.println("left");       System.out.println("right");       System.out.println("demoai");       System.out.println("restart");       System.out.println("exit");       while(true){         System.out.print("->");         String command = input.readLine();         if(command.equals("exit"))         {           break;         }         else if (command.equals("left"))         {            gp.mainCallLeft();         }         else if (command.equals("right"))         {            gp.mainCallRight();         }         else if (command.equals("up"))         {            gp.mainCallUp();         }         else if (command.equals("down"))         {           gp.mainCallDown();         }         else if (command.equals("demoai"))         {           gp.aI();         }         else if (command.equals("cheat"))         {           gp.cheat();         }         else if (command.equals("restart"))         {           gp.init();         } 
        else         {           System.out.println(command+" is not support ~Z");         } 
      }     } } 
寒假时候为了给同学演示怎样做个游戏,而做了一个最简单的拼图游戏。规则,如下,生成 0 1 2 3 4 5 6 7 8 个数列,然后随机的放到一个二维数组里面:  比如:  1 3 2  4 6 5  0 7 8  8总是在最右脚,智能用8和他临近的值交换。直到得到如下序列游戏成功?;  0 1 2  3 4 5  6 7 8  。现在我想让游戏具有人工智能,用自己的思考建造一棵搜索树,找到一个路径,自己排列数组:  于是我编了一个简单的控制台程序,建了一些命令和程序交互,当输入demoai的时候,人工智能启动,计算了超过3个小时也没有得到结果!后来,我加入了一条cheat的命令,把初始值定义为:  0 1 8  3 4 2  6 7 5  :其实,人一眼就看出只需走两步:  然后我运行demoai,  可以看到计算机是如此思考的:  G:\PTGAI>java GamePlat  Now the X2 & Y1 & boardArrayVALUE is : X : 2 Y : 1 BV : 8  Now the X2 & Y2 & boardArrayVALUE is : X : 2 Y : 2 BV : 6  Now you can play the Game in console!  Following are commands  up  down  left  right  demoai  restart  exit  ->cheat  CHEAT:)  0 1 2  3 4 8  6 7 5  ->demoai  The tree become useful in searching the answer for every successful condidtion  0  1  2  3  The answer found when constructing tree  ULRUDUDLRLRLRLRUDUDUDUDUDUDUDUD  ->  结果分析:  U L R U D U D L R L R L R L R U D U D U D U D U D U D U D U D  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30  0 0U  
  
 1 1L 2R  
 2 3U 4D 5U 6D  
 3 7L 8R 9L 10R 11L 12R 13L 14R  
 4 15U 16D U17 18D U19 20D U21 22D U23 24D U25 26D U27 28D U29 30D  
G:\PTGAI>java GamePlat  Now the X0 & Y1 & boardArrayVALUE is : X : 0 Y : 1 BV : 8  Now the X2 & Y2 & boardArrayVALUE is : X : 2 Y : 2 BV : 2  TEST THE ARRAY  5 2 7  3 1 6  4 0 8  Now you can play the Game in console!  Following are commands  up  down  left  right  demoai  restart  exit  ->cheat  CHEAT:)  0 1 2  3 4 8  6 7 5  ->up  TEST THE ARRAY  0 1 8  3 4 2  6 7 5  ->right  TEST THE ARRAY  0 1 8  3 4 2  6 7 5  ->down  TEST THE ARRAY  0 1 2  3 4 8  6 7 5  ->right  TEST THE ARRAY  0 1 2  3 4 8  6 7 5  ->down  TEST THE ARRAY  0 1 2  3 4 5  6 7 8  ->exit  
G:\PTGAI>  够恐怖吧? 
欢迎批评指正, 
希望有人找到更好的智能方法告诉我!  
 
  |