现在的位置: 首页 > 综合 > 正文

【Java】揭秘如何利用不等概率随机数制作十赌九骗的赌大小游戏,请不要沉迷各种游戏

2018年05月06日 ⁄ 综合 ⁄ 共 4371字 ⁄ 字号 评论关闭

上次在《【Java】在一定的范围内产生不同的随机数》(点击打开链接)中说明了如何产生随机数,然后还说了如何在一定的范围内产生不同的随机数,但是这些都是等概率产生随机的问题。等概率在正常情况下,更应该说是学术上是够用了,但是在现实生活中,尤其在现在游戏必须打黄赌毒的擦边球吸引人的大背景下,等概率产生随机数是远远不够用的。你作为游戏商家,说得难听点就是庄家,肯定要不等概率产生随机数来圈玩家的钱。比如,合成装备就你就不能让它合成成功是50%,合成不成功是50%,你必须把合成成功设置为1%甚至更小。这样你才能让玩家通过墨菲定律来给你上供大量的人力、物力。所谓的墨菲定律在概率论里面有:也就是小概率事件通过大量测试必然发生,通俗点来说,就是“圣人千虑,必有一失。愚者千虑,必有一得。”

一、基本目标

设置一个十赌九骗的赌大小游戏,不等概率地产生出大和小的结果。

1、首先,这是个非常简单的赌大小游戏,考虑到还有小部分没有接触过黄赌毒的好孩子,还是介绍一下:用户输入0代表下注“小”,1代表“大”,之后随机产生出三个1-6的整数,如果这三个数相等就是“通杀”,无论用户下注什么都是是输,如果这三个数的和在3-10之间,那么就是“小”,如果是11-18之间就是“大”,对比用户猜的结果,看用户是否猜中。

当然,我们也同时考虑到你乱输入的情况,本程序是健壮的,你输入什么都不会崩溃。

2、如果这个程序正常来写,很简单,随机产生3个数,合计判断就行了,但是,为了让玩家不知不觉地消耗掉金钱,程序绝对不能这样写,如果玩家猜“小”,你产生1-3的机率要调小一点,如果玩家猜“大”,你产生4-6的概率就小一点,所以能够有如下的结果,假如玩家玩50次,都下注“小”,他只能赢8次:

3、假如玩家玩1000次,都下注“大”,它只能赢361次:

4、加入玩家玩二十万次,都下注“大”,它只能赢七万次

反正综上所述,玩家相对来说,肯定赢不了庄家。

二、基本思想

玩家之所以打死都赢不了庄家,也就是游戏厂商永远都是赚钱的核心思想是:游戏产生对玩家有利的事件的概率要调少,当然你也不能调得过少,过少让玩家觉得你是在骗人、圈钱,虽然你确实是在圈钱,但也要做到不知不觉地圈钱。

三、制作过程

1、首先要处理玩家输入的信息,我们要求玩家必须输入0和1,那么要排除其他结果,初始化一个N,用来接收玩家输入的数字,这里用到了Java的输入输出流,是课本上基础的事情,如果你理解不了,就当作这是C语言的scanf记住它就可以了。之后再定义一个存放结果的数组。用来存放每一次随机产生出来的数字。

System.out.println("赌大小的游戏,输入0代表小,输入1代表大");
int n = 0;
try {
	n = Integer.parseInt(new BufferedReader(new InputStreamReader(
			System.in)).readLine());
} catch (Exception e) {
	System.out.println("N必须为正整数");
	return;
}
if (n < 0 || n > 1) {
	System.out.println("N是0和1");
	return;
}
if (n == 0) {
	System.out.println("你猜的是“小”");
} else {
	System.out.println("你猜的是“大”");
}
int resultArr[] = new int[3];

2、之后就是整个程序的核心部分,如何根据用户输入的概率产生每一个结果的问题,这里利用到概率论的二项分布的思想。如果用户输入的0,也就是小,那么,所产生的结果,有70%的概率是4-6,new Random().nextInt(3) + 4;能够产生一个4-6的整数,这是在《【Java】在一定的范围内产生不同的随机数》(点击打开链接)中已经说明,其它部分与其互补,不再赘述。主要说说是如何设置有70%产生的结果是4-6。你在产生结果之前,先利用new
Random().nextDouble()产生一个随机数,这个随机数是等概率的在0-1之间的小数,这个小数小于0.7的概率肯定就是70%,那么则意味着有70%概率进入这个if,只有30%的概率进入else。利用这种随机数再嵌套事件的方式,你可以做很多事情。其实也就一个考研考生,甚至参加过概率论期末考的学生都懂的二项分布而已,没什么大不了。

