// MfcKatsunariDoc.h : CMfcKatsunariDoc クラスの宣言およびインターフェイスの定義をします。
//
/////////////////////////////////////////////////////////////////////////////

#define BOARD_SIZE 21/*11*//*15*//*21*/
#define PURE_BOARD_SIZE (BOARD_SIZE-2)

#define SPACE 0
#define BLACK 1
#define WHITE 2
#define OB    3	// Out of Boards

#define WM_NEXT_MOVE	(WM_USER+101)
#define WM_INITIAL_LOADED	(WM_USER+102)

#ifdef __cplusplus
////////////////////////////////////////////////////////////////////////
// 思考部分に取り揃えていないといけない関数群
// 思考部分はC++でなく、Cで書くと想定。
// C++で書く場合は、extern "C"を削除すること。
////////////////////////////////////////////////////////////////////////
extern "C" void initAll();												// 全体の初期化
extern "C" int setStoneOnGameBoard(int x, int y, int color, int move, int size);		// ユーザが指した手および自分の指した石を盤に置く
extern "C" void clearGameBoard(int boardSize);										// 盤をクリアする
extern "C" void setHandicapStoneGameBoard(int Handicap);				// 盤に、置石をする
extern "C" char *selectNextMove(int *x, int *y, int *eval, int color, int move/*, int kind*/, int ko_x, int ko_y, int ko_num, int size, int playout, int komi);	// 現在の盤を見て次の一手を返す
extern "C" void copyEvaluation(int buf[][BOARD_SIZE], int size);					// selextNextMoveの後、盤上の各指し手の評価値を返す
extern "C" int copyStatus(int buf[][BOARD_SIZE], int size);						// 現在の盤面認識を返す
																		////////////////////////////////////////////////////////////////////////
																		// copyStatusの盤面認識の返し方：
																		// 生きている黒石:1  生きている白石: 2 黒の地: 7 白の地: 8
																		// 死んでいる黒石:17 死んでいる白石:18 
																		////////////////////////////////////////////////////////////////////////

																		// 手番が誰にあるか
#define HUMAN		0
#define COMPUTER	1
#define COMM		2	// 通信
#define REPLAY		3	// ゲームの再現中。
#define NO_PLAY		-1	// ゲームをしていない状態。


class CUpdateKatsunari : public CObject
{
public:
	int OldBan[BOARD_SIZE][BOARD_SIZE];
	int NewBan[BOARD_SIZE][BOARD_SIZE];
	int OldX, OldY;
};

class CLog
{
public:
	int hama[3];
	int x, y;
};

#define MOVE_COUNT_MAX 500
/* 棋譜 */
typedef struct {
	int x;	/* ｘ座標 */
	int y;	/* ｙ座標 */
	int color;	/* 石の種類 (SPACE/BLACK/WHITE/OUT) */
} Score;

/* 対局の設定 */
typedef struct {
	int   handicap;   /* 手合い(0〜9) */
	int   blackSide;  /* 黒番(HUMAN/COMPUTER) */
	int   whiteSide;  /* 白番(HUMAN/COMPUTER) */
	int   boardSize;  /* 盤の大きさ(19 or 13 or 9) */
	char *blackName;  /* 黒番の名前 */
	char *whiteName;  /* 白番の名前 */
} Setting;

class CMfcKatsunariDoc : public CDocument
{
protected: // シリアライズ機能のみから作成します。
	CMfcKatsunariDoc();
	DECLARE_DYNCREATE(CMfcKatsunariDoc)

	// アトリビュート
public:
	int Ban[BOARD_SIZE][BOARD_SIZE];
	int Value[BOARD_SIZE][BOARD_SIZE];		// 思考ルーチンから貰った、各指し手の価値
	char Message[512];						// 思考ルーチンから貰ったメッセージ（未使用）

	int Teban;
	int color;
	int move;
	int KindBlack, KindWhite;
	int port;
	int BWSide[3];
	int hama[3];
	int UndoDepth;
	unsigned int Time[3];
	unsigned int LastTime;
	int LastMove[3];
	int LastMoveX[3];
	int LastMoveY[3];
	int LastX, LastY;
	HANDLE hThread;							// 思考ルーチンのスレッドID
	CLog PlayLog[MOVE_COUNT_MAX + 2];
	int EndFlag;
	int Initialized;
	int DispLastValue;
	BOOL isCommPortOpen;
	int ko_x, ko_y, ko_num;					// 劫　の判定用

