ポケモンGO 個体値計算

ポケモンGOでは、多くのトレーナーが最強のポケモンを探しています。
しかし、100%個体値と呼ばれる最強ポケモンが手に入ることは、めったにありません。
なので、90%や80%で我慢するわけですが、この%で表せられる個体値とは何だろうと思い、調べてみました。

各ポケモンには、基本となる種族値(攻撃力・防御力・体力)が設定されていて、
それぞれの個体には、+αとなる、攻撃力・防御力・体力が与えられる。
ゲーム画面上で表示される値は、強さを表すCPと体力を表すHPだけが表示されている。





個体特有値(Individual)は、攻撃力・防御力・体力それぞれに、0〜15の範囲で決定される。

ポケモンには、1〜40のレベルがあり、0.5キザミで指定される。
このレベルは、強化することによって、0.5上げることができる。
ポケモンレベルにより、CP補正値が一意に定まる。

ポケモン毎の種族値や、CP補正値については、ネット上に沢山の情報が出ている。

CPやHPの計算方法がわかったところで、
では、自分の持っているポケモンの個体値は、どうしたらわかるのだろう。
ネット上には、個体値計算機なるものがあるが、どうやって計算しているのだろう。

HPから考えてみる。
ポケモンの名前から種族値はわかる。「強化に必要な砂」からおおよそのポケモンレベルがわかる。
ならば、レベルの該当範囲内で片っ端からHP計算を行い、ゲーム画面に出ているHPと合致すれば、それが正解となる。
しかし、複数の正解が出ることも考えられるので、これらは正解候補となる。

CPも同じように計算を行うが、既にHP計算でレベル候補が絞られているので、その分だけで済む。
ゲーム画面に出ているCPと合致すれば、やはりこれも、正解候補となる。

正解候補をテーブルにして表示すれば、捕まえたポケモンの個体値の目安となる。
チームリーダーによる評価がわかれば、更に正解候補を絞り込むことができる。

ここまで来れば、後はプログラムに落とし込むだけです。

おそらく、このプログラムの難しさは、種族値テーブルの更新だと思います。
Niantic社の変更を随時、追跡しなければならないことです。

実行サンプルはこちら

Chrome, FF で動作確認しています。
以下はソースコードです。index.htmlの1本です。


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>poke5 個体値計算ツール</title>
<style>
* {
	margin:0;
	padding: 0;
}
body {
	padding:5px;
	background:#ace url(kinkoi.jpg);
}
#namediv input {
	width:70px;
	height:25px;
	font-size:12px;
}
input.pk_inp {
	display:block;
	margin:2px 10px 2px 0;
	padding: 2px;
}
form.hyouka input {
	margin:2px 2px 2px 20px;
	padding: 2px;
}
span.inp_lavel {
	display:block;
	width:60px;
	float:left;
	clear:both;
}
select {
	margin:5px;
	padding: 2px;
}
table {
	margin:5px;
	padding: 2px;
}
td {
	width:100px;
	text-align:center;
}
</style>

<script type="text/javascript">

