当前访客身份:游客 [ 登录 | 加入 OSCHINA ]

代码分享

当前位置:
代码分享 » Java  » 算法分析
优雅先生

三人射击智力题模拟

优雅先生 发布于 2013年05月24日 11时, 5评/960阅
分享到: 
收藏 +0
2
游戏说明及游戏策略见代码,最终可以发现二号位小黄活下来的概率最高,获胜概率比33.58 : 41.82 : 24.60
好像网上说我这种策略不对,菜鸟李第一枪应该放空枪,这种情况下小李活下来的概率最高,获胜概率比38.08 : 26.94 : 34.98
标签: <无>

代码片段(4) [全屏查看所有代码]

1. [图片] 1.png    

2. [图片] 2.png    

3. [代码]小李第一枪不放空     跳至 [3] [4] [全屏预览]

import java.util.HashMap;
import java.util.Map;

/**
 * @author jiangxiaoqiang
 * 求存活概率问题
 * 
 * 三个小伙子同时爱上了一 个姑娘,为了决定他们谁能娶这个姑娘,他们决定用手枪进行一次决斗。
 * 小李的命中率是30%,
 * 小黄比他好些,命中率是50%,
 * 最出色的枪手是小林,他从不失 误,命中率是100%。
 * 由于这个显而易见的事实,为公平起见,他们决定按这样的顺序:小李先开枪,小黄第二,小林最后。
 * 然后这样循环,直到他们只剩下一个 人。
 * 那么这三个人中谁活下来的机会最大呢?他们都应该采取什么样的策略?
 * 
 * 很明显:
 * 小李应该先向小林射击,因为如果他向小黄射击,如果碰巧击中那他之后必死无疑,既然这样先向小黄
 * 射击就没有意义了。
 * 而小黄在小林还活着的情况,肯定也先向小林开枪。
 * 而小林在小黄还活着的情况下自然先向命中率更高的小黄开枪。
 */
public class ShootDemo {
	
	private static boolean isFirstAlive;   // 小李是否活着 
	private static boolean isSecondAlive;  // 小黄是否活着
	private static boolean isThirdAlive;   // 小林是否活着
	private static Map<Boolean, Integer> counterDict = new HashMap<Boolean, Integer> ();
	static {
		counterDict.put(true, 1);
		counterDict.put(false, 0);
	}

	// 初始设置三人都存活
	public static void init() {
		isFirstAlive = true;
		isSecondAlive = true;
		isThirdAlive = true;
	}
	
	// 开始射击游戏
	public static void startGame() {
		init();   // 初始化
		
		while(!isGameEnd()) {   // 只要游戏未结束就一直持续下去
			int shootNum = 0;   // 射击点数
			
			// 小李还存活,由他射击
			if(isFirstAlive) {   
				// 如果小林还存活就向小林开枪,如果小林挂了,那么说明小黄还活着,则向小黄开枪
				shootNum = (int)(Math.random() * 10);
				if(shootNum <= 2) {   // 命中率为十分之三
					if(isThirdAlive) {
						isThirdAlive = false;
					}
					else {
						isSecondAlive = false;
					}
				}
			}
			
			// 小黄还活着,由他射击
			if(isSecondAlive) {
				// 如果小林还活着就先向小黄开枪,毫无疑问;否则向小李开枪
				shootNum = (int)(Math.random() * 2);
				if(shootNum == 1) {   // 命中率为二分之一
					if(isThirdAlive) {
						isThirdAlive = false;
					}
					else {
						isFirstAlive = false;
					}
				}
			}
			
			// 神枪手小林还活着
			if(isThirdAlive) {
				// 如果小黄还活着,先向他射击
				if(isSecondAlive) {
					isSecondAlive = false;
				}
				else {
					isFirstAlive = false;
				}
			}
		}
	}
	
	// 判断游戏是否结束
	public static boolean isGameEnd() {
		return (counterDict.get(isFirstAlive)+
				 counterDict.get(isSecondAlive)+
				  counterDict.get(isThirdAlive)) == 1;
	}
	