switch (n) {
case 0:
	for (int i = 0; i < 3; i++) {
		if (new Random().nextDouble() < 0.7) {
			int j = new Random().nextInt(3) + 4;
			resultArr[i] = j;
			System.out.print(j + " ");
		} else {
			int j = new Random().nextInt(3) + 1;
			resultArr[i] = j;
			System.out.print(j + " ");
		}
	}
	break;
case 1:
	for (int i = 0; i < 3; i++) {
		if (new Random().nextDouble() < 0.7) {
			int j = new Random().nextInt(3) + 1;
			resultArr[i] = j;
			System.out.print(j + " ");
		} else {
			int j = new Random().nextInt(3) + 4;
			resultArr[i] = j;
			System.out.print(j + " ");
		}
	}
	break;
}

3、之后就是判断结果,结算部分,没有什么大不了的,Java、甚至是程序设计中的基础的基础,就是一堆for跟if,所以为什么说条件结构、循环结构,你能够写好,你就写好程序了。首先判断是不是通杀,因为通杀就不用想了嘛,大小全收,这里遍历整个数组,不要变量到最后,遍历到倒数第二个就可以了。看是否都是上一个数等于后一个数,如果不是则不是通杀。不是通杀的话,则对结果数组求和,这里的求和用到了JDK1.5之后的一种新型遍历,这个在《【Java】用JDK1.5之后的新型数组遍历方法遍历HashMap、HashMap不应该存储多元组》(点击打开链接)已经说了,不再赘述。这里新型的条件结构?:只能用到一个变量,不好写,因此还是用旧式的if与else。把得出来的和与玩家猜的N对照,如果相等那么就玩家就赢了,反之亦然。

boolean isAllIdentical = true;
for (int i = 0; i < resultArr.length - 1; i++) {
	if (resultArr[i] != resultArr[i + 1]) {
		isAllIdentical = false;
		break;
	}
}
if (isAllIdentical) {
	System.out.println("通杀!你输了!");
} else {
	int total = 0;
	for (int e : resultArr) {
		total += e;
	}
	if (total < 11) {
		System.out.print("结果:小!");
		if (n == 0) {
			System.out.println("你赢了!");
		} else {
			System.out.println("你输了!");
		}
	} else {
		System.out.print("结果:大!");
		if (n == 1) {
			System.out.println("你赢了!");
		} else {
			System.out.println("你输了!");
		}
	}
}

至此,就随机数的不等概率问题就做完了,整个程序连起来的结果如下:

import java.util.*;
import java.io.*;

public class Random_Probability {
	public static void main(String[] args) throws IOException {
		System.out.println("赌大小的游戏,输入0代表小,输入1代表大");
		int n = 0;
		try {
			n = Integer.parseInt(new BufferedReader(new InputStreamReader(
					System.in)).readLine());
		} catch (Exception e) {
			System.out.println("N必须为正整数");
			return;
		}
		if (n < 0 || n > 1) {
			System.out.println("N是0和1");
			return;
		}
		if (n == 0) {
			System.out.println("你猜的是“小”");
		} else {
			System.out.println("你猜的是“大”");
		}
		int resultArr[] = new int[3];
		switch (n) {
		case 0:
			for (int i = 0; i < 3; i++) {
				if (new Random().nextDouble() < 0.7) {
					int j = new Random().nextInt(3) + 4;
					resultArr[i] = j;
					System.out.print(j + " ");
				} else {
					int j = new Random().nextInt(3) + 1;
					resultArr[i] = j;
					System.out.print(j + " ");
				}
			}
			break;
		case 1:
			for (int i = 0; i < 3; i++) {
				if (new Random().nextDouble() < 0.7) {
					int j = new Random().nextInt(3) + 1;
					resultArr[i] = j;
					System.out.print(j + " ");
				} else {
					int j = new Random().nextInt(3) + 4;
					resultArr[i] = j;
					System.out.print(j + " ");
				}
			}
			break;
		}
		boolean isAllIdentical = true;
		for (int i = 0; i < resultArr.length - 1; i++) {
			if (resultArr[i] != resultArr[i + 1]) {
				isAllIdentical = false;
				break;
			}
		}
		if (isAllIdentical) {
			System.out.println("通杀!你输了!");
		} else {
			int total = 0;
			for (int e : resultArr) {
				total += e;
			}
			if (total < 11) {
				System.out.print("结果:小!");
				if (n == 0) {
					System.out.println("你赢了!");
				} else {
					System.out.println("你输了!");
				}
			} else {
				System.out.print("结果:大!");
				if (n == 1) {
					System.out.println("你赢了!");
				} else {
					System.out.println("你输了!");
				}
			}
		}

	}

}

抱歉!评论已关闭.