var mltbl = [
// ポケモンレベルに関するテーブル
//  ml:    ポケモンレベル
//  perc:  レベル40に対する割合
//  c:     CP補正値
//  sand:  強化に必要な砂
//  candy: 強化に必要な飴
{ml:1,perc:1.414724036,c:0.094,sand:0,candy:0},
{ml:1.5,perc:2.923932542,c:0.1351374,sand:200,candy:1},
{ml:2,perc:4.433141061,c:0.1663979,sand:200,candy:1},
{ml:2.5,perc:5.942349554,c:0.1926509,sand:200,candy:1},
{ml:3,perc:7.451557498,c:0.2157325,sand:200,candy:1},
{ml:3.5,perc:8.960765971,c:0.2365727,sand:400,candy:1},
{ml:4,perc:10.4699736,c:0.2557201,sand:400,candy:1},
{ml:4.5,perc:11.97918208,c:0.2735304,sand:400,candy:1},
{ml:5,perc:13.48839026,c:0.2902499,sand:400,candy:1},
{ml:5.5,perc:14.99759871,c:0.3060574,sand:600,candy:1},
{ml:6,perc:16.50680775,c:0.3210876,sand:600,candy:1},
{ml:6.5,perc:18.01601622,c:0.335445,sand:600,candy:1},
{ml:7,perc:19.52522443,c:0.3492127,sand:600,candy:1},
{ml:7.5,perc:21.03443291,c:0.3624578,sand:800,candy:1},
{ml:8,perc:22.54364161,c:0.3752356,sand:800,candy:1},
{ml:8.5,perc:24.05285006,c:0.3875924,sand:800,candy:1},
{ml:9,perc:25.56206057,c:0.3995673,sand:800,candy:1},
{ml:9.5,perc:27.07126902,c:0.4111936,sand:1000,candy:1},
{ml:10,perc:28.58047697,c:0.4225,sand:1000,candy:1},
{ml:10.5,perc:30.00849419,c:0.4335117,sand:1000,candy:1},
{ml:11,perc:31.43650994,c:0.4431076,sand:1000,candy:1},
{ml:11.5,perc:32.86452696,c:0.45306,sand:1300,candy:2},
{ml:12,perc:34.29254396,c:0.4627984,sand:1300,candy:2},
{ml:12.5,perc:35.72056114,c:0.4723361,sand:1300,candy:2},
{ml:13,perc:37.14857675,c:0.481685,sand:1300,candy:2},
{ml:13.5,perc:38.5765939,c:0.4908558,sand:1600,candy:2},
{ml:14,perc:40.00461398,c:0.4998584,sand:1600,candy:2},
{ml:14.5,perc:41.43263118,c:0.5087018,sand:1600,candy:2},
{ml:15,perc:42.86064648,c:0.517394,sand:1600,candy:2},
{ml:15.5,perc:44.28866364,c:0.5259425,sand:1900,candy:2},
{ml:16,perc:45.71668075,c:0.5343543,sand:1900,candy:2},
{ml:16.5,perc:47.14469795,c:0.5426358,sand:1900,candy:2},
{ml:17,perc:48.57271292,c:0.5507927,sand:1900,candy:2},
{ml:17.5,perc:50.00073006,c:0.5588306,sand:2200,candy:2},
{ml:18,perc:51.42875488,c:0.5667545,sand:2200,candy:2},
{ml:18.5,perc:52.85677208,c:0.5745692,sand:2200,candy:2},
{ml:19,perc:54.28478797,c:0.5822789,sand:2200,candy:2},
{ml:19.5,perc:55.71280516,c:0.5898879,sand:2500,candy:2},
{ml:20,perc:57.14082102,c:0.5974,sand:2500,candy:2},
{ml:20.5,perc:58.56883825,c:0.6048188,sand:2500,candy:2},
{ml:21,perc:59.99873261,c:0.6121573,sand:2500,candy:2},
{ml:21.5,perc:61.42674981,c:0.6194041,sand:3000,candy:3},
{ml:22,perc:62.8566514,c:0.6265671,sand:3000,candy:3},
{ml:22.5,perc:64.28466862,c:0.6336492,sand:3000,candy:3},
{ml:23,perc:65.7145723,c:0.640653,sand:3000,candy:3},
{ml:23.5,perc:67.14258943,c:0.647581,sand:3500,candy:3},
{ml:24,perc:68.57248641,c:0.6544356,sand:3500,candy:3},
{ml:24.5,perc:70.00050364,c:0.6612193,sand:3500,candy:3},
{ml:25,perc:71.43040741,c:0.667934,sand:3500,candy:3},
{ml:25.5,perc:72.85842452,c:0.6745819,sand:4000,candy:4},
{ml:26,perc:74.28832607,c:0.6811649,sand:4000,candy:4},
{ml:26.5,perc:75.71634322,c:0.6876849,sand:4000,candy:4},
{ml:27,perc:77.14623491,c:0.6941437,sand:4000,candy:4},
{ml:27.5,perc:78.57425209,c:0.7005429,sand:4500,candy:4},
{ml:28,perc:80.00416311,c:0.7068842,sand:4500,candy:4},
{ml:28.5,perc:81.43218023,c:0.7131691,sand:4500,candy:4},
{ml:29,perc:82.86207287,c:0.7193991,sand:4500,candy:4},
{ml:29.5,perc:84.29009019,c:0.7255756,sand:5000,candy:4},
{ml:30,perc:85.71999464,c:0.7317,sand:5000,candy:4},
{ml:30.5,perc:86.43399483,c:0.734741,sand:5000,candy:4},
{ml:31,perc:87.14799422,c:0.7377695,sand:5000,candy:4},
{ml:31.5,perc:87.86199453,c:0.7407856,sand:6000,candy:6},
{ml:32,perc:88.57599299,c:0.7437894,sand:6000,candy:6},
{ml:32.5,perc:89.28999328,c:0.7467812,sand:6000,candy:6},
{ml:33,perc:90.00399022,c:0.749761,sand:6000,candy:6},
{ml:33.5,perc:90.71799057,c:0.7527291,sand:7000,candy:8},
{ml:34,perc:91.43199898,c:0.7556855,sand:7000,candy:8},
{ml:34.5,perc:92.14599918,c:0.7586304,sand:7000,candy:8},
{ml:35,perc:92.85999484,c:0.7615638,sand:7000,candy:8},
{ml:35.5,perc:93.57399517,c:0.7644861,sand:8000,candy:10},
{ml:36,perc:94.28799738,c:0.7673972,sand:8000,candy:10},
{ml:36.5,perc:95.00199776,c:0.7702973,sand:8000,candy:10},
{ml:37,perc:95.71600203,c:0.7731865,sand:8000,candy:10},
{ml:37.5,perc:96.43000241,c:0.776065,sand:9000,candy:12},
{ml:38,perc:97.14399355,c:0.7789328,sand:9000,candy:12},
{ml:38.5,perc:97.85799386,c:0.7817901,sand:9000,candy:12},
{ml:39,perc:98.57199794,c:0.784637,sand:9000,candy:12},
{ml:39.5,perc:99.2859983,c:0.7874736,sand:10000,candy:15},
{ml:40,perc:100,c:0.7903,sand:10000,candy:15}
];

