You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

硬币翻转游戏的获胜者判定与重复模拟可视化需求

公平硬币翻转游戏模拟与问题解答

游戏规则

  • 1000人参与公平硬币翻转游戏
  • 第1轮:掷出反面(tails)的玩家被淘汰
  • 第2轮:剩余玩家再次掷硬币,掷出反面的玩家被淘汰
  • 以此类推,直到所有玩家都被淘汰

R模拟实现代码

# 游戏初始化
num_players <- 1000
results <- data.frame(player = paste0("player", 1:num_players))
status <- rep("playing", num_players)
round <- 1

# 模拟循环
while (any(status == "playing")) {
    # 生成硬币翻转结果
    coin_flips <- ifelse(runif(num_players) > 0.5, "heads", "tails")
   
    # 记录当前轮次状态:未淘汰玩家显示翻转结果,已淘汰显示"eliminated"
    current_round <- ifelse(status == "playing", coin_flips, "eliminated")
    
    # 更新玩家状态:未淘汰且掷出反面的玩家被淘汰
    status <- ifelse(status == "playing" & coin_flips == "tails", "eliminated", status)
    
    # 将当前轮次结果合并到总结果中
    results <- cbind(results, current_round)
    colnames(results)[ncol(results)] <- paste0("round_", round)
    
    round <- round + 1
}

模拟结果示例

> head(results)
   player round_1    round_2    round_3    round_4    round_5    round_6    round_7    round_8    round_9   round_10
1 player1   heads      heads      heads      heads      heads      heads      tails eliminated eliminated eliminated
2 player2   tails eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated
3 player3   tails eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated
4 player4   tails eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated
5 player5   tails eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated
6 player6   heads      tails eliminated eliminated eliminated eliminated eliminated eliminated eliminated eliminated

问题解答

1. 判断单次模拟是否存在唯一获胜者

唯一获胜者的判定标准是:游戏过程中存在某一时刻,其余999名玩家均已被淘汰,仅剩下1名玩家仍在游戏中。

实现方法

方法1:模拟过程中实时检查

修改原模拟代码,在每轮结束后检查剩余玩家数,一旦出现剩余1人的情况,即可标记存在唯一获胜者:

num_players <- 1000
status <- rep("playing", num_players)
has_unique_winner <- FALSE
round <- 1

while (any(status == "playing")) {
    coin_flips <- ifelse(runif(num_players) > 0.5, "heads", "tails")
    status <- ifelse(status == "playing" & coin_flips == "tails", "eliminated", status)
    
    # 检查当前剩余玩家数
    remaining <- sum(status == "playing")
    if (remaining == 1) {
        has_unique_winner <- TRUE
        # 可提前终止循环,无需继续模拟
        break
    }
    round <- round + 1
}

# 输出结果
cat("是否存在唯一获胜者:", ifelse(has_unique_winner, "是", "否"), "\n")
方法2:事后处理模拟结果

从已生成的results数据框中提取每轮的玩家状态,计算每轮剩余的活跃玩家数,检查是否有轮次剩余数为1:

# 提取所有轮次的状态数据(排除player列)
round_status <- results[, -1]
# 计算每轮剩余的活跃玩家数(即该轮掷出heads的玩家数)
remaining_players <- apply(round_status, 2, function(x) sum(x == "heads"))
# 判断是否存在剩余1人的轮次
has_unique_winner <- any(remaining_players == 1)

cat("是否存在唯一获胜者:", ifelse(has_unique_winner, "是", "否"), "\n")

2. 重复模拟1000次并绘制获胜者数量分布

以下提供两种常见需求的实现方案:

方案1:统计是否存在唯一获胜者的分布

# 封装单次模拟函数,返回是否存在唯一获胜者(1=是,0=否)
simulate_game <- function(num_players = 1000) {
  status <- rep("playing", num_players)
  has_unique_winner <- FALSE
  while (any(status == "playing")) {
    coin_flips <- ifelse(runif(num_players) > 0.5, "heads", "tails")
    status <- ifelse(status == "playing" & coin_flips == "tails", "eliminated", status)
    remaining <- sum(status == "playing")
    if (remaining == 1) {
      has_unique_winner <- TRUE
      break
    }
    if (remaining == 0) break
  }
  return(ifelse(has_unique_winner, 1, 0))
}

# 重复模拟1000次
set.seed(123) # 设置随机种子保证结果可重复
sim_results <- replicate(1000, simulate_game())

# 绘制柱状图
library(ggplot2)
ggplot(data.frame(winner_count = factor(sim_results, labels = c("无唯一获胜者", "存在唯一获胜者"))), 
       aes(x = winner_count)) +
  geom_bar(fill = "steelblue", width = 0.6) +
  labs(title = "1000次模拟的获胜者情况分布",
       x = "模拟结果",
       y = "模拟次数") +
  theme_minimal()

方案2:统计最终剩余玩家数的分布

如果需要展示每次模拟最后一轮淘汰前的剩余玩家数(即最多同时存活的玩家数),可以使用以下代码:

# 封装单次模拟函数,返回最后一轮淘汰前的剩余玩家数
simulate_game <- function(num_players = 1000) {
  status <- rep("playing", num_players)
  last_remaining <- num_players
  while (any(status == "playing")) {
    coin_flips <- ifelse(runif(num_players) > 0.5, "heads", "tails")
    status <- ifelse(status == "playing" & coin_flips == "tails", "eliminated", status)
    current_remaining <- sum(status == "playing")
    if (current_remaining > 0) {
      last_remaining <- current_remaining
    } else {
      break
    }
  }
  return(last_remaining)
}

# 重复模拟1000次
set.seed(123)
sim_results <- replicate(1000, simulate_game())

# 绘制直方图
ggplot(data.frame(remaining_players = sim_results), aes(x = remaining_players)) +
  geom_histogram(binwidth = 1, fill = "steelblue", color = "black") +
  labs(title = "1000次模拟的最终剩余玩家数分布",
       x = "最终剩余玩家数",
       y = "模拟次数") +
  theme_minimal()

内容的提问来源于stack exchange,提问作者konofoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:35:10