今天突然想起以前同事提到过的一个过河问题,游戏设计思路
需要使用程序代码体现其过程,心血来潮,来一把.....如下:
三个僧侣和三个食人族过河
目的:需要把他们六个一起使用一条船送到河的对面岸上
条件:当食人族的数目超出僧侣的数目时,就会出现食人族吃人的想象(是不允许的)
每条船最多能坐下两个(僧侣或者食人族),每次船启动时必须有一个在船上。
思路:必须先将所有的食人族过河,再利用食人族将所有的僧侣送过河,最后将食人族再送过河。
模拟僧侣的攻击力为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;
}
}