三个僧侣过河问题模拟实现(原创)

今天突然想起以前同事提到过的一个过河问题,游戏设计思路

需要使用程序代码体现其过程,心血来潮,来一把.....如下:

 三个僧侣和三个食人族过河
 目的:需要把他们六个一起使用一条船送到河的对面岸上
 条件:当食人族的数目超出僧侣的数目时,就会出现食人族吃人的想象(是不允许的)
          每条船最多能坐下两个(僧侣或者食人族),每次船启动时必须有一个在船上。
 思路:必须先将所有的食人族过河,再利用食人族将所有的僧侣送过河,最后将食人族再送过河。  
          模拟僧侣的攻击力为4(总攻击力为12),食人族攻击力为3(总攻击力为9),
          当每边食人族的攻击力和超出僧侣的攻击力和的时候就发生事故,   
          必须控制僧侣攻击力和超出食人族攻击力和的值。
 结果:最短应该是小于等于11次往返次数    

 

 

 

 

 

执行环境(WinXP+java version "1.5.0_06")

/**
*created by zxb
*date  2010-4-5 - 上午10:05:38 
*zxb 开源测试项目 test
*to do TODO
**/


package com.java.algorism;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 三个僧侣和三个食人族过河
 * 目的:需要把他们六个一起使用一条船送到河的对面岸上
 * 条件:当食人族的数目超出僧侣的数目时,就会出现食人族吃人的想象(是不允许的)
 *      每条船最多能坐下两个(僧侣或者食人族),每次船启动时必须有一个在船上。
 * 思路:必须先将所有的食人族过河,再利用食人族将所有的僧侣送过河,最后将食人族再送过河。  
 *      模拟僧侣的攻击力为4(总攻击力为12),食人族攻击力为3(总攻击力为9),
 *      当每边食人族的攻击力和超出僧侣的攻击力和的时候就发生事故,   
 *      必须控制僧侣攻击力和超出食人族攻击力和的值。
 * 结果:最短应该是小于等于11次往返次数     
 */
public class CrossRiver {

	private static final List<Integer> list=new ArrayList<Integer>();
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Senglv sl1=new Senglv();
		Senglv sl2=new Senglv();
		Senglv sl3=new Senglv();
		Shirenzu sr1=new Shirenzu();
		Shirenzu sr2=new Shirenzu();
		Shirenzu sr3=new Shirenzu();
		List<Object> l1=new ArrayList<Object>();
		List<Object> l2=new ArrayList<Object>();
		l1.add(sl1);l1.add(sl2);l1.add(sl3);
		l2.add(sr1);l2.add(sr2);l2.add(sr3);
		List<Object> right=new ArrayList<Object>();//右边数据
		List<Object> left=new ArrayList<Object>();//左边数据
		right.addAll(l1);right.addAll(l2);
		for (int i = 1; i < 1000; i++) {
			boolean flag=((i+1)%2)==0?true:false;
			transportData(flag?left:right,flag?right:left,flag);
		}
		Collections.sort(list);
		System.out.println("最小折返次数:"+list.get(0));
	}

	/**
	 * 
	 * @param left
	 * @param right
	 * @param ship=true 为右边;ship=false 为左边 
	 */
	public static void transportData(List<Object> left,List<Object> right,boolean ship){
		int count=0;//计数器
		int k=0;
		List<Object> l=null;
		while((right !=null && (k=right.size())>0)){
			if(ship){
				l=getRandomNum(right,2);
				left.addAll(l);
				right.removeAll(l);
				if(!compareATK(right) || !compareATK(left)){
					right.addAll(l);
					left.removeAll(l);
					continue;
				}
				ship=false;
				count++;
			}else{
				l=getRandomNum(left,2);
				left.removeAll(l);
				right.addAll(l);
				if(!compareATK(right) || !compareATK(left)){
					right.removeAll(l);
					left.addAll(l);
					continue;
				}
				ship=true;
				count++;
			}
		}
		//System.out.println("往返次数==="+count);
		list.add(count);
	}
	
	/**
	 * 攻击力比较大小 僧侣的攻击力和大于食人族的攻击力和时返回true,
	 * 当一边为空时也返回true,否则计算实际攻击力大小
	 * @param l
	 * @return
	 */
	public static boolean compareATK(List<Object> l){
		int s1=0,s2=0;
		for (int i = 0, len = l.size(); i < len; i++) {
			if(l.get(i) instanceof Senglv){
				s1+=((Senglv)l.get(i)).getATK();
			}else if(l.get(i) instanceof Shirenzu){
				s2+=((Shirenzu)l.get(i)).getATK();
			}
		}
		return s1==0 || s2==0 || s1>s2;
	}
	/**
	 * 从List集合中随机抽取count个数以下的list集合(list.size()<=count)
	 * @param list
	 * @param count
	 * @return
	 */
	public static List<Object> getRandomNum(List<Object> list,int count){
		List<Object> l=new ArrayList<Object>();
		int k=0,m=0;
		k=(list!=null?list.size():0);
		if(list!=null && k>=count){
			Collections.shuffle(list);
			m=(new Random().nextInt(count)+1);
			for (int i = 0; i < m; i++) {
				l.add(list.get(i));
			}
		}else{
			l.addAll(list);
		}
		return l;
	}
	
	/**
	 * 
	 * @param m1
	 * @param m2
	 * @return
	 */
	public static boolean compareATK(Map<String,Integer> m1,Map<String,Integer> m2){
		int s1=0,s2=0;
		while(m1.values().iterator().hasNext()){
			s1+=m1.values().iterator().next();
		}
		while(m2.values().iterator().hasNext()){
			s2+=m2.values().iterator().next();
		}
		return s1>s2;
	}
}

class Senglv{
	
	public Senglv(){
	}
	
	private int ATK=4;
	
	public int getATK() {
		return ATK;
	}
	
	public void setATK(int atk) {
		ATK = atk;
	}
}

class Shirenzu{
	
	public Shirenzu(){
	}
	
	private int ATK=3;
	
	public int getATK() {
		return ATK;
	}
	
	public void setATK(int atk) {
		ATK = atk;
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值