Подтвердить что ты не робот

Code Golf: 2D Платформер

Задача

  • Достигните конца уровня!
  • Бонусные очки, если вы нажмете каждый из блоков (C) oin ровно 2 раза.

Disallowed

  • Жесткое кодирование последовательности команд любым способом.
  • Ваш любимый "Один символ языка" , который выполняет только одну вещь, решающую этот гольф.

Как

Ваша программа получает уровень ниже (без разрывов строк) через стандартный ввод.
Затем он должен распечатать команды, необходимые для успешного завершения уровня.

Уровень

  • S - ваша стартовая позиция.
  • E позиция, в которой вы должны быть, чтобы завершить уровень.
  • C представляет собой монетный блок с двумя монетами в нем, вам никогда не придется пропустить один из них, чтобы иметь возможность завершить уровень.
  • Оба C и _ считаются почтовыми, там сплошная земля не плавающая платформа.
  • | - стена, все стены, которые вам нужно подпрыгнуть, чтобы завершить уровень, находятся на высоте не более 1 стены, все, что выше, вы можете рассмотреть пропасть, которую вы не можете Избегайте.
  • x - это всплески, угадайте, что произойдет, если вы коснетесь. Шипы всегда будут на один уровень ниже того, что окружает их.

Все уровни имеют высоту 4 строки, каждая из линий - 63 символа. Это составляет 252 символа на уровень.

>                       ______  ____       ________  ___        <
>    C            ______|    |  |  |  C  __|      |  | |   ____E<
>S______  __  ____|          |  |  |_____|        |__| |___|    <
>       xx  xx                xx                                <

Примечания: > < просто для иллюстрации границ, они НЕ включены во вкладку вашей программы. Также следите за своим текстовым редактором, так как моя несколько раз прикручивала пробелы.

Команды

  • M= Перемещает вас 1 вправо, если нет земли под вами, вы упадете, пока не нажмете. Вы не можете перемещаться во время падения.
  • J= Перейти, перемещает вас на 1 для следующих 3 команд или пока вы не нажмете блок (C). После этого вы упадете, пока не достигнете земли. Вы можете прыгать только на земле. Если M приносит вам тот же уровень, что и земля, скачок отменяется.
  • O= NOP, заставит вас ждать/ничего не делать. Таким образом, вы можете прыгать с отверстиями и шипами, которые имеют ширину всего в 1 блок (вам не нужно это для уровня выше, но вы получите дополнительные очки, если сможете решить уровни, которые в этом нуждаются).

Решение (с монетными блоками)

Последовательные команды сложены друг на друга.
F указывает, где вы упадете (помните, что вы не можете ничего делать при падении),

                            MMMF                 MMMF            
    M                 MMMMMMJ  MMMMF M   MMMMMMMMJ  MMMF        
M   J MMMFMMMF  MMMMMMJ|    |  |  |F J MMJ|      |  | |F MMMMME
SMMMJMJ  MJ  MMMJ|          |  |  |MMJMJ|        |__| |MMJ|    
       xx  xx                xx                                

Результирующая последовательность команд, длина 75 символов:

MMMMJJMMJMMMMJMMMMMMJMMMMMMJMMMMMMJMMMMMMMMMJJMMJMMJMMMMMMMMJMMMMMMMMJMMMMM

Надеемся, что это даст некоторые интересные результаты... и не тонны пламени: O

ИЗМЕНИТЬ

ОК, есть больше возможностей, чем я изначально думал, прошу прощения за все изменения.

4b9b3361

Ответ 1

JavaScript:

Короткая версия ( 334 280 256 240 238 236 233 223 207 205 196 184забастовкa > 182 символа)

a=prompt();j=i=0;while(a[++j*63]<(o="M"));while(++i<62){while(a[h=j*63+i]<"_")j++;if(a[h-63]>"B")o+="JJ";if(a[h+1]>"z")o+="J",j--;if(a[h+3]+a[h+1]=="_ ")o+="JMM",i+=2;o+="M"}alert(o)

