【问题标题】:How do I continue tic-tac-toe game from saved yaml file?如何从保存的 yaml 文件中继续井字游戏?
【发布时间】:2015-09-02 07:23:59
【问题描述】:

我有以下井字游戏:(我是菜鸟,请忽略课程的设计,游戏有效,这就是我现在关心的所有内容。)

#a tic tac toe game
class TicTacToe
    require "yaml"
    attr_accessor :player1, :player2
    #crates playes and a game board to play tic tac toe
    def initialize()
        @player1 = Player.new("Player One", "x")
        @player2 = Player.new("Player Two", "o")
        @game_board = Board.new
    end

    #prints the board
    def print_board
        @game_board.board.each_with_index do |row, index| 
            puts "#{row.join(" | ")}"
            puts "---------" unless index == 2
        end
        puts
    end

    #determines whose move it is
    def move
        if @turn % 2 == 1
            player_one_turn
        else
            player_two_turn
        end
        @turn += 1
    end

    def valid_move?(row, col)
        if @game_board.board[row][col] == " "
            return true
        else
            return false
        end
    end

    #player ones turn
    def player_one_turn
        print_board
        puts "#{@player1.name} it's your turn:"
        puts "Enter a row (0-2)"
        row = gets.chomp.to_i
        puts "Enter a column (0-2)"
        col = gets.chomp.to_i
        if valid_move?(row, col)
            @game_board.board[row][col] = @player1.shape
        else
            puts "There's already a shape at that position."
            player_one_turn
        end

        if win?(@player1.shape)
            winner(@player1.name)
            @winner = true
        end
    end

    #player two's turn
    def player_two_turn
        print_board
        puts "#{@player2.name} it's your turn:"
        puts "Enter a row (0-2)"
        row = gets.chomp.to_i
        puts "Enter a column (0-2)"
        col = gets.chomp.to_i
        if valid_move?(row, col)
            @game_board.board[row][col] = @player2.shape
        else
            puts "There's already a shape at that position."
            player_two_turn
        end

        if win?(@player2.shape)
            winner(@player2.name)
            @winner = true
        end
    end

    def win?(shape)
        if (@game_board.board[0][0] == shape) && (@game_board.board[0][1] == shape) && (@game_board.board[0][2] == shape)
            return true
        elsif (@game_board.board[1][0] == shape) && (@game_board.board[1][1] == shape) && (@game_board.board[1][2] == shape)
            return true
        elsif (@game_board.board[2][0] == shape) && (@game_board.board[2][1] == shape) && (@game_board.board[2][2] == shape)
            return true
        elsif (@game_board.board[0][0] == shape) && (@game_board.board[1][0] == shape) && (@game_board.board[2][0] == shape)
            return true
        elsif (@game_board.board[0][1] == shape) && (@game_board.board[1][1] == shape) && (@game_board.board[2][1] == shape)
            return true
        elsif (@game_board.board[0][2] == shape) && (@game_board.board[1][2] == shape) && (@game_board.board[2][2] == shape)
            return true
        elsif (@game_board.board[0][0] == shape) && (@game_board.board[1][1] == shape) && (@game_board.board[2][2] == shape)
            return true
        elsif (@game_board.board[0][2] == shape) && (@game_board.board[1][1] == shape) && (@game_board.board[2][0] == shape)
            return true
        else
            return false
        end
    end

    def draw?
        if @turn > 9
            print_board
            puts "The game ended in a draw. :)"
            @winner = true
            return true
        end
        false
    end

    def winner(winner_name)
        puts "#{winner_name}, YOU WIN!!!"
    end

    def play
        @turn = 1
        @winner = false

        until @winner
            move unless draw?
            save
        end
    end


    #a class that generates an empty board
    class Board
    attr_accessor :board
        def initialize
            @board = [[' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
        end
    end

    #a class that assigns creates plaers and assigns them a shape "x" or "o"
    class Player
        attr_accessor :name, :shape
        def initialize(name, shape)
            @name = name
            @shape = shape
        end
    end

    def save
        yaml = YAML::dump(self)
        File.open("save.txt", "w"){|file| file.write(yaml)}
    end

    def self.load
        file = File.read("save.txt")
        YAML::load_file(file)
    end
end

game = TicTacToe.new
game.play

我想开始玩游戏,在游戏中途退出程序,等我打电话给TicTacToe.load后再回来完成。但是,当我现在执行此操作时,会加载 YAML 文件,但程序不会从应有的位置恢复。

谁能告诉我是否有办法做我想做的事?

【问题讨论】:

  • 你已经展示了很多代码,包括.save.load棋盘的方法定义(关键的是,你没有任何东西可以存储其他游戏状态,比如轮到谁了,这可能是您缺少什么的线索)。但是,我在代码中看不到您实际使用这些方法的任何地方,或者您如何尝试退出、保存、加载和重新启动游戏。您需要显示该代码 - 即使它只是在 IRB 中尝试某些东西 - 因为否则它是任何人对错误的猜测。

标签: ruby serialization yaml dump


【解决方案1】:

我在区域上认为执行YAML::load(self) 之类的操作会通过某种魔法自动加载我所指的文件的保存状态。但是,我开始了解到,如果我的文件,我设计类的方式和“播放”函数中的依赖项将不允许我加载以前的状态。

加载 YAML 文件时,必须将文件加载到变量中,然后手动将对象值分配给类的值。这样,变量的当前状态几乎可以手动分配给类的实例变量。例如,我可以这样做:file = YAML.load("file_name"),然后分配变量值,例如:@board = file.board

如果我以前知道这一点,我会设计我的类具有更少的依赖关系,以便它可以以更清洁和更方便的方式加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多