Question

I'm just learning Ruby and having a hard time with this error, I read some posts which all said to define the method like this...

def self.methodname

I did this but to no avail. here is my code Hopefully it's a simple thing I'm missing. Thanks for the help.

class Cannibals
@VEGANS = 3
@CANNIBALS = 3
@VEGAN_ID = 0
@CANNIBAL_ID = 1
@EMPTY_ID = 2
@CROSSED_ID = 0
@SHORE_ID = 1

@vegansCrossed=0
@cannibalsCrossed=0
@vegansLeft = @VEGANS
@cannibalsLeft = @CANNIBALS
@boat = [@EMPTY_ID,@EMPTY_ID]
@boatLocation = @SHORE_ID


#/* take an integer as argument1, 
# * 0- load 2 cannibals
# * 1- load 2 vegans
# * 2- load one of each.
# * 3- load 1 cannibal
# * 4- load 1 vegan 
# * argument 2 is destionation
# * 0- crossed
# * 1- shore*/
def self.populateBoat (choice,destination )
    message = "Invalid arguments delivered"
    boatDestination

    validChoice = false
case choice
    when 0
        validChoice = true
        if destination == @CROSSED_ID
            @cannibalsLeft -= 2
        elsif destination == @SHORE_ID 
            @cannibalsCrossed -=2
        end
        @boat[0] = @CANNIBAL_ID
        @boat[1] = @CANNIBAL_ID

    when 1
        validChoice = true
        if destination == @CROSSED_ID
            @vegansLeft -= 2
            elsif destination == @SHORE_ID 
            @vegansCrossed -= 2
        end
        @boat[0] = @VEGAN_ID
        @boat[1] = @VEGAN_ID
    when 2
        validChoice = true
        if destination == @CROSSED_ID
            --@vegansLeft
            --@cannibalsLeft
            elsif destination == @SHORE_ID
                --@vegansCrossed
                --@cannibalsCrossed
        end
        @boat[0] = @VEGAN_ID
        @boat[1] = @CANNIBAL_ID
    when 3
        validChoice = true
        if destination == @CROSSED_ID
            --@cannibalsLeft
            elsif destination == @SHORE_ID 

            --@cannibalsCrossed
        end

        @boat[0] = @CANNIBAL_ID
        @boat[1] = @EMPTY_ID
    when 4
        validChoice = true
        if destination == @CROSSED_ID 

            --@vegansLeft
            elsif destination == @SHORE_ID 

            --@vegansCrossed
        end

        @boat[0] = @VEGAN_ID
        @boat[1] = @EMPTY_ID
    else
        message = "Invalid choice"
end
    if validChoice 

        if destination == @SHORE_ID 
            boatDestination = "the starting point."
            elsif destination == @CROSSED_ID 
                boatDestination = "the ending point."
        else
            boatDestination = "a place unknown, they're off track."
        message = @getBoatOccupants   + "heading to " + boatDestination +"\n"
        end
    end
    return message

end
#/*Unload the boat, takes an integer for an argument
# * 0- unload crossed
# * 1- unload at shore */
def unloadBoat (where) 


    #create message
    String message = "They sunk the boat. \n"
    if @boatLocation == @SHORE_ID 
        message = "Boat unloaded at ending point. \n"

        elsif @boatLocation == @CROSSED_ID 
            message = "Boat unloaded at starting point. \n"
    end

    i = 0
    if where == @CROSSED_ID 
        for i in 0..1 
            if @boat[i] == @VEGAN_ID 
                @vegansCrossed += 1
            end
            if @boat[i] == @CANNIBAL_ID 
                @cannibalsCrossed += 1
            end
            @boat[i]=@EMPTY_ID
        end
        @boatLocation = @CROSSED_ID
        elsif where == @SHORE_ID        

            for i in 0..1 

                if @boat[i] == @VEGAN_ID 

                    @vegansLeft += 1
                    elsif @boat[i] == @CANNIBAL_ID 

                        @cannibalsLeft+= 1
                end
                @boat[i]=@EMPTY_ID
            end
            @boatLocation = @SHORE_ID
    end

    return message
end


#build a string describing boat's occupants.
def getBoatOccupants  

    message = ""
    occupants = Array.new(2)


    #Get names for occupants
    i = 0
    for i in 0..2

        occupants[i] = ""
        if @boat[i] == @VEGAN_ID 
            occupants[i] = "vegan"
        end
        if @boat[i] == @CANNIBAL_ID 
            occupants[i] = "cannibal"
        end

    end
    #if boat is full start building string
    if @boat[1] != @EMPTY_ID 


        if @boat[0] == @boat[1] 

            message = "Two " + occupants[0]
            message +=  "s are "
        else

            message =  "One "+occupants[0]
            message += " and one " + occupants[1] + " are "
        end

    #if boat is empty start building string
        elsif @boat[1] == @EMPTY_ID 

            message = "One "+occupants[0]
            message +=  " is "
    end
    message +=  "in the boat "
    return message
end
def getBoatPosition  

    String location = ""
    if @boatLocation == @SHORE_ID 
        location = "at the starting position."
        elsif @boatLocation == @CROSSED_ID 
            location = "across the river."
    end
    return location
end


#/*Check to see if game is over and i programmed it wrong perfectGameLogic  or if user got eaten. */
def eaten  

    boolean gameOver = false

    if  @cannibalsLeft > @vegansLeft and @vegansLeft != 0  ||  @cannibalsCrossed > @vegansCrossed and @vegansCrossed != 0  
        gameOver = true
    return gameOver
end

