<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>hxpwork</title>
    <description></description>
    <link>http://hxpwork.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Drools4：Manners示例分析</title>
        <author>hxpwork</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hxpwork.javaeye.com">hxpwork</a>&nbsp;
          链接：<a href="http://hxpwork.javaeye.com/blog/112597" style="color:red;">http://hxpwork.javaeye.com/blog/112597</a>&nbsp;
          发表时间: 2007年08月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title"></div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">/* </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;manners示例是一个安排座位的例子，它的要求如下： </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;1、客人应当按照男女性别相邻而坐，围成一圈 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;2、假设客人会有2-3个个人爱好（爱好的可选范围是3种），为了让大家能够更好的交流， </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;要安排每个人都和相邻座位的两个人有共同的爱好，并且与左右两边的共同爱好不要相同 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;3、客人的人数在本例中为64人，男女各一半 </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;解题思路： </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;1)&nbsp;按照规则引擎的特性，首先应当将所有可能的数据准备好，从本例来看，客人是主要的数据对象， </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;姓名/性别/兴趣&nbsp;是三个主要属性，姓名和性别是固定的，可能有多个选择的就是兴趣爱好， </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那么首先应当将客人的兴趣分别与姓名/性别组合后放入WorkingMemory </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;2)&nbsp;再考虑一下，本例中规定了每个客人都会有三种爱好里的两种，也就是说任意两个人都必然有相同爱好 </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;只要注意不要性别相同以及两边爱好一致就可以；那么只要先安排一个人坐下（这个人应当三种爱好都有）， </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;然后找一个性别不同，有一种相同爱好的客人A坐在左边；接下去找一个坐在A旁边的客人B，同样与A性别 </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;不同，并且和前一位的共同爱好也不同。这样一直排下去，直到最后一个座位。这里解释一下为什么一开始 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第一个人要三种爱好齐备，因为这种算法有一个漏洞是没有考虑第一个客人和最后一个客人是相邻而坐的， </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果第一个客人和最后一个客人只有一个共同兴趣而这个兴趣又正好是第一和第二个客人的共同兴趣，那么 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这种算法会得到不正确的结果，但只要第一个坐下来的人三种爱好都有，那么必然和两边的人都有不同爱好， </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这也弥补了算法的不同。 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注：从本例中准备的数据和算法来看并没有考虑到这个问题，虽然按照原始数据可以得到正确的结果，但是 </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;进行针对性的调整后就会发现结果会有问题 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;3)&nbsp;因为座位是一个一个找出来的，因此要有合适的流程控制方法。&nbsp;&nbsp; </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">package</span><span>&nbsp;org.drools.benchmark.manners &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>#&nbsp;从客人中找出一位放入第一个座位 &nbsp;&nbsp;</span> </li>
    <li class=""><span>#&nbsp;根据Drools引擎的特性，应当是最后一个加入的Guest &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>#&nbsp;利用Context.state属性控制该规则只执行一次 &nbsp;&nbsp;</span> </li>
    <li class=""><span>rule&nbsp;assignFirstSeat &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Context用于流程控制 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context&nbsp;:&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.START_UP&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;原例中使用的是&nbsp;&nbsp;Guest()&nbsp;，&nbsp;获得最后插入的Fact，但是这样会引起之前提到的Bug &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;因此在下面进行了改进，保证找出三个兴趣都有的客人 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;guest&nbsp;:&nbsp;Guest(&nbsp;$name:name&nbsp;,&nbsp;$hobby&nbsp;:&nbsp;hobby&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guest&nbsp;(&nbsp;name&nbsp;==&nbsp;$name&nbsp;,&nbsp;hobby&nbsp;!=&nbsp;$hobby&nbsp;,&nbsp;$hobby1&nbsp;:&nbsp;hobby&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guest&nbsp;(&nbsp;name&nbsp;==&nbsp;$name&nbsp;,&nbsp;hobby&nbsp;!=&nbsp;$hobby&nbsp;,&nbsp;hobby&nbsp;!=&nbsp;$hobby1&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count&nbsp;:&nbsp;Count() &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;guestName&nbsp;=&nbsp;guest.getName(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Seating用于记录每个座位上的客人，是寻找下一个座位的客人的依据 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Seating&nbsp;seating&nbsp;=&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;Seating(&nbsp;count.getValue(),&nbsp;</span><span class="number">1</span><span>,&nbsp;</span><span class="keyword">true</span><span>,&nbsp;</span><span class="number">1</span><span>,&nbsp;guestName,&nbsp;</span><span class="number">1</span><span>,&nbsp;guestName); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;seating&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Path用来避免已经入座的客人再次被选中 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Path&nbsp;path&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Path(&nbsp;count.getValue(),&nbsp;</span><span class="number">1</span><span>,&nbsp;guestName&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;path&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;用于计数，并作为Seating的ID &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count.setValue(&nbsp;&nbsp;count.getValue()&nbsp;+&nbsp;</span><span class="number">1</span><span>&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;count&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</span><span class="string">&quot;assign&nbsp;first&nbsp;seat&nbsp;:&nbsp;&nbsp;&quot;</span><span>&nbsp;+&nbsp;seating&nbsp;+&nbsp;</span><span class="string">&quot;&nbsp;:&nbsp;&quot;</span><span>&nbsp;+&nbsp;path&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;进入找下一个座位环节 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setState(&nbsp;Context.ASSIGN_SEATS&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;context&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>end &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>#&nbsp;寻找相邻的同伴 &nbsp;&nbsp;</span> </li>
    <li class=""><span>rule&nbsp;findSeating &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;when&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context&nbsp;:&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.ASSIGN_SEATS&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;获得最近安排好座位的客人 &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$s:Seating(&nbsp;seatingId:id,&nbsp;seatingPid:pid,&nbsp;pathDone&nbsp;==&nbsp;</span><span class="keyword">true</span><span>,&nbsp;seatingRightSeat:rightSeat,&nbsp;seatingRightGuestName:rightGuestName&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;找到一位有共同兴趣但性别不同的相邻客人 &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guest(&nbsp;name&nbsp;==&nbsp;seatingRightGuestName,&nbsp;rightGuestSex:sex,&nbsp;rightGuestHobby:hobby&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guest(&nbsp;leftGuestName:name&nbsp;,&nbsp;sex&nbsp;!=&nbsp;rightGuestSex,&nbsp;hobby&nbsp;==&nbsp;rightGuestHobby&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count&nbsp;:&nbsp;Count() &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;排除已经入座的客人 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;原例中使用了Path.id作为一个约束条件，而事实上要排除已经入座的客人只要判断guestName就可以了 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;因此原例中的makePath规则如果注释掉，然后将下面的语句改为 &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;not&nbsp;(&nbsp;Path(&nbsp;guestName&nbsp;==&nbsp;leftGuestName)&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;执行后也可以得到完全相同的结果</span><span>&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Manners是作为规则引擎的测试基准发布的，因此这里完全按照标准实现，所以这里虽然</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 可以进行改进，但是可能因为为了测试规则引擎，因此保留这种算法</span></li>
    <li class=""><span>&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; #</li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(&nbsp;Path(&nbsp;id&nbsp;==&nbsp;seatingId,&nbsp;guestName&nbsp;==&nbsp;leftGuestName)&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;排除入座客人已经和使用过的兴趣，保证两边相邻的客人共同兴趣不一样 &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(&nbsp;Chosen(&nbsp;id&nbsp;==&nbsp;seatingId,&nbsp;guestName&nbsp;==&nbsp;leftGuestName,&nbsp;hobby&nbsp;==&nbsp;rightGuestHobby)&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;rightSeat&nbsp;=&nbsp;seatingRightSeat; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;seatId&nbsp;=&nbsp;seatingId; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;countValue&nbsp;=&nbsp;count.getValue(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;安排一个新的座位 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Seating&nbsp;seating&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Seating(&nbsp;countValue,&nbsp;seatId,&nbsp;</span><span class="keyword">false</span><span>,&nbsp;rightSeat,&nbsp;seatingRightGuestName,&nbsp;rightSeat&nbsp;+&nbsp;</span><span class="number">1</span><span>,&nbsp;leftGuestName&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;seating&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;记录已经入座的客人&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Path&nbsp;path&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Path(&nbsp;countValue,&nbsp;rightSeat&nbsp;+&nbsp;</span><span class="number">1</span><span>,&nbsp;leftGuestName&nbsp;&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;path&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;记录已经使用的兴趣爱好 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Chosen&nbsp;chosen&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Chosen(&nbsp;seatId,&nbsp;leftGuestName,&nbsp;rightGuestHobby&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;chosen&nbsp;&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(&nbsp;</span><span class="string">&quot;find&nbsp;seating&nbsp;:&nbsp;&quot;</span><span>&nbsp;+&nbsp;seating&nbsp;+&nbsp;</span><span class="string">&quot;&nbsp;:&nbsp;&quot;</span><span>&nbsp;+&nbsp;path&nbsp;+&nbsp;</span><span class="string">&quot;&nbsp;:&nbsp;&quot;</span><span>&nbsp;+&nbsp;chosen); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count.setValue(&nbsp;&nbsp;countValue&nbsp;+&nbsp;</span><span class="number">1</span><span>&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;count&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setState(&nbsp;Context.MAKE_PATH&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;context&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract&nbsp;(&nbsp;$s&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>end &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="comment">/* </span>&nbsp; </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;这个规则的执行将为之前所有入座的客人建立一个路径 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;如果使用一个打印语句，部分打印内容如下： </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=1,&nbsp;seat=1,&nbsp;guest=63] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=2,&nbsp;seat=1,&nbsp;guest=63] </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=2,&nbsp;seat=2,&nbsp;guest=52] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=3,&nbsp;seat=2,&nbsp;guest=52] </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=3,&nbsp;seat=1,&nbsp;guest=63] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=3,&nbsp;seat=3,&nbsp;guest=64] </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=4,&nbsp;seat=3,&nbsp;guest=64] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=4,&nbsp;seat=1,&nbsp;guest=63] </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=4,&nbsp;seat=2,&nbsp;guest=52] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=4,&nbsp;seat=4,&nbsp;guest=50] </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=5,&nbsp;seat=4,&nbsp;guest=50] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=5,&nbsp;seat=2,&nbsp;guest=52] </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=5,&nbsp;seat=1,&nbsp;guest=63] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=5,&nbsp;seat=3,&nbsp;guest=64] </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;makePath&nbsp;:[Path&nbsp;id=5,&nbsp;seat=5,&nbsp;guest=62] </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;...... </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;也就是每个id的数值就对应有多少个Path，而事实上这种数据模型对本例来说并不是太需要 </span>&nbsp;</span> </li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;在之前的findSeating规则中有说明。 </span>&nbsp;</span> </li>
    <li class="alt"><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>rule&nbsp;makePath &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.MAKE_PATH&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Seating(&nbsp;seatingId:id,&nbsp;seatingPid:pid,&nbsp;pathDone&nbsp;==&nbsp;</span><span class="keyword">false</span><span>&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$path&nbsp;:&nbsp;Path(&nbsp;id&nbsp;==&nbsp;seatingPid,&nbsp;pathGuestName:guestName,&nbsp;pathSeat:seat&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;Path(&nbsp;id&nbsp;==&nbsp;seatingId,&nbsp;guestName&nbsp;==&nbsp;pathGuestName&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(&nbsp;</span><span class="string">&quot;makePath&nbsp;:&quot;</span><span>&nbsp;+&nbsp;$path&nbsp;&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Path(&nbsp;seatingId,&nbsp;pathSeat,&nbsp;pathGuestName&nbsp;)&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>end&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>#&nbsp;结束座位的路径设置 &nbsp;&nbsp;</span> </li>
    <li class=""><span>rule&nbsp;pathDone &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context&nbsp;:&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.MAKE_PATH&nbsp;)&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seating&nbsp;:&nbsp;Seating(&nbsp;pathDone&nbsp;==&nbsp;</span><span class="keyword">false</span><span>&nbsp;)&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seating.setPathDone(&nbsp;</span><span class="keyword">true</span><span>&nbsp;);&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;seating&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setState(&nbsp;Context.CHECK_DONE&nbsp;);&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;context&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>end &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>#&nbsp;检查是否安排的客人座位已经到达指定人数，结束规则运算 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>rule&nbsp;areWeDone &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context&nbsp;:&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.CHECK_DONE&nbsp;)&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LastSeat(&nbsp;lastSeat:&nbsp;seat&nbsp;) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Seating(&nbsp;rightSeat&nbsp;==&nbsp;lastSeat&nbsp;)&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setState(Context.PRINT_RESULTS&nbsp;);&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;context&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>end &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>#&nbsp;如果之前的areWeDone规则没有允许，则继续座位查找 &nbsp;&nbsp;</span> </li>
    <li class=""><span>rule&nbsp;</span><span class="keyword">continue</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context&nbsp;:&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.CHECK_DONE&nbsp;)&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.setState(&nbsp;Context.ASSIGN_SEATS&nbsp;);&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;context&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>end &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>#&nbsp;打印完成提示 &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>rule&nbsp;allDone &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context&nbsp;:&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.PRINT_RESULTS&nbsp;)&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</span><span class="string">&quot;All&nbsp;Done&quot;</span><span>&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>end &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="comment">//query&nbsp;getResults </span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="comment">//&nbsp;&nbsp;context&nbsp;:&nbsp;Context(&nbsp;state&nbsp;==&nbsp;Context.PRINT_RESULTS&nbsp;)&nbsp; </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="comment">//end&nbsp; </span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span> </li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://hxpwork.javaeye.com/blog/112597#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 15 Aug 2007 16:32:19 +0800</pubDate>
        <link>http://hxpwork.javaeye.com/blog/112597</link>
        <guid>http://hxpwork.javaeye.com/blog/112597</guid>
      </item>
      <item>
        <title>drools4: Conway示例分析</title>
        <author>hxpwork</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hxpwork.javaeye.com">hxpwork</a>&nbsp;
          链接：<a href="http://hxpwork.javaeye.com/blog/110968" style="color:red;">http://hxpwork.javaeye.com/blog/110968</a>&nbsp;
          发表时间: 2007年08月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title"></div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">/* </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Conway:&nbsp;元细胞自动机模型，俗称生命游戏 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;它有些类似于一张围棋棋盘，但是可以更大。每个棋盘上的格子（元细胞）只能是生/死两种状态之一。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;游戏遵循下面的规则 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;1）格子的状态只能是生/死两种状态之一 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;2）格子以其上下左右及斜角方向的8个格子为邻居 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;3）一个格子的生死由其在该时刻本身的生死状态和周围八个邻居的状态&nbsp;(确切讲是状态的和)决定: </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a、在当前时刻，如果一个格子状态为&quot;生&quot;，且八个相邻格子中有两个或三个的状态为&quot;生&quot;， </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;则在下--时刻该格子继续保持为&quot;生&quot;，否则&quot;死&quot;去； </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b、在当前时刻。如果一个格子状态为&quot;死&quot;。且八个相邻格子中正好有三个为&quot;生&quot;。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;则该格子在下一时刻&nbsp;&quot;复活&quot;。否则保持为&quot;死&quot;。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment"></span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;元细胞自动机模型已在多方面得到应用。它的演化规则近似地描述了生物群体的生存繁殖规律: </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;在生命密度过小(相邻元胞数&lt;2)&nbsp;时，由于孤单、缺乏配种繁殖机会、缺乏互助也会出现生命危机，元胞状态值由1变为0; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;在生命密度过大&nbsp;(相邻元胞数&gt;3)时，由于环境恶化、资源短缺以及相互竞争而出现生存危机，元胞状态值由1变为0; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;只有处于个体适中(相邻元胞数为2或3)位置的生物才能生存(保持元胞的状态值为1)和繁衍后代(元胞状态值由0变为1)。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;正由于它能够模拟生命活动中的生存、灭绝、竞争等等复杂现象，因而得名&quot;生命游戏&quot;。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;J&middot;H&middot;Conway还证明，这个元胞自动机具有通用图灵机的计算能力(谢惠民，1994;李才伟，1997)， </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;与图灵机等价，也就是说给定适当的初始条件，生命游戏模型能够模拟任何一种计算机。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment"></span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;本示例设计到界面显示，用到的类比较多，这里简单说明一下每个类的用途，不再详细列举代码 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;AbstractRunConway.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;建立GUI界面 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;ConwayGUI.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在这里定义好了界面，以及按钮相关事件 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;CellGridCanvas.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;绘制界面 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;ConwayRuleFlowGroupRun.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;继承AbstractRunConway，使用规则流模式启动程序 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;ConwayAgendaGroupRun.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;继承AbstractRunConway，使用Agenda组模式启动程序，之前版本不推荐 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;ConwayApplicationProperties.java&nbsp;&nbsp;&nbsp;&nbsp;用于从conway.properties中读取预定义的属性 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;ConwayRuleDelegate.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;作为Agenda和规则流两种模式的统一接口 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*RuleFlowDelegate.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;规则流模式行为响应代理，界面按钮的动作由该类转发给规则引擎，引起WorkingMemory中的变化 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用规则流控制规则执行时，针对应用的不同操作共使用了4组规则流如下： </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;初始化init&nbsp;-&nbsp;规则流&quot;register&nbsp;neighbor&quot; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;产生下一步的变化nextGeneration&nbsp;-&nbsp;规则流&quot;generation&quot;，连续变化通过重复调用该步骤进行 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;清除killAll&nbsp;-&nbsp;规则流&quot;kill&nbsp;all&quot; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;模式设置setPattern&nbsp;-&nbsp;规则流&quot;calculate&quot; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;AgendaGroupDelegate.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Agenda模式行为响应代理，作用同上 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Cell.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代表一个格子，有行列属性和状态属性 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;CellGrid.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;控制表格的抽象接口 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*CellGridImpl.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;表格接口的实现，用于向规则引擎中插入数据，以及调用响应代理 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据的插入分为两种情况 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、初始化棋盘 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将代表棋盘的CellGrid实例插入 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将棋盘上的每一个格子产生一个Cell对象插入 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、设置初始模式 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据提供的模式数组长宽向棋盘中间对齐，对于True的数组数据 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;修改对应格子的Cell状态为Live </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;CellState.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;格子状态（生/死） </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Phase.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在规则中用于控制格子处理的阶段，间接影响格子的状态 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Neighbor.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用于保存两个格子之间的邻居关系 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;ConwayPattern.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;模型初始化数据读取接口 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Border.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一种模型初始格式，实现ConwayPattern接口 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Hi.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同上 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Pentadecathalon.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同上 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Pulsar.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同上 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;SimpleGlider.java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同上&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;思路： </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从元细胞自动机模型的规则中我们可以发现几个关键要点， </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、一个格子的状态由相邻格子的状态决定；因此在规则处理中我们要能够方便的确定每个格子的相邻格子情况 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、格子的状态变化是一次性完成计算的，格子状态的改变不会对本次变化产生影响；因此在规则处理时要注意 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;解决fact变化激活新的规则的问题 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;作者将所有规则按照规则流分组的方式分为下面几个组 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;register&nbsp;north&nbsp;east&quot;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;建立格子间的邻居关系（再次提醒，规则引擎推理基于数据，应当将所有需要的数据事先准备好 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据模型的好坏直接影响规则的效率和质量） </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;evaluate&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;根据格子邻居的情况判定格子下一步的状态，并预设一个值；这里之所以没有直接改变格子 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;状态就是因为上面提到的一次性计算问题，如果直接改变状态会影响对其它邻居格子的判断 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Phase：只对Phase==EVALUATE的格子执行 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;calculate&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;遍历每一个格子，根据该格子的生存/死亡状态更新邻居格子的&lsquo;邻居&rsquo;生存个数 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里留意的是，按照正常的编程思路，应当是找到格子后获得所有邻居状态，然后计算有多少 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;个邻居格子是生存状态的，然后更新本格子中的LiveNeighbors计数；但是要采用这样的 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;思路，必然涉及到对集合的处理以及一些循环语句，这样增加了规则的复杂度以及引入了过程 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代码，这都是在规则中应当避免的问题；而换一个角度思考我们就会得到更为简单的规则。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Phase：规则完成后将格子的Phase设为EVALUATE </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注：使用规则引擎不只是掌握一门新技术，而是要求在编程思维上的改变。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;reset&nbsp;calculate&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;取消&quot;calculate&quot;组激活的规则，因为每次格子重新设置pattern时，盘面上还有生存的格子 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这时如果使用kill&nbsp;all规则来将格子设为死亡，如果之前的calcuate规则还起作用，那么就会 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;引起calcuate规则执行，建立新的生存格子，反过来又会引起kill&nbsp;all规则执行，造成无限循环 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;kill&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;将Phase为KILL的格子状态设为死亡 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;birth&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;将Phase为BIRTH的格子状态设为生存 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;kill&nbsp;all&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;将所有格子的状态设为死亡，是用在初始化棋盘时 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">package</span><span>&nbsp;org.drools.examples &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.drools.examples.conway.Cell; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;org.drools.examples.conway.CellGrid; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.drools.examples.conway.Neighbor; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;org.drools.examples.conway.Phase; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.drools.examples.conway.CellState; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.drools.WorkingMemory; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;org.drools.common.InternalWorkingMemoryActions; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.drools.RuleBase; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="comment">/* </span>&nbsp;</li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;下面的四条规则都属于ruleflow-group：&quot;register&nbsp;neighbor&quot; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;它们的作用是建立格子之间彼此的邻居关系。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;我们知道每个格子会有8个相邻的格子，而规则建立关系时都是成对建立的， </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;因此只用四条规则即可完成所有邻居关系建立 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>#&nbsp;建立格子与其右上角格子的邻居关系 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;register&nbsp;north&nbsp;east&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;register&nbsp;neighbor&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;获得棋盘列数 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;CellGrid(&nbsp;$numberOfColumns&nbsp;:&nbsp;numberOfColumns&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;获得棋盘内的每个格子，最右边除外，因为最右边没有右上角 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;$cell:&nbsp;Cell(&nbsp;$row&nbsp;:&nbsp;row&nbsp;&gt;&nbsp;</span><span class="number">0</span><span>,&nbsp;$col&nbsp;:&nbsp;col&nbsp;&lt;&nbsp;(&nbsp;$numberOfColumns&nbsp;-&nbsp;</span><span class="number">1</span><span>&nbsp;)&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;获得上面格子的东北角格子&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;$northEast&nbsp;:&nbsp;Cell(&nbsp;row&nbsp;&nbsp;==&nbsp;($row&nbsp;-&nbsp;</span><span class="number">1</span><span>),&nbsp;col&nbsp;==&nbsp;(&nbsp;$col&nbsp;+&nbsp;</span><span class="number">1</span><span>&nbsp;)&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;为这两个格子建立邻居关系 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$cell,&nbsp;$northEast&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$northEast,&nbsp;$cell&nbsp;)&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;建立格子与其正上方格子的邻居关系 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;register&nbsp;north&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;register&nbsp;neighbor&quot;</span><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$cell:&nbsp;Cell(&nbsp;$row&nbsp;:&nbsp;row&nbsp;&gt;&nbsp;</span><span class="number">0</span><span>,&nbsp;$col&nbsp;:&nbsp;col&nbsp;)&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;$north&nbsp;:&nbsp;Cell(&nbsp;row&nbsp;&nbsp;==&nbsp;($row&nbsp;-&nbsp;</span><span class="number">1</span><span>),&nbsp;col&nbsp;==&nbsp;$col&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$cell,&nbsp;$north&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$north,&nbsp;$cell&nbsp;)&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>end &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;建立格子与其左上角格子的邻居关系 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;register&nbsp;north&nbsp;west&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;register&nbsp;neighbor&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>when &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;$cell:&nbsp;Cell(&nbsp;$row&nbsp;:&nbsp;row&nbsp;&gt;&nbsp;</span><span class="number">0</span><span>,&nbsp;$col&nbsp;:&nbsp;col&nbsp;&gt;&nbsp;</span><span class="number">0</span><span>&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$northWest&nbsp;:&nbsp;Cell(&nbsp;row&nbsp;&nbsp;==&nbsp;($row&nbsp;-&nbsp;</span><span class="number">1</span><span>),&nbsp;col&nbsp;==&nbsp;(&nbsp;$col&nbsp;-&nbsp;</span><span class="number">1</span><span>&nbsp;)&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$cell,&nbsp;$northWest&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$northWest,&nbsp;$cell&nbsp;)&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;建立格子与其左边格子的邻居关系 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;register&nbsp;west&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;register&nbsp;neighbor&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$cell:&nbsp;Cell(&nbsp;$row&nbsp;:&nbsp;row&nbsp;&gt;=&nbsp;</span><span class="number">0</span><span>,&nbsp;$col&nbsp;:&nbsp;col&nbsp;&gt;&nbsp;</span><span class="number">0</span><span>&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;$west&nbsp;:&nbsp;Cell(&nbsp;row&nbsp;&nbsp;==&nbsp;$row,&nbsp;col&nbsp;==&nbsp;(&nbsp;$col&nbsp;-&nbsp;</span><span class="number">1</span><span>&nbsp;)&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$cell,&nbsp;$west&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Neighbor(&nbsp;$west,&nbsp;$cell&nbsp;)&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>end &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="comment">/* </span>&nbsp;</li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;下面的三条规则都属于ruleflow-group：&quot;evaluate&quot; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;它们是用在进行下一步的变化评估中的，这3个规则中并没有直接改变Cell.CellState, </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;因为CellState是用来进行评估用的，随意改变会造成无限的循环调用，因此规则使用了Phase字段来控制格子状态变化 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;在评估中只是改变Phase，最后根据Phase的状态完成所有格子CellState的设置，并将Phase设回EVALUATE状态 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;将格子的邻居中少于两个是生存状态的格子的状态设为死 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Kill&nbsp;The&nbsp;Lonely&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;evaluate&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;no-loop &nbsp;&nbsp;</span></li>
    <li class="alt"><span>when &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;&nbsp;&nbsp;A&nbsp;live&nbsp;cell&nbsp;has&nbsp;fewer&nbsp;than&nbsp;</span><span class="number">2</span><span>&nbsp;live&nbsp;neighbors &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(liveNeighbors&nbsp;&lt;&nbsp;</span><span class="number">2</span><span>,&nbsp;cellState&nbsp;==&nbsp;CellState.LIVE,&nbsp;phase&nbsp;==&nbsp;Phase.EVALUATE) &nbsp;&nbsp;</span></li>
    <li class=""><span>then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setPhase(Phase.KILL); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;theCell&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;将格子的邻居中超过</span><span class="number">3</span><span>个状态是生存的格子状态设为死 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Kill&nbsp;The&nbsp;Overcrowded&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;evaluate&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;no-loop &nbsp;&nbsp;</span></li>
    <li class="alt"><span>when &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;&nbsp;&nbsp;A&nbsp;live&nbsp;cell&nbsp;has&nbsp;more&nbsp;than&nbsp;</span><span class="number">3</span><span>&nbsp;live&nbsp;neighbors &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(liveNeighbors&nbsp;&gt;&nbsp;</span><span class="number">3</span><span>,&nbsp;cellState&nbsp;==&nbsp;CellState.LIVE,&nbsp;phase&nbsp;==&nbsp;Phase.EVALUATE) &nbsp;&nbsp;</span></li>
    <li class=""><span>then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setPhase(Phase.KILL); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;theCell&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;将格子的邻居中正好有</span><span class="number">3</span><span>个是生存状态的死亡格子变为生 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Give&nbsp;Birth&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;evaluate&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;no-loop &nbsp;&nbsp;</span></li>
    <li class="alt"><span>when &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;&nbsp;&nbsp;A&nbsp;dead&nbsp;cell&nbsp;has&nbsp;</span><span class="number">3</span><span>&nbsp;live&nbsp;neighbors &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(liveNeighbors&nbsp;==&nbsp;</span><span class="number">3</span><span>,&nbsp;cellState&nbsp;==&nbsp;CellState.DEAD,&nbsp;phase&nbsp;==&nbsp;Phase.EVALUATE) &nbsp;&nbsp;</span></li>
    <li class=""><span>then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setPhase(Phase.BIRTH); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;theCell&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;取消ruleflow-group为</span><span class="string">&quot;calculate&quot;</span><span>的所有激活规则 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;clearRuleFlowGroup&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;Clears&nbsp;the&nbsp;RuleFlow&nbsp;group,&nbsp;cancelling&nbsp;all&nbsp;its&nbsp;Activations &nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;因为在</span><span class="string">&quot;generation&quot;</span><span>后，</span><span class="string">&quot;calculate&quot;</span><span>组的规则还留在引擎中，如果不事先取消，就会引起无限循环 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;reset&nbsp;calculate&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;reset&nbsp;calculate&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;WorkingMemory&nbsp;wm&nbsp;=&nbsp;drools.getWorkingMemory(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;wm.clearRuleFlowGroup(&nbsp;</span><span class="string">&quot;calculate&quot;</span><span>&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>end &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;将所有格子的Phase为Kill的格子状态设置为死，并将处理阶段Phase设置为DONE &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;kill&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;kill&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;no-loop &nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(phase&nbsp;==&nbsp;Phase.KILL) &nbsp;&nbsp;</span></li>
    <li class=""><span>then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setCellState(CellState.DEAD); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setPhase(Phase.DONE);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;theCell&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>end&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;将所有格子的Phase为Birth的格子状态设置为生，并将处理阶段Phase设置为完成 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;birth&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;birth&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;no-loop &nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(phase&nbsp;==&nbsp;Phase.BIRTH) &nbsp;&nbsp;</span></li>
    <li class=""><span>then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setCellState(CellState.LIVE); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setPhase(Phase.DONE); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;theCell&nbsp;);&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>end&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;根据格子的生存状态改变邻居格子中LiveNeighbors属性的计数 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Calculate&nbsp;Live&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;calculate&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;lock-on-active&nbsp;&nbsp;#&nbsp;本规则更新的数据在规则流处理完成前不激活新的规则 &nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;获得状态为生存的格子 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(cellState&nbsp;==&nbsp;CellState.LIVE) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;找到该格子的每一个邻居 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Neighbor(cell&nbsp;==&nbsp;theCell,&nbsp;$neighbor&nbsp;:&nbsp;neighbor)&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;为这个格子的每一个邻居的LiveNeighbors属性加</span><span class="number">1</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$neighbor.setLiveNeighbors(&nbsp;$neighbor.getLiveNeighbors()&nbsp;+&nbsp;</span><span class="number">1</span><span>&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;将邻居格子的处理阶段Phase设置为EVALUATE &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$neighbor.setPhase(&nbsp;Phase.EVALUATE&nbsp;);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;$neighbor&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</span><span class="string">&quot;--live--&quot;</span><span>&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</span><span class="string">&quot;theCell:&nbsp;row&quot;</span><span>+theCell.getRow()+</span><span class="string">&quot;col&quot;</span><span>+theCell.getCol()); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(&nbsp;</span><span class="string">&quot;Neighbor:&nbsp;row:&quot;</span><span>+$neighbor.getRow()+</span><span class="string">&quot;col&quot;</span><span>+$neighbor.getCol()+</span><span class="string">&quot;;LiveNeighbors:&quot;</span><span>+&nbsp;$neighbor.getLiveNeighbors())&nbsp;; &nbsp;&nbsp;</span></li>
    <li class=""><span>end&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;类似上一规则，只是进行递减操作 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;对于这个规则，不太熟悉规则引擎的程序员可能会有所迷惑，所有的格子初始化状态都是DEAD &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;那这样的话很多格子的LiveNeighbors就会变成负数了，有这样的想法是因为忽略了规则引擎不是从数据里找到规则合适的地方 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;而是在数据插入或发生变化时找到规则，一开始初始化所有格子为DEAD时确实激活了</span><span class="string">&quot;Calculate&nbsp;Dead&quot;</span><span>的很多实例，但是在 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;setPattern时首先执行了</span><span class="string">&quot;reset&nbsp;calculate&quot;</span><span>，这取消了之前的所有</span><span class="string">&quot;Calculate&nbsp;Dead&quot;</span><span>的激活实例 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;然后运行</span><span class="string">&quot;kill&nbsp;all&quot;</span><span>规则，如果是第一次，该规则不改变任何数据也不会激发新的规则 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;然后是根据数据设置格子的生存状态，此时上面的</span><span class="string">&quot;Calculate&nbsp;Live&quot;</span><span>规则被激活 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;在后面的规则运算中每次执行</span><span class="string">&quot;evalaute&quot;</span><span>规则组都要运行</span><span class="string">&quot;reset&nbsp;calculate&quot;</span><span>也是这个原因 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;然后在运行了</span><span class="string">&quot;birth&quot;</span><span>和</span><span class="string">&quot;kill&quot;</span><span>规则后才执行</span><span class="string">&quot;Calculate&nbsp;Live&quot;</span><span>和</span><span class="string">&quot;Calculate&nbsp;Dead&quot;</span><span>规则 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Calculate&nbsp;Dead&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;calculate&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;lock-on-active&nbsp;#&nbsp;本规则更新的数据在规则流处理完成前不激活新的规则 &nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(cellState&nbsp;==&nbsp;CellState.DEAD) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Neighbor(cell&nbsp;==&nbsp;theCell,&nbsp;$neighbor&nbsp;:&nbsp;neighbor&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;$neighbor.setLiveNeighbors(&nbsp;$neighbor.getLiveNeighbors()&nbsp;-&nbsp;</span><span class="number">1</span><span>&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$neighbor.setPhase(&nbsp;Phase.EVALUATE&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;$neighbor&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</span><span class="string">&quot;--dead--&quot;</span><span>&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</span><span class="string">&quot;theCell:&nbsp;row&quot;</span><span>+theCell.getRow()+</span><span class="string">&quot;col&quot;</span><span>+theCell.getCol()); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(&nbsp;</span><span class="string">&quot;Neighbor:&nbsp;row:&quot;</span><span>+$neighbor.getRow()+</span><span class="string">&quot;col&quot;</span><span>+$neighbor.getCol()+</span><span class="string">&quot;;LiveNeighbors:&quot;</span><span>+&nbsp;$neighbor.getLiveNeighbors())&nbsp;; &nbsp;&nbsp;</span></li>
    <li class=""><span>end&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;将所有生存状态的格子设为死亡 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Kill&nbsp;All&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ruleflow-group&nbsp;</span><span class="string">&quot;kill&nbsp;all&quot;</span><span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;no-loop &nbsp;&nbsp;</span></li>
    <li class=""><span>when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell:&nbsp;Cell(cellState&nbsp;==&nbsp;CellState.LIVE) &nbsp;&nbsp;</span></li>
    <li class=""><span>then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;theCell.setCellState(CellState.DEAD); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;update(&nbsp;theCell&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end&nbsp;&nbsp;</span></li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://hxpwork.javaeye.com/blog/110968#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 10 Aug 2007 18:24:51 +0800</pubDate>
        <link>http://hxpwork.javaeye.com/blog/110968</link>
        <guid>http://hxpwork.javaeye.com/blog/110968</guid>
      </item>
      <item>
        <title>Drools4：对Sudoku示例的分析</title>
        <author>hxpwork</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hxpwork.javaeye.com">hxpwork</a>&nbsp;
          链接：<a href="http://hxpwork.javaeye.com/blog/109129" style="color:red;">http://hxpwork.javaeye.com/blog/109129</a>&nbsp;
          发表时间: 2007年08月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title"></div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">/* </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;Sodu：数独游戏，一个9x9的方格棋盘中，按照每三行三列再细分为9个小棋盘,如下 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|a|a|a|b|b|b|c|c|c| </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|a|a|a|b|b|b|c|c|c| </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|a|a|a|b|b|b|c|c|c| </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|d|d|d|e|e|e|f|f|f| </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|d|d|d|e|e|e|f|f|f| </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|d|d|d|e|e|e|f|f|f| </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|g|g|g|h|h|h|i|i|i| </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|g|g|g|h|h|h|i|i|i| </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|g|g|g|h|h|h|i|i|i| </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中a,b...i分别代表大棋盘中的9个小棋盘，规则是： </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、使用1-9，九个数字填入字母a-i所在位置 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、大棋盘上的每一行，每一列都不能有重复数字 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、小棋盘上也不能有重复的数字 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数独游戏实际上是一个推理游戏，与数字计算无关；首先会随机产生一些数字在棋盘上，然后游戏者完成剩下的填空 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;数独游戏通常会在棋盘上事先准备好一些数字，然后由游戏者完成剩下的格子。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;如何使用规则引擎完成这一任务呢？ </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;--首先我们要对Drools这种正向推理性的引擎有一个认识前提，就是它是基于数据进行规则推导的， </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;也就是说如果需要规则引擎帮你找到结果，那首先必须将所有可能的结果都准备好。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;这一方法在Golfer球员排序时也使用过，当时是将所有球员组合情况都放到引擎中，由引擎自己找出答案。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;那么现在我们第一步要做的就是在所有未确定数据的空格子位置上准备所有可能的结果，也就是在那里放上从1-9的数字，最后由引擎自己挑选。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;现在我们在每个空格子里面都准备好了数据，那么下面就是要将格子中无关的数据去掉，如果剩下一个，那显然就是答案了。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;要如何去掉格子中无效的数据呢？那显然就是要遵循行、列、区域中都不能有重复数字的规则了。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;设想一下，获得某一行上有数据的格子，那么空格子中与这些格子的数据显然就不能重复，这样就可以排除掉无用的数据。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;依次类推，在列与区域中也进行这样的检查，那么最终会有空格子的可选数据会只剩一个，此时就将该可选数据转换为正式数据， </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;同时又会引发新的筛选，进一步减少可选值。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;但是这样的规则够了吗？从实际效果上看显然是不够的，因为在很多情况下，这样的规则并不能确定所有格子的值，还需要继续的挖掘潜在的规则。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;从游戏的原则中我们又可以推导从下面的规则： </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;如果在一个区域/行/列内，某一个空格子上的可选值在这个区域/行/列里是唯一的，并且不会违反行列区域已有数字冲突的原则，那么该可选值就是格子真正的数字。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;采用了这个规则后，大部分的格子可以完成推导，有时甚至可以完成全部格子推导，但是仍然存在不可以得到结果的情况。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;或许对于数学非常精通的程序员，可以通过数学定理推导规则是否可以满足所有情况，但是作为大多数人，多测试是唯一的办法。 </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;这也提醒我们，使用规则引擎解决复杂推理问题时，一定要多想多测试，并尽可能找到显式规则以及所有的潜在规则， </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;宁多勿缺，只要规则正确，最多就是走走弯路，好过没有完成任务！ </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;最后我们再找到一组潜在的规则 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;如果在区域中有两个格子都只剩两个可选值，并且这两个可选值一样的情况下，显然这两个格子只能是这两个可选值中的一个； </span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;这时删除区域中其它空格子中相同的可选值。 </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>Fact 插入</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>StatefulSession&nbsp;session&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Collection&nbsp;fields&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ArrayList(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;对于数独阵列中的每一个格子有4个属性：数字，行，列，区域 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;下面就是根据这四个属性建立Fact数据，顺便将每一行数据打印出来 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(&nbsp;</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;field.length;&nbsp;i++&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;row&nbsp;=&nbsp;</span><span class="string">&quot;{&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(&nbsp;</span><span class="keyword">int</span><span>&nbsp;j&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;j&nbsp;&lt;&nbsp;field[i].length;&nbsp;j++&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;+=&nbsp;field[i][j]&nbsp;+&nbsp;</span><span class="string">&quot;,&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fields.add(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Field(&nbsp;</span><span class="string">&quot;&quot;</span><span>&nbsp;+&nbsp;field[i][j], &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;+&nbsp;</span><span class="number">1</span><span>, &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;+&nbsp;</span><span class="number">1</span><span>, &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getZone(&nbsp;i, &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;)&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;+=&nbsp;</span><span class="string">&quot;}&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;row&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;启动规则引擎 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;RuleBase&nbsp;ruleBase&nbsp;=&nbsp;readRule(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;session&nbsp;=&nbsp;ruleBase.newStatefulSession(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;将每一个Field实例插入WorkingMemory，同时保存FachHandle </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Iterator&nbsp;iter&nbsp;=&nbsp;fields.iterator(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Collection&nbsp;handles&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ArrayList(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>&nbsp;(&nbsp;iter.hasNext()&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handles.add(&nbsp;session.insert(&nbsp;iter.next()&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;session.fireAllRules(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</span><span class="string">&quot;Size:&nbsp;&quot;</span><span>&nbsp;+&nbsp;iteratorToList(&nbsp;session.iterateObjects()&nbsp;).size()&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;完成计算以后将数据写回阵列 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;iter&nbsp;=&nbsp;session.iterateObjects(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//Copy&nbsp;the&nbsp;values&nbsp;of&nbsp;the&nbsp;fields&nbsp;into&nbsp;the&nbsp;matrix </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>&nbsp;(&nbsp;iter.hasNext()&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;next&nbsp;=&nbsp;iter.next(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(&nbsp;next&nbsp;</span><span class="keyword">instanceof</span><span>&nbsp;Field&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;field[((Field)&nbsp;next).getRow()&nbsp;-&nbsp;</span><span class="number">1</span><span>][((Field)&nbsp;next).getColumn()&nbsp;-&nbsp;</span><span class="number">1</span><span>]&nbsp;=&nbsp;Integer.parseInt(&nbsp;((Field)&nbsp;next).getValue()&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;打印结果 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(&nbsp;</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;field.length;&nbsp;i++&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;row&nbsp;=&nbsp;</span><span class="string">&quot;{&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(&nbsp;</span><span class="keyword">int</span><span>&nbsp;j&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;j&nbsp;&lt;&nbsp;field[i].length;&nbsp;j++&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;+=&nbsp;field[i][j]&nbsp;+&nbsp;</span><span class="string">&quot;,&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;+=&nbsp;</span><span class="string">&quot;}&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;row&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(&nbsp;Throwable&nbsp;t&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;t.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;</span><span class="keyword">finally</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(&nbsp;session&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>&nbsp;)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.dispose(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>规则</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>#&nbsp;首先将所有数字为</span><span class="number">0</span><span>的格子删除，并对这个格子插入从</span><span class="number">1</span><span>-</span><span class="number">9</span><span>的所有可能情况 &nbsp;&nbsp;</span></span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;1:&nbsp;If&nbsp;a&nbsp;field&nbsp;has&nbsp;the&nbsp;value&nbsp;0,&nbsp;it&nbsp;is&nbsp;empty:&nbsp;remove&nbsp;it&nbsp;and&nbsp;insert&nbsp;the&nbsp;PossibleValues&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">100</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$field&nbsp;:&nbsp;Field(&nbsp;value&nbsp;==&nbsp;</span><span class="number">0</span><span>,&nbsp;$row&nbsp;:&nbsp;row,&nbsp;$column&nbsp;:&nbsp;column,&nbsp;$zone&nbsp;:&nbsp;zone&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;1&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;2&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;3&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;4&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;5&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;6&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;7&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;8&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;PossibleValue(</span><span class="string">&quot;9&quot;</span><span>,&nbsp;$field&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;插入完毕后删除Field，因为该Field中的数据不是我们所需要的， </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;我们需要的只是它的位置信息，而这些是不变的，已经在PossibleValue初始化时保留。 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$field&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;1&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;这个规则是当某一个格子上的PossibleValue只剩下一个时，那么这个PossibleValue的值就是要寻找的值 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;2:&nbsp;If&nbsp;there&nbsp;is&nbsp;one&nbsp;PossibleValue&nbsp;left&nbsp;at&nbsp;a&nbsp;certain&nbsp;position,&nbsp;it&nbsp;should&nbsp;be&nbsp;the&nbsp;Fields&nbsp;value&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">5</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$pv&nbsp;:&nbsp;PossibleValue&nbsp;(&nbsp;$row&nbsp;:&nbsp;row,&nbsp;$zone&nbsp;:&nbsp;zone,&nbsp;$column&nbsp;:&nbsp;column,&nbsp;$value&nbsp;:&nbsp;value&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(&nbsp;PossibleValue&nbsp;(&nbsp;row&nbsp;==&nbsp;$row,&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;column&nbsp;==&nbsp;$column,&nbsp;value&nbsp;!=&nbsp;$value&nbsp;)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Field(&nbsp;$value,&nbsp;$column,&nbsp;$row,&nbsp;$zone&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(&nbsp;</span><span class="string">&quot;Field&nbsp;be&nbsp;found&nbsp;in&nbsp;row=&quot;</span><span>+$row+</span><span class="string">&quot;;col=&quot;</span><span>+$column+</span><span class="string">&quot;value=&quot;</span><span>+$value&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$pv&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;2&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;获得行中已确定的数字，将该行上空格子中的相同备选数字删除 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;3:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;field&nbsp;with&nbsp;a&nbsp;value&nbsp;in&nbsp;a&nbsp;row,&nbsp;remove&nbsp;all&nbsp;PossibleValues&nbsp;with&nbsp;this&nbsp;value&nbsp;in&nbsp;this&nbsp;row&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">15</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$field2&nbsp;:&nbsp;Field(&nbsp;$row&nbsp;:&nbsp;row,&nbsp;$value&nbsp;:&nbsp;value&nbsp;!=&nbsp;</span><span class="number">0</span><span>&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$possible&nbsp;:&nbsp;PossibleValue(&nbsp;row&nbsp;==&nbsp;$row,&nbsp;value&nbsp;==&nbsp;$value&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$possible&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;3&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>end &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;获得列中已确定的数字，将该列上空格子中的相同备选数字删除 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;4:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;field&nbsp;with&nbsp;a&nbsp;value&nbsp;in&nbsp;a&nbsp;column,&nbsp;remove&nbsp;all&nbsp;PossibleValues&nbsp;with&nbsp;this&nbsp;value&nbsp;in&nbsp;this&nbsp;column&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">15</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$field1&nbsp;:&nbsp;Field(&nbsp;$column&nbsp;:&nbsp;column,&nbsp;$value&nbsp;:&nbsp;value&nbsp;!=&nbsp;</span><span class="number">0</span><span>&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$possible&nbsp;:&nbsp;PossibleValue(&nbsp;column&nbsp;==&nbsp;$column,&nbsp;value&nbsp;==&nbsp;$value&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$possible&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;4&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;获得区域中已确定的数字，将该区域上空格子中的相同备选数字删除 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;5:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;field&nbsp;with&nbsp;a&nbsp;value&nbsp;in&nbsp;a&nbsp;zone,&nbsp;remove&nbsp;all&nbsp;PossibleValues&nbsp;with&nbsp;this&nbsp;value&nbsp;in&nbsp;this&nbsp;zone&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">15</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$field1&nbsp;:&nbsp;Field(&nbsp;$zone&nbsp;:&nbsp;zone,&nbsp;$value&nbsp;:&nbsp;value&nbsp;!=&nbsp;</span><span class="number">0</span><span>&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$possible&nbsp;:&nbsp;PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;value&nbsp;==&nbsp;$value&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$possible&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;5&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>end &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;一旦产生新的格子数字，则删除在这个格子上的所有可选值 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;Rule&nbsp;</span><span class="number">2</span><span>,</span><span class="number">3</span><span>,</span><span class="number">4</span><span>,</span><span class="number">5</span><span>&nbsp;不会引起该规则的调用，因为这几个规则是将其它可选值删除后剩余的值设为格子数字。 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;该规则是由Rule&nbsp;</span><span class="number">7</span><span>，</span><span class="number">8</span><span>，</span><span class="number">9</span><span>激发的 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;6:&nbsp;For&nbsp;fields&nbsp;with&nbsp;a&nbsp;value&nbsp;remove&nbsp;all&nbsp;PossibleValues&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">250</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Field(&nbsp;value&nbsp;!=&nbsp;</span><span class="number">0</span><span>,&nbsp;$col&nbsp;:&nbsp;column,&nbsp;$row&nbsp;:&nbsp;row,&nbsp;$zone&nbsp;:&nbsp;zone&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$pv&nbsp;:&nbsp;PossibleValue(&nbsp;column&nbsp;==&nbsp;$col,&nbsp;row&nbsp;==&nbsp;$row,&nbsp;zone&nbsp;==&nbsp;$zone&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$pv&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;6&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;如果在一个小区域内，某一个空格子上的可选值在这个区域里是唯一的 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;并且不会违反行列区域数字冲突的原则，那么该可选值就是格子真正的数字 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;7:&nbsp;If&nbsp;there&nbsp;is&nbsp;only&nbsp;one&nbsp;PossibleValue&nbsp;left&nbsp;in&nbsp;a&nbsp;zone,&nbsp;it&nbsp;must&nbsp;have&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;field&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">4</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$pv&nbsp;:&nbsp;PossibleValue(&nbsp;$zone&nbsp;:&nbsp;zone,&nbsp;$value&nbsp;:&nbsp;value,&nbsp;$col&nbsp;:&nbsp;column,&nbsp;$row&nbsp;:&nbsp;row) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;value&nbsp;==&nbsp;$value&nbsp;)) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;zone&nbsp;==&nbsp;$zone)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;row&nbsp;==&nbsp;$row)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;column&nbsp;==&nbsp;$col)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Field(&nbsp;$value,&nbsp;$col,&nbsp;$row,&nbsp;$zone&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$pv&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;7&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;如果在一列上，某一个空格子上的可选值在这个列上是唯一的 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;并且不会违反行列区域数字冲突的原则，那么该可选值就是格子真正的数字 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;8:&nbsp;If&nbsp;there&nbsp;is&nbsp;only&nbsp;one&nbsp;PossibleValue&nbsp;left&nbsp;in&nbsp;a&nbsp;column,&nbsp;it&nbsp;must&nbsp;have&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;field&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">4</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$pv1&nbsp;:&nbsp;PossibleValue(&nbsp;$zone&nbsp;:&nbsp;zone,&nbsp;$value&nbsp;:&nbsp;value,&nbsp;$col&nbsp;:&nbsp;column,&nbsp;$row&nbsp;:&nbsp;row) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(PossibleValue(&nbsp;column&nbsp;==&nbsp;$col,&nbsp;value&nbsp;==&nbsp;$value&nbsp;)) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;zone&nbsp;==&nbsp;$zone)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;row&nbsp;==&nbsp;$row)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;column&nbsp;==&nbsp;$col)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Field(&nbsp;$value,&nbsp;$col,&nbsp;$row,&nbsp;$zone&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$pv1&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;8&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;如果在一行上，某一个空格子上的可选值在这个行上是唯一的 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;并且不会违反行列区域数字冲突的原则，那么该可选值就是格子真正的数字 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;9:&nbsp;If&nbsp;there&nbsp;is&nbsp;only&nbsp;one&nbsp;PossibleValue&nbsp;left&nbsp;in&nbsp;a&nbsp;row,&nbsp;it&nbsp;must&nbsp;have&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;field&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">4</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$pv&nbsp;:&nbsp;PossibleValue(&nbsp;$zone&nbsp;:&nbsp;zone,&nbsp;$value&nbsp;:&nbsp;value,&nbsp;$col&nbsp;:&nbsp;column,&nbsp;$row&nbsp;:&nbsp;row) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(PossibleValue(&nbsp;row&nbsp;==&nbsp;$row,&nbsp;value&nbsp;==&nbsp;$value&nbsp;)) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;zone&nbsp;==&nbsp;$zone)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;row&nbsp;==&nbsp;$row)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(Field(&nbsp;value&nbsp;==&nbsp;$value,&nbsp;column&nbsp;==&nbsp;$col)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(&nbsp;</span><span class="keyword">new</span><span>&nbsp;Field(&nbsp;$value,&nbsp;$col,&nbsp;$row,&nbsp;$zone&nbsp;)&nbsp;); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$pv&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;9&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;如果在一个区域中的两个空格子只剩两个可选值，则删除该区域中与这两个可选值相同的其它可选值 &nbsp;&nbsp;</span></li>
    <li class=""><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;10:&nbsp;If&nbsp;there&nbsp;are&nbsp;two&nbsp;fields&nbsp;with&nbsp;only&nbsp;two&nbsp;possible&nbsp;values,&nbsp;remove&nbsp;the&nbsp;PossibleValues&nbsp;for&nbsp;the&nbsp;same&nbsp;Value&nbsp;in&nbsp;the&nbsp;rest&nbsp;of&nbsp;the&nbsp;zone&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">1</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;找到一个可选值A &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PossibleValue(&nbsp;$zone&nbsp;:&nbsp;zone,&nbsp;$val1&nbsp;:&nbsp;value,&nbsp;$row1&nbsp;:&nbsp;row,&nbsp;$col1&nbsp;:&nbsp;column&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;要求在相同区域中，不同列上具有与A数字相同的可选值C &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;value&nbsp;==&nbsp;$val1,&nbsp;$row2&nbsp;:&nbsp;row,&nbsp;$col2&nbsp;:&nbsp;column&nbsp;!=&nbsp;$col1) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;要求与A在同一个格子里有其它可选值B &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;row&nbsp;==&nbsp;$row1,&nbsp;column&nbsp;==&nbsp;$col1,&nbsp;$val2&nbsp;:&nbsp;value&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;要求在C的格子里有与B的数字相同的可选值 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;row&nbsp;==&nbsp;$row2,&nbsp;column&nbsp;==&nbsp;$col2,&nbsp;value&nbsp;==&nbsp;$val2&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;要求在A格子中不存在除A与B的数字以外的可选值，也就是说A格子中的可选值不超过两个 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(&nbsp;PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;row&nbsp;==&nbsp;$row1,&nbsp;column&nbsp;==&nbsp;$col1,&nbsp;value&nbsp;!=&nbsp;$val1,&nbsp;value&nbsp;!=&nbsp;$val2&nbsp;)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;要求在C格子中不存在除A与B的数字以外的可选值，也就是说C格子中的可选值不超过两个 &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;这两个not条件组合起来要表达的就是区域中有A，C两个格子中的可选值一样，并且只有两个 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;(&nbsp;PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;row&nbsp;==&nbsp;$row2,&nbsp;column&nbsp;==&nbsp;$col2,&nbsp;value&nbsp;!=&nbsp;$val1,&nbsp;value&nbsp;!=&nbsp;$val2&nbsp;)&nbsp;) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;获得区域中与A数字相同的其它可选值 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$pv&nbsp;:&nbsp;PossibleValue(&nbsp;zone&nbsp;==&nbsp;$zone,&nbsp;value&nbsp;==&nbsp;$val1) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;then &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retract(&nbsp;$pv&nbsp;); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#System.out.println(</span><span class="string">&quot;Rule&nbsp;10&nbsp;fired.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>end &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#&nbsp;如果在一个区域中的两个空格子只剩两个可选值，则删除该区域中与这两个可选值相同的其它可选值 &nbsp;&nbsp;</span></li>
    <li class=""><span>#&nbsp;本规则与上一规则基本一样区别是寻找C格子时使用不同行而不是不同列 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>rule&nbsp;</span><span class="string">&quot;Rule&nbsp;11:&nbsp;If&nbsp;there&nbsp;are&nbsp;two&nbsp;fields&nbsp;with&nbsp;only&nbsp;two&nbsp;possible&nbsp;values,&nbsp;remove&nbsp;the&nbsp;PossibleValues&nbsp;for&nbsp;the&nbsp;same&nbsp;Value&nbsp;in&nbsp;the&nbsp;rest&nbsp;of&nbsp;the&nbsp;zone&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;salience&nbsp;</span><span class="number">1</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;when &nbsp;&nbsp;</span></li>
    <li cl