Need help with shortening my code

Hello, i was wondering if anyone was willing to help me get started with shortening my code? I got the hang of just coding without classes or objects and just used a bunch of code and a lot of it is similar, but didn’t know how to put them into classes. I currently have over 40k lines because of a lot of just copy and past and changed a word or two here and their.

That’s a broad question! And I’m amazed you got to 40k lines …

The key to shortening is the same in all cases: what parts of the code are changing, and what are staying the same?

We have loops, methods (also called functions) and classes to prevent copy-pasting.

If you have a loop, the body of the loop is the thing ‘staying the same’ with the loop variable ‘the part that changes’.

When you have a method, you pass it values for the ‘parts that change’ - its parameters - and its body, again, is what has stayed the same.

Classes represent related variables and methods. You create a class with some values for its own variables - the parts that change - and the methods work on those values - the methods here are staying the same.

If you want to simplify your code, look for the pieces that you copy-pasted - those words you changed, could you make them variables and the piece you copy-pasted a method?

Do you have lots of related variables, and slightly different methods working on those variables in the same way? Then that’s where you could use a class.

Take it in pieces. If you have some smallish bit of code you’re not sure about, post it here with what you are trying to simplify.

require_relative “Player_Object”
require_relative "Current_Stats_Object
class Game
def initialize
player = Player.new()
puts player
class_choice = gets.chomp()
stats = Stats.new()
puts stats

end

end

class Player
attr_accessor :weapon, :hp, :max_hp, :damage, :defense, :luck
def initialize(weapon, hp, max_hp, damage, defense, luck)
weapon = weapon
hp = hp
max_hp = max_hp
damage = damage
defense = defense
luck = luck
end

end
player1 = Player.new(“wand”, 13, 13, 3, 3, 10)

	player2 = Player.new("dagger", 11, 11, 4, 2, 30)

	player3 = Player.new("sword", 17, 17, 3, 4, 15)

	player4 = Player.new("bow", 15, 14, 2, 3, 25)

	puts "Please choose a starting class. mage/rogue/warrior/archer"
	puts "Class   : Mage     Rogue     Warrior     Archer"
	puts "Weapon  : " + player1.weapon + "    " + player2.weapon + "      " + player3.weapon + "       " + player4.weapon
	puts "HP      : " + player1.hp.to_s + "        " + player2.hp.to_s + "          " + player3.hp.to_s + "        " + player4.hp.to_s
	puts "Damage  : " + player1.damage.to_s + "         " + player2.damage.to_s + "           " + player3.damage.to_s + "         " + player4.damage.to_s 
	puts "Defense : " + player1.defense.to_s + "         " + player2.defense.to_s + "           " + player3.defense.to_s + "         " + player4.defense.to_s
	puts "Luck    : " + player1.luck.to_s + "        " + player2.luck.to_s + "          " + player3.luck.to_s + "        " + player4.luck.to_s

class Stats
if
class_choice == “mage”
puts "Your current stats are " + player1.hp.to_s + " " + player1.damage.to_s + " " + player1.defense.to_s + " " + player1.luck.to_s
elsif
class_choice == “rogue”
puts "Your current stats are " + player2.hp.to_s + " " + player2.damage.to_s + " " + player2.defense.to_s + " " + player2.luck.to_s
elsif
class_choice == “warrior”
puts "Your current stats are " + player3.hp.to_s + " " + player3.damage.to_s + " " + player3.defense.to_s + " " + player3.luck.to_s
elsif
class_choice == “archer”
puts "Your current stats are " + player4.hp.to_s + " " + player4.damage.to_s + " " + player4.defense.to_s + " " + player4.luck.to_s
end
end

Also, i couldnt put the @ in the position because im a new user and deleted them

You’ve got a Player class, which holds information on each player.
Then you create instances of Player: player1, player2, etc.

For a start, look at your if-statement in Stats: see that all the print statements are the same?

In the Player Class, put this duplicate code in a method:

class Player
  # the code you already have

  def get_stats()
"Your current stats are " + @hp.to_s + " " + @damage.to_s + " " + @defense.to_s + " " + @luck.to_s
  end
end

Then, to print the players’ stats you can call:

puts player1.get_stats()
puts player2.get_stats()
puts player3.get_stats()
puts player4.get_stats()

You should also think of a collection to store your players in. A ‘map’ makes sense, as you have those ‘class_choice’ names:

AllPlayers = {"mage" => player1, "rogue" => player2, "warrior" => player3, "archer" => player4}

You can then show the stats for the named player by looking them up:

class_choice = gets.chomp()
puts AllPlayers[class_choice].get_stats()

So, I have complied the code but am getting an error on the undefined allplayers variable. This is what I have so far.

require_relative “Player_Object”

class Game
def initialize
puts Player.new()

