企業のIT系製品開発のプロセスを「○✕ゲーム」(三目並べ)を作りながら解説。

  • URLをコピーしました!

2020年にプログラミングが必修化されましたが、2024年には大学受験科目「情報Ⅰ・Ⅱ」として再編が検討されています。もしかしたら、試験科目にプログラミングが出題される日も遠くは無いかもしれません。

そのような背景もあり、情報系院卒の僕としてはプログラミング教育に関心があって、本記事を書いています。この記事では、C言語で「○✕ゲーム」(三目並べ)をプログラミングしますが、設計から実装に至るまで、実際に企業が製品開発としてやっている具体化の流れを解説していきます。

目次

趣旨・目的、他サイトの記事と違い

「○✕ゲーム」(三目並べ)のサンプルは、ありふれています。ただ、この記事では、企業でやる所謂製品開発に沿った設計から実装(簡単なテスト)までの流れを解説していきます。なので、この記事を読めば、「○✕ゲーム」(三目並べ)のサンプルコードが分からなくても、大企業で行われてるソフトウェアの製品設計・開発工程の外観を掴めると思います(少なくとも、僕は大企業でこのように開発してました。)。

また、その他に特異な点は、完全AIとまではいきませんが、CPUの思考ルーチンを実装して紹介します。思考ルーチンのアルゴリズムには、Min-Max法というCPUが「相手の利益を最小に、自分の利益を最大に行動する」アルゴリズムを組み込んでみます。

「○✕ゲーム」(三目並べ)をゲーム的な観点で述べますと、二人零和有限確定完全情報ゲームに属しており、初手時点で引き分け確定の読み切り可能なゲームです(つまり、CPUは人間相手に必ず引き分けます。)。

開発の流れ・開発手法

「○✕ゲーム」(三目並べ)のような単純なプログラム開発の場合は、いきなりプログラミング(実装)から始めてしまっても構いませんが、大抵の場合、いきなりプログラミングから始めることは、先ずありません。

ここでは、プログラミングの前段階での準備について、大企業でのソフト開発の進め方を例にしながら進ます。とは言え、大企業の開発の進め方も独自の進め方ではなく、広く一般に知られる開発手法に基づきます。

開発手法とは?

開発手法とは、文字通りソフトウェアを開発する手法のことです。難しくなくほとんどの企業で標準として取り入れられている手法です。具体的には、Vモデル開発と呼ばれる開発手法です。

要求分析、基本設計、詳細設計、実装、単体テスト、統合テスト、リリースという一連の流れに沿ってソフトウェアを開発していきます。各々のフェーズがV字のように対応するため「Vモデル開発(あるいは、Vモデル)」と呼ばれます。要するに、プログラミング(実装)する前に、紙面上でも良いので今から作るプログラムの設計をしておきましょう。という心構えです。

留意点

Q1:必ずVモデルに沿って開発しなければなりませんか?
A1:必要ありません。いきなりプログラミングしても全然構いません。

Q2:必ずVモデルに沿って開発しますが、全フェーズを守るべきですか?
A2:Vモデルの利点は、この工程に沿ってソフト開発を行えば、バグの少ないプログラムを作ることが出来ます。言うなら「ソフト開発やることリスト」です。これを踏まえた上で、不要なフェーズを飛ばすなどは全然構いません。

Q3:Vモデルに沿って開発する際、何か成果物(書面)を定義すべきですか?
A3:これは僕の意見ですが不要です。理由は、プログラミングは最終的に動くモノと、それを後追い可能な最低限のメモ書きで十分だと思うからです。企業内では、振り返りもしない細かな基本(概要)設計書などを作成したりしますが、糞無駄な仕事の一つであるにも関わらず作成していたります。

Q4:繰り返しますが、ドキュメント(書面)は不要ですか?
A4:不要です。目が腐るだけです。さっさとプログラム開発に取り組みましょう。

基本設計