var pktbl = [
// 種族値テーブル
//  no:    ポケモン番号
//  name:  名前
//  maxcp: 最大CP(Lv=40)
//  atk:   種族値 攻撃
//  def:   種族値 防御
//  hp:    種族値 体力
{no:1,name:"フシギダネ",maxcp:981,atk:118,def:118,hp:90},
{no:2,name:"フシギソウ",maxcp:1552,atk:151,def:151,hp:120},
{no:3,name:"フシギバナ",maxcp:2568,atk:198,def:198,hp:160},
{no:4,name:"ヒトカゲ",maxcp:831,atk:116,def:96,hp:78},
{no:5,name:"リザード",maxcp:1484,atk:158,def:129,hp:116},
{no:6,name:"リザードン",maxcp:2686,atk:223,def:176,hp:156},
{no:7,name:"ゼニガメ",maxcp:808,atk:94,def:122,hp:88},
{no:8,name:"カメール",maxcp:1324,atk:126,def:155,hp:118},
{no:9,name:"カメックス",maxcp:2291,atk:171,def:210,hp:158},
{no:10,name:"キャタピー",maxcp:393,atk:55,def:62,hp:90},
{no:11,name:"トランセル",maxcp:419,atk:45,def:94,hp:100},
{no:12,name:"バタフリー",maxcp:1701,atk:167,def:151,hp:120},
{no:13,name:"ビードル",maxcp:397,atk:63,def:55,hp:80},
{no:14,name:"コクーン",maxcp:392,atk:46,def:86,hp:90},
{no:15,name:"スピアー",maxcp:1777,atk:169,def:150,hp:130},
{no:16,name:"ポッポ",maxcp:580,atk:85,def:76,hp:80},
{no:17,name:"ピジョン",maxcp:1085,atk:117,def:108,hp:126},
{no:18,name:"ピジョット",maxcp:1994,atk:166,def:157,hp:166},
{no:19,name:"コラッタ",maxcp:588,atk:103,def:70,hp:60},
{no:20,name:"ラッタ",maxcp:1549,atk:161,def:144,hp:110},
{no:21,name:"オニスズメ",maxcp:673,atk:112,def:61,hp:80},
{no:22,name:"オニドリル",maxcp:1814,atk:182,def:135,hp:130},
{no:23,name:"アーボ",maxcp:778,atk:110,def:102,hp:70},
{no:24,name:"アーボック",maxcp:1737,atk:167,def:158,hp:120},
{no:25,name:"ピカチュウ",maxcp:787,atk:112,def:101,hp:70},
{no:26,name:"ライチュウ",maxcp:2025,atk:193,def:165,hp:120},
{no:27,name:"サンド",maxcp:1194,atk:126,def:145,hp:100},
{no:28,name:"サンドパン",maxcp:2328,atk:182,def:202,hp:150},
{no:29,name:"ニドラン♀",maxcp:736,atk:86,def:94,hp:110},
{no:30,name:"ニドリーナ",maxcp:1218,atk:117,def:126,hp:140},
{no:31,name:"ニドクイン",maxcp:2338,atk:180,def:174,hp:180},
{no:32,name:"ニドラン♂",maxcp:739,atk:105,def:76,hp:92},
{no:33,name:"ニドリーノ",maxcp:1252,atk:137,def:112,hp:122},
{no:34,name:"ニドキング",maxcp:2386,atk:204,def:157,hp:162},
{no:35,name:"ピッピ",maxcp:1085,atk:107,def:116,hp:140},
{no:36,name:"ピクシー",maxcp:2353,atk:178,def:171,hp:190},
{no:37,name:"ロコン",maxcp:774,atk:96,def:122,hp:76},
{no:38,name:"キュウコン",maxcp:2157,atk:169,def:204,hp:146},
{no:39,name:"プリン",maxcp:713,atk:80,def:44,hp:230},
{no:40,name:"プクリン",maxcp:1906,atk:156,def:93,hp:280},
{no:41,name:"ズバット",maxcp:569,atk:83,def:76,hp:80},
{no:42,name:"ゴルバット",maxcp:1830,atk:161,def:153,hp:150},
{no:43,name:"ナゾノクサ",maxcp:1069,atk:131,def:116,hp:90},
{no:44,name:"クサイハナ",maxcp:1512,atk:153,def:139,hp:120},
{no:45,name:"ラフレシア",maxcp:2367,atk:202,def:170,hp:150},
{no:46,name:"パラス",maxcp:836,atk:121,def:99,hp:70},
{no:47,name:"パラセクト",maxcp:1657,atk:165,def:146,hp:120},
{no:48,name:"コンパン",maxcp:902,atk:100,def:102,hp:120},
{no:49,name:"モルフォン",maxcp:1937,atk:179,def:150,hp:140},
{no:50,name:"ディグダ",maxcp:465,atk:109,def:88,hp:20},
{no:51,name:"ダグトリオ",maxcp:1333,atk:167,def:147,hp:70},
{no:52,name:"ニャース",maxcp:638,atk:92,def:81,hp:80},
{no:53,name:"ペルシアン",maxcp:1539,atk:150,def:139,hp:130},
{no:54,name:"コダック",maxcp:966,atk:122,def:96,hp:100},
{no:55,name:"ゴルダック",maxcp:2270,atk:191,def:163,hp:160},
{no:56,name:"マンキー",maxcp:1002,atk:148,def:87,hp:80},
{no:57,name:"オコリザル",maxcp:2105,atk:207,def:144,hp:130},
{no:58,name:"ガーディ",maxcp:1110,atk:136,def:96,hp:110},
{no:59,name:"ウインディ",maxcp:2839,atk:227,def:166,hp:180},
{no:60,name:"ニョロモ",maxcp:695,atk:101,def:82,hp:80},
{no:61,name:"ニョロゾ",maxcp:1313,atk:130,def:130,hp:130},
{no:62,name:"ニョロボン",maxcp:2441,atk:182,def:187,hp:180},
{no:63,name:"ケーシィ",maxcp:1148,atk:195,def:103,hp:50},
{no:64,name:"ユンゲラー",maxcp:1859,atk:232,def:138,hp:80},
{no:65,name:"フーディン",maxcp:2887,atk:271,def:194,hp:110},
{no:66,name:"ワンリキー",maxcp:1199,atk:137,def:88,hp:140},
{no:67,name:"ゴーリキー",maxcp:1910,atk:177,def:130,hp:160},
{no:68,name:"カイリキー",maxcp:2889,atk:234,def:162,hp:180},
{no:69,name:"マダツボミ",maxcp:916,atk:139,def:64,hp:100},
{no:70,name:"ウツドン",maxcp:1475,atk:172,def:95,hp:130},
{no:71,name:"ウツボット",maxcp:2268,atk:207,def:138,hp:160},
{no:72,name:"メノクラゲ",maxcp:956,atk:97,def:182,hp:80},
{no:73,name:"ドククラゲ",maxcp:2374,atk:166,def:237,hp:160},
{no:74,name:"イシツブテ",maxcp:1193,atk:132,def:163,hp:80},
{no:75,name:"ゴローン",maxcp:1815,atk:164,def:196,hp:110},
{no:76,name:"ゴローニャ",maxcp:2916,atk:211,def:229,hp:160},
{no:77,name:"ポニータ",maxcp:1502,atk:170,def:132,hp:100},
{no:78,name:"ギャロップ",maxcp:2252,atk:207,def:167,hp:130},
{no:79,name:"ヤドン",maxcp:1204,atk:109,def:109,hp:180},
{no:80,name:"ヤドラン",maxcp:2482,atk:177,def:194,hp:190},
{no:81,name:"コイル",maxcp:1083,atk:165,def:128,hp:50},
{no:82,name:"レアコイル",maxcp:2237,atk:223,def:182,hp:100},
{no:83,name:"カモネギ",maxcp:1092,atk:124,def:118,hp:104},
{no:84,name:"ドードー",maxcp:1011,atk:158,def:88,hp:70},
{no:85,name:"ドードリオ",maxcp:2138,atk:218,def:145,hp:120},
{no:86,name:"パウワウ",maxcp:899,atk:85,def:128,hp:130},
{no:87,name:"ジュゴン",maxcp:1894,atk:139,def:184,hp:180},
{no:88,name:"ベトベター",maxcp:1269,atk:135,def:90,hp:160},
{no:89,name:"ベトベトン",maxcp:2709,atk:190,def:184,hp:210},
{no:90,name:"シェルダー",maxcp:958,atk:116,def:168,hp:60},
{no:91,name:"パルシェン",maxcp:2475,atk:186,def:323,hp:100},
{no:92,name:"ゴース",maxcp:1002,atk:186,def:70,hp:60},
{no:93,name:"ゴースト",maxcp:1716,atk:223,def:112,hp:90},
{no:94,name:"ゲンガー",maxcp:2619,atk:261,def:156,hp:120},
{no:95,name:"イワーク",maxcp:1002,atk:85,def:288,hp:70},
{no:96,name:"スリープ",maxcp:992,atk:89,def:158,hp:120},
{no:97,name:"スリーパー",maxcp:2048,atk:144,def:215,hp:170},
{no:98,name:"クラブ",maxcp:1386,atk:181,def:156,hp:60},
{no:99,name:"キングラー",maxcp:2694,atk:240,def:214,hp:110},
{no:100,name:"ビリリダマ",maxcp:857,atk:109,def:114,hp:80},
{no:101,name:"マルマイン",maxcp:1900,atk:173,def:179,hp:120},
{no:102,name:"タマタマ",maxcp:1102,atk:107,def:140,hp:120},
{no:103,name:"ナッシー",maxcp:2916,atk:233,def:158,hp:190},
{no:104,name:"カラカラ",maxcp:943,atk:90,def:165,hp:100},
{no:105,name:"ガラガラ",maxcp:1691,atk:144,def:200,hp:120},
{no:106,name:"サワムラー",maxcp:2406,atk:224,def:211,hp:100},
{no:107,name:"エビワラー",maxcp:2098,atk:193,def:212,hp:100},
{no:108,name:"ベロリンガ",maxcp:1322,atk:108,def:137,hp:180},
{no:109,name:"ドガース",maxcp:1091,atk:119,def:164,hp:80},
{no:110,name:"マタドガス",maxcp:2183,atk:174,def:221,hp:130},
{no:111,name:"サイホーン",maxcp:1679,atk:140,def:157,hp:160},
{no:112,name:"サイドン",maxcp:3300,atk:222,def:206,hp:210},
{no:113,name:"ラッキー",maxcp:1469,atk:60,def:176,hp:500},
{no:114,name:"モンジャラ",maxcp:2208,atk:183,def:205,hp:130},
{no:115,name:"ガルーラ",maxcp:2463,atk:181,def:165,hp:210},
{no:116,name:"タッツー",maxcp:921,atk:129,def:125,hp:60},
{no:117,name:"シードラ",maxcp:1979,atk:187,def:182,hp:110},
{no:118,name:"トサキント",maxcp:1006,atk:123,def:115,hp:90},
{no:119,name:"アズマオウ",maxcp:2040,atk:175,def:154,hp:160},
{no:120,name:"ヒトデマン",maxcp:926,atk:137,def:112,hp:60},
{no:121,name:"スターミー",maxcp:2303,atk:210,def:184,hp:120},
{no:122,name:"バリヤード",maxcp:1984,atk:192,def:233,hp:80},
{no:123,name:"ストライク",maxcp:2464,atk:218,def:170,hp:140},
{no:124,name:"ルージュラ",maxcp:2512,atk:223,def:182,hp:130},
{no:125,name:"エレブー",maxcp:2196,atk:198,def:173,hp:130},
{no:126,name:"ブーバー",maxcp:2254,atk:206,def:169,hp:130},
{no:127,name:"カイロス",maxcp:2770,atk:238,def:197,hp:130},
{no:128,name:"ケンタロス",maxcp:2488,atk:198,def:197,hp:150},
{no:129,name:"コイキング",maxcp:220,atk:29,def:102,hp:40},
{no:130,name:"ギャラドス",maxcp:3281,atk:237,def:197,hp:190},
{no:131,name:"ラプラス",maxcp:2603,atk:165,def:180,hp:260},
{no:132,name:"メタモン",maxcp:718,atk:91,def:91,hp:96},
{no:133,name:"イーブイ",maxcp:969,atk:104,def:121,hp:110},
{no:134,name:"シャワーズ",maxcp:3157,atk:205,def:177,hp:260},
{no:135,name:"サンダース",maxcp:2730,atk:232,def:201,hp:130},
{no:136,name:"ブースター",maxcp:2904,atk:246,def:204,hp:130},
{no:137,name:"ポリゴン",maxcp:1567,atk:153,def:139,hp:130},
{no:138,name:"オムナイト",maxcp:1345,atk:155,def:174,hp:70},
{no:139,name:"オムスター",maxcp:2685,atk:207,def:227,hp:140},
{no:140,name:"カブト",maxcp:1172,atk:148,def:162,hp:60},
{no:141,name:"カブトプス",maxcp:2517,atk:220,def:203,hp:120},
{no:142,name:"プテラ",maxcp:2608,atk:221,def:164,hp:160},
{no:143,name:"カビゴン",maxcp:3355,atk:190,def:190,hp:320},
{no:144,name:"フリーザー",maxcp:2933,atk:192,def:249,hp:180},
{no:145,name:"サンダー",maxcp:3330,atk:253,def:188,hp:180},
{no:146,name:"ファイヤー",maxcp:3272,atk:251,def:184,hp:180},
{no:147,name:"ミニリュウ",maxcp:860,atk:119,def:94,hp:82},
{no:148,name:"ハクリュー",maxcp:1609,atk:163,def:138,hp:122},
{no:149,name:"カイリュー",maxcp:3581,atk:263,def:201,hp:182},
{no:150,name:"ミュウツー",maxcp:4760,atk:330,def:200,hp:212},
{no:151,name:"ミュウ",maxcp:3090,atk:210,def:209,hp:200},
{no:152,name:"チコリータ",maxcp:801,atk:92,def:122,hp:90},
{no:153,name:"ベイリーフ",maxcp:1296,atk:122,def:155,hp:120},
{no:154,name:"メガニウム",maxcp:2227,atk:168,def:202,hp:160},
{no:155,name:"ヒノアラシ",maxcp:831,atk:116,def:96,hp:78},
{no:156,name:"マグマラシ",maxcp:1484,atk:158,def:129,hp:116},
{no:157,name:"バクフーン",maxcp:2686,atk:223,def:176,hp:156},
{no:158,name:"ワニノコ",maxcp:1011,atk:117,def:116,hp:100},
{no:159,name:"アリゲイツ",maxcp:1598,atk:150,def:151,hp:130},
{no:160,name:"オーダイル",maxcp:2721,atk:205,def:197,hp:170},
{no:161,name:"オタチ",maxcp:519,atk:79,def:77,hp:70},
{no:162,name:"オオタチ",maxcp:1667,atk:148,def:130,hp:170},
{no:163,name:"ホーホー",maxcp:640,atk:67,def:101,hp:120},
{no:164,name:"ヨルノズク",maxcp:2040,atk:145,def:179,hp:200},
{no:165,name:"レディバ",maxcp:663,atk:72,def:142,hp:80},
{no:166,name:"レディアン",maxcp:1275,atk:107,def:209,hp:110},
{no:167,name:"イトマル",maxcp:685,atk:105,def:73,hp:80},
{no:168,name:"アリアドス",maxcp:1636,atk:161,def:128,hp:140},
{no:169,name:"クロバット",maxcp:2466,atk:194,def:178,hp:170},
{no:170,name:"チョンチー",maxcp:1067,atk:106,def:106,hp:150},
{no:171,name:"ランターン",maxcp:2077,atk:146,def:146,hp:250},
{no:172,name:"ピチュー",maxcp:376,atk:77,def:63,hp:40},
{no:173,name:"ピィ",maxcp:620,atk:75,def:91,hp:100},
{no:174,name:"ププリン",maxcp:512,atk:69,def:34,hp:180},
{no:175,name:"トゲピー",maxcp:540,atk:67,def:116,hp:70},
{no:176,name:"トゲチック",maxcp:1543,atk:139,def:191,hp:110},
{no:177,name:"ネイティ",maxcp:925,atk:134,def:89,hp:80},
{no:178,name:"ネイティオ",maxcp:1975,atk:192,def:146,hp:130},
{no:179,name:"メリープ",maxcp:887,atk:114,def:82,hp:110},
{no:180,name:"モココ",maxcp:1402,atk:145,def:112,hp:140},
{no:181,name:"デンリュウ",maxcp:2695,atk:211,def:172,hp:180},
{no:182,name:"キレイハナ",maxcp:2108,atk:169,def:189,hp:150},
{no:183,name:"マリル",maxcp:420,atk:37,def:93,hp:140},
{no:184,name:"マリルリ",maxcp:1503,atk:112,def:152,hp:200},
{no:185,name:"ウソッキー",maxcp:2065,atk:167,def:198,hp:140},
{no:186,name:"ニョロトノ",maxcp:2371,atk:174,def:192,hp:180},
{no:187,name:"ハネッコ",maxcp:508,atk:67,def:101,hp:70},
{no:188,name:"ポポッコ",maxcp:882,atk:91,def:127,hp:110},
{no:189,name:"ワタッコ",maxcp:1553,atk:118,def:197,hp:150},
{no:190,name:"エイパム",maxcp:1188,atk:136,def:112,hp:110},
{no:191,name:"ヒマナッツ",maxcp:316,atk:55,def:55,hp:60},
{no:192,name:"キマワリ",maxcp:2048,atk:185,def:148,hp:150},
{no:193,name:"ヤンヤンマ",maxcp:1326,atk:154,def:94,hp:130},
{no:194,name:"ウパー",maxcp:596,atk:75,def:75,hp:110},
{no:195,name:"ヌオー",maxcp:1929,atk:152,def:152,hp:190},
{no:196,name:"エーフィ",maxcp:3000,atk:261,def:194,hp:130},
{no:197,name:"ブラッキー",maxcp:2052,atk:126,def:250,hp:190},
{no:198,name:"ヤミカラス",maxcp:1392,atk:175,def:87,hp:120},
{no:199,name:"ヤドキング",maxcp:2482,atk:177,def:194,hp:190},
{no:200,name:"ムウマ",maxcp:1781,atk:167,def:167,hp:120},
{no:201,name:"アンノーン",maxcp:1022,atk:136,def:91,hp:96},
{no:202,name:"ソーナンス",maxcp:1024,atk:60,def:106,hp:380},
{no:203,name:"キリンリキ",maxcp:1863,atk:182,def:133,hp:140},
{no:204,name:"クヌギダマ",maxcp:1045,atk:108,def:146,hp:100},
{no:205,name:"フォレトス",maxcp:2263,atk:161,def:242,hp:150},
{no:206,name:"ノコッチ",maxcp:1615,atk:131,def:131,hp:200},
{no:207,name:"グライガー",maxcp:1758,atk:143,def:204,hp:130},
{no:208,name:"ハガネール",maxcp:2439,atk:148,def:333,hp:150},
{no:209,name:"ブルー",maxcp:1124,atk:137,def:89,hp:120},
{no:210,name:"グランブル",maxcp:2440,atk:212,def:137,hp:180},
{no:211,name:"ハリーセン",maxcp:1910,atk:184,def:148,hp:130},
{no:212,name:"ハッサム",maxcp:2801,atk:236,def:191,hp:140},
{no:213,name:"ツボツボ",maxcp:300,atk:17,def:396,hp:40},
{no:214,name:"ヘラクロス",maxcp:2938,atk:234,def:189,hp:160},
{no:215,name:"ニューラ",maxcp:1868,atk:189,def:157,hp:110},
{no:216,name:"ヒメグマ",maxcp:1184,atk:142,def:93,hp:120},
{no:217,name:"リングマ",maxcp:2760,atk:236,def:144,hp:180},
{no:218,name:"マグマッグ",maxcp:750,atk:118,def:71,hp:80},
{no:219,name:"マグカルゴ",maxcp:1543,atk:139,def:209,hp:100},
{no:220,name:"ウリムー",maxcp:663,atk:90,def:74,hp:100},
{no:221,name:"イノムー",maxcp:2284,atk:181,def:147,hp:200},
{no:222,name:"サニーゴ",maxcp:1214,atk:118,def:156,hp:110},
{no:223,name:"テッポウオ",maxcp:749,atk:127,def:69,hp:70},
{no:224,name:"オクタン",maxcp:2124,atk:197,def:141,hp:150},
{no:225,name:"デリバード",maxcp:937,atk:128,def:90,hp:90},
{no:226,name:"マンタイン",maxcp:2032,atk:148,def:260,hp:130},
{no:227,name:"エアームド",maxcp:2032,atk:148,def:260,hp:130},
{no:228,name:"デルビル",maxcp:1110,atk:152,def:93,hp:90},
{no:229,name:"ヘルガー",maxcp:2529,atk:224,def:159,hp:150},
{no:230,name:"キングドラ",maxcp:2424,atk:194,def:194,hp:150},
{no:231,name:"ゴマゾウ",maxcp:1175,atk:107,def:107,hp:180},
{no:232,name:"ドンファン",maxcp:3022,atk:214,def:214,hp:180},
{no:233,name:"ポリゴン2",maxcp:2546,atk:198,def:183,hp:170},
{no:234,name:"オドシシ",maxcp:1988,atk:192,def:132,hp:146},
{no:235,name:"ドーブル",maxcp:389,atk:40,def:88,hp:110},
{no:236,name:"バルキー",maxcp:404,atk:64,def:64,hp:70},
{no:237,name:"カポエラー",maxcp:1905,atk:173,def:214,hp:100},
{no:238,name:"ムチュール",maxcp:1230,atk:153,def:116,hp:90},
{no:239,name:"エレキッド",maxcp:1073,atk:135,def:110,hp:90},
{no:240,name:"ブビィ",maxcp:1178,atk:151,def:108,hp:90},
{no:241,name:"ミルタンク",maxcp:2312,atk:157,def:211,hp:190},
{no:242,name:"ハピナス",maxcp:3219,atk:129,def:229,hp:510},
{no:243,name:"ライコウ",maxcp:3349,atk:241,def:210,hp:180},
{no:244,name:"エンテイ",maxcp:3377,atk:235,def:176,hp:230},
{no:245,name:"スイクン",maxcp:2823,atk:180,def:235,hp:200},
{no:246,name:"ヨーギラス",maxcp:904,atk:115,def:93,hp:100},
{no:247,name:"サナギラス",maxcp:1608,atk:155,def:133,hp:140},
{no:248,name:"バンギラス",maxcp:3670,atk:251,def:212,hp:200},
{no:249,name:"ルギア",maxcp:3598,atk:193,def:323,hp:212},
{no:250,name:"ホウオウ",maxcp:4650,atk:263,def:301,hp:212},
{no:251,name:"セレビィ",maxcp:3090,atk:210,def:210,hp:200},
];

