
jQuery MobileとAjax通信で作る十種競技得点計算ツール
十種競技、その世界チャンピオンはキングオブアスリートの称号で知られる数ある陸上競技の中でも屈指のタフさを誇る競技。
最近ではタレントの武井壮さんは陸上を初めて僅かでこの競技で日本選手権のチャンピオンに輝いたことは陸上界隈ではかなり有名なお話。
最近は右代啓祐選手が日本記録をどんどん更新して密かに盛り上がってます。
世界の壁はまだまだ厚く米国のアシュトン・イートンみたいなモンスターにはまだまだ及びませんが高校生の記録などを見ても確実にレベルは上がってます。
そんな僕自身も実は大学一年生の頃に十種競技をやっていました。
と言っても高校生の頃に練習の一環として八種競技(高校生向けの十種競技、棒高と円盤投げが無い。)をやっていたのと大学の陸上部も一年で辞めたので少し齧った程度ですが。
学生時代には良く十種競技や八種競技、三種競技AやB(現在は四種競技)の計算ツールを使って自分が何点ぐらい取れるのかを良く計算していましたが、今思うと不便な所も色々あったので自分でも作ってみようと思いました。
まず完成品がこちら。
モバイル、又はインラインフレームが正しく表示されない方はこちら。
SportTools | 十種競技
以下、作った際に気をつけた点など。
jQuery MobileによるモバイルファーストなUIの実装。
今の時代、デスクトップやノートPCよりタブレットやモバイル端末によるアクセスの方が圧倒的に多いWEBサイトも珍しくありません。
このブログは性質上まだPCからのアクセスの方が多いですが、運営している(放置している)アンテナサイトなどはアクセスを見てみると圧倒的にモバイル端末からのアクセスのほうが多いです。
まずWEBサイトを作ってレスポンシブにして簡略化したWEBサイトを使ってモバイル対応というのはよくやりますが、最初からモバイル端末向けに作ったことはありませんでした。
存在は知っていて結構前にドットインストールを観て基礎的な部分は抑えてありましたが2年前とはバージョンも違いclass名など基本的な部分も大幅に変更されていました。
というかjQMはバージョンが変わるごとに仕様が変わりすぎて1.3系のコードはコピペのままじゃ動かない事が多い・・・。
※今回使用したのはjQuery v1.10.2とjQuery Mobile V1.4.3
jQuery Mobileは基本的に一つのHTMLソースに複数ページを記述するので最初に読み込むJavaScriptの量が多すぎると全体的にモッサリします。
特にこれに関しては十種競技だけではなく七種、八種、男女四種競技に加えて他のスポーツでも使えるツールも同一ソースはへ後々加える予定なのでJavaScriptは主にUI処理のみにしました。
Ajaxを利用したPHPとの連携
JavaScriptのみでの実装も訳あって後に行いましたが、基本的には上記の理由から計算処理の中身はPHPで行うことにしました。
この程度の処理ならほぼリアルタイムでできるので通信によるストレスは感じません。
PHPの中身に関しては似たようで微妙に違う処理が多いので関数を作るのに苦労しました。
まだまだ簡略化出来そうですがあとから色々追加していく予定なので自分が読むのに時間がかかったら元も子もないのでかなり妥協しました。
HTML
種目 : 得点 - 累計
JavaScript
function decaCal(e){ function total(result){ id.html(result); } var deca = [e]; var id = $(document.getElementById(e+'Total')); $('#'+e+' input').each(function(){ if($(this).val().match(/[^0-9]+/)){ id.text("Error(半角数字のみで入力して下さい。)"); exit; }else{ deca.push($(this).val()) } }); $.post('decathlon.php', { score:deca.join() }, total); }
PHP
$score = explode(",",htmlspecialchars($_POST['score'], ENT_QUOTES,"UTF-8")); $i=0; foreach ($score as $value) { switch ($i) { case 0: $score[$i] = (string)$value; break; default: $score[$i] = (int)$value; break; } $i++; } //ヘッダー設定 header('Content-type:text/plain; charset=utf8'); //変数設定 $cnt = count($score); $total = 0; $sex = substr($score[0], 0, 4); //性別による処理の分岐 if($sex==="male"){ $decathlon = array('十種競技','100m : ','LJ : ','SP : ','HJ : ','400m : ','110mH : ','DT : ','PV : ','JT : ','1500m : '); $octathlon = array('八種競技','100m : ','LJ : ','SP : ','400m : ','110mH : ','JT : ','HJ : ','1500m : '); $mtetra = array('男子四種競技','110mH : ','SP : ','HJ : ','400m : '); / /種目毎の公式に入れる値 $male100 = array('a' => 25.4347,'b' => 18,'c' => 1.81); $male200 = array('a' => 5.8425,'b' => 38,'c' => 1.81); $male400 = array('a' => 1.53775,'b' => 82,'c' => 1.81); $male1500 = array('a' => 0.03768,'b' => 480,'c' => 1.85); $male110H = array('a' => 5.74352,'b' => 28.5,'c' => 1.92); $maleHJ = array('a' => 0.8465,'b' => 75,'c' => 1.42); $malePV = array('a' => 0.2797,'b' => 100,'c' => 1.35); $maleLJ = array('a' => 0.14354,'b' => 220,'c' => 1.40); $maleSP = array('a' => 51.39,'b' => 1.5,'c' => 1.05); $maleDT = array('a' => 12.91,'b' => 4,'c' => 1.1); $maleJT = array('a' => 10.14,'b' => 7,'c' => 1.08); }else{ //Female Events $heptathlon = array('七種競技','110mH : ','HJ : ','SP : ','200m : ','LJ : ','JT : ','800 : '); $fmtetra = array('女子四種競技','100mH : ','SP : ','HJ : ','200m : '); $fm200 = array('a' => 4.99087,'b' => 42.5,'c' => 1.81); $fm800 = array('a' => 0.11193,'b' => 254,'c' => 1.88); $fm100H = array('a' => 9.23076,'b' => 26.7,'c' => 1.835); $fmHJ = array('a' => 1.84523,'b' => 75,'c' => 1.348); $fmLJ = array('a' => 0.188807,'b' => 210,'c' => 1.41); $fmSP = array('a' => 56.0211,'b' => 1.5,'c' => 1.05); $fmJT = array('a' => 15.9803,'b' => 3.8,'c' => 1.04); } //関数設定 //関数1(合計の計算と出力) function total($p1,$p2){ $t=$p1+$p2; echo $p1." - ".$t." "; return $t; } //関数2(トラック種目の処理) function tracks($mark,$a,$b,$c){ if($mark<10000){ $sec=$mark*0.01; }else{ $sec=floor($mark*0.0001)*60+($mark % pow(10, 4))*0.01; } if($mark!==0){ return floor($a*pow(($b-$sec),$c)); }else{ return 0; } } //関数3(跳躍種目の処理) function jumps($mark,$a,$b,$c){ if($mark!=0){ return floor($a*pow(($mark-$b),$c)); }else{ return 0; } } //関数4(投擲種目の処理) function throws($mark,$a,$b,$c){ $mt=$mark*0.01; if($mark!=0){ return floor($a*pow(($mt-$b),$c)); }else{ return 0; } } if($score[0]=="maledeca"){//男子の十種競技の場合の処理 echo $decathlon[0]." "; echo $decathlon[1];//種目名の出力 $total = total(tracks($score[1],$male100['a'],$male100['b'],$male100['c']),$total);//得点計算と加算処理 echo $decathlon[2]; $total = total(jumps($score[2],$maleLJ['a'],$maleLJ['b'],$maleLJ['c']),$total); echo $decathlon[3]; $total = total(throws($score[3],$maleSP['a'],$maleSP['b'],$maleSP['c']),$total); echo $decathlon[4]; $total = total(jumps($score[4],$maleHJ['a'],$maleHJ['b'],$maleHJ['c']),$total); echo $decathlon[5]; $total = total(tracks($score[5],$male400['a'],$male400['b'],$male400['c']),$total); echo $decathlon[6]; $total = total(tracks($score[6],$male110H['a'],$male110H['b'],$male110H['c']),$total); echo $decathlon[7]; $total = total(throws($score[7],$maleDT['a'],$maleDT['b'],$maleDT['c']),$total); echo $decathlon[8]; $total = total(jumps($score[8],$malePV['a'],$malePV['b'],$malePV['c']),$total); echo $decathlon[9]; $total = total(throws($score[9],$maleJT['a'],$maleJT['b'],$maleJT['c']),$total); echo $decathlon[10]; $total = total(tracks($score[10],$male1500['a'],$male1500['b'],$male1500['c']),$total); }elseif($score[0]=="fmhepta"){ //その他の混成競技の処理 }else{ echo "Error(2):正しく値を入力して下さい。";//一応例外が出た場合の処理。 } echo "合計 : ".$total;
ひとこと
このツールを作って初めて知ったんですが、IAAFの発表した計算式では一般で行われる十種競技(七種競技)も中学生がやる四種競技も同一種目の計算方法は同じなんですね。
道理で中学生の頃にやっていた三種競技A(100m、砲丸投、走高跳)では、一般より投擲物の軽い砲丸投の記録が伸びて投擲の強い選手が強かった訳だ、納得。
四種競技ではハードルも入ってくるのでハードルが低い分スプリント系も有利ですね。
跳躍選手は不遇です!
陸上・混成競技トリビア
Alwaysが有名な歌手の光永亮太さんは東京の三種競技Aの中学記録をもっている。
当時、中学生で大会の冊子にはいつも光永亮太の名前があったので陸上部の中では結構話題になった。
自分たちが高校生になった翌々年だかに三種競技ABは廃止されて四種競技になったので為末大選手の三種競技B全国中学記録同様永久保存記録です。
ALWAYS/光永亮太