Тетрис, очищающий полные ряды - PullRequest
0 голосов
/ 20 октября 2018

Итак, я делаю тетрис, используя haskell, и у меня возникают проблемы с реализацией последней функции, очисткой полных строк и уменьшением каждого кортежа над ней.xcoord, ycoord)] только с занятыми координатами.

Я думаю о том, чтобы проверить, есть ли в списке 15 (ширина тетриса) кортежей с той же самой ycoord и так, если это такстрока заполнена, и все, что находится над строкой, получает значение ycoord, уменьшенное на 1.

removeFullRow :: [(Int,Int)] -> [(Int,Int)]
removeFullRow list = ?

Как лучше всего это сделать в haskell?

Спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Вот метод, который мы будем использовать:

  1. Мы свернем список, подсчитав, сколько элементов в каждой строке
  2. Мы, если какие-либо строки заполнены
  3. мы отфильтровываем координаты элементов в полных строках

Intro

import Data.Map as M

Шаг 1

countInRows :: [(Int,Int)] -> M.Map Int Int
countInRows items =
  M.fromListWith (+) [(row,1) | (col,row) <- items]

Работает:

  1. преобразование элементов списка в вещи, которые говорят: «Я знаю о 1 полном квадрате в строке n »
  2. Объединение их вместе путем суммирования количества полных квадратов для каждой строки,
  3. Помещение этого результата в карту, связывающее строку с тем, насколько она заполнена

Шаг 2

isFull :: Int -> M.Map Int Int -> Int -> Bool
isFull width counts row =
  M.findWithDefault 0 row counts >= width

Это позволит определить, насколько заполнена строка (еслиего нет на карте, тогда он должен иметь 0 полных квадратов).Если полных квадратов столько, сколько ширины доски, то строка должна быть полной.

Шаг 3 (собрать все вместе)

import Data.Map as M
removeFullRows :: Int -> [(Int,Int)] -> [(Int,Int)]
removeFullRows items =
  filter (not . isFull . row) items where
  counts = M.fromListWith (+) [(row,1) | (col,row) <- items]
  isFull row =
    M.findWithDefault 0 row counts >= width
  row (x,y) = y

Мы отфильтровываем элементы, получаястрока, проверяя, заполнена ли она, а если нет, то сохраняем элемент.

0 голосов
/ 20 октября 2018

Это довольно сложная вещь, с учетом используемой структуры данных [(Int, Int)].Я бы порекомендовал более подходящий.

С учетом сказанного, есть несколько этапов.Вот один из возможных способов сделать это:

  1. Сортировать список ввода по значениям (y, x) (вы можете Data.Tuple.swap преобразовать кортежи из (x, y)), чтобы все элементыв каждой строке расположены рядом друг с другом, поэтому нижние строки находятся в начале списка.
  2. Группируйте входной список по значениям y, чтобы все строки находились в разных подсписках.
  3. Преобразоватькортежи только для значений x.
  4. Отфильтруйте все подсписки, содержащие 15 элементов.
  5. Восстановите кортежи, добавив индекс каждого подсписка в качестве значений y его элементов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...