大家好,我是赛博红兔。在我第一期的《和大货聊聊天》的节目里提到一句我研究过美国的PowerBall强力球博彩,拿它做了一个预测彩票的项目,结果项目失败了但是Python技巧提高了不少。有朋友对这个项目比较感兴趣,正巧不是在今年2月6日福彩双色球的开奖时,贵州一位“彩民”独中了6.8个亿元的巨奖,让看到的人心痒痒。那么,我们就用Python来构建一个咱们中国福彩双色球的抽奖模型,来模拟一下这个天上掉馅饼的美事。这个项目也比较适合刚学完Python的新手们来上手实践,有些朋友觉得总找不到项目去练习和实践,其实项目不需要很大很复杂,只需要你足够感兴趣,对你的学习生活工作有帮助有意义就行。
现在,我们一起来看一下具体咱们的Python项目。首先,有些朋友不了解双色球的玩法,我先来介绍一下。双色球就是有两组颜色的球组成,彩民需从1到33号中不带重复地选择6个红球号码,然后从1到16号中选择1个蓝球号码。中奖的等级分为多个级别,其中一等奖需要所有红球和蓝球号码完全匹配,也就是6+1。二等奖是全中红球,也就是6+0,三等奖是5+1,四等奖是5+0或者4+1,五等奖是4+0或者3+1,末等奖是2+1,1+1,或者0+1。奖金根据中奖等级和当期销售额进行分配,不同级别的奖金从固定金额到高达数百万甚至数亿元不等。大概就是这么一个情况。

