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