LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1118|回复: 13

请教大家一种游戏的算法和代码,谢谢了

[复制链接]
发表于 2005-5-19 18:07:24 | 显示全部楼层 |阅读模式
[php]
【游戏说明】
    有一种游戏,其规则如下:有一个3×3的方格,每个方格中只可画‘+’符号或‘-’符号,表示该方格的值。图(a)定义了各方格的位置,表1为每个方格位置定义了与其相关联的位置集,各方格的初值如图(b)所示。游戏开始后,每次可选一个值为‘+’的方格位置,然后根据表1将该位置所对应的每个相关联的位置上的符号重画成与其不同的符号,即将‘+’重画成‘-’,将‘-’重画成‘+’。重画操作可用所选的位置编号来描述。例如在图(b)所示的情况下,选择位置4时,重画结果如图(c)所示。经过连续的若干次这样的操作后,当3×3方格呈现出图(d)所示的图形时,表示获胜;当呈现出图(e)所示的图形时,表示失败。
下列流程图旨在输出从初始状态出发直至获胜的重画操作(即所选的位置编号)序列。图中假定数组A[0..8]存放3×3方格的值,数组c[0..8][1..5]存放表 1所示的各方格位置的相关联的位置集、数组d[0..8]存放各方格位置的相关联的位置个数,数组元素 S[1]~ S[k]存放各次重画操作所对应的位置编号,变量N存放3×3 方格中当前的‘+’符号的个数。
              012        ———    -+-         +++                 ——-
              345        -+-    +-+         +-+                 ―――
              678        ———    一+一         +++                 ——一
             图(a)    图(b)     图(C)      图(d)        图(e)




方格位置      相关位置集
0                0134
1                012
2                1245
3                036
4                13457
5                258
6                3467
7                678
8                4578

[/php]

还有一个流程图,不知道怎么弄上来了,这好象某年的程序员考试题,我想了7.72小时还是没有什么头绪,请大家帮提示提示,谢谢了
发表于 2005-5-20 12:48:14 | 显示全部楼层
查《数据结构》——图的遍历,或《人工智能导论》——盲目搜索或启发式搜索。
回复 支持 反对

使用道具 举报

发表于 2005-5-20 19:35:08 | 显示全部楼层
有限状态机(FSM)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-20 19:57:35 | 显示全部楼层

re

唉,等于没回,算了也等于我没问吧
回复 支持 反对

使用道具 举报

发表于 2005-5-20 20:18:31 | 显示全部楼层

