はじめに
本記事を元にした完成系のルーレットはこちらです。
GitHub Copilot
GitHub Copilot(コパイロット)はGitHubが提供するAIサービスで、IDEの拡張機能として動作します。コーディング時における疑問をかつてないほど迅速に的確に解決してくれます。
一般的な開発ではIDEなどのコードエディタを開き、疑問が出てきたらブラウザを開いてググる。でも、なかなか答えに辿り着かず、色々なサイトをサーフィンする。サーフィンしている途中で広告が目に入ってきたりして気が散る。そして集中力が切れる。切れた集中力が復活するのには時間が掛かりますよね?
でもCopilotはIDE内で全て完結しており、コーディング中に次にタイピングするかもしれない候補をいくつか提案してくれる。その提案内容もIDEで参照しているファイルを走査した上なので、外れが少ない。
さらにIDE内のGit Copilot Chatを使用しChatGPTのようにコマンドで会話を重ねると、理想のコードを示してくれる。
今回はその過程を紹介します。
VSCODEに拡張機能をインストール
最初にGitHub Copilotのみをインストールしたのですが、いつの間にかChatもセットでインストールされていました。どこかでポチポチとしたのかもしれません。
ちなみにIDEはVSCODE、VisualStudio、Eclipse、Intellijなど様々に対応しており、それらの拡張機能を利用してCopilotを使用できます。
GitHub Copilot Chat 出現
拡張機能のインストールが完了するとVSCODEのサイドメニューに「チャット」というのが出現します。これがGitHub Copilot Chatです。ChatGPTの3か3.5が使用されているはずです。このあたりは時流に合わせてアップグレードされていくと思われます。
ルーレット作成開始
早速、Chatにコマンドを入力します。
ルーレットを表示したい
少々のシンキングタイムののち、次のようなコードを返してくれました。
実はChatに頼む前に自力でルーレットを作成しようとして挫折した中途半端なコード(Vue.js)を開いたまままでした。Chatはそれを見て提案したようです。少し入っているコメントはCopilotが入れてくれたものです。
GitHub Copilot Chatの回答
<template>
<div>
<canvas ref="canvas" width="500" height="500"></canvas>
<button @click="startRoulette">開始</button>
<button @click="stopRoulette">停止</button>
</div>
</template>
<script>
export default {
data() {
return {
canvas: null,
ctx: null,
startAngle: 0,
arc: Math.PI / 6, // 12個のセクションに分ける
spinTimeout: null,
};
},
mounted() {
this.canvas = this.$refs.canvas;
this.ctx = this.canvas.getContext("2d");
this.drawRouletteWheel();
},
methods: {
drawRouletteWheel() {
let outsideRadius = 200;
let insideRadius = 125;
this.ctx.clearRect(0, 0, 500, 500);
this.ctx.strokeStyle = "black";
this.ctx.lineWidth = 2;
this.ctx.font = "bold 12px Helvetica, Arial";
for (let i = 0; i < 12; i++) {
let angle = this.startAngle + i * this.arc;
this.ctx.fillStyle = i % 2 == 0 ? "#A52A2A" : "#FFD700";
this.ctx.beginPath();
this.ctx.arc(250, 250, outsideRadius, angle, angle + this.arc, false);
this.ctx.arc(250, 250, insideRadius, angle + this.arc, angle, true);
this.ctx.stroke();
this.ctx.fill();
this.ctx.save();
this.ctx.fillStyle = "black";
this.ctx.translate(
250 + Math.cos(angle + this.arc / 2) * 150,
250 + Math.sin(angle + this.arc / 2) * 150
);
this.ctx.rotate(angle + this.arc / 2 + Math.PI / 2);
let text = i.toString();
this.ctx.fillText(text, -this.ctx.measureText(text).width / 2, 0);
this.ctx.restore();
}
},
spinRoulette() {
this.startAngle += (Math.PI / 60);
this.drawRouletteWheel();
this.spinTimeout = setTimeout(this.spinRoulette, 16);
},
startRoulette() {
clearTimeout(this.spinTimeout);
this.spinRoulette();
},
stopRoulette() {
clearTimeout(this.spinTimeout);
},
},
};
</script>
こちらが出来上がったルーレットです。世にも珍しいドーナツ型ルーレットの完成です。
動画も撮りました。
きちんとルーレットの動きをしていて驚きです。
Vue2のOptionAPIからVue3のCompositionAPIに変換する
CopilotはVueの場合OptionAPIを率先して提案してきます。私はCompositionAPIを勉強中の身なので変換を依頼します。
composition api に変換して
Vueを触ったことがある方はわかると思いますが、この変換、結構、頭と時間を使いますよね。でもCopilot Chatは一瞬でした。もちろん、ルーレットは正常に動作します。
GitHub Copilot Chatの回答
<template>
<div>
<canvas ref="canvas" width="500" height="500"></canvas>
<button @click="startRoulette">開始</button>
<button @click="stopRoulette">停止</button>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const canvas = ref(null);
let ctx = null;
let startAngle = 0;
const arc = Math.PI / 6; // 12個のセクションに分ける
let spinTimeout = null;
onMounted(() => {
ctx = canvas.value.getContext("2d");
drawRouletteWheel();
});
function drawRouletteWheel() {
let outsideRadius = 200;
let insideRadius = 125;
ctx.clearRect(0, 0, 500, 500);
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.font = "bold 12px Helvetica, Arial";
for (let i = 0; i < 12; i++) {
let angle = startAngle + i * arc;
ctx.fillStyle = i % 2 == 0 ? "#A52A2A" : "#FFD700";
ctx.beginPath();
ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
ctx.arc(250, 250, insideRadius, angle + arc, angle, true);
ctx.stroke();
ctx.fill();
ctx.save();
ctx.fillStyle = "black";
ctx.translate(
250 + Math.cos(angle + arc / 2) * 150,
250 + Math.sin(angle + arc / 2) * 150
);
ctx.rotate(angle + arc / 2 + Math.PI / 2);
let text = i.toString();
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
ctx.restore();
}
}
function spinRoulette() {
startAngle += (Math.PI / 60);
drawRouletteWheel();
spinTimeout = setTimeout(spinRoulette, 16);
}
function startRoulette() {
clearTimeout(spinTimeout);
spinRoulette();
}
function stopRoulette() {
clearTimeout(spinTimeout);
}
onUnmounted(() => {
clearTimeout(spinTimeout);
});
</script>
ドーナツ型のルーレットを改善する
Vue3のCompositionAPIに変換できましたが、このままだと、なかなか珍しいドーナツ型のルーレットのままなので、少し改造していきます。半径125という設定があったので、半径0に変更してみます。ここはCopilotを使用せず、自分で修正します。さて、どうでしょうか。
let outsideRadius = 200;
let insideRadius = 125;
↓
let outsideRadius = 200;
let insideRadius = 0;
当初想像していた通りのルーレットの形になりました。
回転もスムーズに行われます。
ルーレットに表示する文字を変更できるようにしたい
ルーレットに表示する文字を自由に変更できるようにしたい
CopilotChatにコマンドを送信して返ってきたメッセージです。処理の説明もしてくれています。
GitHub Copilot Chatの回答
そのままのコードをエディタに貼り付け、動かすと初期表示ではルーレットの数字が消え、新たにテキストボックスが追加されています。(CSS効いていないので分かりづらいです)
Copilotが追加してくれたテキストボックスに文字を入れ、開始ボタンを押すと・・・
すべてのマスに同じ文字が表示されました。ちょっと期待とは異なる結果でした。これは私の依頼したコマンドの内容が悪かったです。
具体的に指示する
ルーレットに表示する文字はセクションごとに自由に変更できるようにしたい
もう少し具体的な依頼を行ってみると、ルーレットのマス分のテキストボックスが追加されそうなソースを提案してくれました。
GitHub Copilot Chatの回答
実際に動かしてみると、初期表示の時点でマス分のテキストボックスが表示されました。
テキストボックスに値を入れて開始ボタンを押すと、各マス目に入力した文字が表示されました
10分で完成したルーレット
こちらが完成したルーレットです。これをゼロから作ろうとすると数時間・・・数日かかってしまう可能性もあります。でも、Copilotのサポートによって、10分でここまでの仕上がりになりました。
ルーレットという題材は非常にシンプルですが、実際にはサイン(sin)、コサイン(cos)や円周率などを使用する必要があり、数学が苦手な場合、かなりの苦行になります。
AIに対し具体的で明確なコマンドを示せば、ビックデータをバックグラウンドとした適切な回答を提案してくれることを実証できました。
自身が思い描いていることを受け手(AI)の立場になってきちんと伝えてあげる能力が必要不可欠です。
これは昔~現代のシステム開発においても同様です。プログラマーに対して、明確な設計書を提示し、製造していただく。ここには曖昧さは不要で、理路整然としているのがベストです。
きちんとした仕様があれば、そのコーディングをGitHub Copilotが力強くサポートしてくれます。これはGitHub Copilotがプログラマーの代わりになるという意味ではなく、あくまでサポートであることを忘れてはいけません。最終は人間が(上述の半径を変更した件)コードを作り上げていく必要があります。
コメント