vlkamov: Рембрандт. Автопортрет с широко открытыми глазами. (Default)
vlkamov ([personal profile] vlkamov) wrote2011-07-05 01:37 pm

Код Hamurabi

Это не прославленный свод законов шумерского царя Хаммурапи (Hammurabi Code), а код некогда популярной игры Hamurabi. Одна буковка m выпала из-за того, что до нашей эры имя файла состояло максимум из 8 букв.

Собственно код программы под катом. Захотелось посмотреть что это было, но перловой версии под руку как-то не попалось. Чаще всего выложены коды для Бейсика, видел джавовый, С и даже действующий Джаваскрипт - можно поиграть онлайн :-)
Перловку пришлось варить самому. Взял топор код на Бейсике и тупо-построчно заменил на соответствующие операторы Perl'а. Благо, что в Perl'е тоже есть оператор goto :-) Бейсиковые строчки я не удалял, а только закомментировал - можно сравнить при желании.

Все прелести "макаронного" программирования налицо. В давние-давние времена в книжном магазине попалась мне книжка про то, что программы должны быть похожи на моделируемые процессы. Я тогда не понял, что имелось в виду, но ознакомившись с этим листингом понял, с чем предлагали бороться авторы. Например, прямо посередение рутинного годового отчета в управляемом поселении случается эпидемия чумы - это действительно мало на что похоже.

#!/usr/bin/perl
#hamurabi.pl

#10 REM *** CONVERTED FROM THE ORIGINAL FOCAL PROGRAM AND MODIFIED
#20 REM *** FOR EDUSYSTEM 70 BY DAVID AHL, DIGITAL
#30 REM *** MODIFIED FOR 8K MICROSOFT BASIC BY PETER TURNBULL
#80 PRINT "TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA"
#85 PRINT "SUCCESSFULLY FOR A 10-YR TERM OF OFFICE.":PRINT
#90 REM RANDOMIZE REMOVED

# режиссер дубляжа - vl.kamov

#95 D1=0:P1=0
$D1 = 0; $P1 = 0;

#110 Z=0:P=95:S=2800:H=3000:E=H-S
$Z = 0; $P=95; $S=2800; $H=3000; $E = $H - $S;

#120 Y=3:A=H/Y:I=5:Q=1
$Y = 3; $A = $H / $Y; $I=5; $Q=1;

#210 D=0
m210:
$D = 0;

#215 PRINT:PRINT:PRINT "HAMURABI: I BEG TO REPORT TO YOU,":Z=Z+1
m215:
print "\n\nХамураппи: прошу отчитаться.\n"; $Z = $Z+1;

#217 PRINT "IN YEAR"Z","D"PEOPLE STARVED,"I"CAME TO THE CITY."
print "В ", $Z, " году ", $D, " человек умерло от голода, ", $I," прибыли в город.\n";

#218 P=P+I
$P = $P + $I;

#227 IF Q>0 THEN 230
goto m230 if $Q>0 ;

#228 P=INT(P/2)
$P = int ($P / 2);

#229 PRINT "A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED."
print "Ужасная чума ! Половина народу умерло.\n";

#230 PRINT "POPULATION IS NOW"P
m230:
print "Сейчас население составляет ", $P, " человек\n";

#232 PRINT "THE CITY NOW OWNS"A"ACRES."
print "Город владеет ", $A, " акрами.\n";

#235 PRINT "YOU HARVESTED"Y"BUSHELS PER ACRE."
print "Вы собрали ", $Y, " бушелей с акра.\n";

#250 PRINT "RATS ATE"E"BUSHELS."
print "Крысы съели ", $E, " бушелей.\n";

#260 PRINT "YOU NOW HAVE"S"BUSHELS IN STORE.":PRINT
print "Сейчас ", $S, " бушелей в амбаре.\n\n";

#270 IF Z=11 THEN 860
goto m860 if $Z==11;

#310 C=INT(10*RND(1)):Y=C+17
$C = int (10* rand()); $Y = $C + 17;

#312 PRINT "LAND IS TRADING AT"Y"BUSHELS PER ACRE."
print "Земля торгуется по ", $Y, " бушелей за акр.";

#320 PRINT "HOW MANY ACRES DO YOU WISH TO BUY";
m320:
print "Сколько акров вы намерены купить ? ";

#321 INPUT Q:IF Q<0 THEN 850
$Q = <STDIN>; goto m850 if $Q<0;

#322 IF Y*Q<=S THEN 330
goto m330 if $Y*$Q <= $S;

#323 GOSUB 710
m710();

#324 GOTO 320
goto m320;

#330 IF Q=0 THEN 340
m330:
goto m340 if $Q==0;

#331 A=A+Q:S=S-Y*Q:C=0
$A = $A + $Q; $S = $S - $Y*$Q; $C = 0;

