2014-09-08 4 views
0

Я реализую гомуку в Ruby, это вариация tic-tac-toe, играемая на доске 15x15, и первый игрок, который размещает 5 O или X в горизонтальном, вертикальном или побеждает диагональный ряд.Ruby count duplicates в диагональных рядах матрицы

Во-первых, я назначая Матрицу переменной и заполнить его с числами от 0 до 224, так что нет никаких повторений, и я мог сосчитать их позже

gomoku = Matrix.zero(15) 
num = 0 
15.times do |i| 
    15.times do |j| 
    gomoku[i, j] = num 
    num += 1 
    end 
end 

затем игроки по очереди, и после каждого хода I проверить выигрыш с помощью метода win?

def win? matrix 
    15.times do |i| 
    return true if matrix.row_vectors[i].chunk{|e| e}.map{|_, v| v.length}.max > 4 # thanks to sawa for this way of counting adjacent duplicates 
    return true if matrix.column_vectors[i].chunk{|e| e}.map{|_, v| v.length}.max > 4 
    end 
    return false 
end 

Я знаю, что я, вероятно, делаю это неправильно, но моя проблема не в том, хотя предложения приветствуются. Проблема заключается в диагональных строках. Я не знаю, как считать дубликаты в диагональных рядах.

+0

«Матрица» неизменна, вы не сможете делать «gomoku [i, j] = num' ... – Amadan

+0

Вы ошиблись, я просто попробовал – budkin

+0

Если вы используете [стандартную Ruby' Matrix' ] (http://www.ruby-doc.org/stdlib-2.1.2/libdoc/matrix/rdoc/Matrix.html#method-i-clone): «... Не должно быть веских оснований для этого так как * Матрицы неизменяемы *. Также обратите внимание на то, как 'Matrix # [] =' не существует. 'ruby -r matrix -e" a = Matrix.zero (2); a [0, 0] = 1 "' будет возвращать 'private method' [] = 'для Matrix [[0, 0], [0, 0]]: Матрица (NoMethodError) '. Если, с другой стороны, вы используете библиотеку, возможно, вы хотели бы указать ее. – Amadan

ответ

1
diagonal_vectors = (-10 .. 10).flat_map do |x| 
    i = x < 0 ? 0 : x 
    j = x < 0 ? -x : 0 
    d = 15 - x.abs 
    [ 
    d.times.map { |k| 
     gomoku[i + k, j + k] 
    }, 
    d.times.map { |k| 
     gomoku[i + k, 14 - j - k] 
    } 
    ] 
end 

С помощью этого вы можете применить ту же самую тестовую пилу.

EDIT: Что это делает

При взгляде на диагоналях, есть два вид: спускающиеся налево, и идущий вниз-вправо. На данный момент мы сосредоточимся на правых. В матрице 15x15 есть 29 правых диагоналей: один начинается с каждого элемента первой строки, один начинается с каждого элемента первого столбца, но старайтесь не считать тот, который начинается с [0, 0] дважды. Но некоторые диагонали слишком короткие, поэтому мы хотим брать только те, которые начинаются с первых одиннадцати строк и столбцов (потому что другие будут короче 5 элементов). Это то, что делают первые три линии: [i, j] будет [10, 0], [9, 0] ... [0, 0], [0, 1], ... [0, 10]. d - это длина диагонали, начиная с этой позиции. Затем d.times.map { |k| gomoku[i + k, j + k] } собирает все элементы в этой диагонали. Скажем, мы работаем на [10, 0]: d is 5, поэтому у нас есть [10, 0], [11, 1], [12, 2], [13, 3], [14, 4]; и мы собираем значения в этих координатах в списке. Одновременно мы будем работать и по левой-левой диагонали; это другая работа map, которая переворачивает одну координату. Таким образом, внутренний блок будет возвращать двухэлементный массив, который представляет собой две диагонали, одну вниз-левую, одну вниз-право. flat_map позаботится об итерации, одновременно сжимая двухэлементные массивы, чтобы мы получили один большой массив диагоналей, а не массив двухэлементных массивов диагоналей.

+0

Большое спасибо! Я не совсем понимаю это, но он работает! – budkin

Смежные вопросы