Class: RpgLevel

Inherits:
Object
  • Object
show all
Defined in:
lib/rpg_level.rb,
lib/rpg_level/version.rb

Constant Summary collapse

CLEARED_CACHED_CURRENT_LEVEL_STATUS =
nil
VERSION =
"0.1.0"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(min_level: 1) ⇒ RpgLevel

Returns a new instance of RpgLevel.



8
9
10
11
12
13
14
15
16
# File 'lib/rpg_level.rb', line 8

def initialize(min_level: 1)
  @exp = 0
  @min_level = min_level
  # Necessary exps from the @min_level
  @necessary_exps = []
  # A cache of the #generate_status_of_current_level calculation
  # It is too heavy for access to #level_status like a static value
  @cached_current_level_status = CLEARED_CACHED_CURRENT_LEVEL_STATUS
end

Instance Attribute Details

#expObject (readonly)

Returns the value of attribute exp.



6
7
8
# File 'lib/rpg_level.rb', line 6

def exp
  @exp
end

#min_levelObject (readonly)

Returns the value of attribute min_level.



6
7
8
# File 'lib/rpg_level.rb', line 6

def min_level
  @min_level
end

#necessary_expsObject (readonly)

Returns the value of attribute necessary_exps.



6
7
8
# File 'lib/rpg_level.rb', line 6

def necessary_exps
  @necessary_exps
end

Instance Method Details

#alter_exp(exp_delta) ⇒ Object

Raises:

  • (ArgumentError)


77
78
79
80
81
82
83
# File 'lib/rpg_level.rb', line 77

def alter_exp(exp_delta)
  raise ArgumentError.new('exp_delta is not a integer') unless exp_delta.is_a?(Integer)
  before_exp = @exp
  change_exp_result = change_exp(@exp + exp_delta)
  self.class.generate_exp_change_result(
    before_exp, @exp, change_exp_result[:before_level], change_exp_result[:after_level])
end

#calculate_total_necessary_exp(from_level, to_level) ⇒ Object

Raises:

  • (ArgumentError)


50
51
52
53
54
55
56
57
58
# File 'lib/rpg_level.rb', line 50

def calculate_total_necessary_exp(from_level, to_level)
  raise ArgumentError.new('from_level is greater than to_level') if from_level > to_level
  raise ArgumentError.new('from_level is out of range') unless is_allowed_level?(from_level)
  raise ArgumentError.new('to_level is out of range') unless is_allowed_level?(to_level)

  (from_level..to_level).inject(0) do |result, level|
    result + find_necessary_exp_by_level(level)
  end
end

#clear_expObject



95
96
97
98
# File 'lib/rpg_level.rb', line 95

def clear_exp
  change_exp(0)
  nil
end

#define_exp_table(max_level) ⇒ Object

Raises:

  • (ArgumentError)


28
29
30
31
32
33
34
# File 'lib/rpg_level.rb', line 28

def define_exp_table(max_level)
  raise ArgumentError.new('max_level is less than min_level') if max_level < @min_level
  raise ArgumentError unless block_given?
  # TODO: How to convert the block to a proc?
  necessary_exps = generate_necessary_exps(max_level) {|info| yield(info)}
  define_exp_table_from_array(necessary_exps)
end

#define_exp_table_from_array(necessary_exps) ⇒ Object



18
19
20
21
22
23
24
25
26
# File 'lib/rpg_level.rb', line 18

def define_exp_table_from_array(necessary_exps)
  necessary_exps.each do |v|
    raise ArgumentError.new('some of necessary_exps are not a integer') unless v.is_a?(Integer)
    raise ArgumentError.new('some of necessary_exps are less than 0') if v < 0
  end

  @necessary_exps = necessary_exps
  @necessary_exps.freeze
end

#drain_exp(decrease_of_exp) ⇒ Object

Raises:

  • (ArgumentError)


90
91
92
93
# File 'lib/rpg_level.rb', line 90

def drain_exp(decrease_of_exp)
  raise ArgumentError.new('decrease_of_exp is less than 0') if decrease_of_exp < 0
  alter_exp(-decrease_of_exp)
end

#drain_exp_by_level(decrease_of_level, fraction_mode) ⇒ Object

