Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет vlkamov ([info]vlkamov)
@ 2011-07-06 12:07:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Код Hamurabi_2
(начало см. http://vlkamov.livejournal.com/722060.html )
Переведенный на русскоперловый язык код игры стал существенно более прозрачным. Это позволило побороть почти все "макароны", остались две малосущественные, описывающие экстремальное увольнение. Вся программа разбита на последовательно исполняемые блоки с ясными функциями. Для красоты кода пришлось немножко изменить порядок исполнения блоков и привести его в соответствие естественному ходу вещей. В оригинальном коде первый годовой цикл отрабатывается без участия игрока, так что диалог начинается годового отчета. Я не поленился отчет перенести в конец, так что игрок отдает распоряжения с первого же года, а итоги года подводятся в его конце.

Чума, голодомор и прирост населения вынесены в отдельный демографический блок. Интересно отметить, что в формуле прироста население стоит в знаменателе, что заставляет сомневаться в ориентации авторов.

При сборке-разборке традиционно остались лишние детали:
$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

сразу конвертирует в латиницу и запускает исполнение.