	public static void main(String[] args) {
		int firstWin = 0, secondWin = 0, thirdWin = 0;
		for(int i = 0; i < 1000000; i++) {
			startGame();
			
			if(isFirstAlive) {
				firstWin++;
			}
			
			if(isSecondAlive){
				secondWin++;
			}
			
			if(isThirdAlive) {
				thirdWin++;
			}
		}
		
		System.out.println("小李共赢场数:" + firstWin);
		System.out.println("小黄共赢场数:" + secondWin);
		System.out.println("小林共赢场数:" + thirdWin);
	}

}

4. [代码]小李第一枪放空枪     跳至 [3] [4] [全屏预览]

public class ShootDemo {
	
	private static boolean isFirstAlive;   // 小李是否活着 
	private static boolean isSecondAlive;  // 小黄是否活着
	private static boolean isThirdAlive;   // 小林是否活着
	private static Map<Boolean, Integer> counterDict = new HashMap<Boolean, Integer> ();
	static {
		counterDict.put(true, 1);
		counterDict.put(false, 0);
	}

	// 初始设置三人都存活
	public static void init() {
		isFirstAlive = true;
		isSecondAlive = true;
		isThirdAlive = true;
	}
	
	// 开始射击游戏
	public static void startGame() {
		init();   // 初始化
		
		while(!isGameEnd()) {   // 只要游戏未结束就一直持续下去
			int shootNum = 0;   // 射击点数
			
			// 小黄还活着,由他射击
			if(isSecondAlive) {
				// 如果小林还活着就先向小黄开枪,毫无疑问;否则向小李开枪
				shootNum = (int)(Math.random() * 2);
				if(shootNum == 1) {   // 命中率为二分之一
					if(isThirdAlive) {
						isThirdAlive = false;
					}
					else {
						isFirstAlive = false;
					}
				}
			}
			
			// 神枪手小林还活着
			if(isThirdAlive) {
				// 如果小黄还活着,先向他射击
				if(isSecondAlive) {
					isSecondAlive = false;
				}
				else {
					isFirstAlive = false;
				}
			}
			
			// 小李还存活,由他射击
			if(isFirstAlive) {   
				// 如果小林还存活就向小林开枪,如果小林挂了,那么说明小黄还活着,则向小黄开枪
				shootNum = (int)(Math.random() * 10);
				if(shootNum <= 2) {   // 命中率为十分之三
					if(isThirdAlive) {
						isThirdAlive = false;
					}
					else {
						isSecondAlive = false;
					}
				}
			}
		}
	}
	
	// 判断游戏是否结束
	public static boolean isGameEnd() {
		return (counterDict.get(isFirstAlive)+
				 counterDict.get(isSecondAlive)+
				  counterDict.get(isThirdAlive)) == 1;
	}
	
	public static void main(String[] args) {
		int firstWin = 0, secondWin = 0, thirdWin = 0;
		for(int i = 0; i < 10000000; i++) {
			startGame();
			
			if(isFirstAlive) {
				firstWin++;
			}
			
			if(isSecondAlive){
				secondWin++;
			}
			
			if(isThirdAlive) {
				thirdWin++;
			}
		}
		
		System.out.println("小李共赢场数:" + firstWin);
		System.out.println("小黄共赢场数:" + secondWin);
		System.out.println("小林共赢场数:" + thirdWin);
	}

}


开源中国-程序员在线工具:Git代码托管 API文档大全(120+) JS在线编辑演示 二维码 更多»

发表评论 回到顶部 网友评论(5)

  • 1楼:V 发表于 2013-05-24 12:23 回复此评论

    界面在哪、。?

  • 2楼:优雅先生 发表于 2013-05-24 13:31 回复此评论

    引用来自“V”的评论

    界面在哪、。?

    啥界面?
  • 3楼:amonxu 发表于 2013-05-24 13:49 回复此评论
    还以为是个游戏。。
  • 4楼:V 发表于 2013-05-30 14:50 回复此评论

    引用来自“jxqlovedn”的评论

    引用来自“V”的评论

    界面在哪、。?

    啥界面?
    图啊
  • 5楼:accesstolaw 发表于 2013-06-17 15:48 回复此评论

    引用来自“V”的评论

    引用来自“jxqlovedn”的评论

    引用来自“V”的评论

    界面在哪、。?

    啥界面?
    图啊
    没有界面的 文字游戏。
开源从代码分享开始 分享代码