roll: add dices
This commit is contained in:
parent
252e5590e6
commit
8fddfbf580
2
Gemfile
2
Gemfile
|
@ -23,8 +23,8 @@ gem "rack_csrf", "~> 2"
|
|||
gem "doc_my_routes"
|
||||
|
||||
# debug and helpers
|
||||
gem "colorize", "~> 0.8"
|
||||
gem "activesupport", "~> 6"
|
||||
gem "colorize", "~> 0.8"
|
||||
|
||||
# tests
|
||||
group :test do
|
||||
|
|
21
Rakefile
Normal file
21
Rakefile
Normal file
|
@ -0,0 +1,21 @@
|
|||
require "rake"
|
||||
require "rake/testtask"
|
||||
|
||||
Rake::TestTask.new do |t|
|
||||
t.pattern = "test/*_test.rb"
|
||||
end
|
||||
|
||||
# namespace "db" do
|
||||
# desc "Migrate the database to the lasted schema"
|
||||
# task "migrate" do
|
||||
# require_relative "./init/migrate_db"
|
||||
# end
|
||||
|
||||
# desc "Reset all tables, schema, data"
|
||||
# task "reset" do
|
||||
# require_relative "./init/load_env"
|
||||
# DB.tables.each {|t| DB.drop_table t }
|
||||
# end
|
||||
# end
|
||||
|
||||
task default: :test
|
3
config.ru
Normal file
3
config.ru
Normal file
|
@ -0,0 +1,3 @@
|
|||
require_relative "./src/web/app"
|
||||
|
||||
run MetalAdventuresWeb::App
|
192
src/dice.rb
Normal file
192
src/dice.rb
Normal file
|
@ -0,0 +1,192 @@
|
|||
module MetalAdventures
|
||||
class Dice
|
||||
class Modifiers
|
||||
# normal modifier = all dice
|
||||
# partial modifier = only one dice
|
||||
# 2 partial change to one onrmal
|
||||
# sc and pmf cancel e2f
|
||||
#
|
||||
# :sc|:SC : "seconde chance", reroll failed dice and sum
|
||||
# :pmf|:PMF : "peut mieux faire", reroll success and sum
|
||||
# :e2f|:E2F : "easy to fail", reroll success to confirm
|
||||
# :td : "très difficile", only 6 are success
|
||||
# :tf : "très facile", only 1 are failures
|
||||
#
|
||||
# @param [Array(Symbol)] list
|
||||
# @param [:pmf|:sc] priority if :sc and :pmf are available, choose only one
|
||||
def initialize(*list, priority: :pmf)
|
||||
@list = list
|
||||
@priority = priority
|
||||
reduce!
|
||||
end
|
||||
|
||||
%i[SC sc PMF pmf E2F e2f td tf].each do |modifier|
|
||||
define_method(:"#{modifier}?") do
|
||||
@reduced == modifier
|
||||
end
|
||||
end
|
||||
|
||||
# @param [:sc, :SC, :pmf, :PMF, :e2f]
|
||||
def <<(modifier)
|
||||
@list << modifier
|
||||
reduce!
|
||||
self
|
||||
end
|
||||
|
||||
PRIORITY_MAP = {
|
||||
big: {
|
||||
pmf: :PMF,
|
||||
sc: :SC,
|
||||
},
|
||||
small: {
|
||||
pmf: :pmf,
|
||||
sc: :sc,
|
||||
},
|
||||
}
|
||||
|
||||
private def reduce!
|
||||
count_sc = @list.count(:sc) + (2 * @list.count(:SC))
|
||||
count_pmf = @list.count(:pmf) + (2 * @list.count(:PMF))
|
||||
count_e2f = @list.count(:e2f) + (2 * @list.count(:E2F))
|
||||
count_bonus = count_sc + count_pmf
|
||||
count_malus = count_e2f
|
||||
count_total = count_bonus - count_malus
|
||||
|
||||
# puts "count_sc = #{count_sc}"
|
||||
# puts "count_pmf = #{count_pmf}"
|
||||
# puts "count_e2f = #{count_e2f}"
|
||||
# puts "count_bonus = #{count_bonus}"
|
||||
# puts "count_malus = #{count_malus}"
|
||||
# puts "count_total = #{count_total}"
|
||||
# TODO: use cond for pattern matching rather than if/else shit
|
||||
@reduced =
|
||||
if count_total == 0
|
||||
nil
|
||||
elsif count_total >= 2 && (count_sc >= 2 || count_pmf >= 2)
|
||||
PRIORITY_MAP[:big][
|
||||
if count_sc >= 2 && count_pmf >= 2
|
||||
@priority
|
||||
elsif count_sc >= 2
|
||||
:sc
|
||||
else
|
||||
:pmf
|
||||
end
|
||||
]
|
||||
elsif count_total >= 2
|
||||
PRIORITY_MAP[:small][@priority]
|
||||
elsif count_total == 1
|
||||
PRIORITY_MAP[:small][
|
||||
if count_sc >= 1 && count_pmf >= 1
|
||||
@priority
|
||||
elsif count_sc >= 1
|
||||
:sc
|
||||
else
|
||||
:pmf
|
||||
end
|
||||
]
|
||||
else # count_total < 0
|
||||
count_total == -1 ? :e2f : :E2F
|
||||
end
|
||||
end
|
||||
|
||||
# Given the current modifiers, give the list of dice that are success
|
||||
def successes
|
||||
return 4..6 if @td && @tf
|
||||
return 6..6 if @td
|
||||
return 2..6 if @tf
|
||||
|
||||
4..6
|
||||
end
|
||||
|
||||
# Given the current modifeirs, tell if a die is a success or not
|
||||
def success?(int)
|
||||
successes.include?(int)
|
||||
end
|
||||
|
||||
DICE = (1..6).freeze
|
||||
def roll(n)
|
||||
rolled = Modifiers.raw_roll(n)
|
||||
success = rolled.count { success?(_1) }
|
||||
failures = n - success
|
||||
|
||||
if self.PMF?
|
||||
rolled += Modifiers.raw_roll(sucess)
|
||||
elsif self.pmf?
|
||||
rolled += Modifiers.raw_roll(1) if success >= 1
|
||||
elsif self.SC?
|
||||
rolled += Modifiers.raw_roll(failures)
|
||||
elsif self.sc?
|
||||
rolled += Modifiers.raw_roll(1) if failures >= 1
|
||||
elsif self.E2F?
|
||||
rolled.delete_if { success?(_1) }
|
||||
rolled += Modifiers.raw_roll(success)
|
||||
elsif self.e2f?
|
||||
if success >= 1
|
||||
rolled.delete_at(-1)
|
||||
rolled += Modifiers.raw_roll(1)
|
||||
end
|
||||
end
|
||||
rolled
|
||||
end
|
||||
|
||||
def self.raw_roll(n)
|
||||
Array.new(n) { rand(DICE) }.sort
|
||||
end
|
||||
|
||||
# def failures
|
||||
# return [1, 2, 3] if @td && @td
|
||||
# return [1, 2, 3, 4, 5] if @td
|
||||
# return [1] if @tf
|
||||
|
||||
# [1, 2, 3]
|
||||
# end
|
||||
end
|
||||
|
||||
attr_accessor :n, :difficulty, :modifiers, :result
|
||||
|
||||
# @param [Integer] n is the number of dice to roll
|
||||
# @param [Integer] difficulty is the amount of success to get
|
||||
# @param [Modifier] modifiers
|
||||
def initialize(n:, difficulty: 1, modifiers: Modifiers.new)
|
||||
@n = n
|
||||
@difficulty = difficulty
|
||||
@modifiers = modifiers
|
||||
end
|
||||
|
||||
def add_difficulty(add = 1)
|
||||
@difficulty += add
|
||||
end
|
||||
|
||||
def remove_difficulty(remove = 1)
|
||||
@difficulty -= remove
|
||||
end
|
||||
|
||||
def add_die(add = 1)
|
||||
@n += add
|
||||
end
|
||||
|
||||
def remove_die(remove = 1)
|
||||
@n -= remove
|
||||
end
|
||||
|
||||
# @return [Integer] the amount of success of a new roll
|
||||
def roll
|
||||
@modifiers.roll(@n)
|
||||
# failures = @n - successes
|
||||
end
|
||||
|
||||
def roll!
|
||||
@last_roll = roll
|
||||
@result = @last_roll.count { @modifiers.success?(_1) }
|
||||
self
|
||||
end
|
||||
|
||||
# @return [nil|true|false] if the last #roll! was a success or not
|
||||
def success?
|
||||
if @result
|
||||
@result >= @difficulty
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
46
test/dice_test.rb
Normal file
46
test/dice_test.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
require "test/unit"
|
||||
require "pry"
|
||||
require_relative "../src/dice"
|
||||
|
||||
module MetalAdventures
|
||||
class DiceTest < Test::Unit::TestCase
|
||||
def test_modifiers_init
|
||||
assert Dice::Modifiers.new(:sc).sc?
|
||||
refute Dice::Modifiers.new(:sc).SC?
|
||||
|
||||
refute Dice::Modifiers.new(:sc, :sc).sc?
|
||||
assert Dice::Modifiers.new(:sc, :sc).SC?
|
||||
|
||||
refute Dice::Modifiers.new(:pmf, :pmf).pmf?
|
||||
assert Dice::Modifiers.new(:pmf, :pmf).PMF?
|
||||
|
||||
refute Dice::Modifiers.new(:sc, :sc, :sc).sc?
|
||||
assert Dice::Modifiers.new(:sc, :sc, :sc).SC?
|
||||
|
||||
assert Dice::Modifiers.new(:sc, :sc, :e2f).sc?
|
||||
refute Dice::Modifiers.new(:sc, :sc, :e2f).SC?
|
||||
refute Dice::Modifiers.new(:sc, :sc, :e2f).e2f?
|
||||
|
||||
assert Dice::Modifiers.new(:sc, :pmf, :e2f, priority: :pmf).pmf?
|
||||
assert Dice::Modifiers.new(:sc, :pmf, :e2f, priority: :sc).sc?
|
||||
|
||||
assert Dice::Modifiers.new(:SC, :PMF, :e2f, priority: :pmf).PMF?
|
||||
assert Dice::Modifiers.new(:SC, :PMF, :e2f, priority: :sc).SC?
|
||||
|
||||
assert Dice::Modifiers.new(:sc, :pmf, priority: :pmf).pmf?
|
||||
assert Dice::Modifiers.new(:sc, :pmf, priority: :sc).sc?
|
||||
assert Dice::Modifiers.new(:sc, :pmf, :pmf, priority: :sc).PMF?
|
||||
|
||||
assert Dice::Modifiers.new(:E2F, :SC, :pmf, priority: :sc).sc?
|
||||
|
||||
assert Dice::Modifiers.new(:SC, :pmf, :E2F, :E2F).e2f?
|
||||
assert Dice::Modifiers.new(:SC, :pmf, :E2F, :E2F, :e2f).E2F?
|
||||
assert Dice::Modifiers.new(:sc, :pmf, :PMF, :e2f).PMF?
|
||||
end
|
||||
|
||||
# def test_modifiers_roll
|
||||
# binding.pry
|
||||
# end
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user