用邻接表表示的图来解决也很不错。

  1. using System;
  2. using System.Collections;
  3. using System.Text;

  4. namespace myWorkFlow.kernel
  5. {
  6.         //边表结点类
  7.         public class EdgeNode
  8.         {
  9.                 public int adjvex;
  10.                 public EdgeNode next;

  11.                 public EdgeNode()
  12.                 {
  13.                         next=null;
  14.                 }


  15.         }

  16.         ////顶点表结点类
  17.         public class VertexNode
  18.         {
  19.                 public object vertex;
  20.                 public EdgeNode firstedge;

  21.                 public VertexNode()
  22.                 {
  23.                         firstedge=null;
  24.                 }


  25.         }

  26.         //图的类型
  27.         public enum GraphType
  28.         {
  29.                 UnDiGraph = 0,//无向图       
  30.                 DiGraph = 1//有向图
  31.         }
  32.        
  33.         //图类
  34.         public class ALGraph
  35.         {
  36.                 public VertexNode[] AdjList;//顶点表

  37.                 public  int VertexNodeCount;//顶点数
  38.                 public  int BordeCount;//边数

  39.                 public GraphType theType;//图的类型
  40.         
  41.                 public ALGraph( int n,int e ,GraphType cuType)
  42.                 {
  43.                        
  44.                         VertexNodeCount = n;
  45.                         BordeCount= e;
  46.                         AdjList = new VertexNode[n];
  47.                         theType = cuType;
  48.                 }

  49.                
  50.         }

  51.         //图对象操作类
  52.         public class GraphOperation
  53.         {
  54.                 private bool[] visited;
  55.                 private StringBuilder sb ;

  56.                 public GraphOperation()
  57.                 {

  58.                 }

  59.                 /// <summary>
  60.                 /// 建全一个有向图对象
  61.                 /// (不是建立 ^_^)
  62.                 /// </summary>
  63.                 /// <param name="G"></param>
  64.                 public   void CreateALGraph(ALGraph G)
  65.                 {
  66.                         int i,j,k;

  67.                         EdgeNode s;

  68.                         for(int vnc = 0 ;vnc < G.VertexNodeCount; vnc++)
  69.                         {
  70.                                 VertexNode cuVN = new VertexNode();
  71.                                 Console.Write("请输入顶点的编号 : ");
  72.                                 cuVN.vertex = Console.ReadLine();
  73.                                 cuVN.firstedge = null;
  74.                                 G.AdjList[vnc]=cuVN;
  75.                         }

  76.                         for(k = 0; k < G.BordeCount; k++)
  77.                         {
  78.                                 Console.Write("请输入边开始顶点的序号 : ");

  79.                                 i = int.Parse(Console.ReadLine());

  80.                                 Console.Write("请输入边结束顶点的序号 : ");

  81.                                 j =int.Parse(Console.ReadLine());

  82.                                 s = new EdgeNode();

  83.                                 s.adjvex = j;

  84.                                 s.next = G.AdjList[i].firstedge;
  85.                                 //邻接表头插法
  86.                                 G.AdjList[i].firstedge = s;
  87.                                
  88.                                 //建立无向图
  89.                                 if(G.theType == GraphType.UnDiGraph)
  90.                                 {
  91.                                         s = new EdgeNode();

  92.                                         s.adjvex = i;
  93.                                         s.next = G.AdjList[j].firstedge;
  94.                                         G.AdjList[j].firstedge = s;
  95.                                 }
  96.                                
  97.                                
  98.                        
  99.                         }
  100.        
  101.                        
  102.                 }
  103.                
  104.                 /// <summary>
  105.                 /// 深度优先遍历以邻接表表示的图G.
  106.                 /// </summary>
  107.                 /// <param name="G"></param>
  108.                 public  void DFSTraverse(ALGraph G)
  109.                 {
  110.                         visited = new bool[G.VertexNodeCount];
  111.                         sb = new StringBuilder();
  112.                         for(int i = 0;i < G.VertexNodeCount;i++)
  113.                         {
  114.                                 visited[i] = false;

  115.                         }

  116.                         for(int i = 0;i < G.VertexNodeCount;i++)
  117.                         {
  118.                                 if(!visited[i])
  119.                                 {
  120.                                         DFS(G,i);
  121.                                 }

  122.                         }
  123.                         Console.Write("深度优先遍历以邻接表表示的图G 的结果:\n ");
  124.                        
  125.                         Console.Write(sb);


  126.                 }

  127.                 private void DFS(ALGraph G,int i)
  128.                 {
  129.                         EdgeNode p;
  130.                         sb.Append(G.AdjList[i].vertex.ToString()+"--->");
  131.                        
  132.                         visited[i] = true;
  133.                         p = G.AdjList[i].firstedge;
  134.                         while(p != null)
  135.                         {
  136.                                 if(!visited[p.adjvex])
  137.                                 {
  138.                                         DFS(G,p.adjvex);//递归
  139.                                 }
  140.                                 p = p.next;
  141.                         }

  142.                 }

  143.                 /// <summary>
  144.                 /// 广度优先遍历以邻接表表示的图G
  145.                 /// </summary>
  146.                 /// <param name="G"></param>
  147.                 public  void BFSTraverse(ALGraph G)
  148.                 {
  149.                         visited = new bool[G.VertexNodeCount];
  150.                         sb = new StringBuilder();
  151.                         for(int i = 0;i < G.VertexNodeCount;i++)
  152.                         {
  153.                                 visited[i] = false;

  154.                         }

  155.                         for(int i = 0;i < G.VertexNodeCount;i++)
  156.                         {
  157.                                 if(!visited[i])
  158.                                 {
  159.                                         BFS(G,i);
  160.                                 }

  161.                         }
  162.                         Console.Write("广度优先遍历以邻接表表示的图G 的结果:\n ");
  163.                        
  164.                         Console.Write(sb);


  165.                 }
  166.                 private void BFS(ALGraph G,int k)
  167.                 {
  168.                         int i;
  169.                         Queue Q;
  170.                         EdgeNode p;

  171.                         Q = new Queue();

  172.                         sb.Append(G.AdjList[k].vertex.ToString()+"--->");
  173.                        
  174.                         visited[k] = true;
  175.                         Q.Enqueue(k);

  176.                         while(Q.Count != 0)
  177.                         {
  178.                                 i = (int)Q.Dequeue();
  179.                                 p = G.AdjList[i].firstedge;

  180.                                 while(p != null)
  181.                                 {
  182.                                         if(!visited[p.adjvex])
  183.                                         {
  184.                                                 sb.Append(G.AdjList[p.adjvex].vertex.ToString()+"--->");
  185.                                                 visited[p.adjvex] = true;
  186.                                                 Q.Enqueue(p.adjvex);
  187.                                         }
  188.                                         p = p.next;
  189.                                 }
  190.                         }
  191.                 }

  192.                 /// <summary>
  193.                 /// 有向图无前驱的顶点优先之拓扑排序
  194.                 /// </summary>
  195.                 /// <param name="G"></param>
  196.                 public void NonPreFirstTopSort(ALGraph G)
  197.                 {
  198.                         if(G.theType == GraphType.UnDiGraph)
  199.                         {
  200.                                 Console.Write("对无向图进行拓扑排序是不对的!");
  201.                                 return;

  202.                         }
  203.                         StringBuilder SB = new StringBuilder() ;
  204.                         int [] indegree = new int[G.VertexNodeCount];


  205.                         Stack S;

  206.                         int i,j,count = 0;

  207.                         EdgeNode p;

  208.                         for(i = 0;i < G.VertexNodeCount;i++)
  209.                         {
  210.                                 indegree[i] = 0;
  211.                         }

  212.                         for(i = 0;i < G.VertexNodeCount;i++)
  213.                         {
  214.                                 for(p = G.AdjList[i].firstedge; p != null;p = p.next)
  215.                                 {
  216.                                         indegree[p.adjvex]++;
  217.                                 }

  218.                         }

  219.                         S = new Stack();

  220.                         for(i = 0;i < G.VertexNodeCount; i++)
  221.                         {
  222.                                 if(indegree[i] == 0)
  223.                                 {
  224.                                         S.Push(i);
  225.                                 }
  226.                         }

  227.                         while(S.Count != 0)
  228.                         {
  229.                                 i = (int)S.Pop();

  230.                                 SB.Append(G.AdjList[i].vertex.ToString()+"--->");

  231.                                 count++;

  232.                                 for(p = G.AdjList[i].firstedge; p != null; p = p.next)
  233.                                 {
  234.                                         j = p.adjvex;
  235.                                         indegree[j]--;
  236.                                         if(indegree[j] == 0)
  237.                                         {
  238.                                                 S.Push(j);
  239.                                         }

  240.                                 }
  241.                                

  242.                         }
  243.                         if(count < G.VertexNodeCount)
  244.                         {
  245.                                 Console.Write("图中有环,排序失败");
  246.                         }
  247.                         else
  248.                         {
  249.                                 Console.Write("拓扑排序结果如下 : \n"+SB);
  250.                        

  251.                         }



  252.                 }

  253.        
  254.         }

  255. }