// ポケモン名ボタンを、番号順または名前順に並べて表示
var changetbl = function(mode){
	var len = pktbl.length;
	var div = document.getElementById("namediv");
	while (div.firstChild){
		div.removeChild(div.firstChild);
	}

	if (mode == 0){
		pktbl.sort(function(a,b){
			if (a.no > b.no) return 1;
			if (a.no < b.no) return -1;
			return 0;
		});
	}else if (mode == 1){
		pktbl.sort(function(a,b){
			if (a.name > b.name) return 1;
			if (a.name < b.name) return -1;
			return 0;
		});
	}

	for (var i=0; i<len; i++){
		var inp = document.createElement("input");
		inp.type = "button";
		inp.value = pktbl[i].name;
		if (pktbl[i].no < 152){
			inp.style.backgroundColor = "#8ca";
		}else{
			inp.style.backgroundColor = "#c8a";
		}
		inp.onclick = function(e){setname(this.value);};
		div.appendChild(inp);
	}
};

// 入力内容のクリア
var clearinp = function(mode){
	var elm = null;
	if (mode){
		elm = document.getElementById("pkname");
		elm.value = "";
		elm = document.getElementById("pk_cp");
		elm.value = "";
		elm = document.getElementById("pk_hp");
		elm.value = "";
		elm = document.getElementById("selsand");
		elm.selectedIndex = 0;
	}

	elm = document.getElementById("pk_choice1_1");
	elm.checked = false;
	elm = document.getElementById("pk_choice1_2");
	elm.checked = false;
	elm = document.getElementById("pk_choice1_3");
	elm.checked = false;
	elm = document.getElementById("pk_choice1_4");
	elm.checked = false;
	elm = document.getElementById("pk_choice2_1");
	elm.checked = false;
	elm = document.getElementById("pk_choice2_2");
	elm.checked = false;
	elm = document.getElementById("pk_choice2_3");
	elm.checked = false;
	elm = document.getElementById("pk_choice2_4");
	elm.checked = false;
	elm = document.getElementById("pk_choice3_1");
	elm.checked = false;
	elm = document.getElementById("pk_choice3_2");
	elm.checked = false;
	elm = document.getElementById("pk_choice3_3");
	elm.checked = false;

	elm = document.getElementById("answer");
	while (elm.firstChild){
		elm.removeChild(elm.firstChild);
	}
};