接下来,我们来看看怎么用Python逻辑非常顺畅地来一步步模拟这个双色球的。这段代码模拟156次彩票抽奖,每次抽取1张彩票。红球号码范围是1到33,蓝球号码范围是1到16。每次购买彩票花费2元,记录每次抽奖的奖金。根据红球和蓝球匹配情况确定奖金,奖金分为一等奖到六等奖和“感谢参与”。最后输出总花费、总收入和各奖项的中奖次数。
import random
# 红球,蓝球号码范围
red_balls = range(1, 34)
blue_balls = range(1, 17)
# 每次抽奖的彩票数量
tickets_per_drawing = 1
# 抽奖次数
num_drawings = 156
# 总支出,收入
total_spending = 0
total_earnings = 0
# 奖项历史记录
prizes_history = {
"一等奖": 0,
"二等奖": 0,
"三等奖": 0,
"四等奖": 0,
"五等奖": 0,
"六等奖": 0,
"感谢参与": 0
}
# 计算奖金的函数
def calculate_prize(my_numbers, winning_numbers):
# 计算红球匹配数和蓝球是否匹配
red_matches = len(my_numbers["red"] & winning_numbers["red"])
blue_match = (my_numbers["blue"] == winning_numbers["blue"])
# 奖金映射表
prize_map = {
(6, True): (700_000_000, "一等奖"),
(6, False): (28_000_000, "二等奖"),
(5, True): (3_000, "三等奖"),
(5, False): (200, "四等奖"),
(4, True): (200, "四等奖"),
(4, False): (10, "五等奖"),
(3, True): (10, "五等奖"),
(2, True): (5, "六等奖"),
(1, True): (5, "六等奖"),
(0, True): (5, "六等奖"),
}
# 根据匹配结果得到奖金和类别
if (red_matches, blue_match) in prize_map:
prize, category = prize_map[(red_matches, blue_match)]
prizes_history[category] += 1
else:
prize = 0
prizes_history["感谢参与"] += 1
return prize
# 购买彩票并计算结果
for _ in range(num_drawings):
red_drawing = set(random.sample(red_balls, 6))
blue_drawing = random.choice(blue_balls)
drawn_numbers = {"red": red_drawing, "blue": blue_drawing}
for _ in range(tickets_per_drawing):
total_spending += 2
my_red = set(random.sample(red_balls, k=6))
my_blue = random.choice(blue_balls)
player_numbers = {"red": my_red, "blue": my_blue}
earning = calculate_prize(player_numbers, drawn_numbers)
total_earnings += earning
# 打印总支出和总收入
print(f'总花费: ¥{total_spending}')
print(f'总收入: ¥{total_earnings}')
print(prizes_history)
下面这段代码模拟彩票抽奖,直到中奖或达到正利润。红球范围1-33,蓝球范围1-16,每次抽100张彩票。通过随机抽取红球和蓝球计算奖金,记录支出、收入和各奖项中奖次数。绘制年利润图。最终输出总支出、总收入和各奖项中奖次数。我们需要1000多年才中到大奖。不知道大家能不能等这么多久。我知道有一只叫阿德维塔的亚达伯拉象龟,是世界上活的时间最长的动物,活了256岁。美国加洲东部有一棵树,估计活了有4854岁。我就想说咱们这回是每次抽奖都买了一百张彩票,还是算挺狂热的彩民了,因为每星期花六百块钱去买彩票,可不是小数目了。但即使这样,回归到咱们个体上,也用了超过1000年的时间才中了大奖。这个项目,完美地回答了我什么时候能中大奖的问题。我现在心满意足了。
import random
import matplotlib.pyplot as plt
# 红球,蓝球号码范围
red_balls = range(1, 34)
blue_balls = range(1, 17)
# 每次抽奖的彩票数量
tickets_per_drawing = 100
# 抽奖次数
num_drawings = 156
# 总支出,收入
total_spending = 0
total_earnings = 0
# 奖项历史记录
prizes_history = {
"一等奖": 0,
"二等奖": 0,
"三等奖": 0,
"四等奖": 0,
"五等奖": 0,
"六等奖": 0,
"感谢参与": 0
}
# 支出和收入历史
spending_history = []
earnings_history = []
years = []
# 计算奖金的函数
def calculate_prize(my_numbers, winning_numbers):
# 计算红球匹配数和蓝球是否匹配
red_matches = len(my_numbers["red"] & winning_numbers["red"])
blue_match = (my_numbers["blue"] == winning_numbers["blue"])
# 奖金映射表
prize_map = {
(6, True): (700_000_000, "一等奖"),
(6, False): (28_000_000, "二等奖"),
(5, True): (3_000, "三等奖"),
(5, False): (200, "四等奖"),
(4, True): (200, "四等奖"),
(4, False): (10, "五等奖"),
(3, True): (10, "五等奖"),
(2, True): (5, "六等奖"),
(1, True): (5, "六等奖"),
(0, True): (5, "六等奖"),
}
# 根据匹配结果得到奖金和类别
if (red_matches, blue_match) in prize_map:
prize, category = prize_map[(red_matches, blue_match)]
prizes_history[category] += 1
else:
prize = 0
prizes_history["感谢参与"] += 1
return prize
# 初始化中奖标志、抽奖次数和年份计数器
hit_bigprize = False
drawings = 0
year_count = 0
# 如果没有中最大奖,就继续抽奖
while not hit_bigprize:
drawings += 1
# 随机选取6个红球和1个蓝球
red_drawing = set(random.sample(red_balls, 6))
blue_drawing = random.choice(blue_balls)
# 将抽出的号码存储为字典
drawn_numbers = {"red": red_drawing, "blue": blue_drawing}
# 购买彩票并计算结果
for _ in range(tickets_per_drawing):
total_spending += 2
my_red = set(random.sample(red_balls, k=6))
my_blue = random.choice(blue_balls)
player_numbers = {"red": my_red, "blue": my_blue}
earning = calculate_prize(player_numbers, drawn_numbers)
total_earnings += earning
# 如果中了最大奖,则结束循环
if earning == 700_000_000:
hit_bigprize = True
break
# 如果有了正利润,则结束循环
# if total_earnings - total_spending > 0:
# hit_bigprize = True
# 如果达到了一年的抽奖次数,更新年度记录
if drawings % num_drawings == 0:
year_count += 1
spending_history.append(total_spending / 1e4)
earnings_history.append(total_earnings / 1e4)
years.append(year_count)
print(f'{year_count} 年')
# 如果循环结束时不是在156次抽奖结束,也要记录下来
if drawings % num_drawings != 0:
year_count += 1
spending_history.append(total_spending / 1e4)
earnings_history.append(total_earnings / 1e4)
years.append(year_count)
# 绘制利润图
profits = [earn - spend for earn,
spend in zip(earnings_history, spending_history)]
plt.figure(figsize=(10, 5))
plt.plot(years, profits, marker='o', linestyle='-', color='b')
plt.title('Double Color Ball Profit Chart')
plt.xlabel('Year')
plt.ylabel('Profit (unit: 10k RMB)')
plt.grid(True)
plt.show()
# 打印总支出和总收入
print(f'总花费: ¥{total_spending}')
print(f'总收入: ¥{total_earnings}')
print(prizes_history)
这里给大家展示的是一个刚学完Python的新人如何去按照现实的双色球玩法逻辑来编译的代码。这段代码其实不是最好的写法有很多可以优化的地方,比如,在抽奖模拟过程中,重复生成彩票和抽奖的操作不是非常高效,有更高效的随机数生成的方法。部分数值比如说彩球数量、每次抽奖的彩票数量都是硬编码,可以定义常量变量来增加灵活性和可读性。还有代码里面包含了重复的一些逻辑,比如说年度记录更新,是可以通过封装函数来优化。当然大家也可以在这个项目之上进行拓展,比如说增加用户的交互来面对不同的投注情况,还可以将结果保存到文件里进行进一步统计分析,还可以模拟别的抽奖玩法等等。我会把代码分享在GitHub和我的博客上,链接贴在下方,后面就交给大伙去玩了。好了今天双色球我们就玩到这里,拜拜!

Leave a comment