競馬であそぶ 5

 倒産は経営者の、財政破綻は内閣の責任て、当然だろ。
責任取れるのか?
それとも選んだ国民の自己責任か?笑えるね。 




5.   スクリプトを改造(3)  

サブルーチンの続きです。kbs をざっと眺めたところ、2〜3書き換えた方が
よさそうな場所があるのでソコだけでも最初に、、

sub kbs {   ################################################################
while( $racenum and $bbcd and $yymmdd ) { 
    my $bbrr = sprintf "%02d%02d", $bbcd, $racenum ;
############################################################################
    my $kline = $racejho[$bbcd][$racenum] ;
    my $raceCD = substr( $kline, 11, 16 ) ;
    my $ti =  substr( $kline, 492, 6 ) ;
    
    ( 10行省略 )

    my $jyf = ( $jy == 999 or $jy < 700 ) ? $jy : 0 ;
    $jyf += $gr eq 'A' ? 3 : $gr eq 'B' ? 2 : $gr eq 'C' ? 1 : 0 ;
#### ===【 除外条件 】* 出力したければコメントアウト * =======###
    sub jogair {
        print "\tこのレース条件は出力できません。\n" ;
        last ;
    }

my $kline = $racejho[$bbcd][$racenum] のあとに、 or &jogair() ;を書き加えて
    my $kline = $racejho[$bbcd][$racenum] or &jogair() ;
print "\tこのレース条件は出力できません。\n" ; の行は、
        print "\tこのレース条件は出力できません。$ba_of[$bbcd]:${racenum}R\n\n" ;
今までは、障害レースなどだけに出していたコメントですが、こうすることで、例えば有馬記念 のとき
のように10Rまでしかないような場合に、11Rを指定しても、コメントが出るように なります。
無いレースや除外するレースを、disabled にするのはコスト高なので、この方法にしました。

全体の行で、 1054 行目
                $mkk = $ana ;
ここは、$mkk ではなくて、 $mkq ですね。
それ以外にも、間違いや直した方がいい個所はタクサンあると思います。


sub step1 {
    if ( $racenum and $bbcd and $yymmdd ) {
        &kbs() ;
    }
}

の if を while に書き換えることで、kbs の while の大きな括りを外せます。試してください。
kbs の while を含む最初の行と、最後の } だけの行が要らなくなる ということです。
書き換えや追加を繰り返していると、こうした、未熟かつ無駄な部分がアチコチに残る 場合があり
ます。
そんな場合でも、サブルーチン化しておけば見通しは幾分よくなる筈ですが、 結構エネルギーを要
しそうなので、、


この項は、修正ではなくて改造がテーマです。モジュールからは少し外れた感じ かも、
改造の目標は、仮に「オッズを表示できるようにする」ということで進みたいと思 います。
実際にソコまでいけるかどうかは分かりませんが、、

サブルーチン kbs は、基本情報・その他を出すためのものですが、オッズを出す 場合には必要な
部分と不要な部分とが含まれています。
条件分けなどの整理をすることで、少しは効率よく出来るかもしれません。まず、 その方向で考え
ます。

追加や修正は予定を決めずに、のんびり行きます。

おや??前日検討が出来ませんね。ココまでの修正を含めた版をUPしておきます。

⇒⇒ 0018 (2005.06.17) はコチラから


思い出したので、ついでに書いておきます。Shift-JIS を使っているのは理由などナニも ありません。
まぁこれで二進も三進も行かなくなったら、他を使うかもしれません。

背景色、文字色、サイズ、位置などは好きなように変更することができるので試してください。




6.  スクリプトを改造(4) 

今回は、三連複オッズの表示にチャレンジします。

my @selec = ( '基本情報', '+過去3走', '+戦績集計', '三連複odds', '三連単odds' ) ;

前に書いた方法で 情報選択ボタンの数を2コ増やし、 @selec にも項目を追加します。

sub push_butta {
    $racenum = shift ;
    $buffer = sprintf( "%2d", $racenum ) . 'R' ;
    if( $rad < 3 ) {
        &step1() ;
    } elsif( $rad == 3 ) {
        &sr1_window() ;
    } elsif( $rad == 4 ) {
        &sr1_window() ;
    }
}

push_butta も例えば上記のように、とりあえず書き換えておきます。
三連複オッズに関しては、上の場合 $rad == 3 の括りの中に入れればいいわけです。

sub sr1_window {
    print "\n\t\t 三連複odds は準備中です。 \n" ;
}

sub sr2_window {
    print "\n\t\t 三連単odds は準備中です。 \n" ;
}

sub get_odds {      # オッズを取得
    ;
}

sub push_go {       # Go!ボタンを押したとき
    ;
}

 ↑ この4つ程度は必要ですかね。中身は後から少しづつ考えましょう。

いよいよ始める前に、表示させるまでの流れを考えてみます。
 1. 情報分岐ボタンで三連複を選ぶ。場名ボタン選ぶ。
 2. レースNo. を押す。
 3. 馬番選択用の新しい画面が現れる。
 4. 馬番を、何頭か選んで Go! ボタンを押す。
 5. 三連複オッズが表示される。

とすると、3. の馬番選択用の新しい画面を作らないといけないですね。
馬番選択なら、レースNo.選択と同じようなボタンを並べればいいわけですが、出走頭数が 分から
なければボタンの数が決まりません。仮に $tosu とします。
出走頭数、というのは正確ではないですね。正しくは馬番確定後の登録頭数 です。
これは、JVData仕様書のフォーマットを参照してください。(←常識ですね)

問題はこの、882Byte目からの 2Byte ⇒ 例えば Perl の場合、substr( $_, 881, 2) でも
encoding による影響(2Byte文字の数え方)で、位置の調整が必要です。
この位置までに、全角文字が使われている部分が278Byteなので、半分の139の位置調整。
つまり正しく出すには、このスクリプトでは
$tosu = substr( $racejho[$bbcd][$racenum], 742, 2 ) ; となります。

全角が使われる位置が確定している場合は、この方法でいいのですが同じ位置に混在する場合 も
あります。
例えば、UM(競走馬マスタ)ファイルでは、lengthで文字数を出して本来の長さ と比較する方法を使
いました。SE(馬毎レース)ファイルでも同じ作業が必要なのですが、こちらはマダやってい ません。
これらの事情については、JVData仕様書を参考にしてください。


sub sr1_window {
    if ( Exists( $s1 ) ) {
        for my $i ( 1..$#cb ) {
            $cb[$i]->destroy() ;
        }
    } else  {
        $s1 = $mw->Toplevel( -title => '三連複' ) ;
        $s1->Label( -text => '三連複BOX〜準備中',
             -foreground => "#800000",
             -background => "#f0f0d0",
             -font => [ "FixedSys", 12 ] )->pack() ;
        $s1->Button( -text => "Go!",
             -command => \&push_go )->pack() ;
    }
    @cb = () ;
    my $tosu = substr( $racejho[$bbcd][$racenum], 742, 2 ) ;
    for my $i ( 1..$tosu ) {    # 馬番号のついたボタン
        my $j = sprintf "%2d", $i ;
        $cb[$i] = $s1->Checkbutton( -text => $j,
                                    -indicatoron => 'no',
                                    -selectcolor => "#d5f7be"
        )->pack( -side => 'left' ) ;
    }
}

見栄えは各自勝手に変えてもらうにしても、こんな感じですか?
あとは、三連複オッズを取り込むサブルーチンと、Go!ボタンを押したときの 処理を考えるだけで
すね。

オッズ取り込みに関しては、kbs の中にも一部ありますが、ココは自前で 用意したいと思います。
というか、サブルーチンとして分離したほうよさそうです。
下手に弄ると動かなくなるのが大体こういう場面ですが自信満々、行きます。

この辺りで既に sSeia の能力の限界を超えているので、間違いも連発しているかもしれ ません
が、ツマランこと気にしていたら、人生楽しくないからね〜 とヨッパライの口説き文句かぃ。

my @odds_tan = () ;
my @odds_3rn = () ;

sub get_odds {      # オッズを取得
    my $bbrr = sprintf "%02d%02d", $bbcd, $racenum ;
    {       # 単勝オッズ
        my $odds_1 = "${zpass}/${yymmdd}/0B31${yymmdd}${bbrr}\.dat" ;
        next unless -e $odds_1 ;
        open DAT, $odds_1 ;
        while ( <DAT> ) {
            $do1->() ;
            my @ozdat = unpack 'A8' x 18, substr( $_, 43, 144 ) ;
            for ( @ozdat ) {        # 単ODDS
                my ( $umb, $todds ) = unpack 'A2A6', $_ ;
                $odds_tan[$umb] = $todds ;
            }
        }
        close DAT ;
    }

    if( $rad == 3 ) {       # 三連複オッズ
        my $odds_5 = "${zpass}/${yymmdd}/0B35${yymmdd}${bbrr}\.dat" ;
        next unless -e $odds_5 ;
        open DAT, $odds_5 ;
        while ( <DAT> ) {
            $do1->() ;
            my ( $kubn, $jifun, $to, $alls, $hyo ) = unpack
                '@2 A1 @31 A4 @35 A2 @40 a12240 @12280 a11', $_ ;
            my @ozdat = unpack 'A15' x 816, $alls ;
            for ( @ozdat ) {        # 三連複ODDS
                my ( $z1, $z2, $z3, $zoz, $zj ) = unpack 'A2A2A2A6A3', $_ ;
                $odds_3rn[$z1][$z2][$z3] = $zoz ;
            }   
        }
        close DAT ;
    }

    if( $rad == 4 ) {       # 三連単オッズ
        my $odds_6 = "${zpass}/${yymmdd}/0B36${yymmdd}${bbrr}\.dat" ;
        next unless -e $odds_6 ;
        open DAT, $odds_6 ;
        while ( <DAT> ) {
            $do1->() ;
            my ( $kubn, $jifun, $to, $alls, $hyo ) = unpack
                '@2 A1 @31 A4 @35 A2 @40 a83232 @83272 a11', $_ ;
            my @ozdat = unpack 'A17' x 4896, $alls ;
            for ( @ozdat ) {        # 三連単ODDS
                my ( $z1, $z2, $z3, $zoz, $zj ) = unpack 'A2A2A2A7A4', $_ ;
                $odds_3rn[$z1][$z2][$z3] = $zoz ;
            }   
        }
        close DAT ;
    }
}

こんな感じじゃないでしょうか。使うかもしれないデータも未検証ですが押さえてあります。
面倒がらなければ表示に関してはイロイロ細工の施しようもあるけれど、あとは好きにやって もらう
ことにしましょう。


次は、いよいよ表示するための最後のサブルーチンpush_go の予定です。

 ↑ かなりの修正があります。
例えば、登録頭数などもオッズデータに含まれており、@racejho からワザワザもってくる必要 はあり
ません。
get_odds で入手して、それを使うのが正しいようです。
その他にも、この項ではスクリプトの修正はしませんが次項以降でかなりの修正があります。


INDEXへ トップページへ 次へ