ニーズ発掘など要求分析は特にないので基本設計していきます。基本設計では、主に機能、変数名、構造体名(オブジェクト指向であればクラス名)を明確にしましょう。

機能①(main部)
 ーvoid main(int argc, char *argv[]):main関数内でゲームループ

機能②(CPU部)
  ーint think(Game *game):評価関数

構造体
 ーstruct Game:盤面情報を管理する構造体

定数
 ー#define IAM 0
 ー#define CPU 1

「これ、なんとなく使いそうだなぁ」という内容をメモ書きすれば良いです。イメージは、プログラミングで使いそうな箱(定数、変数、関数)を用意するイメージです。箱の中身は考えなくても構いません。料理で言うなら、具材の準備と言ったところです。

詳細設計

基本設計で用意した箱の中身を具体化していきます。ここでは、あえて2つ詳細設計を例示してみます。どちらでも構いません。

詳細設計の例①

機能①(main部)
 ーvoid main(int argc, char *argv[]):main関数内でゲームループ

#include<stdio.h>
void main(int argc, char *argv[]){
 /* 変数 */
 while(1){ /*ゲームループ*/ }
}

機能②(CPU部)
  ーint think(Game *game):評価関数

構造体
 ーstruct Game:盤面情報を管理する構造体

typedef struct Game {
 /* メンバ変数 */
 int turn; /* プレイヤーのターンを保持 */
 char board[3][3]; /* 3x3の盤面情報を保持 */
} Game; /* typedefで別名「Game」をつけたことで、変数宣言はGameのみで出来る。 */

※ここで急に登場する「typedef」は、変数宣言時のstructを省きたいが為に使用しています。「struct Game」を「Game」という別名一つで使えるようにしています。「どうして?意味ないことをするか?」と疑問に思うかもしれませんが、プログラミングの根底には「タイプ数を減らす。」意識がけが大切だからです。省略出来ることは、極力省略記法にして簡潔にプログラムを組むようにしてください。これが、後々のバグを減らす秘訣でもあります。

定数
 ー#define IAM 0
 ー#define CPU 1

実装(プログラミング)

基本設計、詳細設計を通して机上で「○✕ゲーム」(三目並べ)の具体化をしてきました。当初ぼんやりしたイメージが、かなりハッキリと具体化されていることが実感出来ていると思います。そして、ここから実装(プログラミング)をしていく訳です。

/* 編集中 */

実装のお作法:ファイル分割でコードを整理

さて、プログラミングは出来たと思います。もうひと工夫してみましょう(難しくないです。)。ここまでの、プログラムは、一つの「.c」ファイルのみを編集してきました。これは、所謂一つのファイルだけに「ベタ書き」された状態です。

少々「ごちゃごちゃしていませんか?」

まだ、コードの行数から少ないから思わないかもしれませんが、行数が増えると整理しづらくなってきます。この原因は、変数・定数、機能(CPU側の思考ルーチンなどの関数)、本体(main部)が、一つのファイルで同居しているからです。このため、各ファイルに分けて整理していきます。

ただ、今回は既に基本設計で整理されており、下記のようにファイル分割すれば良いです。

機能①(main部)
 ーvoid main(int argc, char *argv[]):main関数内でゲームループ

機能②(CPU部)
  ーint think(Game *game):評価関数

構造体
 ーstruct Game:盤面情報を管理する構造体

定数
 ー#define IAM 0
 ー#define CPU 1

このようなプログラミング(実装)のお作法を知っているか、知っていないかだけでも、将来に渡るプログラミングの上達の伸び代が代わってきます。余談ですが、このお作法すら知らないでソフトウェアを開発しているレベルの低い技術者がザラにいます(僕は見たことがあります。)。そのようなレベルの低い技術者が作る製品もまたガラクタでしか無いと思っていました。

僕はコードの綺麗さは気になりませんが、お作法くらいは最低限度で守ってもらいたいと言います。理由は、ソースコードの見通し、バグ対応(デバッグ)の勘づき方が全然変わります。

コメント

コメントする

目次