Примечание. Приглашение метода Javascript имеет тенденцию удалять пространство в каком-либо браузере (например, Google Chrome). По этой причине они могут работать не так, как ожидалось. На других (например, Firefox) он будет работать нормально.

Прокомментированная версия

a=prompt(); // Read the input //
j=i=0;
while(a[++j*63]<(o="M")); // Place the cursor at the "S" //
while(++i<62){ // While we are not at the end point //
 while(a[h=j*63+i]<"_")j++; // If we are on a space, we fall //
 if(a[h-63]>"B")o+="JJ";// We jump for coins //
 if(a[h+1]>"z")o+="J",j--; // We jump when we reach a wall //
 if(a[h+3]+a[h+1]=="_ ")o+="JMM",i+=2; // We jump on gap //
 o+="M" // We add the movemment in the output
}
alert(o) // Output

Ответ 2

Python 2.6 318 - 302 - 300 - 284 - 277 - 206 - 203 - 191 - 184 символа

В основном тот же подход, что и HoLyVieR (интересно, может ли быть много радикально разных направлений решения). Читает из stdin.

Обновление 1 (318 → 302): не проверяйте E, но предположите, что он находится в позиции 63 (как задано в комментарии).
Обновление 2 (302 → 300): изменено range(0,252,63) на (0,63,126,189) (два целых символа) Обновление 3 (300 → 284): кажется, что raw_input также извлекает stdin, поэтому import sys и т.д. можно отбросить. Обновление 4 (284 → 277): [y][x+3]=="_"and p[y][x+1]==" " до p[y][x:x+4]==list("_ _") Обновление 5 (277 → 206): для строки вместо 2-мерной обработки списка, для большого количества... Обновление 6 (206 → 203): реализованы предложения в комментарии к ответу HoLyVieR (по Nabb) Обновление 7 (203 → 191): нарушение 200 char -limit с помощью построения булевой строки...
Обновление 8 (191 → 184): мелкие хитрости

Все комментарии или предложения приветствуются!

Примечание: Я добавил (ненужный) \ и newline в приведенный ниже код (EOL 5- > 6) (чтобы избежать полос прокрутки здесь)

l=raw_input()
x,y,o=0,l.index('S')//63,''
while x<62:
 while l[y*63+x]==" ":y+=1
 b=y*63+x;g=l[b+1]>"z";h=l[b:b+4]=="_  _";o+=(l[b-63]>"A")*"JJ"+g*"J"+h*"JMM"+\
"M";y-=g;x+=1+h*2
print o

Использование python 2dplatform.py < level.txt

Ответ 3

Ruby - 231 226 218 198 197 символов

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

l=?\s*63+gets
c=l=~/S/
r=->{c-=62;'JM'}
(print l[c-63]==?C?r[]:(l[c+1]>?\s&&l[c+1]<?x?(c+=1;?M):(l[c+1]<?C&&l[c]>?\s?(c-=61;'JMM'+(l[c+63]<?C?(c+=1;?M):?O)):r[]))
c+=63 while l[c]<?C)while l[c]!=?E

Ответ 4

C - 275 байтов (окончание строк DOS)

#define A(B,C)!memcmp(p+1,B,C)
#define P printf
char*p,l[318],k=63;f(){P("M");++p;while(*p<33)p+=k;}main(){read(0,l+k,4*k);p=strchr(l+k,83);while(*p!=69)p[-k]==67?(P("JJM"),++p):(p[1-k]>94?(P("JM"),p+=1-k):(A("  _",3)?(P("JMMM"),p+=3):(A(" _",2)?(P("JMMO"),p+=2):f())));}

Это относится к разрыву 1 char, и случай, когда игрок идет по самой верхней строке уровня. Вы можете немного сэкономить, если вам не нравятся эти 2 случая.