Multifunctional Monty Hall Simulator
Style is generally ok, but I'd recommend a more object-oriented approach - especially if you want to learn Ruby, since Ruby is thoroughly object-oriented.

Things I noticed:


Global variables (apart from built-in ones like $ARGV) are rare in Ruby. They're rare because you'll usually want to encapsulate your data in objects.
No need to write return at the end of methods; the result of the last expression is always implicitly returned.
You've quite a few methods that take 3 arguments, and some that return tuples. This is a general code-smell, in my opinion, because it's not very descriptive. Long parameter lists aren't easy to remember or parse, and multiple return values are also a fairly opaque data structure.
Overall structure is indeed very script'y and procedural. 


Basically, you're passing all your data around, letting the methods modify them. A bit of basic object modelling could make your code better by encapsulation all that.

For instance, here's one way to model the game itself (not the full simulation). Just to give you something to chew on.

# A really simple Door class
class Door
  def initialize
    @open = false
  end

  def open?
    @open
  end

  def open!
    @open = true
  end
end

# This class models 1 instance/round of the game
class Game
  attr_reader :doors

  # Init a new game with +door_count+ doors, and randomly
  # picks one of them to be the winning door.
  # Raises an exception if door count is less than 3
  def initialize(door_count)
    raise ArgumentError, "There must be at least 3 doors" if door_count.to_i &lt; 3
    @doors = Array.new(door_count.to_i) { Door.new }
    @winning_door = @doors.sample
  end

  # Set a random door as the player's pick
  # Raises an exception if there are no doors left to pick
  def pick_door
    raise "No doors to pick" if pickable_doors.empty?
    @picked_door = pickable_doors.sample
  end

  # open +count+ number of doors
  def open_doors(count)
    shuffled = openable_doors.shuffle
    [count, shuffled.count].min.times do 
      shuffled.pop.open!
    end
  end

  # Returns true if the player's pick is the winning door
  def won?
    @picked_door == @winning_door
  end

  # Array of doors that an be picked by the player
  def pickable_doors
    closed_doors - [@picked_door]
  end

  # Array of doors that can be safely opened by Monty
  def openable_doors
    closed_doors - [@picked_door, @winning_door]
  end

  # Array of closed doors
  def closed_doors
    @doors.reject(&amp;:open?)
  end
end


The Door class may seem sort of pointless (and indeed there are many ways to do things), but instead of using, say, an array of plain booleans, an array of door objects allows us to reference specific doors. Not as array indices, but as the doors themselves.

Again, I'm not saying this is the only - or even a particularly great - way of doing things. But it reads pretty well, and is easy to use.

For instance, this code will play a basic game with 3 doors, of which 1 will be revealed, and the player changes their pick:

game = Game.new(3)
game.pick_door     # initial pick
game.open_doors(1) # reveal what's behind a door
game.pick_door     # change pick
game.won?          # =&gt; (~67% chance of a win)


You could make classes for Choice, Prize, or, heck, even Goat, if you want to completely model everything. But I'd at least make a SimulationRun (or similar) class.

This would encapsulate the notion of "a run" as in "N rounds of the game", and keep state out of the global scope.

I'd also consider modelling the actors (the player and Monty), and inject them into the simulation.

For instance, imagine being able to say something like:

sim = Simulation.new(3, Monty::Classic, Player::Fickle)
win_ratio = sim.run(1000)


i.e. create a simulation using 3 doors, run it 1000 times, using the "classic" Monty rules that leave two doors unrevealed, and a player that'll always pick a different door second time around.

Monty and the player could be classes or simply lambdas. For instance, the player can simply be a lambda that returns true/false when asked whether to change the pick. And "the Monty" could simply return the number of doors to open. Or you could make them a lot more complex, letting the player's reaction depend on, say, the phase of the Moon or something.

Again, I'm not saying that the above is the only way - or even a particularly great way - to do things, but I'd certainly encourage you to try doing object modelling of some kind.

All of this is of course presuming you don't just want to do the math, but actually want to be empirical :)