	Score score[MOVE_COUNT_MAX + 2];
	int scoreCount;
	Setting initialSetting;

	int R, G, B;								// 評価値を表示する色

												// オペレーション
	int playout;
	int komi;
	int boardSize;
	int pureBoardSize;
public:
	int getSpentTime(int color);
	void ClearGameBoard(int boardSize);
	void SetHandicapStoneGameBoard(int Handicap);

	int _getKeyValue(FILE *fp, char *key, char *val);
	int loadScore(const char *filename);
	void getScore(int move, int &x, int &y, int &color);
	void recordScore(int x, int y, int color, int move);
	int saveScore(const char *filename);

	int getBlackSide() {
		return initialSetting.blackSide;
	}
	int getWhiteSide() {
		return initialSetting.whiteSide;
	}
	int getHandicap() {
		return initialSetting.handicap;
	}

	void replayFromScoreGameBoard(int move);

	int check[BOARD_SIZE][BOARD_SIZE];			// DoRemove,CheckRemove用のワークエリア
	int DoRemoveRecursive(int x, int y, int color, int board[BOARD_SIZE][BOARD_SIZE]);
	int DoRemove(int x, int y, int color, int board[BOARD_SIZE][BOARD_SIZE]);
	int CheckRemoveRecursive(int x, int y, int color, int board[BOARD_SIZE][BOARD_SIZE]);
	int CheckRemove(int x, int y, int color, int board[BOARD_SIZE][BOARD_SIZE]);
	int checkSuicide(int x, int y, int color, int board[BOARD_SIZE][BOARD_SIZE]);
	int checkSetStoneGameBoard(int x, int y, int color, int move);
	int SetStoneOnGameBoard(int x, int y, int color, int move);

	void LoadInitialFiles();

	void NextMove(int x, int y);
	int getSize() {
		return pureBoardSize;
	}
	//オーバーライド
	// ClassWizard は仮想関数を生成しオーバーライドします。
	//{{AFX_VIRTUAL(CMfcKatsunariDoc)
public:
	virtual BOOL OnNewDocument();
	virtual void Serialize(CArchive& ar);
	virtual void SetTitle(LPCTSTR lpszTitle);
	//}}AFX_VIRTUAL

	// インプリメンテーション
public:
	virtual ~CMfcKatsunariDoc();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:
	void GoKatsunari();
	void GoComm();
	void GameOver(int win);

	void Play();

	void SetLastMoveFromReplay();

	// 生成されたメッセージ マップ関数
protected:
	//{{AFX_MSG(CMfcKatsunariDoc)
	afx_msg void OnNewgame();
	afx_msg void OnUpdatePass(CCmdUI* pCmdUI);
	afx_msg void OnPass();
	afx_msg void OnUpdateUndo(CCmdUI* pCmdUI);
	afx_msg void OnUndo();
	afx_msg void OnEvaluate();
	afx_msg void OnUpdateRedo(CCmdUI* pCmdUI);
	afx_msg void OnRedo();
	afx_msg void OnUpdateFileOpen(CCmdUI* pCmdUI);
	afx_msg void OnUpdateGoKatsunari(CCmdUI* pCmdUI);
	afx_msg void OnUpdateNewgame(CCmdUI* pCmdUI);
	afx_msg void OnLastvalue();
	afx_msg void OnUpdateLastvalue(CCmdUI* pCmdUI);
	afx_msg void OnUpdateEvaluate(CCmdUI* pCmdUI);
	afx_msg void OnSetColor();
	afx_msg void OnUpdateSetColor(CCmdUI* pCmdUI);
	afx_msg void OnUpdateContinue(CCmdUI* pCmdUI);
	afx_msg void OnContinue();
	afx_msg void OnUpdateStop(CCmdUI* pCmdUI);
	afx_msg void OnStop();
	afx_msg void OnMatta();
	afx_msg void OnUpdateMatta(CCmdUI* pCmdUI);
	afx_msg void OnGoKatsunari();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};
#endif

/////////////////////////////////////////////////////////////////////////////