end
class_choice = gets.chomp()
puts allplayers[class_choice].get_stats()

end

class Player
attr_accessor :weapon, :hp, :max_hp, :damage, :defense, :luck
def initialize(weapon, hp, max_hp, damage, defense, luck)
weapon = weapon
hp = hp
max_hp = max_hp
damage = damage
defense = defense
luck = luck #(These have the @ sign, but new user problem of referencing >2 users, so I took them out.)
end

	player1 = Player.new("wand", 13, 13, 3, 3, 10)
	
	player2 = Player.new("dagger", 11, 11, 4, 2, 30)

	player3 = Player.new("sword", 17, 17, 3, 4, 15)

	player4 = Player.new("bow", 15, 14, 2, 3, 25)

	puts "Please choose a starting class. mage/rogue/warrior/archer"
	puts "Class   : Mage     Rogue     Warrior     Archer"
	puts "Weapon  : " + player1.weapon + "    " + player2.weapon + "      " + player3.weapon + "       " + player4.weapon
	puts "HP      : " + player1.hp.to_s + "        " + player2.hp.to_s + "          " + player3.hp.to_s + "        " + player4.hp.to_s
	puts "Damage  : " + player1.damage.to_s + "         " + player2.damage.to_s + "           " + player3.damage.to_s + "         " + player4.damage.to_s 
	puts "Defense : " + player1.defense.to_s + "         " + player2.defense.to_s + "           " + player3.defense.to_s + "         " + player4.defense.to_s
	puts "Luck    : " + player1.luck.to_s + "        " + player2.luck.to_s + "          " + player3.luck.to_s + "        " + player4.luck.to_s

	allplayers = {"mage" => player1, "rogue" => player2, "warrior" => player3, "archer" => player4}

	def get_stats()
		puts "Your current stats are " + hp.to_s + " " + damage.to_s + " " + defense.to_s + " " + luck.to_s #(These have the @ sign, but new user problem of referencing >2 users, so I took them out.)
	end

end

(If you put three back-ticks either side of your code, it will ‘pretty-print’.)

You need to think about visibility of your variables. In this case, all_players seems to be a characteristic of Game, so make it an instance variable.

Try this:

class Player
  attr_accessor :weapon, :hp, :max_hp, :damage, :defense, :luck
  
  def initialize(weapon, hp, max_hp, damage, defense, luck)
    @weapon = weapon
    @hp = hp
    @max_hp = max_hp
    @damage = damage
    @defense = defense
    @luck = luck
  end

  def get_stats()
    "Your current stats are " + @hp.to_s + " " + @damage.to_s + " " + @defense.to_s + " " + @luck.to_s
  end
end

class Game
  # set up your four players, and store them in an instance variable
  def initialize

    player1 = Player.new("wand", 13, 13, 3, 3, 10)
    player2 = Player.new("dagger", 11, 11, 4, 2, 30)
    player3 = Player.new("sword", 17, 17, 3, 4, 15)
    player4 = Player.new("bow", 15, 14, 2, 3, 25)

    @all_players = {"mage" => player1, "rogue" => player2, "warrior" => player3, "archer" => player4}
  end

  def show_menu
    puts "Class   : Mage     Rogue     Warrior     Archer"
    puts "Weapon  : " + @all_players["mage"].weapon + "    " + @all_players["rogue"].weapon + "      " + @all_players["warrior"].weapon + "       " + @all_players["archer"].weapon
    puts "HP      : " + @all_players["mage"].hp.to_s + "        " + @all_players["rogue"].hp.to_s + "          " + @all_players["warrior"].hp.to_s + "        " + @all_players["archer"].hp.to_s
    puts "Damage  : " + @all_players["mage"].damage.to_s + "         " + @all_players["rogue"].damage.to_s + "           " + @all_players["warrior"].damage.to_s + "         " + @all_players["archer"].damage.to_s 
    puts "Defense : " + @all_players["mage"].defense.to_s + "         " + @all_players["rogue"].defense.to_s + "           " + @all_players["warrior"].defense.to_s + "         " + @all_players["archer"].defense.to_s
    puts "Luck    : " + @all_players["mage"].luck.to_s + "        " + @all_players["rogue"].luck.to_s + "          " + @all_players["warrior"].luck.to_s + "        " + @all_players["archer"].luck.to_s
  end

  # This method handles your game play
  def play_game
    show_menu
    puts "Please choose a starting class. mage/rogue/warrior/archer"
    puts "Choice? "
    class_choice = gets.chomp()
    puts @all_players[class_choice].get_stats()
  end
end

# Make a game instance and play the game
game = Game.new
game.play_game

So how will I be able to add stats and make it permanent for a given item to a given player? Been trying to test out different ideas, but none seems to work.

Can you post one of your ideas and what the problem is?

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs