Page 45:C言語でチェスと将棋のゲームを作ってみた

フィンランドの大学では授業は5月までで、6月からは夏休みである事が多いです。僕の通っているオーランド大学も5月の最終週には既に夏休みに入り、新学期が始まるのは8月の終わりごろからとなるので、3か月近い夏休みがある事になります。

3月から夏休み間近になるまでのこの約2か月間は、Laboration 1という授業の課題に多くの時間を費やしていました。これは一言で言えば「自由課題」の授業です。実際には日本の学校の読書感想文の本の選択肢のように「課題リスト」があり、「このリストの中から好きな課題を選ぶ」という形式になっているので完全に自由ではないのですが、それでも選択しはけっこう豊富にあったので自分がやりたいと思えるものを選ぶ事ができました。

で、僕が選んだのは

「C言語でチェスのゲームを作る」

という課題です。

 

《コンテンツ》
・どうやってチェスのゲームを作るのか?
・条件分岐とループ処理
・コードをちょっと紹介
・将棋バージョン
・所感

 

【どうやってチェスのゲームを作るのか?】

チェスのゲームを作ったといっても、いきなり下の画像みたいないかにも「ゲームっぽい画面」のゲームを作るわけではありません。

僕が今回作ったのは、次の下の画像のような、白黒の画面のもっと「いかにも原始的な」チェスゲームです。

ここでは、駒の色(白・黒)と駒の名前(キング・クイーン・ルークなど)をそれぞれアルファベットの頭文字で表現しています。例えば、黒のキングだったらBK、白のビショップだったらWBという感じです。

そして、このチェスのゲームは「人間VSコンピューター」ではなく、同じパソコン・同じキーボードを使って行う「人間VS人間」のチェスなので、後手である黒の手番の時は盤面を反転させて表示させる機能もつけています。

このようなゲームを作る場合、次のような作業が必要になります。

・縦8マス横8マスの、駒のデータを保存できる「盤面」を用意する
・盤面のそれぞれのマスに「駒の色」と「駒の種類」の情報を保存できるようにする
・どの駒がどんな動き方をするのか、ゲームのプログラムが正しく判定できるようにする
・取られた駒は盤上から消えるようにする
・どちらかの王様が取られた時点でゲームが終わるようにする(←今回の僕のプログラムでは「チェックメイト」の状態を判定する機能はつけていません)

他にも細かい部分はいろいろあるのですが、大まかな流れとしては大体こんな感じ。

 

【条件分岐とループ制御】

プログラミング言語を使って上記のようなプログラムを作る場合、

・条件分岐
・ループ制御

というものが必要になります。それぞれどんなものなのか簡潔に説明します。

条件分岐とは、「Aのような状況になったら〇〇を、Bのような状況になったら××をしなさい」というような、「こういう場合はこうしなさい」という「場合分けをして指示を与える」事を言います。

例えば日常生活では、次のような例は「条件分岐」であると言えます。

A: 雨が降っていたら、傘を持って行きなさい
B: それ以外の状況では、傘を持たずに行きなさい

上のAやBの例では、「雨が降っているかどうか」が「条件」であり、「傘を持って行く/傘を持たずに行く」のが「その条件に応じた処理」となります。

ループ制御というのは、「ある条件が満たされている限りこれをやり続けなさい」というものです。

例えばスポーツで言えば、バスケやサッカーのような制限時間のあるスポーツでは、「試合時間は〇〇分間」と予め決められています。そして、

「試合時間がまだ残っている」という条件が満たされている限り、

・自分のチームがボールを持っていたら、敵のゴールをめがけて進み得点を狙う
・相手のチームがボールを持っていたら、自分のゴールを守る(隙あらばボールを奪う)

の2つが延々と続くのです。

このようなものを、プログラミングでは「繰り返し処理」、「ループ処理」または「ループ制御」と呼びます。

従って、僕のチェスのプログラムの場合、

「どちらかの王様が捕まるまで(つまり盤上に王様の駒が2つある限り)、1手ずつ交代で自分の駒を動かす」