fraction_mode

:omitted
  ex) Lv3(15/20) - Lv1 => Lv2( 0/10) - As a Wiz-like games
:full
  ex) Lv3(15/20) - Lv1 => Lv2(14/15) - As a Rogue-like games

Raises:

  • (ArgumentError)


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rpg_level.rb', line 135

def drain_exp_by_level(decrease_of_level, fraction_mode)
  raise ArgumentError.new('decrease_of_level is not a integer') unless decrease_of_level.is_a?(Integer)
  raise ArgumentError.new('decrease_of_level is less than 0') if decrease_of_level < 0
  raise ArgumentError.new('fraction_mode is invalid') unless [:omitted, :full].include?(fraction_mode)

  from_level = level
  to_level = cut_level_into_valid_range(from_level - decrease_of_level)

  exp_delta = case fraction_mode
  when :omitted then
    calculate_total_necessary_exp(min_level, to_level) - @exp
  when :full then
    to_level = [to_level + 1, from_level].min
    calculate_total_necessary_exp(min_level, to_level) - @exp - 1
  end

  alter_exp(exp_delta)
end

#find_necessary_exp_by_level(level) ⇒ Object



44
45
46
47
48
# File 'lib/rpg_level.rb', line 44

def find_necessary_exp_by_level(level)
  return nil unless is_allowed_level?(level)
  return 0 if level == @min_level
  @necessary_exps[level - @min_level - 1]
end

#is_allowed_level?(level) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/rpg_level.rb', line 40

def is_allowed_level?(level)
  level.between?(@min_level, max_level)
end

#is_reached_max_level?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/rpg_level.rb', line 73

def is_reached_max_level?
  level == max_level
end

#levelObject



69
70
71
# File 'lib/rpg_level.rb', line 69

def level
  level_status[:level]
end

#level_statusObject



64
65
66
67
# File 'lib/rpg_level.rb', line 64

def level_status
  @cached_current_level_status = generate_status_of_current_level() unless @cached_current_level_status
  @cached_current_level_status.dup
end

#max_expObject



60
61
62
# File 'lib/rpg_level.rb', line 60

def max_exp
  calculate_total_necessary_exp(@min_level, max_level)
end

#max_levelObject



36
37
38
# File 'lib/rpg_level.rb', line 36

def max_level
  @min_level + @necessary_exps.length
end

#obtain_exp(increase_of_exp) ⇒ Object

Raises:

  • (ArgumentError)


85
86
87
88
# File 'lib/rpg_level.rb', line 85

def obtain_exp(increase_of_exp)
  raise ArgumentError.new('increase_of_exp is less than 0') if increase_of_exp < 0
  alter_exp(increase_of_exp)
end

#obtain_exp_by_level(increase_of_level, fraction_mode) ⇒ Object

fraction_mode

:omitted
  ex ) Lv3(15/20) + Lv1 => Lv4( 0/25) - As a Rogue-like games
:inherited
  ex1) Lv3(15/20) + Lv1 => Lv4(15/25)
  ex2) Lv3(15/20) + Lv1 => Lv4(14/15)

Raises:

  • (ArgumentError)


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/rpg_level.rb', line 106

def obtain_exp_by_level(increase_of_level, fraction_mode)
  raise ArgumentError.new('increase_of_level is not a integer') unless increase_of_level.is_a?(Integer)
  raise ArgumentError.new('increase_of_level is less than 0') if increase_of_level < 0
  raise ArgumentError.new('fraction_mode is invalid') unless [:omitted, :inherited].include?(fraction_mode)

  from_level = level
  to_level = cut_level_into_valid_range(from_level + increase_of_level)

  exp_delta = case fraction_mode
  when :omitted then
    calculate_total_necessary_exp(min_level, to_level) - @exp
  when :inherited then
    next_necessary_exp_after_leveling_up = find_necessary_exp_by_level(to_level + 1)
    inherited_fraction_exp = if next_necessary_exp_after_leveling_up
      [level_status[:obtained_exp_for_next], next_necessary_exp_after_leveling_up - 1].min
    else
      0
    end
    calculate_total_necessary_exp(min_level, to_level) + inherited_fraction_exp - @exp
  end

  alter_exp(exp_delta)
end