复制代码


这个是我前段时间写的一个图数据结构实现(使用C#,你把它转的JAVA用吧)
回复 支持 反对

使用道具 举报

发表于 2005-5-20 20:25:36 | 显示全部楼层
本来想用有向图来解决工作流中的前后动作依赖关系,想做一个.NET下的WFMS,
赫赫。。
回复 支持 反对

使用道具 举报

发表于 2005-5-21 00:16:38 | 显示全部楼层
Post by menglianjing
唉,等于没回,算了也等于我没问吧

那就再详细一点,一种盲目搜索算法:

首先,从初始状态开始,穷举所有可能的选择(这里没有考虑原题中的具体数据,假设0-8都可以选),可以得到 9 种新状态(如果有重复的要去掉,则结果少于 9 种),比较新状态是否目标状态。

然后,从每种新状态出发,穷举(假设0-8),又各得到 9 种新状态(如果与已经出现过的状态重复,要去掉,或称合并),比较新状态是否目标状态。

依次类推......形成一个图:状态就是图节点,如果从一个状态一步可以到达另一状态,这两个状态(节点)之间就有一条弧(有向的)。最终,会找到一个状态和目标状态一致。建立图的过程到此为止。

最后,在图上找到一条从初始状态到目标状态的路径,输出。如果用深度优先搜索并及时释放没用的路径也可以避免最后这一步。(完毕)


附:上面只是个粗略的过程,翻翻书还是有好处的。是你要解决问题,如果你都不想翻书,又怎能期望别人花时间帮你。
回复 支持 反对

使用道具 举报

发表于 2005-5-21 04:21:54 | 显示全部楼层

用JAVA做了一个,见笑了。

[PHP]/*
* 创建日期 2005-5-20
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package menglianjingGame;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
/**
* @author 锋锋
*
* TODO 要更改此生成的类型注释的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
class VertexNode {
       
        public boolean vertex ;//顶点数据
        public int[]  correlativeList ;//关联顶点列表

        public VertexNode()
        {
               
        }
}
class ALGraph {
       
        public VertexNode[] AdjList ;//顶点表

        public  int VertexNodeCount;//顶点数
       
        public ALGraph( int n )
        {
                VertexNodeCount = n;
                AdjList = new VertexNode[n];
       
        }

}

public class PlayGame {
       
        private static ALGraph g = new ALGraph(9);
        //游戏当前状态
        private static boolean[] cuState = new boolean[9];
        //游戏胜利状态
        private static boolean[] winState = new boolean[]{true,
                                                                     true,
                                                                     true,
                                                                     true,
                                                                                                                 false,
                                                                                                                 true,
                                                                                                                 true,
                                                                                                                 true,
                                                                                                                 true };
        //游戏失败状态
        private static boolean[] failState = new boolean[]{false,
                                                          false,
                                                          false,
                                                          false,
                                                                      false,
                                                                      false,
                                                                      false,
                                                                      false,
                                                                      false };
       
       
        public static void main(String[] args) {
               
                initGameData();
               
                PrintGameState(cuState);
                System.out.println("游戏开始...\n 请选择\n 请输入一个0-8之间的整数!\n");
               
                while(true){
                       
                        int guess = -1;
                       
                        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
                        try
                        {
                           guess = Integer.parseInt(input.readLine());
                        }
                        catch (NumberFormatException e)
                        {
                           System.out.println("请输入一个0-8之间的整数!");
                           continue;
                       
                        }
                        catch (IOException e)
                        {
                           System.out.println("程序发生异常错误将被关闭!");
                           e.printStackTrace();
                        }

                        if ((guess > 8)||(guess == -1)||(!cuState[guess])){
                        System.out.println("输入无效!请重输..");
                        continue;
                        }

                       
                        GameAction(guess);
                        UpDataGameCuState();
                        PrintGameState(cuState);
                       
                        if(Arrays.equals(cuState,winState)){
                               
                                System.out.println("恭喜!你赢了!");
                               
                                break;
                               
                        }
                       
                        if(Arrays.equals(cuState,failState)){
                               
                                System.out.println("恭喜!你输了!");
                               
                                break;
                               
                        }
                       
                        System.out.println("游戏继续\n 请输入一个0-8之间的整数!\n");
                       
                }
       
        }
       
       
        private static void initGameData(){
               
                System.out.println("初始化游戏...");
               
                g.AdjList[0] = new VertexNode();
                g.AdjList[0].vertex =false;
        g.AdjList[0].correlativeList = new int[]{0,1,3,4};
        
        g.AdjList[1] = new VertexNode();
        g.AdjList[1].vertex =false;
        g.AdjList[1].correlativeList = new int[]{0,1,2};
        
        g.AdjList[2] = new VertexNode();
        g.AdjList[2].vertex =false;
        g.AdjList[2].correlativeList = new int[]{1,2,4,5};
        
        g.AdjList[3] = new VertexNode();
        g.AdjList[3].vertex =false;
        g.AdjList[3].correlativeList = new int[]{0,3,6};
        
        g.AdjList[4] = new VertexNode();
        g.AdjList[4].vertex =true;
        g.AdjList[4].correlativeList = new int[]{1,3,4,5,7};
        
        g.AdjList[5] = new VertexNode();
        g.AdjList[5].vertex =false;
        g.AdjList[5].correlativeList = new int[]{2,5,8};
        
        g.AdjList[6] = new VertexNode();
        g.AdjList[6].vertex =false;
        g.AdjList[6].correlativeList = new int[]{3,4,6,7};
        
        g.AdjList[7] = new VertexNode();
        g.AdjList[7].vertex =false;
        g.AdjList[7].correlativeList = new int[]{6,7,8};
        
        g.AdjList[8] = new VertexNode();
        g.AdjList[8].vertex =false;
        g.AdjList[8].correlativeList = new int[]{4,5,7,8};
        
        UpDataGameCuState ();
        
        System.out.println("初始化游戏完成!");

        }
       
//根据用户输入(动作),改变游戏当前状态.
        private static void  GameAction(int choose){
               
                for(int i = 0;i < g.AdjList[choose].correlativeList.length; i++){
                       
                g.AdjList[g.AdjList[choose].correlativeList].vertex =
                        !g.AdjList[g.AdjList[choose].correlativeList].vertex;
               
                }
               
                UpDataGameCuState ();//更新游戏当前状态
               
        }
//更新游戏当前状态
        private static void UpDataGameCuState (){
               
                for(int i = 0;i < g.VertexNodeCount;i++){
                       
                        cuState = g.AdjList.vertex;       
                       
                }
               
        }
       
//打印游戏当前状态(其中布尔值和字符转换)       
        private static void PrintGameState(boolean[] custate){
               
                for( int c = 0 ;c < custate.length;c+=3)
                {
                        for(int i =0 ;i < 3;i++){
                               
                                if(custate[c+i]){
                                        System.out.print("+ ");       
                                }else{
                                        System.out.print("- ");       
                                }
                        }
                       
                        System.out.print("\n");
                       
                }
        }
       
       
}

[/PHP]



控制台下测试结果如下:

[PHP]初始化游戏...
初始化游戏完成!
- - -
- + -
- - -
游戏开始...
请选择
请输入一个0-8之间的整数!

4
- + -
+ - +
- + -
游戏继续
请输入一个0-8之间的整数!

1
+ - +
+ - +
- + -
游戏继续
请输入一个0-8之间的整数!

2
+ + -
+ + -
- + -
游戏继续
请输入一个0-8之间的整数!

3
- + -
- + -
+ + -
游戏继续
请输入一个0-8之间的整数!

4
- - -
+ - +
+ - -
游戏继续
请输入一个0-8之间的整数!

5
- - +
+ - -
+ - +
游戏继续
请输入一个0-8之间的整数!

6
- - +
- + -
- + +
游戏继续
请输入一个0-8之间的整数!

7
- - +
- + -
+ - -
游戏继续
请输入一个0-8之间的整数!

8
- - +
- - +
+ + +
游戏继续
请输入一个0-8之间的整数!

5
- - -
- - -
+ + -
游戏继续
请输入一个0-8之间的整数!

1
+ + +
- - -
+ + -
游戏继续
请输入一个0-8之间的整数!

2
+ - -
- + +
+ + -
游戏继续
请输入一个0-8之间的整数!

3
- - -
+ + +
- + -
游戏继续
请输入一个0-8之间的整数!
[/PHP]


回复 支持 反对

使用道具 举报

发表于 2005-5-21 04:35:29 | 显示全部楼层
我faint,楼主要的是让机器自动的找到一个求解方法,不是让用户输入123然后显示结果。
回复 支持 反对

使用道具 举报

发表于 2005-5-21 04:39:15 | 显示全部楼层
这样啊,那就很有难度了,真的要搞人工智能啊?!

我还以为是做个游戏来玩的,哈哈。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表