main.cgi
ヘッダー
#!c:/perl/bin/perl
各ファイル位置の名義付け
$CHARSET='Shift_JIS';
$CsvCity='city.csv';
$CsvItem='item.csv';
$CsvCulture='culture.csv';
$CsvMain='main.csv';
上記プログラムはファイル位置が変更した場合に、位置情報をここを弄るだけで全て正常に動きます。
メインルーチン
loadFormdata();
loadCsvfile();
processPickup();
processCalculate();
printData();
exit;
メインルーチンです。主に読込、データ計算、出力という順番になっています。
下層ルーチン
loadFormdata();
loadCsvfile();
processPickup();
processCalculate();
printData();
loadFormdata();
sub loadFormdata
{
my ($query, $pair, @pairs);
if($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
}
else {
$query = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $query);
foreach $pair (@pairs) {
my ($key, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$FORM{$key} = $value;
}
}
フォームデータを全て$FORM(キー)に格納します。
loadCsvfile();
sub loadCsvfile
{
open(FileCity,$CsvCity) or printErrorpage("Cityデータファイルが開けません");
eval{flock(FileCity,1)};
@DataCity=<FileCity>;
close FileCity;
open(FileItem,$CsvItem) or printErrorpage("Itemデータファイルが開けません");
eval{flock(FileItem,1)};
@DataItem=<FileItem>;
close FileItem;
open(FileCulture,$CsvCulture) or printErrorpage("Cultureデータファイルが開けません");
eval{flock(FileCulture,1)};
@DataCulture=<FileCulture>;
close FileCulture;
open(FileMain,$CsvMain) or printErrorpage("Mainデータファイルが開けません");
eval{flock(FileMain,1)};
@DataMain=<FileMain>;
close FileMain;
}
CSVファイルを開き、Dataリストに格納します。
上から都市データ、交易品データ、文化圏データ、メインデータです。
下層ルーチン
printErrorpage("出力コメント");
processPickup();
sub processPickup
{
my($i);
LOOPPICKUPITEM:for($i=0;$i<@DataItem;++$i){
my($diNumber,$diName,$diCategory,$diClass,$diCulture,$diPrice)=split(/,/,$DataItem[$i]);
if($diNumber==$FORM{'item'}){
$GlItem{'number'}=$diNumber;
$GlItem{'name'}=$diName;
$GlItem{'category'}=$diCategory;
$GlItem{'class'}=$diClass;
$GlItem{'culture'}=$diCulture;
$GlItem{'price'}=$diPrice;
last LOOPPICKUPITEM;
}
}
LOOPPICKUPCULTURE:for($i=0;$i<@DataCulture;++$i){
if($i==$GlItem{'culture'}){
@GlCulture=split(/,/,$DataCulture[$i]);
last LOOPPICKUPCULTURE;
}
}
for($i=0;$i<@DataMain;++$i){
my($dmNumber,$dmUpdate,$dmCity,$dmItem,$dmDirect,$dmPrice,$dmMarket,$dmPurchase,$dmTax)=split(/,/,$DataMain[$i]);
if($dmItem==$GlItem{'number'}){
push @PickupData,($dmNumber.','.$dmUpdate.','.$dmCity.','.$dmItem.','.$dmDirect.','.$dmPrice.','.$dmMarket.','.$dmPurchase.','.$dmTax);
}
}
}
計算する前に必要なデータのみを抽出し、グローバル変数、及びデータリストに格納します。
上から交易品データ抽出格納(@glItem)、文化圏データ抽出格納(@glCalture)、メインデータ抽出格納(@pickupData)。
processCalculate();
sub processCalculate
{
my($i,$j);
LOOPCALCULATEDATA:for($i=0;$i<@PickupData;++$i){
my($pdNumber,$pdUpdate,$pdCity,$pdItem,$pdDirect,$pdPrice,$pdMarket,$pdPurchase,$pdTaxratio)=split(/,/,$PickupData[$i]);
my(%prCity,$prBaseprice,$prCultureprice,$prProfit,$prRatio,$prTax);
LOOPCALCULATECITY:for($j=0;$j<@DataCity;++$j){
my($dcNumber,$dcName,$dcCulture,$dcAlliance)=split(/,/,$DataCity[$j]);
if($pdCity==$dcNumber){
$prCity{'culture'}=$dcCulture;
last LOOPCALCULATECITY;
}
}
if($prGlCulture[$prCity{'culture'}] eq '.'){
$prCultureprice=0;
}else{
$prCultureprice=fRounding($GlItem{'price'}*0.1*$GlCulture[$prCity{'culture'}],1);
}
if($pdDirect==1 and $pdMarket!=0){
$prTax=fRounding(($pdPrice/(100-$pdTaxratio)*$pdTaxratio),1);
$prBaseprice=fRounding((($pdPrice-$prTax)*100/$pdMarket),0);
$prProfit=$GlItem{'price'}-$prBaseprice;
}elsif($pdDirect==1 and $pdMarket==0){
$prTax=fRounding(($pdPrice/(100-$pdTaxratio)*$pdTaxratio),1);
$prBaseprice=0;
$prProfit=$GlItem{'price'}-$prBaseprice;
}elsif($pdDirect==0 and $pdMarket!=0){
$prTax=fRounding((($pdPrice-$pdPurchase)/(100-$pdTaxratio)*$pdTaxratio),1);
$prBaseprice=fRounding((($pdPrice+$prTax-$prCultureprice)*100/$pdMarket)+$prCultureprice,0);
$prProfit=$prBaseprice-$GlItem{'price'};
}elsif($pdDirect==0 and $pdMarket==0){
$prTax=fRounding((($pdPrice-$pdPurchase)/(100-$pdTaxratio)*$pdTaxratio),1);
$prBaseprice=0;
$prProfit=$prBaseprice-$GlItem{'price'};
}
if($GlItem{'price'}==0){
$prRatio=999.99;
}else{
$prRatio=fRounding(($prBasePrice/$GlItem{'price'}),0.01);
}
push @CalculateData,($pdCity.','.$pdDirect.','.$pdUpdate.','.$prBaseprice.','.$prCultureprice.','.$prProfit.','.$prRatio.','.$prTax.','.$pdPrice.','.$pdMarket.','.$pdPurchase.','.$pdTaxratio);
}
}
抽出されたデータを元に計算を行います。前ルーチンで抽出されたデータファイルを上から順に計算し、
新しい出力用データファイルに格納していきます。
LOOPCALCULATECITYで都市情報に関するデータを抽出し、
中段で名産ボーナス、税金、基準価格、利潤額等を計算しています。
最後のpush @CalculateDataで出力用データファイルに格納していきます。
下層関数
fRounding(数値,要素):要素=0,上3桁残留、要素=他,その位まで残留
printData();
sub printData
{
print qq(Content-type: text/plain; charset=$CHARSET\n\n);
print qq(<HTML><HEAD>\n);
print qq(<TITLE>NFT:Base price of $GlItem{'name'}</TITLE>\n);
print qq(<LINK REL="stylesheet" HREF="./design.css" TYPE="text/css">);
print qq(</HEAD><BODY>\n);
print qq(<SPAN CLASS="spItemname">$GlItem{'name'}</SPAN><BR>\n);
print qq(カテゴリ:$GlItem{'category'}<BR>\n);
print qq(種類:$GlItem{'class'}<BR>\n);
print qq(名産:$GlCulture[0]名産品<BR>\n);
print qq(基本価格:$GlItem{'price'}<BR>\n<BR>\n);
printDataCulture(1,'北欧');
printDataCulture(2,'ドイツ');
printDataCulture(3,'ネーデル');
printDataCulture(4,'ブリテン');
printDataCulture(5,'フランス北部');
printDataCulture(6,'イベリア');
printDataCulture(7,'南フランス・イタリア');
printDataCulture(8,'バルカン');
printDataCulture(9,'トルコ');
printDataCulture(10,'近東');
printDataCulture(11,'北アフリカ');
printDataCulture(12,'西アフリカ');
printDataCulture(13,'東アフリカ');
printDataCulture(14,'アラブ');
printDataCulture(15,'ペルシャ');
printDataCulture(16,'インド');
printDataCulture(17,'東南アジア');
printDataCulture(18,'インドシナ');
printDataCulture(19,'大西洋');
printDataCulture(20,'カリブ');
printDataCulture(21,'中南米東岸');
print qq(</BODY></HTML>);
}
ページを出力します。
下層ルーチン
printDataCulture(文化圏番号,文化圏名)
printDataCulture(文化圏番号,文化圏名);
sub printDataCulture
{
print qq(<SPAN CLASS="spCulture">$_[1]</SPAN><BR>\n);
print qq(<TABLE CLASS="tbWhole" BORDER=1 >\n);
print qq(<TR>);
print qq(<TH CLASS="thCity">都市名</TH>);
print qq(<TH CLASS="thYn">購入可否</TH>);
print qq(<TH CLASS="thBaseprice">基準価格</TH>);
print qq(<TH CLASS="thCulture">内名産額</TH>);
print qq(<TH CLASS="thProfit">比較利潤</TH>);
print qq(<TH CLASS="thRatio">利倍率</TH>);
print qq(<TH CLASS="thUpdate">更新日</TH>);
print qq(<TH CLASS="thTax">税金</TH>);
print qq(<TH CLASS="thPrice">価格</TH>);
print qq(<TH CLASS="thMarket">相場</TH>);
print qq(<TH CLASS="thPurchase">仕入価格</TH>);
print qq(<TH CLASS="thTaxRatio">税率</TH>);
print qq(<TH CLASS="thRedata"></TH>);
print qq(</TR>\n);
LOOPCITYOFPRINT:for($i=0;$i<@DataCity;++$i){
my($dcNumber,$dcName,$dcCulture,$dcAlliance)=split(/,/,$DataCity[$i]);
my($tdBgclass);
if($i%2==0){
$tdBgclass='STYLE="background-color:#ffffff;"';
}else{
$tdBgclass='STYLE="background-color:#ffffcc;"';
}
if($dcCulture==$_[0]){
LOOPDATAOFPRINT:for($j=0;$j<@CalculateData;++$j){
my($cdCity,$cdDirect,$cdUpdate,$cdBaseprice,$cdCultureprice,$cdProfit,$cdRatio,$cdTax,$cdPrice,$cdMarket,$cdPurchase,$cdTaxratio)=split(/,/,$CalculateData[$j]);
if($cdCity==$dcNumber){
my($yn);
if($cdDirect==1){
$yn='○';
}else{
$yn='×';
}
print qq(<TR>);
print qq(<TD $tdBgclass CLASS="tdCity">$dcName</TD>);
print qq(<TD $tdBgclass CLASS="tdYn">$yn</TD>);
print qq(<TD $tdBgclass CLASS="tdBaseprice">$cdBaseprice</TD>);
print qq(<TD $tdBgclass CLASS="tdCulture">$cdCultureprice</TD>);
print qq(<TD $tdBgclass CLASS="tdProfit">$cdProfit</TD>);
print qq(<TD $tdBgclass CLASS="tdRatio">$cdRatio</TD>);
print qq(<TD $tdBgclass CLASS="td"Update>$cdUpdate</TD>);
print qq(<TD $tdBgclass CLASS="tdTax">$cdTax</TD>);
print qq(<TD $tdBgclass CLASS="tdPrice">$cdPrice</TD>);
print qq(<TD $tdBgclass CLASS="tdMarket">$cdMarket%</TD>);
print qq(<TD $tdBgclass CLASS="tdPurchase">$cdPurchase</TD>);
print qq(<TD $tdBgclass CLASS="tdTaxratio">$cdTaxratio%</TD>);
print qq(<TD $tdBgclass CLASS="tdRedata"><A HREF="">[更新]</A></TD>);
print qq(</TR>\n);
next LOOPCITYOFPRINT;
}
}
print qq(<TR>);
print qq(<TD $tdBgclass CLASS="tdCity">$dcName</TD>);
print qq(<TD $tdBgclass CLASS="tdYn">.</TD>);
print qq(<TD $tdBgclass CLASS="tdBaseprice">.</TD>);
print qq(<TD $tdBgclass CLASS="tdCulture">.</TD>);
print qq(<TD $tdBgclass CLASS="tdProfit">.</TD>);
print qq(<TD $tdBgclass CLASS="tdRatio">.</TD>);
print qq(<TD $tdBgclass CLASS="td"Update>.</TD>);
print qq(<TD $tdBgclass CLASS="tdTax">.</TD>);
print qq(<TD $tdBgclass CLASS="tdPrice">.</TD>);
print qq(<TD $tdBgclass CLASS="tdMarket">.%</TD>);
print qq(<TD $tdBgclass CLASS="tdPurchase">.</TD>);
print qq(<TD $tdBgclass CLASS="tdTaxratio">.%</TD>);
print qq(<TD $tdBgclass CLASS="tdRedata"><A HREF="">[更新]</A></TD>);
print qq(</TR>\n);
}
}
print qq(</TABLE>\n<BR>\n);
}
printErrorpage(エラーメッセージ);
sub printErrorpage
{
print qq(Content-type: text/html; charset=$CHARSET\n\n);
print qq(<HTML><HEAD><TITLE>NFT:Error</TITLE></HEAD>);
print qq(<BODY>エラー:$_[0]</BODY></HTML>);
exit;
}
予測されうるエラーメッセージを出力します。
fRounding(数値,要素);
sub fRounding
{
my $columns;
if($_[1]==0){
$columns=length($_[0])-3;
if($columns<0){$columns=0;}
$columns=10**$columns;
}else{
$columns=$_[1]
}
return int(($_[0]/$columns)+0.5)*$columns;
}
四捨五入関数です。
要素が0の場合上3桁以外を四捨五入します。
要素が0以外の場合、その桁未満を四捨五入します。
最終更新:2007年08月01日 15:32