こんにちは､ そしてお帰りなさい｡
この講演では､ もう一つの課題を与えたいと思います｡
機能とも関連しますが､ 今回のチャレンジは割り切り型になりそうです｡
これからは､
モジュール単位でプログラムを構成し､ 問題解決に取り組んでいくことになるでしょう｡
三目並べゲームを書いてほしいんです｡
これは､ より優れた問題解決者になるためのもので､ 関数を中心にプログラムを構成するのに役立つものです｡
配列を活用したり､ あるデータのフォーマットを考えたりもしますが､
チックタックトーのゲームのシミュレーションになりますね｡
コンピュータを書くつもりはない｡
プレイヤー1対プレイヤー2になる｡
そこで､ 三目並べをするプログラムを書いてほしい｡
願わくば､ みなさんがこのプログラム､ あるいはこのゲームに親しんでくださることを願っています｡
3×3のマス目に2人で遊ぶだけのゲームなんです｡
交代でやるんです｡
Xは鼻です｡
うまくいけば､ ピンとくるかもしれませんね｡
このゲームについて説明する必要はないと思ったのですが､ できれば三目並べに馴染みがあるといいのですが｡
その仕組みと､ どのような出力が期待できるのか､ ちょっとしたデモンストレーションをお見せします｡
でも､ 基本はチックタックトーのゲームなんですよ｡
実際のボード､ 3 x 3グリッドを表す配列を作成する必要があるでしょう｡
1次元の配列を作るだけで済むと思います｡
行と列を表現するために､ 実際には2次元の配列も作成することができます｡
2Dの方が直感的に分かりやすいかもしれませんが､
コードで可視化するのは少し難しいかもしれません｡
でも､ どちらでもいいんです｡
プログラミングの良いところは､ 問題に対して多くの解決策があることです｡
私の解決策のひとつとデザインの考え方をお伝えしますが､ デザインは自由に変えてください｡
cの構文が正しく使われていれば､ それでいいんです｡
cの使い方を覚えてほしい｡
プログラムがモジュール化され､ 整理され､ メンテナンスが容易で､
質の高いコードであれば､ それはそれで心配なのです｡
そこで､ 1つだけ実装する方法として､ 基板を10個の要素を持つ1次元の配列で表現する方法があります｡
ここで10個の要素を持っているのは､ 0個を使って欲しくないからです｡
この10個の要素はボードを表すことになりますが､
同時にボード上の座標も表すことになります｡
そこで､ これをデモして､ どのように動作させようと考えているかを紹介します｡
しかし､ 実際に描画するボックスを選択する方法は､
要素番号に基づくことになります｡
ボード用の配列を作るだけでなく､ この問題をどう分解していくか､ どう整理していくかを考えるようにしなければなりません｡
最低でも3機能､ おそらくそれ以上は必要かと思います｡
しかし､ 少なくとも勝敗をチェックする機能を1つは持つ必要があります｡
これは基本的にゲームに勝ったかどうかを見るだけですが､ 引き分けかどうかも確認することができます｡
盤面を描画する機能を用意する必要があります｡
なぜなら､ すべてのプレイヤーの手番が終わった後に､ 盤面を描くことになるからです｡
そして､ これを再利用することになるわけです｡
もう一つの碁盤をマークする機能は､
ユーザーが実際にあるボックスにxやoを入れたいときに起こります｡
そのボックスをxやoに設定する関数が必要です｡
その結果､ 配列にxやoが入力されることになります｡
そうすれば､ 配列を見て､ 勝ったか負けたかを確認することができますしね｡
そして､ マークボードでは､ 無効な選択がないかどうかのチェックもできるようになるのです｡
ですから､ 有効な選択項目が1から9で､ ユーザーが10を入力した場合､ 「それはできません､
もう一度やり直してください」と言うことになります｡
ユーザーフレンドリーであること､ ユーザーの視点からは直感的に使えること､
プログラミングの視点からは整理されていること｡
本当に考えてみてください｡
計画を立て､ 紙を出し､ この問題をどう攻略するか､ どんな機能が必要か､
設計図を書き始めるのです｡
私が考えている実行方法は､ 少しデモをお見せしましょう｡
ソースコードはお見せしませんが､ ゲームを走らせるとこんな感じになると想定しています｡
ちょっとしたタイトルで､ おいおい､ ゲームかよってなるかも｡
そして､ プレイヤーに関する情報も少し｡
プレイヤー1がx､ プレイヤー2がoになる｡
これは､ コンピュータをプレイする必要はないことを忘れないでください｡
ターンごとに入れればいいんです｡
そこで､ 隣に座っている友人とこのゲームをすることになるのですが､ その友人がどこに数字を入れるかを教えてくれるのです｡
もし､ 本当に野心的になるなら､ コンピュータと対戦するゲームを書くことができます｡
しかし､ 3×3のグリッドには､ 最初は数字が入っていることに気づくだろう｡
この数字を使って入力することができます｡
つまり､ プレイヤー1が手番でxを表現する場合､
入力した数字に応じてxが置かれることになるわけです｡
そこで､ グリッドを印刷し､ ボードを表示し､ さらにユーザーに誰の番か伝え､
数字を入力するように指示します｡
だから､ この場合は､ 先に2番を入力してリターンを押すんだ｡
そして､ 私が2を打って戻った後､ 何が起こるかというと､
実際に誰かが勝ったかどうかを確認し､ 画面をクリアにして､ 盤面を描き直すのです｡
2を押してエンターキーを押すと､ タイトルが表示され､ プレイヤー1とプレイヤー2が表示されることに気づくでしょう｡
しかし､ 今､ ボックス2には､ xがあります｡
あとは､ ボードを表示する前に､ 勝ちか引き分けかを確認するべきだったということですね｡
そして､ 明らかにそれが最初のエントリーなので､ どちらもないのです｡
当選も抽選もしないので､ 今から番号を入力してもらい､
ここで好きな番号を選んでもらいます｡
今､ 私が10など無効な数字を入力したら､ 無効だと言ってくれるはずです｡
そして､ そのおかげで次の一手を打つことができるはずです｡
2を入力する場合､ 2も無効となるはずです｡
だから､ 2を入力しても､ 2はすでにxで取られているので無効と表示される｡
だから､ もしプログラムが再挑戦を許可してくれているのなら､ 彼らのターンをなくせばいいのですが､
それはあまりフェアではないですよね｡
では､ 今度はどこにoを配置するかということですが｡ 5と言い､ 無効な手を入れると､
盤面が再描画され､ oと5があるんです｡
そして今､ プレイヤー1と表示されています｡
そして､ 当選か抽選になるまで､ これを続けるのです｡
9でいいんじゃない？
今､ 私はそこにxを持っている､ 有効なエントリは1 3 4 6 7と8である｡
3とさせていただきます｡
そして､ 実際にxを勝たせてみましょう｡ 今度はxが8に入るので､ 勝者がいてもゲームが成立することを示すために､
oと6を入れてみます｡
そして､ xに7を入れ､ これでゲームは終了のはずです｡ リターンを押した｡
プレイヤー1が勝つと書いてあるし､ ちょっとした音も流してくれたので､ そこでちょっと派手なことをやってみました｡
というわけで､ ゲーム終了､ プレイヤー1の勝利｡
また､ プレイヤー2が勝った場合や引き分けた場合にも発生するはずです｡
そこで､ この問題をどのように攻略したいかを考えてみましょう｡
小さな素敵なプログラムです｡
次回の講義で解決策を検討し､ ソースコードを提供する予定です｡ ありがとうございます｡