// 初期処理
var init = function(){
	changetbl(0);
};

// ポケモンボタンが押されたとき呼ばれる
var setname = function(name){
	var inp = document.getElementById("pkname");
	inp.value = name;
	inp = document.getElementById("pk_cp");
	inp.focus();
};

// 入力チェック
var precheck = function(cp, hp, sand){
	var str = "該当なし";
	var n = pktbl.length;
	var inp = document.getElementById("pkname");
	var pid = -1;
	for (var i=0; i<n; i++){
		if (inp.value == pktbl[i].name){
			pid = i;
			break;
		}
	}

	if (pid < 0){
		str = "ポケモンを選択して下さい。"
	}else{
		if (!sand){
			str = "強化に必要な星の砂を選択して下さい。"
			pid = -1;
		}
		if (!hp){
			str = "HPを半角数字で入力して下さい。"
			pid = -1;
		}
		if (!cp){
			str = "CPを半角数字で入力して下さい。"
			pid = -1;
		}
	}

	return {pid:pid, str:str};
};

// CP計算
var cpcalc = function(p_atk, p_def, p_hp, m_atk, m_def, m_hp, m_c){
	return parseInt((p_atk+m_atk)*Math.sqrt(p_def+m_def)*Math.sqrt(p_hp+m_hp)*m_c*m_c/10.0);
};

// 計算処理メイン
var calcmain = function(pid, cp, hp, sand, k1, k2, k2f, ares){
	var atk_range = {min:0, max:15}; // 攻撃レンジ 枝刈
	var def_range = {min:0, max:15}; // 防御レンジ 枝刈
	var hp_range = {min:0, max:15};  // 体力レンジ 枝刈

	var kotai1 = [ // チームリーダー第一評価
		{min:37, max:45},
		{min:30, max:36},
		{min:23, max:29},
		{min:0, max:22}
	];
	var kotai2 = [ // チームリーダー第二評価
		{min:15, max:15},
		{min:13, max:14},
		{min:8, max:12},
		{min:0, max:7}
	];

	var m = mltbl.length;
	var ahp = [];
	var batk = parseInt(pktbl[pid].atk); // 種族値 攻撃
	var bdef = parseInt(pktbl[pid].def); // 種族値 防御
	var bhp = parseInt(pktbl[pid].hp);   // 種族値 体力

	if (k2){
		if (k2f & 1){ // 第二評価 攻撃ON
			atk_range = kotai2[k2-1];
			def_range.max = kotai2[k2-1].max;
			hp_range.max = kotai2[k2-1].max;
		}
		if (k2f & 2){ // 第二評価 防御ON
			def_range = kotai2[k2-1];
			atk_range.max = kotai2[k2-1].max;
			hp_range.max = kotai2[k2-1].max;
		}
		if (k2f & 4){ // 第二評価 体力ON
			hp_range = kotai2[k2-1];
			atk_range.max = kotai2[k2-1].max;
			def_range.max = kotai2[k2-1].max;
		}
	}

	// 与えられたパラメータに合致するHPとポケモンレベルのペア一覧を取得 枝刈
	for (var i=hp_range.min; i<=hp_range.max; i++){
		for (var j=0; j<m-1; j++){
			if (mltbl[j+1].sand == sand){
				var thp = parseInt((bhp+i) * mltbl[j].c);
				if (thp == hp){
					ahp.push({hp:i, mli:j});
				}
			}
		}
	}

	for (var i=0; i<ahp.length; i++){ // HPループ
		var mlt = mltbl[ahp[i].mli];
		for (var j=atk_range.min; j<=atk_range.max; j++){ // 攻撃ループ
			for (var k=def_range.min; k<=def_range.max; k++){ // 防御ループ
				// CP計算
				var t = cpcalc(j,k,ahp[i].hp, batk,bdef,bhp, mlt.c);
				if (t == cp){ // CP一致
					var h = ahp[i].hp; // j:攻撃, k:防御, h:体力
					var tot = j+k+h;
					if (k1){
						// 合計が第一評価を満たすか
						if (tot < kotai1[k1-1].min || kotai1[k1-1].max < tot){
							continue;
						}
					}
					if (k2){
						// 攻撃が第2評価範囲を満たしているか
						if (j < atk_range.min || atk_range.max < j){
							continue;
						}
						// 防御が第2評価範囲を満たしているか
						if (k < def_range.min || def_range.max < k){
							continue;
						}
						// 体力が第2評価範囲を満たしているか
						if (h < hp_range.min || hp_range.max < h){
							continue;
						}
						// 攻撃のみチェックの時、攻撃 > 防御,体力であること
						if (k2f == 1 && (j <= k || j <= h)){
							continue;
						}
						// 防御のみチェックの時、防御 > 攻撃,体力であること
						if (k2f == 2 && (k <= j || k <= h)){
							continue;
						}
						// 体力のみチェックの時、体力 > 攻撃,防御であること
						if (k2f == 4 && (h <= j || h <= k)){
							continue;
						}
						// 攻撃/防御チェックの時、攻撃=防御かつ、攻撃>体力であること
						if (k2f == 3 && (j != k || j <= h)){
							continue;
						}
						// 攻撃/体力チェックの時、攻撃=体力かつ、攻撃>防御であること
						if (k2f == 5 && (j != h || j <= k)){
							continue;
						}
						// 防御/体力チェックの時、防御=体力かつ、防御>攻撃であること
						if (k2f == 6 && (k != h || k <= j)){
							continue;
						}
						// 攻撃/防御/体力チェックの時、攻撃=防御=体力であること
						if (k2f == 7 && (j != k || j != h)){
							continue;
						}
					}
					// 配列に追加, {%, レベル, 攻撃, 防御, HP}
					ares.push({per:tot/45, ml:mlt.ml, atk:j, def:k, hp:h});
				}
			}
		}
	}
};

// 計算ボタンが押されたとき呼ばれる
var calc = function(){
	var cp = parseInt(document.getElementById("pk_cp").value);
	var hp = parseInt(document.getElementById("pk_hp").value);
	var sel = document.getElementById("selsand");
	var sand = parseInt( sel.options[sel.selectedIndex].value);
	var pchk = precheck(cp, hp, sand); // 入力チェック
	var ares = [];
	var answerstr = pchk.str;
	var div = document.getElementById("answer");
	var k1 = parseInt(hyouka.pk_choice1.value);
	var k2 = parseInt(hyouka.pk_choice2.value);
	var k2f = 0;
	if (k2){
		if (hyouka.pk_choice3a.checked){
			k2f |= 1;
		}
		if (hyouka.pk_choice3b.checked){
			k2f |= 2;
		}
		if (hyouka.pk_choice3c.checked){
			k2f |= 4;
		}
	}

	if (pchk.pid >= 0){
		// 計算機メイン ares配列に結果が返る
		calcmain(pchk.pid, cp, hp, sand, k1, k2, k2f, ares);

		if (ares.length){
			// %を優先して降順ソート
			ares.sort(function(a,b){
				if (a.per < b.per) return 1;
				if (a.per > b.per) return -1;
				if (a.ml < b.ml) return 1;
				if (a.ml > b.ml) return -1;
				return 0;
			});

			// 結果をテーブルの形に整形
			answerstr = "<table border='1'><tr><th>%</th><th>Lv</th><th>攻撃</th><th>防御</th><th>HP</th></tr>";
			for (var i=0; i<ares.length; i++){
				answerstr += "<tr><td>" + Math.round(ares[i].per * 10000) / 100 + "</td><td>" + ares[i].ml
 + "</td><td>" + ares[i].atk + "</td><td>" + ares[i].def + "</td><td>" + ares[i].hp + "</td></tr>";
			}
			answerstr += "</table>";
		}
	}

	div.innerHTML = answerstr;
};

</script>

</head>

<body onload="init();">
個体値計算ツール 
<input class="pk_choice1" type="radio" name="btn_choice" value="0" checked="checked" onclick="changetbl(0);">番号順 
<input class="pk_choice1" type="radio" name="btn_choice" value="1" onclick="changetbl(1);">名前順
<br />
<div id="namediv"></div>
<br />
<span class="inp_lavel">Name </span><input id="pkname" class="pk_inp" type="text" value="" readonly="true">
<span class="inp_lavel">CP </span><input id="pk_cp" class="pk_inp" type="text" value="">
<span class="inp_lavel">HP </span><input id="pk_hp" class="pk_inp" type="text" value="">
<select id="selsand">
<option value="0">強化に必要な星の砂</option>
<option value="200">200</option>
<option value="400">400</option>
<option value="600">600</option>
<option value="800">800</option>
<option value="1000">1000</option>
<option value="1300">1300</option>
<option value="1600">1600</option>
<option value="1900">1900</option>
<option value="2200">2200</option>
<option value="2500">2500</option>
<option value="3000">3000</option>
<option value="3500">3500</option>
<option value="4000">4000</option>
<option value="4500">4500</option>
<option value="5000">5000</option>
<option value="6000">6000</option>
<option value="7000">7000</option>
<option value="8000">8000</option>
<option value="9000">9000</option>
<option value="10000">10000</option>
</select>
<br />
<br />
<form class="hyouka" name="hyouka">
第一評価<br />
<input id="pk_choice1_1" class="pk_choice1" type="radio" name="pk_choice1" value="1">1st
<input id="pk_choice1_2" class="pk_choice1" type="radio" name="pk_choice1" value="2">2nd
<input id="pk_choice1_3" class="pk_choice1" type="radio" name="pk_choice1" value="3">3rd
<input id="pk_choice1_4" class="pk_choice1" type="radio" name="pk_choice1" value="4">4th
<br />
第二評価<br />
<div>
<input id="pk_choice2_1" class="pk_choice2" type="radio" name="pk_choice2" value="1">1st
<input id="pk_choice2_2" class="pk_choice2" type="radio" name="pk_choice2" value="2">2nd
<input id="pk_choice2_3" class="pk_choice2" type="radio" name="pk_choice2" value="3">3rd
<input id="pk_choice2_4" class="pk_choice2" type="radio" name="pk_choice2" value="4">4th
<br />
<input id="pk_choice3_1" class="pk_choice3" type="checkbox" name="pk_choice3a" value="1">攻撃
<input id="pk_choice3_2" class="pk_choice3" type="checkbox" name="pk_choice3b" value="2">防御
<input id="pk_choice3_3" class="pk_choice3" type="checkbox" name="pk_choice3c" value="3">HP
</div>
</form>
<br />
<input type="button" value=" 計 算 " onclick="calc(); return false;">
<input type="button" value=" 評価クリア " onclick="clearinp(false); return false;">
<input type="button" value=" ALLクリア " onclick="clearinp(true); return false;">
<br />
<br />
<hr>
<div id="answer">
</div>
</body>
</html>




Tags: プログラムメモ
author : HUNDREDSOFT | - | -