#334 GOTO 400
goto m400;

#340 PRINT "HOW MANY ACRES DO YOU WISH TO SELL";
m340:
print "Сколько акров вы намерены продать ? ";

#341 INPUT Q:IF Q<0 THEN 850
$Q = <STDIN>; goto m850 if $Q<0;

#342 IF Q<A THEN 350
goto m350 if $Q < $A;

#343 GOSUB 720
m720();

#344 GOTO 340
goto m340;

#350 A=A-Q:S=S+Y*Q:C=0
m350:
$A = $A - $Q; $S = $S + $Y*$Q; $C = 0;

#400 PRINT
m400:
print "\n";

#410 PRINT "HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE";
m410:
print "Сколько бушелей вы намерены скормить вашим людям ?";

#411 INPUT Q
$Q=<STDIN>;

#412 IF Q<0 THEN 850
goto m850 if $Q < 0;

#418 REM *** TRYING TO USE MORE GRAIN THAN IN THE SILOS?
# попытка использовать больше зерна чем есть в хранилище

#420 IF Q<=S THEN 430
goto m430 if $Q <= $S;

#421 GOSUB 710
m710();

#422 GOTO 410
goto m410;

#430 S=S-Q:C=1:PRINT
m430:
$S = $S - $Q; $C = 1; print "\n";

#440 PRINT "HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED";
m440:
print "Сколько акров вы намерены засеять ?";

#441 INPUT D:IF D=0 THEN 511
$D = <STDIN>; goto m511 if $D == 0;

#442 IF D<0 THEN 850
goto m850 if $D < 0;

#444 REM *** TRYING TO PLANT MORE ACRES THAN YOU OWN?
# Пытаетесь засеять больше акров чем у вас есть

#445 IF D<=A THEN 450
goto m450 if $D <= $A;

#446 GOSUB 720
m720();

#447 GOTO 440
goto m440;

#449 REM *** ENOUGH GRAIN FOR SEED?
# хватит ли семян ?

#450 IF INT(D/2)<S THEN 455
m450:
goto m455 if int($D/2) < $S;

#452 GOSUB 710
m710();

#453 GOTO 440
goto m440;

#454 REM *** ENOUGH PEOPLE TO TEND THE CROPS?
# хватит ли людей ухаживать за урожаем ?

#455 IF D<10*P THEN 510
m455:
goto m510 if $D < 10*$P;

#460 PRINT "BUT YOU HAVE ONLY"P"PEOPLE TO TEND THE FIELDS. NOW THEN,"
print "Но у вас только ", $P, " человек чтобы обрабатывать поля. Итак, \n";

#470 GOTO 440
goto m440;

#510 S=S-INT(D/2)
m510:
$S = $S - int($D/2);

#511 GOSUB 800
m511:
m800();

#512 REM *** A BOUNTYFULL HARVEST!!
# обильный урожай !

#515 Y=C:H=D*Y:E=0
$Y = $C; $H = $D*$Y; $E=0;

#521 GOSUB 800
m800();

#522 IF INT(C/2)<>C/2 THEN 530
goto m530 if (int($C/2) != $C/2);

#523 REM *** THE RATS ARE RUNNING WILD!!
# крысы идут !

#525 E=INT(S/C)
$E = int($S/$C);

#530 S=S-E+H
m530:
$S = $S - $E + $H;

#531 GOSUB 800
m800();

#532 REM *** LET'S HAVE SOME BABIES
# деторождение

#533 I=INT(C*(20*A+S)/P/100+1)
$I = int($C*(20*$A + $S)/$P/100 + 1);

#539 REM *** HOW MANY PEOPLE HAD FULL TUMMIES?
# сколько людей накормлено ?

#540 C=INT(Q/20)
$C = int($Q / 20);

#541 REM *** HORRORS, A 15% CHANCE OF PLAGUE
# ужас, 15% вероятность чумы

#542 Q=INT(10*(2*RND(1)-.3))
$Q = int(10*(2*rand() - 0.3));

#550 IF P<C THEN 210
goto m210 if $P<$C;

#551 REM *** STARVE ENOUGH FOR IMPEACHMENT?
# голод достаточен для импичмента ?

#552 D=P-C:IF D>.45*P THEN 560
$D = $P - $C; goto m560 if $D > 0.45*$P;

#553 P1=((Z-1)*P1+D*100/P)/Z
$P1 = (($Z - 1)*$P1 + $D*100/$P)/$Z;

#555 P=C:D1=D1+D:GOTO 215
$P = $C; $D1 = $D1 + $D; goto m215;

m560:
#560 PRINT:PRINT "YOU STARVED"D"PEOPLE IN ONE YEAR!!!"
print "Вы уморили ", $D, " людей за год !!!\n";

