2014-02-04 1 views
5

Я пишу клон Tetris, и я прототипируюсь на C#. Конечный код должен работать во встроенной системе (с использованием 8-битного процессора и очень маленькой ОЗУ), поэтому я пытаюсь использовать наивный алгоритм, чтобы сделать линию чистой.Наивная сила тяжести для игры в тетрис с использованием 2D-массива для игрового поля

Сейчас мое игровое поле представляет собой 2D массив:

private readonly TetrominoType[][] _playfield; 

(где TetrominoType это перечисление, обозначающие либо None, либо один из 7 типов, используемое для окрашивания блоков)

Когда линия очищается, я хочу изменить этот массив на месте, где моя проблема. Возьмем такой пример:

Before  After 
0 #  #  #  # 
1 #  #  #  # 
2 #  #  #  # 
3 #  #  #  # 
4 #  #  #  # 
5 #xxxxxx#  #  # 
6 #x xx#  #  # 
7 #xxxxxx#  #  # 
8 #xxxxxx#  #x xx# 
9 #x xxxx#  #x xxxx# 
    ########  ######## 

я уже определил, что линии 5, 7 и 8 нужно удалить, и, таким образом, другие линии должны упасть, оставив меня с государством справа.

Мой наивный способ для перебора в обратном направлении и скопировать строчку выше очищаемой один, в основном:

for(int iy = 9; iy >= 0; iy--) { 
    if(_linesToClear.Contains(iy)) { 
     for(int ix = 0; ix < 6; ix++) { 
      _playfield[iy][ix] = _playfield[iy-1][ix]; 
     } 
    } 
} 

Проблема здесь в том, что выше линии также может быть очищен (например, если iy == 8 я не» t хочу скопировать строку 7, но строка 6), а также что мне нужно очистить скопированную строку (iy-1) - или скопировать строку над той, которая, в свою очередь, должна стекать вверх.

Я попытался подсчитать, сколько строк я уже пропустил, но это работает только в том случае, если я создаю новый массив и затем меняю его, но я не могу получить математическую работу для модификации массива play-in-place.

Возможно, это действительно просто, но я просто не вижу алгоритма. Кто-нибудь знает, как я могу это сделать?

+2

Это не будет работать, но вы считали, что сканирование игрового поля для * удаленной строки * удалено, и соответственно отрегулируйте остальные, и повторите этот алгоритм до тех пор, пока не будет удаленных строк? Такой алгоритм «развертки» часто используется для деконструирования графиков зависимостей - в то время как они неэффективны, они действительно легко рассуждать и могут соответствовать законопроекту здесь. С другой стороны, они, вероятно, не настолько эффективны, насколько это возможно. –

+0

@KirkWoll Я думал об этом, он казался неэффективным, даже не проверяя его, поэтому я мог бы дать ему еще один выстрел. Даже на процессоре с частотой 1 МГц 6502 (целевой) это должно быть довольно быстро. Чувствует себя слишком грубой силой, но, опять же, иногда грубая сила - именно то, что нужно. –

+2

Я думаю, что обычный код для этого «снизу вверх», скопируйте все строки, которые должны остаться, заполните остальные пустые строки »- всего 2 индекса для запоминания - текущая строка для записи и текущая строка для чтения (read> = записывать)...Также вы можете удалить одну строку/перерисовку в зависимости от того, что вы хотите показать. –

ответ

1

Будет ли это работать?

int k = 0; 
for(int iy = 9; iy >= 0; iy--) { 
    if(!_linesToClear.Contains(iy)) { 
     for(int ix = 0; ix < 6; ix++) { 
      _playfield[iy + k][ix] = _playfield[iy][ix]; 
     } 
    } 
    else 
     k++; 
} 
+0

Проблема с этим что он не заботится о нескольких строках и может дублировать строки выше очищенных строк. Это то, что вызывает у меня проблемы. –

+0

@MichaelStum Петля создает «нижнюю часть». После этого вы не можете просто очистить «верхнюю часть», 9 - k строк? – AlexD

+0

Бинго! Даже не нужно было его очищать, способ 'k' используется, чтобы поддерживать текущее количество пропущенных строк. Спасибо! –

2

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

for(int iy = 9; iy >= 0; iy--) 
{ 
    if(_linesToClear.Contains(iy)) 
    { 
     int nextLineIndex = iy-1; 
     while(_linesToClear.contains(nextLineIndex) && nextLineIndex >= 0) 
     { 
      nextLineIndex--; 
     } 
     if (nextLineIndex >= 0) 
     { 
      int amountToDrop = iy - nextLineIndex 
      for(int ix = 0; ix < 6; ix++) 
      { 
       _playfield[iy][ix] = _playfield[iy-amountToDrop][ix]; 
      } 
     } 
    } 
} 

Эта цифра, сколько очищается линии есть в ряд, а затем бросить все вниз, что много линий. Надеюсь, это поможет!

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