未定义的方法`keys'代表nil:NilClass in tic tac toe game RUBY

时间:2021-08-16 22:01:03

I'm trying to build a simple 2 player tic tac toe game in Ruby. Here is the code:

我正在尝试用Ruby构建一个简单的2人tic tac toe游戏。这是代码:

class Morpion

   def init
      create_grid
      get_player
      show_grid
   end
   def get_player
      puts "Let play some Tic Tac Toe"
      puts ""
      @player1 ='X'
      @player2='O'
          puts ""
          puts "Where would you like to move? (check out the grid below and type any number 1-9 to place your symbol): "
          puts " 1 | 2 | 3 "
          puts "---+---+---"
          puts " 4 | 5 | 6 "
          puts "---+---+---"
          puts " 7 | 8 | 9 "
   end

   def create_grid
        @grid = {
            '1' => ' ',
            '2' => ' ',
            '3' => ' ',
            '4' => ' ',
            '5' => ' ',
            '6' => ' ',
            '7' => ' ',
            '8' => ' ',
            '9' => ' '
        }
   end

    def show_grid
        puts ""
        puts "#{@grid['1']}|#{@grid['2']}|#{@grid['3']}"
        puts "-----"
        puts "#{@grid['4']}|#{@grid['5']}|#{@grid['6']}"
        puts "-----"
        puts "#{@grid['7']}|#{@grid['8']}|#{@grid['9']}"
        puts ""
    end

   def play
       number_turns=1
       while number_turns < 10
        number_turns.odd? ? player_turn(@player1) : player_turn(@player2)
        game_checker
        if game_checker
          break
        end
        number_turns+=1
       end  
   end

   def player_turn(player)
        puts player == 'X' ? "It's X's turn!" : "It's O's turn!"
        puts ""
        cell = gets.chomp
        unless @grid.keys.include?(cell) #check if the user entered a number corresponding to the grid
            puts ""
            puts "it has to be a number from 1 to 9"
            player_turn(player)
        end
        if @grid[cell] == ' ' #check if cell in grid is empty for user input
            @grid[cell] = player
        else
            puts ""
            puts "That cell is occupied. Choose again!"
            player_turn(player)
        end
        show_grid
   end

   def game_checker
        end_game = false
      if @grid['1'] != ' ' && @grid['5'] != ' ' && @grid['9'] != ' '
        if (@grid['1'] == @grid['2'] && @grid['1'] == @grid['3'])
            end_game = true
            victory = @grid['1']
          elsif (@grid['4'] == @grid['5'] && @grid['4'] ==@grid['6'])
            end_game = true
            victory = @grid['4']
          elsif (@grid['7'] == @grid['8'] && @grid['7'] == @grid['9'])
            end_game = true
            victory = @grid['7']
          elsif (@grid['1'] == @grid['4'] && @grid['1'] == @grid['7'])
            end_game = true
            victory = @grid['1']
          elsif (@grid['2'] == @grid['5'] && @grid['2'] == @grid['8'])
            end_game= true
            victory = @grid['2']
          elsif (@grid['3'] == @grid['6'] && @grid['3'] == @grid['9'])
            end_game = true
            victory = @grid['3']
          elsif (@grid['1'] == @grid['5'] && @grid['1'] == @grid['9'])
            end_game = true
            victory = @grid['1']
          elsif (@grid['3'] == @grid['5'] && @grid['3'] == @grid['7'])
            end_game = true
            victory = @grid['3']
          else
            end_game = false
        end
      end
        if end_game 
           puts "the winner of this game is #{victory}"
           return true
        end
   end


end


m=Morpion.new
m.play

So my issue is this: 1. I am asking a player to add his symbol (X or O) in the grid that ranges from 1 to 9 (because there is 9 cells)

所以我的问题是:1。我要求玩家在网格中添加他的符号(X或O),范围从1到9(因为有9个单元格)

  1. if I enter 1 for example, which is the upper left cell I get this error:

    如果我输入1,例如,左上角的单元格,我收到此错误:

    (eval):187: undefined method `keys' for nil:NilClass (NoMethodError) from (eval):168:in `play' from (eval):245

    (eval):187:nil的未定义方法`keys':来自(eval)的NilClass(NoMethodError):168:来自(eval)的'play':245

If you want to run this program I suggest using THIS LINK

如果你想运行这个程序我建议使用这个链接

EDIT: The problem as @Paul and @August stated was that I used an incorrect constructor method init instead of using the correct one: initialize. Now my program works. Thanks to them.

编辑:@Paul和@August说的问题是我使用了一个不正确的构造函数方法init而不是使用正确的:initialize。现在我的程序工作了。谢谢他们。

2 个解决方案

#1


1  

The problem is that your @grid variable is never being created; it is nil. Hence the error message, you're attempting to invoke a method on a nil object.

问题是你的@grid变量永远不会被创建;它没有。因此,错误消息,您尝试在nil对象上调用方法。

The cause of your woes is because you've misnamed the constructor method. In Ruby, constructors are named initialize, however you named it init. Rename it to the correct name, and it should work.

你的困境的原因是因为你错误地命名了构造函数方法。在Ruby中,构造函数名为initialize,但是您将其命名为init。将其重命名为正确的名称,它应该工作。

#2


2  

You initialize the @grid hash in a method called init. Ruby won't call this method when you construct a new instance of Game. You should instead rename the init method to initialize, which will be called automatically by Ruby.

您在名为init的方法中初始化@grid哈希。当你构造一个新的Game实例时,Ruby不会调用这个方法。您应该将init方法重命名为initialize,这将由Ruby自动调用。

#1


1  

The problem is that your @grid variable is never being created; it is nil. Hence the error message, you're attempting to invoke a method on a nil object.

问题是你的@grid变量永远不会被创建;它没有。因此,错误消息,您尝试在nil对象上调用方法。

The cause of your woes is because you've misnamed the constructor method. In Ruby, constructors are named initialize, however you named it init. Rename it to the correct name, and it should work.

你的困境的原因是因为你错误地命名了构造函数方法。在Ruby中,构造函数名为initialize,但是您将其命名为init。将其重命名为正确的名称,它应该工作。

#2


2  

You initialize the @grid hash in a method called init. Ruby won't call this method when you construct a new instance of Game. You should instead rename the init method to initialize, which will be called automatically by Ruby.

您在名为init的方法中初始化@grid哈希。当你构造一个新的Game实例时,Ruby不会调用这个方法。您应该将init方法重命名为initialize,这将由Ruby自动调用。