hoopa
hoopa

Reputation: 15

If/elsif/else statement is skipping straight to else

I have the below if statement, but no matter what input I give to matrix (which is an array, and no I can't change the name) the console only outputs "Next turn!". The console will quite happily display that matrix[0], matrix[1] and matrix[2] are all "0" but then continue straight to the else statement. Is there anything wrong with the statement?

def checkwinner
            if @matrix[0] == "0" && @matrix[1] == "0" && @matrix[2] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[3] == "0" && @matrix[4] == "0" && @matrix[5] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[6] == "0" && @matrix[7] == "0" && @matrix[8] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[0] == "0" && @matrix[3] == "0" && @matrix[6] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[1] == "0" && @matrix[4] == "0" && @matrix[7] == "0" then
                puts "Player 1 wins!"
                finish
                exit    
            elsif @matrix[2] == "0" && @matrix[5] == "0" && @matrix[8] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[0] == "0" && @matrix[4] == "0" && @matrix[8] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[2] == "0" && @matrix[4] == "0" && @matrix[6] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[0] == "1" && @matrix[1] == "1" && @matrix[2] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[3] == "1" && @matrix[4] == "1" && @matrix[5] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[6] == "1" && @matrix[7] == "1" && @matrix[8] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[0] == "1" && @matrix[3] == "1" && @matrix[6] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[1] == "1" && @matrix[4] == "1" && @matrix[7] == "1" then
                puts "Player 2 wins!"
                finish
                exit    
            elsif @matrix[2] == "1" && @matrix[5] == "1" && @matrix[8] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[0] == "1" && @matrix[4] == "1" && @matrix[8] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[2] == "1" && @matrix[4] == "1" && @matrix[6] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            else puts "Next turn!"      
            end
        end

Whole code file below:

# Ruby code file - All your code should be located between the comments provided.

# Add any additional gems and global variables here
# require 'sinatra'     # remove '#' character to run sinatra wen server

# Main class module
module OXs_Game
# Input and output constants processed by subprocesses. MUST NOT change.
NOUGHT = 0
CROSS = 1

class Game
    attr_reader :matrix, :input, :output, :player1, :player2, :winner
    attr_writer :matrix, :input, :output, :player1, :player2, :winner

    def initialize(input, output)
        @input = input
        @output = output
    end

    # Any code/methods aimed at passing the RSpect tests should be added below.
        def start
            @output.puts "Welcome to Noughts and Crosses!"
            @output.puts "Starting game..."
            @output.puts "Created by:Stephen Mitchell"
            @output.puts "Player 1: 0 and Player 2: 1"
        end

        def created_by
            return "Stephen Mitchell"
        end

        def student_id
            return 51441219
        end

        def setplayer1
            @player1 = 0
        end

        def setplayer2
            @player2 = 1
        end

        def clearmatrix
            @matrix = ["_", "_", "_", "_", "_", "_", "_", "_", "_"]
        end

        def getmatrixvalue(n)
            @matrix[n]
        end

        def setmatrixvalue(i, v)
            @i = 1
            @v = "0"
            @matrix[i] = "0"            
        end

        def displaykey(matrix)
            @matrix = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
            @output.puts "Table key:\n|#{matrix[0]}|#{matrix[1]}|#{matrix[2]}|\n|#{matrix[3]}|#{matrix[4]}|#{matrix[5]}|\n|#{matrix[6]}|#{matrix[7]}|#{matrix[8]}|\n"
        end

        def displaymatrix
            @matrix = ["_", "_", "_", "_", "_", "_", "_", "_", "_"]
            @output.puts "Table status:\n|#{matrix[0]}|#{matrix[1]}|#{matrix[2]}|\n|#{matrix[3]}|#{matrix[4]}|#{matrix[5]}|\n|#{matrix[6]}|#{matrix[7]}|#{matrix[8]}|\n"
        end

        def finish
            @output.puts "Finishing game..."
        end

        def displaymenu
            @output.puts "Menu: (1)Start | (2)New | (9)Exit\n"
        end

        def checkwinner
            if @matrix[0] == "0" && @matrix[1] == "0" && @matrix[2] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[3] == "0" && @matrix[4] == "0" && @matrix[5] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[6] == "0" && @matrix[7] == "0" && @matrix[8] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[0] == "0" && @matrix[3] == "0" && @matrix[6] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[1] == "0" && @matrix[4] == "0" && @matrix[7] == "0" then
                puts "Player 1 wins!"
                finish
                exit    
            elsif @matrix[2] == "0" && @matrix[5] == "0" && @matrix[8] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[0] == "0" && @matrix[4] == "0" && @matrix[8] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[2] == "0" && @matrix[4] == "0" && @matrix[6] == "0" then
                puts "Player 1 wins!"
                finish
                exit
            elsif @matrix[0] == "1" && @matrix[1] == "1" && @matrix[2] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[3] == "1" && @matrix[4] == "1" && @matrix[5] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[6] == "1" && @matrix[7] == "1" && @matrix[8] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[0] == "1" && @matrix[3] == "1" && @matrix[6] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[1] == "1" && @matrix[4] == "1" && @matrix[7] == "1" then
                puts "Player 2 wins!"
                finish
                exit    
            elsif @matrix[2] == "1" && @matrix[5] == "1" && @matrix[8] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[0] == "1" && @matrix[4] == "1" && @matrix[8] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            elsif @matrix[2] == "1" && @matrix[4] == "1" && @matrix[6] == "1" then
                puts "Player 2 wins!"
                finish
                exit
            else puts "Next turn!"      
            end
        end


    # Any code/methods aimed at passing the RSpect tests should be added above.



end
end

Main program

# Main program
module OXs_Game
@input = STDIN
@output = STDOUT
g = Game.new(@input, @output)
matrixkey = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
matrix = ["_", "_", "_", "_", "_", "_", "_", "_", "_"]
playing = true
input = ""
option = 0
turn = 0

# Any code added to output the activity messages to the command line window should be added below.

g.start
g.displaykey(matrixkey)
g.displaymatrix
puts "Please select one of the following:"
g.displaymenu
menu_input = gets.chomp.to_s


while matrix.include? ("_") do
    puts "Table status:\n|#{matrix[0]}|#{matrix[1]}|#{matrix[2]}|\n|#{matrix[3]}|#{matrix[4]}|#{matrix[5]}|\n|#{matrix[6]}|#{matrix[7]}|#{matrix[8]}|\n"
    g.checkwinner
    turn += 1
    puts "player1 turn"
    x = gets.chomp.to_s
    case x
        when "1"
            matrix[0] = "0"
        when "2"
            matrix[1] = "0"
        when "3"
            matrix[2] = "0"
        when "4"
            matrix[3] = "0"
        when "5"
            matrix[4] = "0" 
        when "6"
            matrix[5] = "0"
        when "7"
            matrix[6] = "0" 
        when "8"
            matrix[7] = "0" 
        when "9"
            matrix[8] = "0" 
    end 
    puts "Table status:\n|#{matrix[0]}|#{matrix[1]}|#{matrix[2]}|\n|#{matrix[3]}|#{matrix[4]}|#{matrix[5]}|\n|#{matrix[6]}|#{matrix[7]}|#{matrix[8]}|\n"
    g.checkwinner
    turn +=1
    puts "player2 turn"
    y = gets.chomp.to_s
    case y
        when "1"
            matrix[0] = "1"
        when "2"
            matrix[1] = "1"
        when "3"
            matrix[2] = "1"
        when "4"
            matrix[3] = "1"
        when "5"
            matrix[4] = "1" 
        when "6"
            matrix[5] = "1"
        when "7"
            matrix[6] = "1" 
        when "8"
            matrix[7] = "1" 
        when "9"
            matrix[8] = "1" 
    end 
end

# Any code added to output the activity messages to the command line window should be added above.

end

Upvotes: 0

Views: 219

Answers (2)

spickermann
spickermann

Reputation: 106932

This is not really an answer to your question, but a tip how to improve your coding style.

You have a lot of repetition in your code and your code will benefit if you try to avoid that. For example your ``checkwinner` method can be simplified to something like this:

PATTERNS = [
  [1,2,3], [4,5,6], [7,8,9],  # rows
  [1,4,6], [2,5,8], [3,6,9],  # columns
  [1,5,9], [3,5,7]            # diagonal
]

def checkwinner
  PATTERNS.each do |pattern|
    values = pattern.map { |position| @matrix[position] }.uniq

    winner = 1 if values == ['0']
    winner = 2 if values == ['1']

    if winner
      puts "Player #{winner} wins!"
      finish
      exit
    end
  end

  puts "Next turn!"
end

Or instead of the long case blocks in your while loop, think about something like this:

if ('1'..'9').include?(x)
  matrix[x.to_i - 1] = '0'
end

...

if ('1'..'9').include?(y)
  matrix[y.to_i - 1] = '1'
end

Upvotes: 0

Dave Newton
Dave Newton

Reputation: 160211

You are modifying a local version of matrix in your gameloop (the while matrix.include? loop).

checkwinner, however, is called on the Game instance g. Game#checkwinner is examining an instance variable @matrix, which is not the same matrix you manipulate in your game loop.

You do not modify the matrix you check, hence checkwinner will always be looking at the same data.

There is a very confusing mix of local and instance variables here, which indicates a significant misunderstanding of either what you're doing, or how you're supposed to be doing it.

The turns (players' moves) should be manipulating the Game's @matrix instance variable.

Upvotes: 3

Related Questions