最可读的编程语言来模拟10,000个滑槽和梯子游戏?

时间:2009-07-03 06:55:14

标签: language-agnostic statistics simulation

我想知道什么语言最适合模拟游戏滑道和梯子(某些国家的蛇和梯子)。我希望收集基本的统计数据,比如游戏长度的平均值和标准差(轮流),基于转弯顺序的胜利概率(谁先玩,第二等),以及你能想到的任何其他感兴趣的东西。具体来说,我正在寻找最易读,可维护和可修改的实现。它还需要非常简短。

如果你是一个成年人并且不花太多时间在年幼的孩子身边,那么你可能不会记得游戏那么好。我会提醒你:

  • 棋盘上有100个方格。
  • 每个玩家轮流旋转一个1-6的随机数(或掷骰子)。
  • 然后玩家推进那么多正方形。
  • 有些正方形在梯子的底部;登陆其中一个方块意味着玩家爬上梯子,将玩家的位置推进到预定的方格。
  • 有些正方形位于滑道(滑道或蛇)的顶部;登陆其中一个方块意味着玩家必须向下滑动,将玩家的位置移回预定的方格。
  • 无论哪个玩家获得第一名,都是胜利者。

7 个答案:

答案 0 :(得分:24)

这有点粗糙,但应该有效:

class Board
  attr_accessor :winner

  def initialize(players, &blk)
    @chutes, @ladders = {}, {}
    @players = players
    @move = 0
    @player_locations = Hash.new(0)
    self.instance_eval(&blk)
  end

  def chute(location)
    @chutes[location[:from]] = location[:to]
  end

  def ladder(location)
    @ladders[location[:from]] = location[:to]
  end

  def spin
    player = @move % @players
    die = rand(6) + 1
    location = (@player_locations[player] += die)

    if endpoint = @chutes[location] || endpoint = @ladders[location]
      @player_locations[player] = endpoint
    end

    if @player_locations[player] >= 100
      @winner = player
    end

    @move += 1
  end
end

num_players = 4

board = Board.new num_players, do
  ladder :from => 4, :to => 14
  ladder :from => 9, :to => 31
  # etc.
  chute :from => 16, :to => 6
  # etc.
end

until board.winner
  board.spin
end

puts "Player #{board.winner} is the winner!"

答案 1 :(得分:14)

你应该查看Ruby或Python的内容。两者基本上都是可执行的伪代码。

你可能能够用Haskell获得一个更短,更精彩的程序,但我认为Ruby或Python可能实际上是可以理解的。

答案 2 :(得分:5)

对于许多统计信息,您不需要模拟。使用Markov链,您可以减少100x100矩阵上的矩阵运算的许多问题,这只需要大约1毫秒的时间来计算。

答案 3 :(得分:4)

我将不同意之前的一些海报,并说面向对象的方法在这里做错了,因为它使事情变得更复杂。

您需要的只是跟踪每个玩家的位置,以及代表棋盘的矢量。如果电路板位置没有滑槽或梯子,则为0.如果它包含梯子,则电路板包含一个正数,表示向前移动的位置数。如果它包含一个滑槽,它包含一个负数可以让你回来。只需跟踪每个玩家的转弯次数和位置。

使用此方法的实际模拟非常简单,您几乎可以使用任何编程语言进行模拟。我建议使用R或python,但这只是因为那些是我最近使用的那些。

我没有滑槽和梯子的副本,所以我编了一个小板。你必须放入正确的董事会:

#!/usr/bin/python

import random, numpy

board = [0, 0, 0, 3, 0, -3, 0, 1, 0, 0]
numplayers = 2
numruns = 100

def simgame(numplayers, board):
    winner = -1
    winpos = len(board)
    pos = [0] * numplayers
    turns = 0
    while max(pos) < winpos:
        turns += 1
        for i in range(0, numplayers):
            pos[i] += random.randint(1,6)
            if pos[i] < winpos:
                pos[i] += board[pos[i]]
            if pos[i] >= winpos and winner == -1:
                winner = i
    return (turns, winner)

# simulate games, then extract turns and winners
games = [simgame(numplayers, board) for x in range(numruns)]
turns = [n for (n, w) in games]
winner = [w for (t, w) in games]
pwins = [len([p for p in winner if p == i]) for i in range(numplayers)]

print "runs:", numruns
print "mean(turns):", numpy.mean(turns)
print "sd(turns):", numpy.std(turns)
for i in range(numplayers):
    print "Player", (i+1), "won with proportion:", (float(pwins[i])/numruns)

答案 4 :(得分:2)

F#也不是太难看,因为简洁而难以击败功能语言:

#light
open System 

let snakes_and_ladders = dict [(1,30);(2,5);(20,10);(50,11)]

let roll_dice(sides) =  
    Random().Next(sides) + 1

let turn(starting_position) =
    let new_pos = starting_position + roll_dice(6)   
    let found, after_snake_or_ladder = snakes_and_ladders.TryGetValue(new_pos)
    if found then after_snake_or_ladder else new_pos 

let mutable player_positions = [0;0]

while List.max player_positions < 100 do
    player_positions <- List.map turn player_positions 

if player_positions.Head > 100 then printfn "Player 1 wins" else printf "Player 2 wins"

答案 5 :(得分:1)

我记得大约4年前它是一个顶级的Coders竞赛,问题是玩家1赢得蛇和梯子的概率是多少。

有一个非常好的报道如何在赛后发布的拼图。现在找不到,但write-up非常好

C / C ++似乎足以解决问题。

答案 6 :(得分:1)

选择任何面向对象的语言,它们是为模拟而发明的。

既然你想要它简短(为什么?),选择一种动态类型的语言,如Smalltalk,Ruby或Python。