#565 PRINT "DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY"
#566 PRINT "BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE"
#567 PRINT "ALSO BEEN DECLARED 'NATIONAL FINK' !!":GOTO 990
m565:
print "Из-за чрезвычайно плохого управления вы не только\nподвергнуты импичменту и выброшены из резиденции, но также\nвы объявлены \"Предателем нации\" !!"; goto m990;

#710 PRINT "HAMURABI: THINK AGAIN. YOU HAVE ONLY"
#711 PRINT S"BUSHELS OF GRAIN. NOW THEN,"
#712 RETURN

sub m710{
print "Хамурапи: думайте снова. У вас только \n", $S, " бушелей зерна. Итак, \n";
}

#720 PRINT "HAMURABI: THINK AGAIN. YOU OWN ONLY"A"ACRES. NOW THEN,"
#730 RETURN

sub m720{
print "Хамурапи: думайте снова. У вас только \n", $A, " акров земли. Итак, \n";
}

#800 C=INT(RND(1)*5)+1
#801 RETURN

sub m800{
$C = int(rand()*5) + 1;
}

#850 PRINT:PRINT "HAMURABI: I CANNOT DO WHAT YOU WISH."
#855 PRINT "GET YOURSELF ANOTHER STEWARD!!!!!"
m850:
print "\nХамурапи: я не могу сделать то, что вы хотите.\n";
print "Замените себя другим управляющим !!!!!";

#857 GOTO 990
goto m990;

#860 PRINT "IN YOUR 10-YEAR TERM OF OFFICE,"P1"PERCENT OF THE"
m860:
print "За время вашего 10 летнего пребывания на посту в среднем ", $P1, "процентов\n";

#862 PRINT "POPULATION STARVED PER YEAR ON AVERAGE, I.E., A TOTAL OF"
print "населения ежегодно умирали от голода, т.е. всего \n";

#865 PRINT D1"PEOPLE DIED!!":L=A/P
print $D1, " человек умерли !!\n"; $L = $A / $P;

#870 PRINT "YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH"
print "Вы начали с 10 акров на человека, а закончили \n";

#875 PRINT L"ACRES PER PERSON.":PRINT
print $L; "акрами на человека.\n\n";

#880 IF P1>33 THEN 565
goto m565 if $P1 > 33;

#885 IF L<7 THEN 565
goto m565 if $L < 7;

#890 IF P1>10 THEN 940
goto m940 if $P1 > 10;

#892 IF L<9 THEN 940
goto m940 if $L < 9;

#895 IF P1>3 THEN 960
goto m960 if $P1 > 3;

#896 IF L<10 THEN 960
goto m960 if $L < 10;

#900 PRINT "A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND"
#905 PRINT "JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!":GOTO 990
print "Фантастический результат !!! Шарлемань, Дизраели и \nДжефферсон вместе не смогли бы сделать лучше ! \n";
goto m990;

#940 PRINT "YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV."
#945 PRINT "THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,"
#950 PRINT "FRANKLY, HATE YOUR GUTS!":GOTO 990
m940:
print "Ваша тяжелая рука припахивает Нероном и Иваном IV. \nВыжившие люди считают вас плохим правителем и ужасно ненавидят ваши потроха ! \n";
goto m990;

#960 PRINT "YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT"
#965 PRINT "REALLY WASN'T TOO BAD AT ALL. ";
m960:
print "Ваши достижения могли бы быть лучше, но \nдела не совсем плохи. \n";

#966 PRINT INT(P*.8*RND(1));"PEOPLE WOULD"
#970 PRINT "DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR"
#975 PRINT "TRIVIAL PROBLEMS."
print int($P*0.8*rand()), " человек хотели бы видеть вас убитым, но это обычная проблема для нас.\n";

#990 PRINT:FOR N=1 TO 10:PRINT CHR$(7);:NEXT N
m990:
print "Биииииииииииип\n";

#995 PRINT "SO LONG FOR NOW.":PRINT
print "Пока.\n\n";

#999 END
exit;
#


Как всегда нашелся неисчерпаемый источник ресурсов, он же объект экспансии - земля.
В ходе тестирования у меня два раза подряд случилась чума, так что народу стало слишком мало, чтобы обрабатывать имеющуюся землю и совершенно непроизвольно подумал "А где бы прикупить рабов..."

Даже в полутора сотнях строк программного кода имени древнего шумерского царя нашлось место для обычного для англосаксов черного пиара:
940 PRINT "YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV."
У британцев были примеры куда как ближе и роднее, не говоря уж о том, что "Васильевичем" Иван IV был прозван отнюдь не за великий голод.

К слову
смотрел британский фильм "Риск Шарпа".
Фишка фильма в том, что там главный злодей наркоторговец - граф Драгомиров. Типичная британская фамилия. Напоминаю, действие в 1818 году, Ост-Индийская кампания.

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org