というのを繰り返し続ける事になります。

 

【コードをちょっと紹介】

そして、今回僕が作ったチェスのコードがこれです。
(まだプログラミングを始めて日が浅い人間の書いたコードなので、上級者の方、「ここがなっちょらん!」という箇所を見つけましたらご指摘・ご指導いただけますと幸いです^^;)

ここに表示されているのはチェスのプログラム全体の流れをつかさどるmain.cというファイルの中身です。他にも、

・BoardControl.c(盤面のデータや手番などを管理する機能を収納するファイル)
・BoardControl.h(BoardControl.cの機能をmain.cの中で使うための「つなぎ」のファイル)
・Pieces.c(駒の動き全般を管理する機能を収納するファイル)
・Pieces.h(Pieces.cの機能をmain.cの中で使うための「つなぎ」のファイル)

の4つのファイルがあるのですが、特にPieces.cなんかは500行以上ありますし、BoardControl.cも300行ぐらいはあり、どちらも長いコードなのでここに載せるのは省略します。

 

【将棋バージョン】

僕がチェスのゲームを作るという課題に取り組んできた、このLaboration 1という授業はほぼ週1のペースで先生とのミーティングがあり、そこで進捗報告をする事になっていたのですが、チェスのゲームは1か月ぐらいでできてしまったので、「残りの1か月の余った時間、ジャパニーズチェス(将棋)を作ってもいいですか」と言ったら「うん、残りの期間でできる所までやってみよう」という事になり、将棋も作る事になったのでした。

将棋は「ジャパニーズチェス」と言われるだけあってチェスとルールが似ており、駒の動き方もほとんど同じであるため、チェスのために書いたコードのかなりの部分をそのまま使い回す事ができました。

将棋のプログラムを書く時にチェスよりも複雑で難しかったのは、主に

・チェスと違って、相手から取った駒を自分の駒として再利用できる事
→そのため、取られた駒のデータも保存しなければいけないし、既に盤上にある駒を動かすのか手持ちの駒を盤上に打つのかも選べるようにしなければいけない
・複数の駒が「成る」事でより強い駒に昇格できる事(チェスでは「成る」事ができる駒はPawnの1種類のみ)
・漢字1文字はアルファベット2文字分に相当するので、それを計算に入れてコードを書かなければいけない事

などですね~。

んで、こんな感じに出来上がりました。

各自できあがった課題を発表するのが今日から数日前の水曜日で、その直前まで将棋のコードを書いていたので、将棋はギリギリの仕上がりでした。というわけで、将棋は後手番の時に盤面を反転して表示させる機能はまだついていません。

 

【所感】

今回、2か月ほどかけてチェスと将棋のゲームを作るというプロジェクトに取り組んできたわけですが、かかった時間は合計で約100時間。

当然全てがスムーズにいったわけではなく、意味不明のバグが発生してそれの対処に時間がかかったからこのトータル時間になったわけです。時にはワケがわからず、

 

うおぉぉぉ、なんでじゃーー!!!!

解せぬ、解せぬぞぉぉおおお!!!!!!!!

てな感じの気分になる事もありましたが、最終的には何とか完成させられてよかったです(^^)

それにしても、今回僕が作ったチェスや将棋は比較的簡単な方で、これに加えて

「人間と対戦できるほどのAI」

を搭載しようとしたりすると、それはそれはものすごい知的作業量になる事が容易に想像できます。

将棋でなくたって、僕らが普段使っているWordやExcelだって、今回の僕のチェスや将棋よりもよっぽど複雑なつくりになっているんですよね~。ましてやGoogleやFacebookのアルゴリズムなんて、何がどうなっているのやら、今の僕のレベルでは見当もつきません。

以前オーストラリアでのワーキングホリデー中にオレンジファームで働いていた時、

「オレンジたった1個育てるのにこんなに手間がかかるのか!!」

と衝撃を受けたのですが、今回も比較的簡単なプロジェクトとはいえ、自分が「作る側の人間」になった事で、裏方の作業の大変さを改めて認識したのでした。