roll: add dices

This commit is contained in:
Arthur POULET 2022-09-11 16:00:46 +02:00
parent 252e5590e6
commit 8fddfbf580
5 changed files with 263 additions and 1 deletions

View File

@ -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
View 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
View File

@ -0,0 +1,3 @@
require_relative "./src/web/app"
run MetalAdventuresWeb::App

192
src/dice.rb Normal file
View 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
View 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