アットウィキロゴ

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