Код Hamurabi_2
Jul. 6th, 2011 12:07 pm(начало см. http://vlkamov.livejournal.com/722060.html)
Переведенный на русскоперловый язык код игры стал существенно более прозрачным. Это позволило побороть почти все "макароны", остались две малосущественные, описывающие экстремальное увольнение. Вся программа разбита на последовательно исполняемые блоки с ясными функциями. Для красоты кода пришлось немножко изменить порядок исполнения блоков и привести его в соответствие естественному ходу вещей. В оригинальном коде первый годовой цикл отрабатывается без участия игрока, так что диалог начинается годового отчета. Я не поленился отчет перенести в конец, так что игрок отдает распоряжения с первого же года, а итоги года подводятся в его конце.
Чума, голодомор и прирост населения вынесены в отдельный демографический блок. Интересно отметить, что в формуле прироста население стоит в знаменателе, что заставляет сомневаться в ориентации авторов.
При сборке-разборке традиционно остались лишние детали:
$C = 0; # ?????????
Что делает эта вспомогательная переменная в операциях с землей и распределении зерна, понять так и не удалось.
Итоговые критерии весьма специфические - площадь земли на душу населения и смертность от голода. Поэтому чума здорово улучшает показатели - чем больше вымерло, тем джефферснее. А если "не повезло" - количество едоков не сокращается по естественным причинам - такая же смертность низведет управляющего в "иваны". Чисто невидимая рука рынка.
Игра сочинена в какие-то дремучие года, и уже тогда либеральная общественность пренебрегала состоянием общества в целом, выпячивая "витрину". Игрокам с детства внушали, что территорию можно сдать, население нехай уменьшается, лишь бы права отдельной личности были защищены.
Update
Если ваш интерпретатор Perl не поддерживает русскоперловый язык, то конвертировать имена в латиницу можно с помощью вот этой программки:
http://vlkamov.narod.ru/rupl.zip
Сгрузите и распакуйте. Скопируйте код, находящийся под катом в файл hamurabi.rupl и команда
perl rupl2pl.pl hamurabi.rupl > tmp.pl ; perl tmp.pl
сразу конвертирует в латиницу и запускает исполнение.
Переведенный на русскоперловый язык код игры стал существенно более прозрачным. Это позволило побороть почти все "макароны", остались две малосущественные, описывающие экстремальное увольнение. Вся программа разбита на последовательно исполняемые блоки с ясными функциями. Для красоты кода пришлось немножко изменить порядок исполнения блоков и привести его в соответствие естественному ходу вещей. В оригинальном коде первый годовой цикл отрабатывается без участия игрока, так что диалог начинается годового отчета. Я не поленился отчет перенести в конец, так что игрок отдает распоряжения с первого же года, а итоги года подводятся в его конце.
Чума, голодомор и прирост населения вынесены в отдельный демографический блок. Интересно отметить, что в формуле прироста население стоит в знаменателе, что заставляет сомневаться в ориентации авторов.
При сборке-разборке традиционно остались лишние детали:
$C = 0; # ?????????
Что делает эта вспомогательная переменная в операциях с землей и распределении зерна, понять так и не удалось.
Итоговые критерии весьма специфические - площадь земли на душу населения и смертность от голода. Поэтому чума здорово улучшает показатели - чем больше вымерло, тем джефферснее. А если "не повезло" - количество едоков не сокращается по естественным причинам - такая же смертность низведет управляющего в "иваны". Чисто невидимая рука рынка.
Игра сочинена в какие-то дремучие года, и уже тогда либеральная общественность пренебрегала состоянием общества в целом, выпячивая "витрину". Игрокам с детства внушали, что территорию можно сдать, население нехай уменьшается, лишь бы права отдельной личности были защищены.
#!/usr/bin/perl
#hamurabi_2.pl
Начальные_условия();
foreach $ГОД (1..10){
Операции_с_землей();
Распределение_зерна();
Планирование();
Сельхоз_цикл();
Демограф_цикл();
Годовой_отчет();
}
Итоги_десятилетия();
goto Выход;
Уволить_за_наглость:
print "\nХаммурапи: я не могу сделать то, что ты хочешь.\nЗаменю тебя другим управляющим !!!!!";
goto Выход;
Досрочное_увольнение:
print "Ты уморил голодом ", $УМЕРЛО_ОТ_ГОЛОДА, " человек за год !!!\n";
print "Из-за чрезвычайно плохого управления ты сейчас же уволен, \nвыброшен из резиденции и\n объявлен \"Предателем нации\" !!";
goto Выход;
Выход:
print "\nБиииииииииииип\nПока.\n\n";
exit;
# =====================================
sub Начальные_условия{
$УМЕРЛО_ОТ_ГОЛОДА_10 = 0; # за 10 лет нарастающим итогом
$СМЕРТНОСТЬ_ОТ_ГОЛОДА_10 = 0;
$ГОД = 0;
$НАСЕЛЕНИЕ = 100;
$ПРИРОСТ_НАСЕЛЕНИЯ = 5;
$Q = 1;
$D = 0;
$ПЛОЩАДЬ = 1000;
$ЗЕРНО_В_АМБАРЕ = 2800;
print "Хаммурапи: поручаю тебе управление поселением в течение 10 лет. На начало периода:\n";
print "население составляет ", $НАСЕЛЕНИЕ, " человек\n";
print "Город владеет ", $ПЛОЩАДЬ, " акрами плодородной земли.\n";
print "Запасы зерна составляют ", $ЗЕРНО_В_АМБАРЕ, " бушелей.\n";
}
# =====================================
sub Операции_с_землей{
# операции с землей
$ЦЕНА_ЗЕМЛИ = int (10*rand()) + 17; # 17..26
print "Земля торгуется по ", $ЦЕНА_ЗЕМЛИ, " бушелей за акр.\n";
Покупка_земли:
print "Сколько акров ты намерен купить ? ";
$Q = <STDIN>;
goto Уволить_за_наглость if $Q<0;
goto Продажа_земли if $Q==0;
if ($ЦЕНА_ЗЕМЛИ*$Q > $ЗЕРНО_В_АМБАРЕ){
print "Хаммурапи: думай снова. У тебя только \n", $ЗЕРНО_В_АМБАРЕ, " бушелей зерна. Итак, \n";
goto Покупка_земли;
}
$ПЛОЩАДЬ = $ПЛОЩАДЬ + $Q; $ЗЕРНО_В_АМБАРЕ = $ЗЕРНО_В_АМБАРЕ - $ЦЕНА_ЗЕМЛИ*$Q;
$C = 0; # ?????????
goto Закончить_операции_с_землей;
Продажа_земли:
print "Сколько акров ты намерен продать ? ";
$Q = <STDIN>;
goto Уволить_за_наглость if $Q<0;
goto Закончить_операции_с_землей if $Q==0;
if ($Q > $ПЛОЩАДЬ) {
print "Хаммурапи: думай снова. У тебя только \n", $ПЛОЩАДЬ, " акров земли. Итак, \n";
goto Продажа_земли;
}
$ПЛОЩАДЬ = $ПЛОЩАДЬ - $Q; $ЗЕРНО_В_АМБАРЕ = $ЗЕРНО_В_АМБАРЕ + $ЦЕНА_ЗЕМЛИ*$Q;
$C = 0; # ?????????
goto Закончить_операции_с_землей;
Закончить_операции_с_землей:
}
# =====================================
sub Распределение_зерна{
print "\n";
Выделить_зерно:
print "Сколько зерна пойдет на продовольствие ?";
$ПРОДОВОЛЬСТВЕННОЕ_ЗЕРНО=<STDIN>;
goto Уволить_за_наглость if $ПРОДОВОЛЬСТВЕННОЕ_ЗЕРНО < 0;
if ($ПРОДОВОЛЬСТВЕННОЕ_ЗЕРНО > $ЗЕРНО_В_АМБАРЕ){
print "Хаммурапи: думай снова. У тебя только \n", $ЗЕРНО_В_АМБАРЕ, " бушелей зерна. Итак, \n";
goto Выделить_зерно;
}
$ЗЕРНО_В_АМБАРЕ = $ЗЕРНО_В_АМБАРЕ - $ПРОДОВОЛЬСТВЕННОЕ_ЗЕРНО;
$C = 1; # ?????????
print "\n";
}
# =====================================
sub Планирование{
Назначить_площадь_посевов:
print "Сколько акров ты намерен засеять ?";
$ПЛОЩАДЬ_ПОСЕВОВ = <STDIN>;
goto Уволить_за_наглость if $ПЛОЩАДЬ_ПОСЕВОВ < 0;
if ($ПЛОЩАДЬ_ПОСЕВОВ > $ПЛОЩАДЬ ) {
print "Хаммурапи: думай снова. У тебя только \n", $ПЛОЩАДЬ, " акров земли. Итак, \n";
goto Назначить_площадь_посевов;
}
# норма посева - 1 бушель на 2 акра
if (int($ПЛОЩАДЬ_ПОСЕВОВ/2) > $ЗЕРНО_В_АМБАРЕ){
print "Хаммурапи: думай снова. У тебя только \n", $ЗЕРНО_В_АМБАРЕ, " бушелей зерна. Итак, \n";
goto Назначить_площадь_посевов;
}
# норма обслуживания - 10 акров на человека
if ($ПЛОЩАДЬ_ПОСЕВОВ > 10*$НАСЕЛЕНИЕ) {
print "Но у тебя только ", $НАСЕЛЕНИЕ, " человек чтобы обрабатывать поля. Итак, \n";
goto Назначить_площадь_посевов;
}
}
# =====================================
sub Сельхоз_цикл{
# норма посева - 1 бушель на 2 акра
$ЗЕРНО_В_АМБАРЕ = $ЗЕРНО_В_АМБАРЕ - int($ПЛОЩАДЬ_ПОСЕВОВ/2);
# вегетационный период
$Y = int(rand()*5) + 1; # урожайность 1..5 бушелей с акра, в среднем 3
# сбор урожая и засыпка зерна на хранение
$УРОЖАЙ = $ПЛОЩАДЬ_ПОСЕВОВ*$Y;
#потери урожая 2 года из пяти
$C = int(rand()*5) + 1; # 1..5
if (int($C/2) != $C/2){
# если нечетное $С потерь нет
$СЪЕДЕНО_КРЫСАМИ = 0;
}
else {
$СЪЕДЕНО_КРЫСАМИ = int($ЗЕРНО_В_АМБАРЕ/$C); # в среднем 3/20 остатка
}
$ЗЕРНО_В_АМБАРЕ = $ЗЕРНО_В_АМБАРЕ - $СЪЕДЕНО_КРЫСАМИ + $УРОЖАЙ;
}
# =====================================
sub Демограф_цикл{
# странно - обратно пропорционально населению
$C = int(rand()*5) + 1; # 1..5
$ПРИРОСТ_НАСЕЛЕНИЯ = int($C*(20*$ПЛОЩАДЬ + $ЗЕРНО_В_АМБАРЕ)/$НАСЕЛЕНИЕ/100 + 1);
# пропитание 20 бушелей в год на человека
$ОБЕСПЕЧЕНО_ПИЩЕЙ = int($ПРОДОВОЛЬСТВЕННОЕ_ЗЕРНО / 20);
if ($ОБЕСПЕЧЕНО_ПИЩЕЙ < $НАСЕЛЕНИЕ){
$УМЕРЛО_ОТ_ГОЛОДА = $НАСЕЛЕНИЕ - $ОБЕСПЕЧЕНО_ПИЩЕЙ;
}
else {
$УМЕРЛО_ОТ_ГОЛОДА = 0;
}
goto Досрочное_увольнение if $УМЕРЛО_ОТ_ГОЛОДА > 0.45*$НАСЕЛЕНИЕ;
$СМЕРТНОСТЬ_ОТ_ГОЛОДА_10 = (($ГОД - 1)*$СМЕРТНОСТЬ_ОТ_ГОЛОДА_10 + $УМЕРЛО_ОТ_ГОЛОДА*100/$НАСЕЛЕНИЕ)/$ГОД;
$НАСЕЛЕНИЕ = $ОБЕСПЕЧЕНО_ПИЩЕЙ;
$УМЕРЛО_ОТ_ГОЛОДА_10 = $УМЕРЛО_ОТ_ГОЛОДА_10 + $УМЕРЛО_ОТ_ГОЛОДА;
$НАСЕЛЕНИЕ = $НАСЕЛЕНИЕ + $ПРИРОСТ_НАСЕЛЕНИЯ;
# 15% вероятность чумы
$ЧУМА = '';
if (rand() < 0.15){
$НАСЕЛЕНИЕ = int ($НАСЕЛЕНИЕ / 2);
$ЧУМА = "Ужасная чума ! Половина народу умерло.\n";
}
}
# =====================================
sub Годовой_отчет{
print "\n\nХаммурапи: прошу отчитаться.\n";
print "В ", $ГОД, " году \n", $УМЕРЛО_ОТ_ГОЛОДА, " человек умерло от голода.\n";
print "Прирост населения составил ", $ПРИРОСТ_НАСЕЛЕНИЯ," человек.\n";
print $ЧУМА;
print "Сейчас население составляет ", $НАСЕЛЕНИЕ, " человек\n";
print "Город владеет ", $ПЛОЩАДЬ, " акрами.\n";
print "Собрано зерна ", $Y, " бушелей с акра.\n";
print "Крысы съели ", $СЪЕДЕНО_КРЫСАМИ, " бушелей.\n";
print "Запасы зерна составляют ", $ЗЕРНО_В_АМБАРЕ, " бушелей.\n";
}
# =====================================
sub Итоги_десятилетия{
$L = $ПЛОЩАДЬ / $НАСЕЛЕНИЕ;
$C = sprintf "%6.2f", $СМЕРТНОСТЬ_ОТ_ГОЛОДА_10;
print "За время вашего 10 летнего пребывания на посту в среднем ", $C , " процентов\n";
print "населения ежегодно умирали от голода, в общей сложности ", $УМЕРЛО_ОТ_ГОЛОДА_10, " человек.\n";
print "Вы начали с 10 акров на человека, а закончили \n", $L; " акрами на человека.\n\n";
goto ЧУДОВИЩНЫЙ_РЕЗУЛЬТАТ if $СМЕРТНОСТЬ_ОТ_ГОЛОДА_10 > 33;
goto ЧУДОВИЩНЫЙ_РЕЗУЛЬТАТ if $L < 7;
goto ПЛОХОЙ_РЕЗУЛЬТАТ if $СМЕРТНОСТЬ_ОТ_ГОЛОДА_10 > 10;
goto ПЛОХОЙ_РЕЗУЛЬТАТ if $L < 9;
goto СРЕДНИЙ_РЕЗУЛЬТАТ if $СМЕРТНОСТЬ_ОТ_ГОЛОДА_10 > 3;
goto СРЕДНИЙ_РЕЗУЛЬТАТ if $L < 10;
#если площадь на человека >= 10 и смертность от голода <= 3%
goto ФАНТАСТИЧЕСКИЙ_РЕЗУЛЬТАТ;
ФАНТАСТИЧЕСКИЙ_РЕЗУЛЬТАТ:
print "Фантастический результат !!! Шарлемань, Дизраели и \nДжефферсон вместе не смогли бы сделать лучше ! \n";
goto ДО_СВИДАНИЯ;
ЧУДОВИЩНЫЙ_РЕЗУЛЬТАТ:
print "Из-за чрезвычайно плохого управления ты объявлен \"Предателем нации\" !!";
goto ДО_СВИДАНИЯ;
ПЛОХОЙ_РЕЗУЛЬТАТ:
print "Ваша тяжелая рука припахивает Нероном и Иваном IV. \nВыжившие люди считают вас плохим правителем и ужасно ненавидят ваши потроха ! \n";
goto ДО_СВИДАНИЯ;
СРЕДНИЙ_РЕЗУЛЬТАТ:
print "Ваши достижения могли бы быть лучше, но \nдела не совсем плохи. \n";
print int($НАСЕЛЕНИЕ*0.8*rand()), " человек хотели бы видеть вас убитым, но это обычная проблема для нас.\n";
goto ДО_СВИДАНИЯ;
ДО_СВИДАНИЯ:
}
# =====================================
exit;
Update
Если ваш интерпретатор Perl не поддерживает русскоперловый язык, то конвертировать имена в латиницу можно с помощью вот этой программки:
http://vlkamov.narod.ru/rupl.zip
Сгрузите и распакуйте. Скопируйте код, находящийся под катом в файл hamurabi.rupl и команда
perl rupl2pl.pl hamurabi.rupl > tmp.pl ; perl tmp.pl
сразу конвертирует в латиницу и запускает исполнение.
no subject
Date: 2011-07-07 05:37 am (UTC)Более сложные модели нашлись в книге Коротаева (http://urss.ru/cgi-bin/db.pl?lang=Ru&blang=ru&page=Book&id=27389). См. также (http://schegloff.livejournal.com/443227.html?thread=15132507#t15132507)...
no subject
Date: 2011-07-07 06:20 am (UTC)no subject
Date: 2011-07-07 06:52 am (UTC)История же начинается (в Шумере, да!), как я понимаю, с работы моего коллеги и до какого-то момента соотечественника биофизика Никласа Рашевски "Looking at History through Mathematics" (1968), которую я до сих пор не могу разыскать (рекомендовал П. Турчин где-то год тому). А идея поиска мат. законов соц. развития - это Айзек Азимов (химик - явно общался и с физиками, в т.ч. ядерщиками, работавшими по атомному проекту, - знаменитое "Основание") и Стас Лем (медик и кибернетик - см. в "Сумме технологий").
no subject
Date: 2011-07-07 06:58 am (UTC)Оригинальный так глубоко запрятан, что найти не удалось. Что характерно. Все ссылки на предысторию дальше бесика не идут.
no subject
Date: 2011-07-07 07:29 am (UTC)"Doug Dyment wrote The Sumer Game in 1968 as a demonstration program for the FOCAL programming language, programming it on a DEC PDP-8." (см. линк на вики выше)
Но, таки да, я тоже не нашёл текст на фокале, ибо и не искал. Мне интересней всё же модель Рашевски, если она его (Doug Dyment ведь откуда-то брал саму ресурсную модель? Вряд ли просто "из головы").
no subject
Date: 2011-07-07 07:55 am (UTC)Re: Сорсы от разработчика
Date: 2011-07-12 01:49 am (UTC)Re: Сорсы от разработчика
Date: 2011-07-12 02:10 am (UTC)>> Aha!:) And I supposed the model was taken from the book "Looking at
>> History through Mathematics" (1968) by Nicolas Rashevsky - may be the
>> fisrt book on popular now cliodynamics...
>
> I'm unaware of that book, so haven't read it (all my reading at the time was
> pure computer science). In my case, the idea for the game/model came from
> some casual comments by a grad student whose name I have long since
> forgotten (she wasn't a student of mine, just one I met while delivering a
> lecture at either the University of Calgary or Edmonton). Beyond that, all
> the thinking was mine.
>
> At the time I wrote the game, I was in charge of software for the Canadian
> arm of DEC, based in Carleton Place (near Ottawa, Canada). A long time ago.
> :)
А вот ответ ещё одного любопытствующего исходниками с одного из форумов:
> Yes, Doug actually sent me a scan of the book his was published in. Turns
> out though that Sumer Game dates back to 1962-ish when it was produced as
> part of a project by BOCES (Board of Cooperative Educational Services) as
> part of the New York school system to integrate technology into elementary
> schools. They produced The Sumer Game and also documented something called
> the Sierra Leone Game with collaboration with IBM. There's a handful of
> articles out there on this (by Leonard Wing and his collaborators), but I've
> been unable to locate the source code for the original game, and had no luck
> going through IBM (but I could try again...). Doug claims he had no
> knowledge of this government-funded project, but the two are basically the
> same thing. He says he got the idea for it at a conference from a woman
> (educator) who must have described it to him in some detail.
Пожалуй, ничего удалять не буду. Ничего личного в переписке нет и разрешения на публикацию получены.
Закрадывается подозрение, что идея игры (как и основания "Основания" Азимова) принадлежит какому-нить биофизику из работавших по ядерным проектам, а потому имевшим доступ к компьютерам, когда они ещё были большими...
Re: Сорсы от разработчика
Date: 2011-07-12 06:01 am (UTC)Обращает на себя внимание, что лексика в "фокальном" листинге намного более определенна, как бы переводчик на Бейсик максимально пытался избежать копирования авторского текста.
Re: Сорсы от разработчика
Date: 2011-07-14 08:26 pm (UTC)> Like I said, the idea for Sumer began in 1962 under the Cooperative Research
> Project #1948. This was a government-grant program conducted by BOCES. The
> CRP proposed the use of technology in the elementary school classroom
> setting. Dyment got the idea from a grad student who was familiar with the
> project. There's a lot of documentation out there, but most of it had to be
> dug up from old records (and it's hard to get magazines and journals from
> the 50s and 60s).
> I have some detailed articles by Wing (now deceased) which explain the
> history of simulation gaming up until this point. I can send one to you if
> you like. His summary is pretty concise and includes a lot more material
> than I have included here. A brief summary:
>
> Pre-1956 - Computers used in the simulation of war by the US Military,
> likely by other countries as well. Prior to this, war games can be traced
> back to Kriegspiel in the 19th Century. These ideas developed I think from
> the philosophy of the Englightenment, primarily the idea that you could
> simulate any aspect of the world using math.
> 1956 - First economics game simulation; the AMA Game. AMA had connections
> with the US Naval War College, whom they consulted before producing this
> game. The history of 'serious games' for business and education can be
> traced back here.
> 1958 - Carnegie Tech Management Game; one of the first games used in
> education
> 1958 - Tennis for Two (independent meme)
> 1961 - Spacewar (independent meme)
> 1962 - BOCES project; development of Sumer begins.
> 1964 - By this time, a digital version of Sumer was working.
>
> I have no clue how they decided to model the AMA Game. I wouldn't even know
> who to ask for the philosophy behind it all, actually!
Прошу прощения за небыстрый ответ, но в ближайшее время у меня не будет времени на пост. Кроме того, я обычно пишу, когда до чего-то определённого докопаюсь, а здесь надо поглядеть материалы упомянутого Leonard Wing. Пока понятно, что начинались эти "игры" с эмуляции военных стратегий. (См. также про "Каиссу" где-то у Михаила Донского (http://itblogs.ru/blogs/donskoy/default.aspx).)
Если нужна будет помощь в написании поста - обращайтесь, но ответ, снова-таки, не будет быстрым :( Мои комменты, конечно же, можно использовать!
Если сам возьмусь, то уже осенью где-то.
Re: Сорсы от разработчика
Date: 2011-08-05 07:05 pm (UTC)no subject
Date: 2011-07-11 10:25 pm (UTC)Коммент удалю через некоторое время как технический.