TicTacToe 无效移动方法问题
TicTacToe invalid move method issue
以下是我对 TicTacToe 游戏的看法。到目前为止它有效,但并不完美。我对其中一种方法有疑问 - Game#invalid_move_check?在游戏问你之后"where to:"一旦选择了新的目的地,游戏就会改变符号,就像是新的回合一样。事实上不是,假设在下一个回合之前保持相同的玩家符号。
P.S 代码可能需要一些重构。我正处于学习阶段。
class Game
def initialize(symbol)
@board = Array.new(3){Array.new(3)}
# [0,1,2]
# [3,4,5]
# [6,7,8]
@symbol = ["X", "O"]
end
WINNING_COMBO = [
# Horizontal wins:
[0, 1, 2], [3, 4, 5], [6, 7, 8],
# Vertical wins:
[0, 3, 6], [1, 4, 7], [2, 5, 8],
# Diagonal wins:
[0, 4, 8], [2, 4, 6]
]
def create_players
# create both players
@names = []
print "Please enter the name of the first player: "
@player_1 =gets.chomp
@names << @player_1
print "Please enter the name of the second player: "
@player_2 = gets.chomp
@names << @player_2
puts "\n"
puts"welcome #{@player_1.upcase} and #{@player_2.upcase}"
puts"------------------------------------------------"
puts"\n"
puts "Randomizing who'll start..."
puts"\n"
# assign player by calling the player_assigment function that will determine who will start first
player_assigment
puts"\n"
end
def player_assigment
# merge the names array and symbol array
# with the zip method and return a nested array with player and symbol.
@choice = @names.zip(@symbol)
# iterate over the choice nested array and
# print out each player and their assigned symbol
@choice.each do |player, symbol|
puts "#{player.upcase} will use #{symbol}"
end
end
def current
@current = @names.first
@current
end
def switch_turn
@current = @names.last
@current
end
def first_turn
current
puts "#{@current.upcase} turn"
@marker = @symbol.first
make_move(@marker)
end
def next_turn
switch_turn
puts "#{@current.upcase} turn"
@marker = @symbol.last
make_move(@marker)
end
def check_win?(first_arr, second_arr)
WINNING_COMBO.select do |item|
if
item == first_arr
puts"#{@player_1} won!!"
elsif
item == second_arr
puts "#{@player_2} won!!"
end
end
end
def mapping(move, marker)
case move
when 0
arr_index = 0
index = 0
invalid_move_check?(arr_index,index)
@board[0][0] = marker
when 1
arr_index = 0
index = 1
invalid_move_check?(arr_index,index)
@board[0][1] = marker
when 2
arr_index = 0
index = 2
invalid_move_check?(arr_index,index)
@board[0][2] = marker
when 3
arr_index = 1
index = 0
invalid_move_check?(arr_index,index)
@board[1][0] = marker
when 4
arr_index = 1
index = 1
invalid_move_check?(arr_index,index)
@board[1][1] = marker
when 5
arr_index = 1
index = 2
invalid_move_check?(arr_index,index)
@board[1][2] = marker
when 6
arr_index = 2
index = 0
invalid_move_check?(arr_index,index)
@board[2][0] = marker
when 7
arr_index = 2
index = 1
invalid_move_check?(arr_index,index)
@board[2][1] = marker
when 8
arr_index = 2
index = 2
invalid_move_check?(arr_index,index)
@board[2][2] = marker
end
end
def invalid
puts"move invalid"
end
def invalid_move_check?(arr_index, index)
array = @board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
@move = gets.chomp.to_i
mapping(@move,@marker)
end
end
def make_move(marker)
# after each turn the make_move method will called to place move on the board
puts "Where to :"
@move = gets.chomp.to_i
mapping(@move,@marker)
print_board
end
# display board in a matrix format
def print_board
@board.each_slice(1) { |a| p a }
puts"\n"
end
def instructions
puts "Instructions :Enter your first move by entering a number 1-9"
puts "corresponding to the grid on the bottom and press enter"
puts"\n"
puts "0 | 1 | 2 ",
"----------",
"3 | 4 | 5 ",
"----------",
"6 | 7 | 8 "
print"\n"
end
def self.start(symbol)
# start a new game
new_game =Game.new(symbol)
# create players
new_game.create_players
new_game.instructions
new_game.print_board
# Checking wining combo for matching patter if none
while new_game.check_win?(@move_first, @move_second) do
new_game.first_turn
# the player switch turn
new_game.next_turn
end
end
loop do
puts"------------------------------------------------"
puts" Welcome to tictactoe ".upcase
puts"------------------------------------------------"
print"\n"
Game.start(@symbol)
end
end
这应该可以解决问题:
#will return true or false to check validity of move
def invalid_move_check?(arr_index, index)
array = @board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
@move = gets.chomp.to_i
mapping(@move,@marker)
return true
end
return false
end
def mapping(move, marker)
case move
...
when 0
arr_index = 0
index = 0
unless invalid_move_check?(arr_index,index) #change all cases
@board[0][0] = marker #to have the assignment of board
#only if the move is valid
end
...
end
end
你的错误的原因是即使移动无效也会发生赋值。
这只是您当前问题的创可贴解决方案,至于重构,可以做一些事情来优化您的代码并使其变得更好:)但是您仍然必须先修复您的 'ending'.重构您自己的代码将是一个很好的做法。祝你旅途愉快ruby
!
在草拟之前的代码并重新思考我提出这个解决方案的代码之后,虽然不像我希望的那样优雅,但它有效。我移动了 if/else 块代码中的符号分配因此,当一个动作无效时,下一步将使用当前玩家的符号
def mapping(move, symbol)
case move
when 0
if @board[0][0]=="X" || @board[0][0] == "O"
invalid
make_move
else
@board[0][0] = symbol
track_move(@move)
print_board
end
...
end
end
以下是我对 TicTacToe 游戏的看法。到目前为止它有效,但并不完美。我对其中一种方法有疑问 - Game#invalid_move_check?在游戏问你之后"where to:"一旦选择了新的目的地,游戏就会改变符号,就像是新的回合一样。事实上不是,假设在下一个回合之前保持相同的玩家符号。
P.S 代码可能需要一些重构。我正处于学习阶段。
class Game
def initialize(symbol)
@board = Array.new(3){Array.new(3)}
# [0,1,2]
# [3,4,5]
# [6,7,8]
@symbol = ["X", "O"]
end
WINNING_COMBO = [
# Horizontal wins:
[0, 1, 2], [3, 4, 5], [6, 7, 8],
# Vertical wins:
[0, 3, 6], [1, 4, 7], [2, 5, 8],
# Diagonal wins:
[0, 4, 8], [2, 4, 6]
]
def create_players
# create both players
@names = []
print "Please enter the name of the first player: "
@player_1 =gets.chomp
@names << @player_1
print "Please enter the name of the second player: "
@player_2 = gets.chomp
@names << @player_2
puts "\n"
puts"welcome #{@player_1.upcase} and #{@player_2.upcase}"
puts"------------------------------------------------"
puts"\n"
puts "Randomizing who'll start..."
puts"\n"
# assign player by calling the player_assigment function that will determine who will start first
player_assigment
puts"\n"
end
def player_assigment
# merge the names array and symbol array
# with the zip method and return a nested array with player and symbol.
@choice = @names.zip(@symbol)
# iterate over the choice nested array and
# print out each player and their assigned symbol
@choice.each do |player, symbol|
puts "#{player.upcase} will use #{symbol}"
end
end
def current
@current = @names.first
@current
end
def switch_turn
@current = @names.last
@current
end
def first_turn
current
puts "#{@current.upcase} turn"
@marker = @symbol.first
make_move(@marker)
end
def next_turn
switch_turn
puts "#{@current.upcase} turn"
@marker = @symbol.last
make_move(@marker)
end
def check_win?(first_arr, second_arr)
WINNING_COMBO.select do |item|
if
item == first_arr
puts"#{@player_1} won!!"
elsif
item == second_arr
puts "#{@player_2} won!!"
end
end
end
def mapping(move, marker)
case move
when 0
arr_index = 0
index = 0
invalid_move_check?(arr_index,index)
@board[0][0] = marker
when 1
arr_index = 0
index = 1
invalid_move_check?(arr_index,index)
@board[0][1] = marker
when 2
arr_index = 0
index = 2
invalid_move_check?(arr_index,index)
@board[0][2] = marker
when 3
arr_index = 1
index = 0
invalid_move_check?(arr_index,index)
@board[1][0] = marker
when 4
arr_index = 1
index = 1
invalid_move_check?(arr_index,index)
@board[1][1] = marker
when 5
arr_index = 1
index = 2
invalid_move_check?(arr_index,index)
@board[1][2] = marker
when 6
arr_index = 2
index = 0
invalid_move_check?(arr_index,index)
@board[2][0] = marker
when 7
arr_index = 2
index = 1
invalid_move_check?(arr_index,index)
@board[2][1] = marker
when 8
arr_index = 2
index = 2
invalid_move_check?(arr_index,index)
@board[2][2] = marker
end
end
def invalid
puts"move invalid"
end
def invalid_move_check?(arr_index, index)
array = @board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
@move = gets.chomp.to_i
mapping(@move,@marker)
end
end
def make_move(marker)
# after each turn the make_move method will called to place move on the board
puts "Where to :"
@move = gets.chomp.to_i
mapping(@move,@marker)
print_board
end
# display board in a matrix format
def print_board
@board.each_slice(1) { |a| p a }
puts"\n"
end
def instructions
puts "Instructions :Enter your first move by entering a number 1-9"
puts "corresponding to the grid on the bottom and press enter"
puts"\n"
puts "0 | 1 | 2 ",
"----------",
"3 | 4 | 5 ",
"----------",
"6 | 7 | 8 "
print"\n"
end
def self.start(symbol)
# start a new game
new_game =Game.new(symbol)
# create players
new_game.create_players
new_game.instructions
new_game.print_board
# Checking wining combo for matching patter if none
while new_game.check_win?(@move_first, @move_second) do
new_game.first_turn
# the player switch turn
new_game.next_turn
end
end
loop do
puts"------------------------------------------------"
puts" Welcome to tictactoe ".upcase
puts"------------------------------------------------"
print"\n"
Game.start(@symbol)
end
end
这应该可以解决问题:
#will return true or false to check validity of move
def invalid_move_check?(arr_index, index)
array = @board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
@move = gets.chomp.to_i
mapping(@move,@marker)
return true
end
return false
end
def mapping(move, marker)
case move
...
when 0
arr_index = 0
index = 0
unless invalid_move_check?(arr_index,index) #change all cases
@board[0][0] = marker #to have the assignment of board
#only if the move is valid
end
...
end
end
你的错误的原因是即使移动无效也会发生赋值。
这只是您当前问题的创可贴解决方案,至于重构,可以做一些事情来优化您的代码并使其变得更好:)但是您仍然必须先修复您的 'ending'.重构您自己的代码将是一个很好的做法。祝你旅途愉快ruby !
在草拟之前的代码并重新思考我提出这个解决方案的代码之后,虽然不像我希望的那样优雅,但它有效。我移动了 if/else 块代码中的符号分配因此,当一个动作无效时,下一步将使用当前玩家的符号
def mapping(move, symbol)
case move
when 0
if @board[0][0]=="X" || @board[0][0] == "O"
invalid
make_move
else
@board[0][0] = symbol
track_move(@move)
print_board
end
...
end
end