4

ゲームのシュートとはしご (一部の国ではヘビとはしご) をシミュレートするには、どの言語が最も適しているのだろうかと考えています。ゲームの長さ (ターン数) の平均と標準偏差、ターン順 (誰が最初にプレイするか、2 番目にプレイするかなど) に基づく勝利の確率、および考えられるその他の興味のあるものなど、基本的な統計を収集しようとしています。具体的には、最も読みやすく、保守しやすく、変更しやすい実装を探しています。また、非常に簡潔にする必要があります。

あなたが大人で、幼い子供たちとあまり時間を過ごしていないのであれば、おそらくゲームのことをあまり覚えていないでしょう. 私はあなたに思い出させます:

  • ボードには 100 個の正方形があります。
  • 各プレイヤーは順番に 1 ~ 6 の乱数を回転させます (またはサイコロを投げます)。
  • その後、プレーヤーはその数の正方形を進めます。
  • いくつかの正方形ははしごの基部にあります。これらの正方形のいずれかに着陸すると、プレーヤーははしごを登り、プレーヤーの位置を所定の正方形に進めます。
  • いくつかの正方形は、スライド (シュートまたはスネーク) の上部にあります。これらの正方形の 1 つに着陸すると、プレーヤーは滑り落ちて、プレーヤーの位置を所定の正方形に戻さなければならないことを意味します。
  • 最初に 100 位になったプレイヤーが勝者です。
4

7 に答える 7

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!"
于 2009-07-03T07:23:34.063 に答える
14

Ruby や Python に沿ったものをチェックアウトする必要があります。どちらも基本的に実行可能な疑似コードです。

Haskell を使用すると、より短くて優れたプログラムを作成できる可能性がありますが、Ruby や Python はおそらく実際には理解できると思います。

于 2009-07-03T07:09:50.933 に答える
5

多くの統計では、シミュレートする必要はありません。マルコフ連鎖を使用すると、多くの問題を 100x100 行列での行列演算に減らすことができます。計算には約 1 ミリ秒しかかかりません。

于 2009-07-03T18:46:32.820 に答える
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)
于 2009-07-04T14:25:41.613 に答える
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"
于 2009-07-06T08:20:03.380 に答える
1

約 4 年前のトップ コーダーズ コンテストで、プレイヤー 1 がスネーク アンド ラダーで勝つ確率はどのくらいかという問題があったことを覚えています。

試合後に投稿されたパズルのやり方について、本当に良い記事がありました。今は見つけられませんが、この書き込みはかなり良いです

問題をうまく解決するには、C/C++ で十分に思えました。

于 2009-07-03T08:05:32.973 に答える
1

シミュレーション用に発明されたオブジェクト指向言語を選択してください。

簡潔にしたいので (なぜ?)、Smalltalk、Ruby、Python などの動的型付け言語を選択します。

于 2009-07-03T08:39:55.230 に答える