私は演習としてさまざまな言語で三目並べを書いてきましたが、1 つのパターンとして、有効な勝者の行を定義するために思いついたすべての表現が、残念なことにハードコーディングされているということがあります。それらは一般的に次の 2 つのカテゴリに分類されます。
まず、ボードは 1 次元または 2 次元の配列として表され、行は位置のトリプレットによって明示的に定義されます (数字は空のスペースです)。
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
これには、非魔法的な明示性という利点がありますが、冗長に見えます。
もう 1 つのアプローチは、配列の配列を使用し、行を map+reduce することです。それは少し良いですが、私を完全に理解することはできません:
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 ですが、好きな言語で自由に投稿してください。私は三目並べのコード ゴルフを見ました。それらの解決策のいくつかは独創的ですが (特に魔方陣!)、もう少し難読化されていないものを探しています。