Class: PoorPokemon::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/poor-pokemon/cli.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCLI

Returns a new instance of CLI.



4
5
6
7
# File 'lib/poor-pokemon/cli.rb', line 4

def initialize
  @player = PoorPokemon::Player.new()
  @pokedex = PoorPokemon::Pokedex.new()
end

Instance Attribute Details

#difficultyObject

Returns the value of attribute difficulty.



2
3
4
# File 'lib/poor-pokemon/cli.rb', line 2

def difficulty
  @difficulty
end

#enemyObject

Returns the value of attribute enemy.



2
3
4
# File 'lib/poor-pokemon/cli.rb', line 2

def enemy
  @enemy
end

#playerObject

Returns the value of attribute player.



2
3
4
# File 'lib/poor-pokemon/cli.rb', line 2

def player
  @player
end

#pokedexObject

Returns the value of attribute pokedex.



2
3
4
# File 'lib/poor-pokemon/cli.rb', line 2

def pokedex
  @pokedex
end

Instance Method Details

#beginFightObject



177
178
179
180
181
182
183
184
# File 'lib/poor-pokemon/cli.rb', line 177

def beginFight
  puts "\'Poorly Designed Boss\' wants to battle!"
  displayBothRosters
  playerSwitch
  until @player.allDead? || @enemy.allDead? do
    turnOrder
  end
end

#callObject



9
10
11
12
13
14
15
16
# File 'lib/poor-pokemon/cli.rb', line 9

def call
  intro
  difficulty
  pokedexSelection
  beginFight
  declareWinner
  restart
end

#currentStatusObject



396
397
398
399
400
401
402
403
# File 'lib/poor-pokemon/cli.rb', line 396

def currentStatus
  #prints current status for both sides
  sepLine
  puts "###CURRENT STATUS###"
  puts "Your #{@player.currentPokemon.name.upcase} has #{@player.currentPokemon.hp} HP"
  puts "Enemy #{@enemy.currentPokemon.name.upcase} has #{@enemy.currentPokemon.hp} HP"
  sepLine
end

#declareWinnerObject



206
207
208
209
210
211
212
# File 'lib/poor-pokemon/cli.rb', line 206

def declareWinner
  if @player.allDead?
    puts "You lost!"
  else
    puts "You won!"
  end
end

#displayBothRostersObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/poor-pokemon/cli.rb', line 186

def displayBothRosters
  maxLength = @player.roster.sort{|a,b| a.name.length<=>b.name.length}.last.name.length+2
  title = "You"
  until title.length >= maxLength do
      title = " " + title
  end
  puts title + " || Enemy"
  sepLine
  @player.roster.each_index{|i|
    text = @player.roster[i].name.upcase
    until text.length >= maxLength do
      text = " " + text
    end
    typeText = @enemy.roster[i].type2!="" ? " (#{@enemy.roster[i].type1.capitalize}+#{@enemy.roster[i].type2.capitalize})" : " (#{@enemy.roster[i].type1.capitalize})"
    text = text + " || " + @enemy.roster[i].name.upcase + typeText
    puts text
  }

end

#displayPokemon(pokeGroup) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/poor-pokemon/cli.rb', line 93

def displayPokemon(pokeGroup)
  #pokeGroup is an array of PokedexPokemon
  #must have at least 1 item in array
  #Displays the group for the user
  maxNameLength = pokeGroup.sort{|a,b| a.name.length<=>b.name.length}.last.name.length+5

  pokeGroup.each_index{|i| 
    name = "#{i+1}. #{pokeGroup[i].name.capitalize}"
    until name.length >= maxNameLength do
      name = name + " "
    end
    types = pokeGroup[i].type2 != "" ? pokeGroup[i].type1.capitalize + "+" + pokeGroup[i].type2.capitalize : pokeGroup[i].type1.capitalize
    puts "#{name} TYPE:#{types} HP:#{pokeGroup[i].hp} ATT:#{pokeGroup[i].att} DEF:#{pokeGroup[i].def} SPD:#{pokeGroup[i].spd} SP-ATT:#{pokeGroup[i].spAtt} SP-DEF:#{pokeGroup[i].spDef}"
  }
end

#dmgText(dmgArray) ⇒ Object



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/poor-pokemon/cli.rb', line 359

def dmgText(dmgArray)
  #depending on the number, will evaluate the effectiveness of the attack
  #returns a string to communicate that effectiveness
  dmg = dmgArray[0]
  num = dmgArray[1]
 
  if num == 0
    output = "No effect!"
  elsif num == 0.5 || num == 0.25
    output = "It's not very effective."
  elsif num == 2
    output = "It's super-effective!"
  elsif num == 4
    output = "Critical hit!" #Not a true critical hit
  else
    output = "It hit!"
  end
  output + " (#{dmg} dmg)"
