表示所有有效“行”的紧凑方式在井字棋网格中
我一直在用各种语言编写井字游戏作为练习,并且出现的一种模式是,我为定义有效获胜行而提出的每一种表示形式都令人失望地被硬编码。它们通常分为两类:
首先,棋盘被表示为一维或二维数组,并且行由位置的三元组明确定义(数字是空格):
board = [1, x, 3, 4, o, 6, 7, 8, x]
def match3(x,y,z)
board[x] == board[y] && board[y] == board[z]
end
def winner
match3(1,2,3) || match3(4,5,6) || ...
end
这具有非神奇的明确性的优点,但看起来很冗长。
另一种方法是使用数组的数组并映射+减少行。它稍微好一点,但并没有完全让我满意:
board = [[nil, 1, nil], [nil, -1, nil], [nil, nil, 1]]
def diag(x,y,z)
[board[x/3,x%3], board[y/3,y%3], board[z/3,z%3]]
end
def winner
rows = board + board.transpose << diag(0,4,8) << diag(2,4,6)
rows.map { |r| r.reduce(:&) }.reduce { |m,c| m || c }
end
垂直和水平匹配很棒,但我仍在对对角线进行硬编码。
谁能想到一种不依赖显式地址的方法来表征对角线(或完全不同的方法)?
我的伪代码是 Rubyish,但请随意用您喜欢的任何语言发布。我看到了井字游戏代码高尔夫,虽然其中一些解决方案很巧妙(尤其是幻方!),但我正在寻找一些不那么令人困惑的东西。
I've been writing tic-tac-toe in a variety of languages as an exercise, and one pattern that has emerged is that every representation I've come up with for the defining valid winning rows has been disappointingly hard-coded. They've generally fallen into two categories:
First, the board is represented as a one- or two-dimensional array, and rows are explicitly defined by triplets of positions (numbers are empty spaces):
board = [1, x, 3, 4, o, 6, 7, 8, x]
def match3(x,y,z)
board[x] == board[y] && board[y] == board[z]
end
def winner
match3(1,2,3) || match3(4,5,6) || ...
end
This has the advantage of non-magical explicitness, but it seems verbose.
The other approach is to use an array of arrays and map+reduce the rows. It's slightly better, but doesn't get me all the way:
board = [[nil, 1, nil], [nil, -1, nil], [nil, nil, 1]]
def diag(x,y,z)
[board[x/3,x%3], board[y/3,y%3], board[z/3,z%3]]
end
def winner
rows = board + board.transpose << diag(0,4,8) << diag(2,4,6)
rows.map { |r| r.reduce(:&) }.reduce { |m,c| m || c }
end
Vertical and horizontal matches are great, but I'm still hardcoding the diagonals.
Can anyone think of a way to characterize the diagonals (or a wholly different approach) that doesn't rely on explicit addresses?
My pseudocode is Rubyish, but please feel free to post in any language you like. I saw the tic-tac-toe code golf, and while some of those solutions are ingenious (especially the magic squares!) I'm looking for something a bit less obfuscating.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一个更快、更紧凑的系统是每个方块使用一位。当前位置可以保存在两个变量中:X 持有所有“X”标记,O 持有所有“O”标记。例如,9 个正方形的可能编码是
使用这种编码,第一行是 1+2+4=7,上/左->下/右对角线是 1+16+ 256=273。
检查 X 是否在第一行获胜只是
if ((X & 7) == 7)
,其他检查类似,但使用不同的数字而不是 7。完整的胜利检查例程变为.. 。A system that's a lot faster and more compact is to use one bit for every square. Current position can be kept in two variables: X holding all the "X" marks, and O holding all "O" marks. A possible encoding for the 9 squares is for example
With this encoding the first row is
1+2+4=7
and top/left->bottom/right diagonal is1+16+256=273
.Checking if X won on the first row is just
if ((X & 7) == 7)
, other checks are similar but with different numbers instead of 7. The full victory checking routine becomes...