Код Гольф: 2D Платформер

Соревнование

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

Недопустимый

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

Как

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

Уровень

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

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

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

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

Команды

  • M = Перемещает вас на 1 вправо, если под вами нет земли, вы будете падать, пока не поразите его. Вы не можете двигаться, пока падаете.
  • J = Прыжок, поднимает вас на 1 для следующих 3 команд или до тех пор, пока вы не нажмете на (С) блок. После этого вы будете падать, пока не достигнете земли. Вы можете прыгать только когда на земле. Если 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

РЕДАКТИРОВАТЬ

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

4 ответа

Решение

Javascript:

Короткая версия (334 280 256 240 238 236 233 223 207 205 196 184 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

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

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

Обновление 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): пошли за строку вместо обработки двумерного списка, большое сохранение...
Обновление 6 (206 -> 203): реализованы предложения в комментарии к ответу HoLyVieR (от Nabb)Обновление 7 (203 -> 191): преодоление ограничения в 200 символов с помощью построения логических строк...
Обновление 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

Рубин - 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

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 символ и случай, когда игрок идет по самой верхней линии уровня. Вы могли бы немного сэкономить, если бы вам не было дела до этих двух случаев.

Другие вопросы по тегам