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?