C言語リバーシ 列挙型

シェアする

  • このエントリーをはてなブックマークに追加

こんにちは。前回はビットボードを用いて盤面の表現を作りました。

今回は手番と手数の情報を追加します。

と、その前に、構造体のタグ名と型名を変えます。

型名はすべて大文字にするというルールでいきます。

また、構造体タグ名と型名は名前空間が異なるというコンパイラ的な事情があるので、タグ名を型名を同じにしてもかまわないので、そうすることにします。

ちなみに、タグ名(struct XXX { ... }のXXXの部分)は、typedefするなら無くても大丈夫です。(構造体の中でその構造体のポインタなどを使う場合はタグ名で指定しないといけませんが。)

ということで、前回までのコードは以下のようになります。

#include <stdio.h>

typedef struct BOARD{
	uint64_t black, white;	// 黒石・白石のビットボード
}BOARD;

列挙型

C言語には「列挙型」と呼ばれる「型の型」が用意されています。

型の型とは、構造体のように型を定義するための記述、という意味で使っている自己流の言い方です。

enum TEBAN{
	SENTE = -1,
	GOTE = 1,
	GAME_OVER = 0
}

これを定義すると、

enum TEBAN a;

と定義した変数aはSENTE, GOTE, GAME_OVERのいずれかのみを値として持つことができ、それぞれ実体は1,-1,0である、というような状態になります。(構造体のstructのように、enumが必要です。)

このenumで定義した型を「列挙型」と言います。

ややこしいですが、簡単に言うと#defineを用いたマクロ定義の進化系です。

実際、board.teban = SENTEのように使う(board構造体のteban変数に1が代入される)ので#define SENTE 1としても同じ効果が得られますが、関連のあるマクロ定義のセットをまとめて型にすることでソースコードの可読性(読みやすさ、理解しやすさ)を高めます。

変数の宣言でint型で宣言するよりもenum TEBAN型で宣言したほうが「これは手番を表す変数だな」ということが分かります。(実際は変数名で分かるようにするのですが、一応です。)

詳しくはロベールのC++教室 - 第76章 列挙子などに説明があります。

毎回enum Tebanと書くのも面倒なので、これにもtypedefを使ってTEBANだけで宣言できるようにします。

typedef enum TEBAN{
	SENTE = -1,
	GOTE = 1,
	GAME_OVER = 0
}TEBAN;

となります。

ちなみに1と-1なのは、-1を掛けるという操作で先手番と後手番を交代できるようにするためです。

さらに、整数型で手数を用意すると、局面の表現は以下のようになります。

#include <stdio.h>

// 手番を表す列挙型
typedef enum TEBAN{
	SENTE = -1,
	GOTE = 1,
	GAME_OVER = 0
}TEBAN;

// 局面を表す構造体
typedef struct BOARD{
	uint64_t black, white;	// 黒石・白石のビットボード
	TEBAN teban;			// 手番
	int move_num;			// 何手動いたか(手数)
}BOARD;

int main(void){
	return 0;
}

コンパイルしてみるためにmain関数を用意してみました。(もちろん実行しても何も起きません。)

今回は局面の表現に手番情報と手数情報を追加しました。

次回は局面を初期局面で初期化する関数を作ろうと思います。

では。

スポンサーリンク
レクタングル(大)
レクタングル(大)

シェアする

  • このエントリーをはてなブックマークに追加

フォローする