oakdex-battle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ module Oakdex
2
+ class Battle
3
+ # Represents a Pokemon Trainer. Owns Pokemon and has a name
4
+ class Trainer
5
+ attr_reader :name, :team, :in_battle_pokemon
6
+
7
+ def initialize(name, team)
8
+ @name = name
9
+ team.each { |p| p.trainer = self }
10
+ @team = team
11
+ @in_battle_pokemon = []
12
+ end
13
+
14
+ def fainted?
15
+ @team.all? { |p| p.current_hp.zero? }
16
+ end
17
+
18
+ def send_to_battle(pokemon, side)
19
+ @in_battle_pokemon << InBattlePokemon.new(pokemon,
20
+ side, side.next_position)
21
+ side.add_to_log 'sends_to_battle', name, pokemon.name
22
+ end
23
+
24
+ def remove_from_battle(pokemon, side)
25
+ ibp_to_remove = @in_battle_pokemon.find { |ibp| ibp.pokemon == pokemon }
26
+ pokemon.reset_stats
27
+ pokemon.status_conditions.each do |s|
28
+ s.after_switched_out(ibp_to_remove.battle)
29
+ end
30
+ @in_battle_pokemon -= [ibp_to_remove]
31
+ side.add_to_log 'removes_from_battle', name, pokemon.name
32
+ end
33
+
34
+ def remove_fainted
35
+ @in_battle_pokemon.each do |ibp|
36
+ next unless ibp.fainted?
37
+ ibp.battle.add_to_log('pokemon_fainted', name, ibp.pokemon.name)
38
+ ibp.pokemon.status_conditions
39
+ .each { |s| s.after_fainted(ibp.battle) }
40
+ end
41
+ @in_battle_pokemon = @in_battle_pokemon.reject(&:fainted?)
42
+ end
43
+
44
+ def left_pokemon_in_team
45
+ @team.select { |p| !p.current_hp.zero? } -
46
+ @in_battle_pokemon.map(&:pokemon)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,70 @@
1
+ require 'forwardable'
2
+
3
+ module Oakdex
4
+ class Battle
5
+ # Represents one Turn within the battle
6
+ class Turn
7
+ extend Forwardable
8
+
9
+ def_delegators :@battle, :sides
10
+ attr_reader :battle
11
+
12
+ def initialize(battle, actions)
13
+ @battle = battle
14
+ @actions = actions
15
+ end
16
+
17
+ def execute
18
+ execute_status_conditions(:before_turn)
19
+
20
+ ordered_actions.each do |action|
21
+ next unless valid_target?(action)
22
+ next if action.pokemon && action.pokemon.current_hp.zero?
23
+ action.execute(self)
24
+ end
25
+
26
+ execute_status_conditions(:after_turn)
27
+ end
28
+
29
+ private
30
+
31
+ def execute_status_conditions(method)
32
+ status_conditions.each do |status_condition|
33
+ status_condition.public_send(method, self)
34
+ end
35
+ battle.remove_fainted
36
+ end
37
+
38
+ def status_conditions
39
+ sides.flat_map(&:in_battle_pokemon)
40
+ .map(&:pokemon)
41
+ .flat_map(&:status_conditions)
42
+ end
43
+
44
+ def valid_target?(action)
45
+ targets = action.target.is_a?(Array) ? action.target : [action.target]
46
+ targets.all? do |target|
47
+ !target.nil? && !target.current_hp.zero?
48
+ end
49
+ end
50
+
51
+ def ordered_actions
52
+ @ordered_actions ||= @actions.sort { |a, b| compare_actions(a, b) }
53
+ end
54
+
55
+ def compare_actions(a, b)
56
+ a_prio = a.priority
57
+ b_prio = b.priority
58
+ if a_prio == b_prio && a_prio < 6
59
+ if a.pokemon.speed == b.pokemon.speed
60
+ [1, -1].sample
61
+ else
62
+ b.pokemon.speed <=> a.pokemon.speed
63
+ end
64
+ else
65
+ b_prio <=> a_prio
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,89 @@
1
+ require 'forwardable'
2
+
3
+ module Oakdex
4
+ class Battle
5
+ # Generates all valid actions within the battle
6
+ class ValidActionService
7
+ extend Forwardable
8
+
9
+ def_delegators :@battle, :actions, :sides
10
+
11
+ def initialize(battle)
12
+ @battle = battle
13
+ end
14
+
15
+ def valid_actions_for(trainer)
16
+ return [] if sides.empty?
17
+ return [] if no_battle_pokemon?(trainer) && own_battle_pokemon?(trainer)
18
+ valid_move_actions_for(trainer) + valid_recall_actions_for(trainer)
19
+ end
20
+
21
+ private
22
+
23
+ def valid_move_actions_for(trainer)
24
+ trainer.in_battle_pokemon.flat_map(&:valid_move_actions)
25
+ end
26
+
27
+ def valid_recall_actions_for(trainer)
28
+ trainer.left_pokemon_in_team.flat_map do |pokemon|
29
+ pokemon_per_trainer.times.map do |position|
30
+ recall_action(trainer,
31
+ trainer.in_battle_pokemon[position],
32
+ pokemon)
33
+ end.compact
34
+ end
35
+ end
36
+
37
+ def recall_action(trainer, in_battle_pokemon, target)
38
+ return if !recall_action_valid?(trainer, in_battle_pokemon, target) ||
39
+ recall_action_for?(target)
40
+ {
41
+ action: 'recall',
42
+ pokemon: in_battle_pokemon&.position || side(trainer).next_position,
43
+ target: target
44
+ }
45
+ end
46
+
47
+ def recall_action_valid?(trainer, in_battle_pokemon, _target)
48
+ if in_battle_pokemon
49
+ !in_battle_pokemon.action_added?
50
+ else
51
+ next_position = side(trainer).next_position
52
+ next_position && !recall_action_for_position?(next_position)
53
+ end
54
+ end
55
+
56
+ def pokemon_per_trainer
57
+ sides.first.trainers.size
58
+ end
59
+
60
+ def recall_action_for?(target)
61
+ actions.any? do |action|
62
+ action.type == 'recall' && action.target == target
63
+ end
64
+ end
65
+
66
+ def recall_action_for_position?(position)
67
+ actions.any? do |action|
68
+ action.type == 'recall' && action.pokemon_position == position
69
+ end
70
+ end
71
+
72
+ def no_battle_pokemon?(trainer)
73
+ other_sides(trainer).all? { |s| s.in_battle_pokemon.empty? }
74
+ end
75
+
76
+ def own_battle_pokemon?(trainer)
77
+ !side(trainer).in_battle_pokemon.empty?
78
+ end
79
+
80
+ def other_sides(trainer)
81
+ sides.select { |s| !s.trainer_on_side?(trainer) }
82
+ end
83
+
84
+ def side(trainer)
85
+ sides.find { |s| s.trainer_on_side?(trainer) }
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,5 @@
1
+ module Oakdex
2
+ class Battle
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oakdex-battle
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jalyna Schroeder
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oakdex-pokedex
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.2
27
+ description: Pokémon Battle Engine Gen 7 Gem, based on oakdex-pokedex
28
+ email: jalyna.schroeder@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - lib/oakdex.rb
35
+ - lib/oakdex/battle.rb
36
+ - lib/oakdex/battle/action.rb
37
+ - lib/oakdex/battle/damage.rb
38
+ - lib/oakdex/battle/in_battle_pokemon.rb
39
+ - lib/oakdex/battle/move.rb
40
+ - lib/oakdex/battle/move_execution.rb
41
+ - lib/oakdex/battle/pokemon.rb
42
+ - lib/oakdex/battle/pokemon_factory.rb
43
+ - lib/oakdex/battle/pokemon_stat.rb
44
+ - lib/oakdex/battle/side.rb
45
+ - lib/oakdex/battle/status_conditions.rb
46
+ - lib/oakdex/battle/status_conditions/badly_poisoned.rb
47
+ - lib/oakdex/battle/status_conditions/base.rb
48
+ - lib/oakdex/battle/status_conditions/burn.rb
49
+ - lib/oakdex/battle/status_conditions/freeze.rb
50
+ - lib/oakdex/battle/status_conditions/non_volatile.rb
51
+ - lib/oakdex/battle/status_conditions/paralysis.rb
52
+ - lib/oakdex/battle/status_conditions/poison.rb
53
+ - lib/oakdex/battle/status_conditions/sleep.rb
54
+ - lib/oakdex/battle/trainer.rb
55
+ - lib/oakdex/battle/turn.rb
56
+ - lib/oakdex/battle/valid_action_service.rb
57
+ - lib/oakdex/battle/version.rb
58
+ homepage: http://github.com/jalyna/oakdex-battle
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.7.3
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Pokémon Battle Engine in Ruby
82
+ test_files: []