#/*Used for gamLogic playable  only
# * decides if a users choice is valid given the circumstances.
# */
def isValid  

    validChoices = [true, true, true, true, true]
    if @boatLocation == @SHORE_ID 

        case @cannibalsLeft 

            when 0
                validChoices[0] = false
                validChoices[2] = false
                validChoices[3] = false
            when 1
                validChoices[0] = false
            else #//do nothing.
        end
        case @vegansLeft 

            when 0
                validChoices[1] = false
                validChoices[2] = false
                validChoices[4] = false
            when 1
                validChoices[1] = false
            else #//do nothing.
        end
        elsif @boatLocation == @CROSSED_ID 

            case @cannibalsCrossed 

                when 0
                    validChoices[0] = false
                    validChoices[2] = false
                    validChoices[3] = false
                when 1
                    validChoices[0] = false
                default:# //do nothing.
            end
            case @vegansCrossed 

                when 0
                    validChoices[1] = false
                    validChoices[2] = false
                    validChoices[4] = false
                when 1
                    validChoices[1] = false
                else #//do nothing.
            end
    end

    return validChoices
end
#/*This is for a preset game where rules are strict.
#no user input is required.
#game must move all cannibals across first,
#then 2 humans across
#then bring back one of each
#then save last human.
#base case: everyone crossed */
def self.perfectGameLogic (run) 

    message = ""

    if run == false 

        message = "Game Over"   
    else

        if  (@cannibalsLeft == 3 || @cannibalsLeft == 2  and @vegansLeft == 3) 

            message = message + populateBoat(0, @CROSSED_ID) 
            message +=unloadBoat(@CROSSED_ID) 
            message +=populateBoat(3, @SHORE_ID) 
            message +=unloadBoat(@SHORE_ID) 
            elsif @vegansLeft == 3 and @cannibalsLeft == 1 

                message +=populateBoat(1, @CROSSED_ID) 
                message +=unloadBoat(@CROSSED_ID) 
                message +=populateBoat(2, @SHORE_ID) 
                message +=unloadBoat(@SHORE_ID) 
            elsif @vegansLeft == 2 and @cannibalsLeft == 2 

                message +=populateBoat(1, @CROSSED_ID) 
                message +=unloadBoat(@CROSSED_ID) 
            elsif @vegansCrossed == 3 and @cannibalsCrossed < 3 
                i = 0
                for i in 0..2

                    message +=populateBoat(3, @SHORE_ID) 
                    message +=unloadBoat(@SHORE_ID) 
                    message +=populateBoat(0, @CROSSED_ID) 
                    message +=unloadBoat(@CROSSED_ID) 
                end
            elsif @vegansCrossed == 3 and @cannibalsCrossed == 3 

                message = "You Win!"
                run = false
        end
        puts message 
        if @eaten   == true 

            puts "you lose" 
            run = false
        end

            perfectGameLogic(run) 


    end
end
#/* this is a game the user gets to interact with.
# * if you get eaten, game is over, or if you win, game is over.
# */
def self.gameLogic(run) 

     message = ""
     error = ""
     choice
     destination = @CROSSED_ID
     choiceOk = false
    isValid = @isValid  


    if run == false 

        message = "Game Over"   
    else

        if @vegansCrossed == 3 and @cannibalsCrossed == 3 

            puts  "You Win!" 
            run = false
        else

            begin
                putsln error+"\n" 
                message = "The boat is " + @getBoatPosition   + "\n" +
                            @vegansCrossed+ " vegans have crossed and \n"+
                            @cannibalsCrossed + " cannibals have crossed. \n"
                            +"Please make a choice, who goes on the boat?: \n" +
                            "0 - load 2 cannibals \n" + 
                            "1 - load 2 vegans \n" +
                            "2 - load one of each \n" +
                            "3 - load 1 cannibal \n" +
                            "4 - load 1 Vegan \n" 
                puts message   
                choice = scan.nextInt  

                if choice < 5 and choice >= 0 

                    if isValid[choice] 

                        #//this is the only case where a choice is acceptable.
                        choiceOk = true
                    else

                        error = "You can't move people who aren't there."
                    end
                else

                    error= "You must choose a number between 0 and 4."
                end
            end
            end while choiceOk == false 

            if @boatLocation == @SHORE_ID 
                destination = @CROSSED_ID
                elsif @boatLocation == @CROSSED_ID 
                    destination = @SHORE_ID
                end
            end

            populateBoat(choice, destination) 
            unloadBoat(destination) 
        end
        if @eaten == true 

            puts "You Lose, those poor vegans! :  " 
            run = false
        end

        gameLogic run 


    end
end


end

Game = Cannibals.new
    #/#perfectGameLogic just runs.
    #//gameLogic is playable.
    #Game.perfectGameLogic(true);
    puts "***********************************Cannibals and vegan river crossing******************************** \n" +
                            "the object of the game is to get all the vegans across the river safetly. If the cannibals out number \n " +
                            "the vegans, they will be eaten alive and you lose the game, so try to avoid that!"
    Game.populateBoat(0,0)                  
    #Game.gameLogic(true)

this is my first attempt at ruby, previously this was coded in java so forgive me if i missed and java specific stuff in the code. And give me some pointers, thanks!

Was it helpful?

Solution

Inside of a class, a method declared using:

class MyClass
  def self.my_method
    # some stuff...
  end
end

Is a "class method". That means you can call it like so:

MyClass.my_method

It's also valid to have an "instance method" which is associated with a member of the class, not the class itself:

class MyClass
  def my_method
    # some stuff
  end
end

In your case, I think your code in "some other code in here........" may have a syntax error and an extra end statement, closing off the class too early and causing the def self.gameLogic(...) to be invalid since it's outside of the class.

There is a visible error in the logic in which you created a class method (as described above) with a def self.gameLogic but you're calling it as if it were an instance method with an instance of the class. You should call a class method as Cannibals.gameLogic(...), or declare gameLogic as an instance method: def gameLogic(...) within the class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top