scobo
scobo

Reputation: 197

undefined method `[]' for nil:NilClass (NoMethodError) in tic-tac-toe game

I am building a Tic-Tac-Toe game to be played on the command line.

module TicTacToe
  class Player 
    attr_accessor :symbol

    def initialize(symbol)
      @symbol = symbol
    end

  end

  class Board 
    attr_reader :spaces

    def initialize
      @spaces = Array.new(9)
    end

    def to_s
      output = ""
      0.upto(8) do |position|
        output << "#{@spaces[position] || position}"
        case position % 3 
        when 0, 1 then output << " | "
        when 2 then output << "\n-----------\n" unless position == 8
        end
      end
      output
    end

    def space_available(cell, sym) 
      if spaces[cell].nil?
        spaces[cell] = sym
      else
        puts "Space unavailable"
      end
    end
  end

  class Game < Board 
    attr_reader :player1, :player2

    def initialize
      play_game
    end

    def play_game
      @player1 = Player.new("X")
      @player2 = Player.new("O")
      puts Board.new
      @current_turn = 1
      turn
    end

    def move(player)
      while victory != true
        puts "Where would you like to move?"
        choice = gets.chomp.to_i
        space_available(choice, player.symbol)
        puts Board
        @current_turn += 1
        turn
      end
    end

    def turn
      @current_turn.even? ? move(@player2) : move(@player1)
    end

    def victory
      #still working on this
    end

  end

end

puts TicTacToe::Game.new

The method that is to take a user's cell choice (space_available) and alter the array with their piece ('X' or 'O') is giving me an error. I can't find why my code is throwing this particular error.

Upvotes: 0

Views: 157

Answers (2)

Yule
Yule

Reputation: 9764

You are calling spaces[cell]. The error is telling you that you are calling [] on nil, which means that spaces must be nil.

Perhaps you mean @spaces? Otherwise - you need to tell the program how spaces is defined and how it is initialized. A simple spaces = {} unless spaces would work

Another way of initialising your spaces variable would be to call super when you initialize the Game:

class Game < Board 
    attr_reader :player1, :player2

    def initialize
      super
      play_game
    end
    ...

Upvotes: 1

ndnenkov
ndnenkov

Reputation: 36110

The problem is that you don't call the parent constructor in your Game class, therefore @spaces is not initialized.

Your hierarchy decision is questionable, but to make it work, you can simply change the Game constructor to:

def initialize
  super
  play_game
end

Upvotes: 1

Related Questions