gpt4 book ai didi

ruby - 我怎样才能在我的井字游戏中干掉这段 Ruby 代码? (使用 1.times block !)

转载 作者:太空宇宙 更新时间:2023-11-03 16:43:02 25 4
gpt4 key购买 nike

我想知道是否有人可以帮我解决这个问题……我敢肯定这是拍额头的事情之一……但我不知道如何擦干这部分。

我正在制作井字棋程序作为学习练习。我实际上已经完成了,但是有一点困扰我,因为它看起来显然很笨拙。当我为计算机的移动做 AI 时,这部分就来了。其运作方式是,您测试八个条件中的每一个以寻找可能的移动。你看第一个条件;如果它导致移动,则返回该移动并跳过其余条件。如果这八个条件都没有引发移动,那么游戏就结束了(棋盘已满)。

嗯,条件非常复杂,每个条件都需要一个单独的方法。因此,为了执行逻辑,我简单地说 1.times(叹气),然后在一个一次性 block 中,一个接一个地执行这些方法。在检查该方法是否返回移动后,我说 break if move,即跳出 block 。很明显我不应该在每个 项之后使用break if move。违反干。我想过使用 if...elsif...switch 语句,但这行不通,因为所有的方法都必须经过,直到一个其中的一个返回一个移动,并且这些方法不只是返回 true 或 false;它们实际上返回移动的索引号或 false

(unless skip_rule == n 位是一种让 AI 变笨的方法;如果玩家希望 AI 可以被打败,另一种方法是选择要跳过的规则。)

如果您想深入了解,请在此处查看第 96 行以上的代码:https://github.com/globewalldesk/tictactoe2/blob/master/lib/board.rb

# Test each set of conditions, until a move is found
move = false
1.times do
# Win: If you have two in a row, play the third to get three in a row.
# puts "Trying 1"
move, length = are_there_two_tokens_in_a_row(@ctoken) unless skip_rule == 0
break if move # skip to end if move is found

# Block: If the opponent has two in a row, play the third to block them.
# puts "Trying 2"
move, length = are_there_two_tokens_in_a_row(@ptoken) unless skip_rule == 1
break if move

# Fork: Create an opportunity where you can win in two ways (a fork).
# puts "Trying 3"
move = discover_fork(@ctoken) unless skip_rule == 2
break if move

# Block Opponent's Fork: If opponent can create fork, block that fork.
# puts "Trying 4"
move = discover_fork(@ptoken) unless skip_rule == 3
break if move

# Center: Play the center.
# puts "Trying 5"
unless skip_rule == 4
move = 4 if @spaces[4].c == " " # if the center is open, move there
end
break if move

# Opposite Corner: If the opponent is in the corner, play the opposite corner.
# puts "Trying 6"
move = try_opposite_corner unless skip_rule == 5
break if move

# Empty Corner: Play an empty corner.
# puts "Trying 7"
move = try_empty_corner
break if move

# Empty Side: Play an empty side.
# puts "Trying 8"
move = play_empty_side

# If move is still false, game is over!

end # of "do" block

# Make the change to @spaces; this edits the individual space and hence also
# the triads and the board, which use it.
@spaces[move].c = @ctoken if move

end # of computer_moves

更新(12/3/2016):我不太能理解下面的建议。但是一位线下的 friend 看了这个问题并建议我制作一个方法数组并对其进行迭代......那是我的手碰到我额头的声音。我知道有一种(相对)简单的方法可以做到这一点。无论如何,在 Ruby 中可能不可能有一个方法数组,但是可以创建一个包含方法的过程数组。所以这就是我所做的。这是更正/改进的代码:

# Initialize array of procs for each step of algorithm
rules = [
# Win: If you have two in a row, play the third to get three in a row.
Proc.new { are_there_two_tokens_in_a_row(@ctoken) },
# Block: If the opponent has two in a row, play the third to block them.
Proc.new { are_there_two_tokens_in_a_row(@ptoken) },
# Fork: Create an opportunity where you can win in two ways (a fork).
Proc.new { discover_fork(@ctoken) },
# Block Opponent's Fork: If opponent can create fork, block that fork.
Proc.new { discover_fork(@ctoken) },
# Center: Play the center.
Proc.new {
unless skip_rule == 4
move = 4 if @spaces[4].c == " " # if the center is open, move there
end
},
# Opposite Corner: If the opponent is in the corner, play the opposite corner.
Proc.new { try_opposite_corner },
# Empty Corner: Play an empty corner.
Proc.new { try_empty_corner },
# Empty Side: Play an empty side.
Proc.new { play_empty_side }
]

# Iterates over rule procs, and breaks out of iteration when move != false
(0..7).each do |rule_index|
move, length = rules[rule_index].call unless skip_rule == rule_index
break if move
end

漂亮,不是吗?据我所知,这段代码干涸了。 Here是程序的更新源文件。顺便说一句,该程序可以设置为无与伦比,但用户可以让它“忘记”随机规则,从而使其成为可击败的。

感谢所有回复的人。下次我会试试 Code Review.SE。

最佳答案

只需将 1.times block 中的代码重构为它自己的方法即可。而不是 break if move 使用显式 return 运算符以相同的方式:return if move

关于ruby - 我怎样才能在我的井字游戏中干掉这段 Ruby 代码? (使用 1.times block !),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40797849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com