玩家与电脑

时间:2018-03-19 22:53:06

标签: ruby

按照在线指南创建了这个连接4游戏,但指南没有解释如何使它成为计算机与播放器它只解释了如何使它成为玩家与玩家。我已经尝试添加一个计算机变量,为列生成一个随机数1..8,但它没有工作只是坐在那里要求玩家二选择一个位置。

以下是播放器代码,如何实现播放器与电脑?

class Board
  attr_accessor :board
  attr_reader :turn, :identifier

  def initialize
    @board = [
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0]
    ]
    @turn = 0
    @identifier = 1
  end

  def choose_column(col)
    7.downto(0) do |i|
      if board[i][col-1] == 0
        board[i][col-1] = identifier
        break
      end
    end
    false
  end

  def win?
    return true if check_rows?
    return true if check_columns?
    return true if check_diagonal?
  end

  def check_validity(sum,num)
    if num == 1
      sum = 0 if sum < 0
      sum += 1
    elsif num == -1
      sum = 0 if sum > 0
      sum -= 1
    else
      sum = 0
    end
  end

  def check_rows?
    8.times do |i|
      board[i].inject(0) do |sum, num|
        sum = check_validity(sum,num)
        return true if sum.abs == 4
        sum
      end
    end
    false
  end

  def check_columns?
    8.times do |i|
      column = []
      board.each { |row| column.push(row[i]) }
      column.inject(0) do |sum, num|
        sum = check_validity(sum,num)
        return true if sum.abs == 4
        sum
      end
    end
    false
  end

  def check_diagonal?
    board[0..2].each_with_index do |row, row_i|
      row.each_with_index do |column, col_i|
        if col_i <=3
          sum = board[row_i][col_i]
          1.upto(3) { |i| sum += board[row_i+i][col_i+i] }
          return true if sum.abs == 4
        end
        if col_i >= 3
          sum = board[row_i][col_i]
          1.upto(3) { |i| sum += board[row_i+i][col_i-i] }
          return true if sum.abs == 4
        end
      end
    end
    false
  end

  def new_game
    @turn = 1
  end

  def game_flow
    new_game
    while turn < 43
      assign_player
      player = @identifier == 1 ? 1 : 2
      puts draw_board
      print "Round #{@turn}. Player #{player}'s turn. Choose column (1-8): "
      input = gets.chomp
      while !validate_input(input) || check_full?(input)
        print "Invalid Pick. Try again: "
        input = gets.chomp
      end
      input = validate_input(input)
      choose_column(input)
      if win?
        puts draw_board
        puts "Congratulations. Player #{player} won"
        break
      end
      @turn += 1
    end
    puts "Draw!" unless win?
    return true
  end

  def assign_player
    @identifier = @turn.odd? ? 1 : -1
  end

  def validate_input(input)
    return input !~ /^[1-8]$/ ? false : input.to_i
  end

  def check_full?(column)
    column = column.to_i
    column -= 1
    return board[0][column] != 0
  end

  def draw_board
    print "1 2 3 4 5 6 7 8\n"
    rep = { 0 => ".", 1 => "O", -1 => "X" }
    board.each do |row|
      print  "#{rep[row[0]]} #{rep[row[1]]} #{rep[row[2]]} #{rep[row[3]]} #{rep[row[4]]} #{rep[row[5]]} #{rep[row[6]]} #{rep[row[7]]}\n"
    end
    print " "
  end
end

board = Board.new
board.game_flow

1 个答案:

答案 0 :(得分:0)

正如Ken White所说,如果您希望计算机选择一个选项,您需要检测它何时是计算机。看起来在您的示例中,它是在@player变量中编码的。你可以拥有一个简单的if分支,当它是人类玩家时,它只会提示输入。其他所有内容都可以保持不变,但您会更新game_flow方法以考虑其他情况:

if player == 1
  print "Round #{@turn}. Player #{player}'s turn. Choose column (1-8): "
  input = gets.chomp
  while !validate_input(input) || check_full?(input)
    print "Invalid Pick. Try again: "
    input = gets.chomp
  end
  input = validate_input(input)
else
  input = rand(1..8)
end

希望这有帮助。