class PtuPokemon < ApplicationRecord validates :name, uniqueness: true validates :name, :base_hp, :base_atk, :base_def, :base_spatk, :base_spdef, :base_speed, presence: true validates :male_chance, inclusion: 0..100, allow_nil: true def female_chance (100.0 - self.male_chance) if self.male_chance end def gender_ratio_string if self.male_chance "Male #{self.male_chance}% / Female #{self.female_chance}%" else "No gender" end end def random_stat_hash(level: 1) nature = PtuNature.find(PtuNature.pluck(:id).sample) if self.male_chance gender = 1 + rand(100) <= self.male_chance ? "Male" : "Female" else gender = "No gender" end hash = { name: self.name, level: level, gender: gender, nature: nature.name, base_stats: { hp: self.base_hp, atk: self.base_atk, def: self.base_def, spatk: self.base_spatk, spdef: self.base_spdef, speed: self.base_speed, }, stats: {}, } # Adjust base stats for nature hash[:base_stats][nature.raises.to_sym] += nature.raises.to_sym == :hp ? 1 : 2 hash[:base_stats][nature.lowers.to_sym] -= nature.lowers.to_sym == :hp ? 1 : 2 hash[:base_stats][nature.lowers.to_sym] = [1, hash[:base_stats][nature.lowers.to_sym]].max # e.g. [[:speed, 9], [:atk, 8], [:def, 8], [:spatk, 6], [:spdef, 6], [:hp, 5]] sorted_base_stats = hash[:base_stats].sort_by { |_, v| -v } rank = 1 # e.g. [1, 2, 2, 4, 4, 6] rankings_array = sorted_base_stats.each_with_index.map { |a, i| sorted_base_stats[i - 1][1] == a[1] ? rank : (rank = i + 1) } # e.g. {:speed=>1, :atk=>2, :def=>2, :spatk=>4, :spdef=>4, :hp=>6} base_stat_rankings = Hash[sorted_base_stats.map { |s| s[0] }.zip(rankings_array)] hash[:stats] = hash[:base_stats].deep_dup points_to_assign = 10 + level points_to_assign.times do loop do stat = hash[:stats].keys.sample higher_base_stats = base_stat_rankings.select { |_, v| v < base_stat_rankings[stat] }.keys if higher_base_stats.select { |s| hash[:stats][s] <= (hash[:stats][stat] + 1) }.any? next else hash[:stats][stat] += 1 and break end end end hash[:hit_points] = 10 + level + (hash[:stats][:hp] * 3) hash end end