mirror of
https://github.com/samsonjs/mystery7-simulator.git
synced 2026-04-27 15:07:42 +00:00
add closing logic
This commit is contained in:
parent
d03190f362
commit
efacab0822
1 changed files with 55 additions and 15 deletions
70
roulette.rb
70
roulette.rb
|
|
@ -22,7 +22,7 @@ class Roulette
|
||||||
# best
|
# best
|
||||||
BettingSequence = [1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 10, 12, 15, 18]
|
BettingSequence = [1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 10, 12, 15, 18]
|
||||||
|
|
||||||
attr_accessor :results, :counts, :set_status, :wins
|
attr_accessor :results, :counts, :set_status, :wins, :closing
|
||||||
|
|
||||||
def initialize(options)
|
def initialize(options)
|
||||||
@options = options
|
@options = options
|
||||||
|
|
@ -41,22 +41,21 @@ class Roulette
|
||||||
# generated numbers are from 0 to max
|
# generated numbers are from 0 to max
|
||||||
@max = @options[:american] ? 38 : 37
|
@max = @options[:american] ? 38 : 37
|
||||||
|
|
||||||
total_per_number = 0
|
@net_profits = net_profits_for_sequence(BettingSequence)
|
||||||
@net_profits = BettingSequence.map do |n|
|
puts "Profit sequence: #{@net_profits.join(', ')}"
|
||||||
total_per_number += n
|
@snake_penalty = snake_penalty_for_sequence(BettingSequence)
|
||||||
36 * n - 7 * total_per_number
|
puts "Snake penalty: #{@snake_penalty}"
|
||||||
end
|
|
||||||
@snake_penalty = 7 * total_per_number
|
|
||||||
|
|
||||||
@cumulative_net = 0
|
@cumulative_net = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def simulate
|
def simulate
|
||||||
@set_status = {}
|
@set_status = {}
|
||||||
Sets.keys.each do |key|
|
Sets.keys.each do |letter|
|
||||||
@set_status[key] = {
|
@set_status[letter] = {
|
||||||
:net => 0,
|
:net => 0,
|
||||||
:sequence => 0,
|
:sequence => 0,
|
||||||
|
:ghost_sequence => 0,
|
||||||
:sleeping => true,
|
:sleeping => true,
|
||||||
:snakes => 0,
|
:snakes => 0,
|
||||||
:wins => 0
|
:wins => 0
|
||||||
|
|
@ -66,8 +65,11 @@ class Roulette
|
||||||
@results = []
|
@results = []
|
||||||
@wins = []
|
@wins = []
|
||||||
@counts = Hash.new { 0 }
|
@counts = Hash.new { 0 }
|
||||||
|
@closing = false
|
||||||
|
@closed = false
|
||||||
|
|
||||||
@options[:spins].times do
|
@options[:spins].times do |i|
|
||||||
|
break if @options[:spins] - i < 10 && @cumulative_net > 100
|
||||||
result = spin
|
result = spin
|
||||||
record(result) if @options[:record]
|
record(result) if @options[:record]
|
||||||
if @results.length % 100_000 == 0
|
if @results.length % 100_000 == 0
|
||||||
|
|
@ -76,6 +78,10 @@ class Roulette
|
||||||
print '.'
|
print '.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if @cumulative_net < 100
|
||||||
|
@closing = true
|
||||||
|
spin until closed?
|
||||||
|
end
|
||||||
puts if @results.length >= 10_000
|
puts if @results.length >= 10_000
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -85,15 +91,25 @@ class Roulette
|
||||||
net = 0
|
net = 0
|
||||||
@sets.each do |letter, set|
|
@sets.each do |letter, set|
|
||||||
status = @set_status[letter]
|
status = @set_status[letter]
|
||||||
if set.include?(n)
|
if set.include?(n) && !status[:closed]
|
||||||
if status[:sleeping]
|
if status[:sleeping]
|
||||||
status[:sleeping] = false
|
status[:sleeping] = false
|
||||||
else
|
else
|
||||||
net = @net_profits[status[:sequence]]
|
net = @net_profits[status[:sequence]]
|
||||||
@wins << { :set => letter, :sequence => 1 + status[:sequence] }
|
@wins << {
|
||||||
|
:set => letter,
|
||||||
|
:sequence => 1 + status[:sequence],
|
||||||
|
:ghost_sequence => 1 + status[:ghost_sequence]
|
||||||
|
}
|
||||||
|
puts "#{letter.upcase} wins #{net} at sequence #{status[:sequence] + 1}" if @options[:verbose]
|
||||||
status[:net] += net
|
status[:net] += net
|
||||||
status[:sequence] = 0
|
status[:sequence] = 0
|
||||||
|
status[:ghost_sequence] = 0
|
||||||
status[:wins] += 1
|
status[:wins] += 1
|
||||||
|
if closing
|
||||||
|
status[:closed] = true
|
||||||
|
puts "[win] closed set #{letter} on spin #{@results.length + 1}" if @options[:verbose]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
@counts[letter] += 1
|
@counts[letter] += 1
|
||||||
letters << letter
|
letters << letter
|
||||||
|
|
@ -101,12 +117,19 @@ class Roulette
|
||||||
end
|
end
|
||||||
@set_status.each do |letter, status|
|
@set_status.each do |letter, status|
|
||||||
next if letters.include?(letter)
|
next if letters.include?(letter)
|
||||||
status[:sequence] += 1 unless status[:sleeping]
|
unless status[:sleeping] || status[:closed]
|
||||||
|
status[:sequence] += 1
|
||||||
|
status[:ghost_sequence] += 1
|
||||||
|
end
|
||||||
# snake
|
# snake
|
||||||
if status[:sequence] >= BettingSequence.length
|
if status[:sequence] >= BettingSequence.length
|
||||||
puts "#{letter}: SNAKE!" if @options[:verbose]
|
puts "#{letter}: SNAKE!" if @options[:verbose]
|
||||||
status[:sequence] = 0
|
status[:sequence] = 0
|
||||||
status[:sleeping] = true
|
status[:sleeping] = true
|
||||||
|
if closing
|
||||||
|
status[:closed] = true
|
||||||
|
puts "[snake] closed set #{letter} on spin #{@results.length + 1}" if @options[:verbose]
|
||||||
|
end
|
||||||
status[:snakes] += 1
|
status[:snakes] += 1
|
||||||
status[:net] -= @snake_penalty
|
status[:net] -= @snake_penalty
|
||||||
net -= @snake_penalty
|
net -= @snake_penalty
|
||||||
|
|
@ -115,21 +138,22 @@ class Roulette
|
||||||
status[:sleeping] = true
|
status[:sleeping] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@closed = @set_status.values.all? { |status| status[:closed] } if closing
|
||||||
@cumulative_net += net
|
@cumulative_net += net
|
||||||
result = {
|
result = {
|
||||||
:roll => n,
|
:roll => n,
|
||||||
:net => net,
|
:net => net,
|
||||||
:cumulative_net => @cumulative_net
|
:cumulative_net => @cumulative_net
|
||||||
}
|
}
|
||||||
|
@results << result
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
puts @results.length
|
puts "spin: #{@results.length}"
|
||||||
puts result.inspect
|
puts result.inspect
|
||||||
@set_status.each do |letter, status|
|
@set_status.each do |letter, status|
|
||||||
puts "#{letter}: #{status.inspect}"
|
puts "#{letter}: #{status.inspect}"
|
||||||
end
|
end
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
@results << result
|
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -137,6 +161,22 @@ class Roulette
|
||||||
@rng.seed
|
@rng.seed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def closed?
|
||||||
|
@closed
|
||||||
|
end
|
||||||
|
|
||||||
|
def net_profits_for_sequence(sequence)
|
||||||
|
total_per_number = 0
|
||||||
|
sequence.map do |n|
|
||||||
|
total_per_number += n
|
||||||
|
36 * n - 7 * total_per_number
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def snake_penalty_for_sequence(sequence)
|
||||||
|
7 * sequence.inject(0) { |sum, n| sum + n }
|
||||||
|
end
|
||||||
|
|
||||||
def db
|
def db
|
||||||
unless @db
|
unless @db
|
||||||
@db = SQLite3::Database.new(@options[:database])
|
@db = SQLite3::Database.new(@options[:database])
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue