「JavascriptBattle」はJavaScriptで記述できるAIを鍛えてオンラインでバトルするゲームです。
AIというとハードルが高いイメージがありますが、実際に自分が考えないといけないのはmoveという移動関数だけなので、それほど身構える必要はないかもしれません。すぐに使えるサンプル関数も何種類か用意されているので、少しずつ理解していけば良いでしょう。
ゲームに参加すると、登録した自分のヒーローが自動的に呼び出されチームバトルを繰り広げていきます。
ゲームに参加しているうちにJavaScriptの知識や、GitHubの使い方まで覚えてしまえるかも。ということで紹介してみたいと主ます。
参加方法
公式サイトの一番下に参加方法が書いてあります。
GitHubのアカウントが必要で、hero-starterというリポジトリをforkし、サイト上の「Login with GitHub」ボタンを押せば参加完了です。
ヒーロー改良方法
forkした自分のリポジトリの中にhero.jsというファイルが含まれていて、このファイルを編集することで自分のヒーローを強化していくことができます。
具体的にはまずリポジトリをcloneし(forrestbthomasのところは自分のGitHubアカウント名に置き換えてください)。
git clone https://github.com/forrestbthomas/hero-starter.git
hero.jsを編集します(後述)。その後以下の手順でGitHubに反映します。
git add hero.js git commit git push origin mast
まとめて書いていますがadd / commit / pushはそれぞれ適切なタイミングで実行した方が良いです。この辺は通常のGitHubを用いた開発と同じです。
hero.jsってなに?
hero.jsがヒーローのAIを定義するファイルで、moveという関数を定義します。
デフォルトでは"Safe Diamond Miner"という名前のAIが設定されていて、この定義は次のようになっています。
// // The "Safe Diamond Miner"
var move = function(gameData, helpers) {
var myHero = gameData.activeHero;
//Get stats on the nearest health well
var healthWellStats = helpers.findNearestObjectDirectionAndDistance(gameData.board, myHero, funct\
ion(boardTile) {
if (boardTile.type === 'HealthWell') {
return true;
}
});
var distanceToHealthWell = healthWellStats.distance;
var directionToHealthWell = healthWellStats.direction;
if (myHero.health < 40) {
//Heal no matter what if low health
return directionToHealthWell;
} else if (myHero.health < 100 && distanceToHealthWell === 1) {
//Heal if you aren't full health and are close to a health well already
return directionToHealthWell;
} else {
//If healthy, go capture a diamond mine!
return helpers.findNearestNonTeamDiamondMine(gameData);
}
};
いきなりこれだと分かりづらいかもしれません。その場合コメントアウトされている他のmoveサンプルを参照してみると良いかもしれません。
例えば"Northerner"というAIは、名前の通り常に北に向かって動くこの上なく単純なAIです。移動する方角を文字列で返せばよいことがわかります。
// // The "Northerner"
// // This hero will walk North. Always.
// var move = function(gameData, helpers) {
// var myHero = gameData.activeHero;
// return 'North';
// };
もうちょっと難しいものだと例えば"unwise Assasin"というのがあります。
// // The "Unwise Assassin"
// // This hero will attempt to kill the closest enemy hero. No matter what.
// var move = function(gameData, helpers) {
// var myHero = gameData.activeHero;
// if (myHero.health < 30) {
// return helpers.findNearestHealthWell(gameData);
// } else {
// return helpers.findNearestEnemy(gameData);
// }
// };
ヒーローのヘルスが30より小さい場合、近くの回復場所を探し、それ以外の場合近くの敵を探しています。
ルールの把握
今まで闇雲にhero.jsのコードを覗いてきましたが、これだけだと、どのような方針で改良すればよいのかよくわかりませんよね。実は当然ながら詳細なルールが設定されているので、これを抑えておかないといけません(Rules、日本語訳)。
簡単に説明すると、ゲームはチームで争われ、全ての敵を殺すか、1250ターン経過後多くのダイヤモンドを収集したチームが勝利となります。ターンごとに各ヒーローはダイヤモンドを探したり、敵を殺したり、味方を回復したりといった行動を行いチームの勝利を目指します。
ヒーローはダイヤモンドがあれば採掘を、敵がいれば攻撃を、味方がいれば回復を行うので、ベストな行動をとるようにmove関数を改良していくというわけです。
まとめ
なかなか自分が強くなっているのかどうなのか把握しづらいところが難点かもしれません。JS BATTLE CODE TESTERというテスト・ツールなんかもあるのでうまく活用してスコア上位を目指したいですね。
はまればJavaScriptの知識やGitHubの使い方などいろんな周辺知識も身につくかも。興味のある方はチャレンジしてみてはいかがでしょうか。