end

#enemyTurnObject



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/poor-pokemon/cli.rb', line 379

def enemyTurn
  puts "###Enemy Turn###"
  if @enemy.currentPokemon.canAttack?
    attackArray = @enemy.attacks(@player.currentPokemon,@difficulty)
    puts "#{@enemy.currentPokemon.name.upcase} used #{attackArray[1].name.split(" (")[0].upcase}  (#{attackArray[1].type})!"
    puts dmgText(attackArray[0])
  else 
    #current pokemon is out of PP for all moves, defaults to "Struggle"
    struggle = PoorPokemon::Move.new("Struggle",40,"Normal",99)
    attackArray = @enemy.attacks(@player.currentPokemon, @difficulty, struggle)
    puts "Enemy #{@enemy.currentPokemon.name.upcase} is out of moves!"
    puts "Enemy #{@enemy.currentPokemon.name.upcase} used STRUGGLE #{struggle.type}!"
    puts dmgText(attackArray[0])
  end
  sepLine
end

#fillMoves(char, diff = nil) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/poor-pokemon/cli.rb', line 47

def fillMoves(char, diff=nil)
  #fills char's pokemon roster with appropriate moves
  #moves are different for enemy
  if char.is_a?(PoorPokemon::Player)
    char.roster.each{|pokemon|
      output = []
      output.push(PoorPokemon::Move.new("Normal Attack",randAtt(45),"Normal",30))
      output.push(PoorPokemon::Move.new("Big Normal Attack",randAtt(110),"Normal",10))
      output.push(PoorPokemon::Move.new("Special Attack",randAtt(70),randType,20))
      output.push(PoorPokemon::Move.new("Big Special Attack",randAtt(100),randType,5))
      pokemon.moves = output
    }
  else
    #Enemy player
    if diff == "easy"
      char.roster.each{|pokemon|
        output = []
        output.push(PoorPokemon::Move.new("Normal Attack",randAtt(45),"Normal",30))
        output.push(PoorPokemon::Move.new("Big Normal Attack",randAtt(110),"Normal",10))
        output.push(PoorPokemon::Move.new("Special Attack",randAtt(70),randType,20))
        output.push(PoorPokemon::Move.new("Big Special Attack",randAtt(100),randType,5))
        pokemon.moves = output
      }
    elsif diff == "hard"
      char.roster.each{|pokemon|
        output=[]
        output.push(PoorPokemon::Move.new("Normal Attack",40,"Normal",30))
        output.push(PoorPokemon::Move.new("Big Normal Attack",100,"Normal",10))
        output.push(PoorPokemon::Move.new("Special Attack",65,pokemon.type1,20))
        output.push(PoorPokemon::Move.new("Big Special Attack",90,pokemon.type1,5))
        pokemon.moves = output
      }
    end
  end

end

#gameWon?Boolean

Returns:

  • (Boolean)


405
406
407
# File 'lib/poor-pokemon/cli.rb', line 405

def gameWon?
  @enemy.allDead? || @player.allDead?
end

#introObject



18
19
20
21
22
23
24
25
26
27
# File 'lib/poor-pokemon/cli.rb', line 18

def intro
  puts 'Welcome to Poorly Designed Pokemon Remake (PDPR)!'
  puts 'I\'ve scraped Pokemon and their stats from a website and created a pokedex.'
  puts 'You\'ll battle \'Poorly Designed Boss\', who has the 6 best pokemon with perfect stats!'
  puts 'To battle him, you\'ll select 6 pokemon from the pokedex to add to your roster'
  puts 'Then you\'ll take turns attacking his pokemon with yours.'
  puts 'Unfortunately, \'Poorly Designed Boss\' has sabatoged your pokemon by giving them random attacks and imperfect stats!'
  puts 'Can you still defeat him, despite being at a disadvantage!?'
  puts 'Good luck, and have fun!'
end

#invalidObject



173
174
175
# File 'lib/poor-pokemon/cli.rb', line 173

def invalid
  puts "{Invalid selection. Try again.}"
end

#playerAttacks(enemyPokemon) ⇒ Object



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/poor-pokemon/cli.rb', line 325

def playerAttacks(enemyPokemon)
  #gives user options on what move to attack with
  sepLine
  if @player.currentPokemon.canAttack?
    userInput = "0"
    availMoves = @player.currentPokemon.usableMoves
    until availMoves.include?(@player.currentPokemon.moves[userInput.to_i-1]) && userInput!="0" do
      puts "Which move should #{@player.currentPokemon.name.capitalize} use?"
      maxLength = @player.currentPokemon.moves.sort{|a,b| a.name.length<=>b.name.length}.last.name.length+5
      @player.currentPokemon.moves.each_index{|i|
        move = @player.currentPokemon.moves[i]
        text = "#{i+1}. #{move.name.upcase}"
        until text.length >= maxLength do
          text = text + " "
        end
        puts "#{text} > PP: #{move.pp}"
      }
      userInput = gets.strip
      if !availMoves.include?(@player.currentPokemon.moves[userInput.to_i-1]) && userInput!="0"
        invalid
      end
    end
    move = @player.currentPokemon.moves[userInput.to_i-1]
    puts "#{@player.currentPokemon.name.upcase} used #{move.name.split(" (")[0].upcase} (#{move.type})!"
    puts dmgText(@player.currentPokemon.attacks(enemyPokemon,move))
  else 
    #current pokemon is out of PP for all moves, defaults to "Struggle"
    struggle = PoorPokemon::Move.new("Struggle",40,"Normal",99)
    puts "#{@player.currentPokemon.name.upcase} is out of moves!"
    puts "#{@player.currentPokemon.name.upcase} used STRUGGLE! #{struggle.type}"
    puts dmgText(@player.currentPokemon.attacks(enemyPokemon,struggle))
  end
end

#playerSelectionObject



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/poor-pokemon/cli.rb', line 132

def playerSelection
  userInput = ""
  until ["1","2"].include?(userInput) do
    puts "Select a pokemon from the Pokedex, to add to your roster (#{6-@player.roster.length} left to pick)"
    puts "Options: (1)List all pokemon (2)Search by name"
    userInput = gets.strip
    case userInput
    when "1"
      searchResults = @pokedex.pokeList #full list of pokemon
    when "2"
      searchResults = []
      until searchResults.length>0 do
        puts 'Type in a name or partial name to search: '
        searchInput = gets.strip
        searchResults = @pokedex.searchName(searchInput)
        if searchResults.length<1
          puts "{No results found. Try again.}"
        end
      end
    else
      invalid
    end
  end  
  sepLine
  # Either list all pokemon, or allow for search by name
  displayPokemon(searchResults)
  sepLine
  #User selects pokemon
  validSelection = ""
  until (1..searchResults.length).map{|x| x.to_s}.include?(validSelection) do
    puts "Select the number of the pokemon to add to your roster"
    validSelection=gets.strip
  end
  sepLine
  @player.add(searchResults[validSelection.to_i-1].clone)
end

#playerSwitchObject



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/poor-pokemon/cli.rb', line 284

def playerSwitch
  #Player switches current pokemon from roster
  sepLine
  if @player.currentPokemon
    puts "Select Pokemon from your roster to switch to:"
  else
    puts "Select Pokemon from your roster to start with:"
  end
  userInput = "0"
  until @player.valids.include?(@player.roster[userInput.to_i-1]) && userInput != "0" do
    showPlayerSwitchRoster
    userInput = gets.strip
    if !@player.valids.include?(@player.roster[userInput.to_i-1])
      invalid
    end
  end
  if @player.currentPokemon
    puts "#{@player.currentPokemon.name.upcase} returns!"
  end
  @player.changeCurrent(userInput.to_i-1)
  puts "#{@player.currentPokemon.name.upcase} enters the battle!"
end

#playerTurnObject



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/poor-pokemon/cli.rb', line 261

def playerTurn
  puts "###Your Turn###"
  typeText = @player.currentPokemon.type2 != "" ? "#{@player.currentPokemon.type1}+#{@player.currentPokemon.type2}" : "#{@player.currentPokemon.type1}"
  puts "Current Pokemon: #{@player.currentPokemon.name.upcase} HP:#{@player.currentPokemon.hp} TYPE: #{typeText.upcase}"
  typeText = @enemy.currentPokemon.type2 != "" ? "#{@enemy.currentPokemon.type1}+#{@enemy.currentPokemon.type2}" : "#{@enemy.currentPokemon.type1}"
  puts "Enemy Pokemon: #{@enemy.currentPokemon.name.upcase} HP:#{@enemy.currentPokemon.hp} TYPE: #{typeText.upcase}"
  sepLine
  puts "What would you like to do? (a)ttack (s)witch"
  userInput = ""
  choices = ["a","attack","s","switch"]
  until choices.include?(userInput) do
    userInput = gets.strip.downcase
    if (userInput == "s" || userInput == "switch")
      playerSwitch
    elsif(userInput == "a" || userInput == "attack")
      playerAttacks(@enemy.currentPokemon)
    else
      invalid
    end
  end
  sepLine
end

#pokedexSelectionObject



109
110
111
112
113
114
115
116
117
118
# File 'lib/poor-pokemon/cli.rb', line 109

def pokedexSelection
  #player will begin selecting desired pokemon from pokedex
  #Ends when player has full roster
  until @player.roster.length>=6 do
    showPlayerRoster
    playerSelection
  end
  showPlayerRoster
  fillMoves(@player)
end

#randAtt(num) ⇒ Object



88
89
90
91
# File 'lib/poor-pokemon/cli.rb', line 88

def randAtt(num)
    var = (num * 0.1).round
    rand(var)+num-var
end

#randTypeObject



84
85
86
# File 'lib/poor-pokemon/cli.rb', line 84

def randType
    ["Bug","Dragon","Ice","Fighting","Fire","Flying","Grass","Ghost","Ground","Electric","Normal","Poison","Psychic","Rock","Water"].sample
end

#restartObject



409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/poor-pokemon/cli.rb', line 409

def restart
  sepLine
  puts "Would you like to play again? (y)es (n)o"
  choices = ["y","n","yes","no"]
  userInput = ''
  until choices.include?(userInput) do
    userInput = gets.strip.downcase
  end

  if(userInput == "y" || userInput == "yes")
    call
  end
end

#sepLineObject



169
170
171
# File 'lib/poor-pokemon/cli.rb', line 169

def sepLine
  puts "____________________"
end

#showPlayerRosterObject



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/poor-pokemon/cli.rb', line 120

def showPlayerRoster
  puts "YOUR ROSTER:"
  if @player.roster.length>0
    @player.roster.each_index{|i|
      puts "#{i+1}. #{@player.roster[i].name.capitalize}"
    }
  else
    puts "{There are no pokemon in your roster}"
  end
  sepLine
end

#showPlayerSwitchRosterObject



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/poor-pokemon/cli.rb', line 307

def showPlayerSwitchRoster
  maxLength = @player.roster.sort{|a,b| a.name.length<=>b.name.length}.last.name.length+5

  @player.roster.each_index{|i|
    health = @player.roster[i].alive? ? @player.roster[i].hp.to_s + " HP" : "FAINTED!"
    text = "#{i+1}. #{@player.roster[i].name.upcase}"
    until text.length >= maxLength do
      text = text + " "
    end
    if health !="FAINTED!"
      puts "#{text}| STATUS: #{health} spAtt1:#{@player.roster[i].moves[2].name.match(/(?<=\().*(?=\))/)[0].upcase}/PP #{@player.roster[i].moves[2].pp}  spAtt2:#{@player.roster[i].moves[3].name.match(/(?<=\().*(?=\))/)[0].upcase}/PP #{@player.roster[i].moves[3].pp}"
    else
      puts "#{text}| STATUS: #{health}"
    end
  }
  sepLine
end

#turnOrderObject



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/poor-pokemon/cli.rb', line 214

def turnOrder
  #decides turn order based on each player's current pokemon's speed
  #in event of tie, random
  if @player.currentPokemon.spd == @enemy.currentPokemon.spd
    if rand()>0.5
      playerTurn
      if @enemy.currentPokemon.alive?
        enemyTurn
      end
    else
      enemyTurn
      if @player.currentPokemon.alive?
        playerTurn
      end
    end
  elsif @player.currentPokemon.spd>@enemy.currentPokemon.spd
    playerTurn
    if @enemy.currentPokemon.alive?
      enemyTurn
    end
  elsif @player.currentPokemon.spd<@enemy.currentPokemon.spd
    enemyTurn
    if @player.currentPokemon.alive?
      playerTurn
    end
  end

  #switch if any dead and player still has usable pokemon
  if !@player.currentPokemon.alive?
    puts "Your #{@player.currentPokemon.name.upcase} fainted!"
    if !@player.allDead?
      playerSwitch
    end
  end
  if !@enemy.currentPokemon.alive?
    puts "Enemy #{@enemy.currentPokemon.name.upcase} fainted!"
    if !@enemy.allDead?
      @enemy.switch
      puts "Enemy sent out #{@enemy.currentPokemon.name.upcase}!"
    end
  end

  if !gameWon?
    currentStatus
  end
end