- プログラム概要
- 各状態の名称と説明
- 全体の処理と対応する関数
- 関数解説
- パターン
- コード
プログラム概要
- 新たに置かれた石がどのような状態を作り出すか判定する
- 評価関数を実装することで、minimaxにより連珠クライアントプログラムを作ることができる
各状態の名称と説明
状態の名称 | 説明 |
三 | 石を1つ加えれば達四になるもの |
四 | 石を1つ加えれば五連になるもの |
達四 | 四のうち両端の止まっていないもの |
五 | 同種の石が5つ繋がったもの |
長連 | 同種の石が6個以上繋がったもの |
全体の処理と対応する関数
- 盤面生成(init_board)
- 盤面表示(print_board)
- ユーザーからの入力(read_position)
- 盤面への一打追加(put_board)
- 一打の影響範囲抽出(pick_9)
- パターンマッチ(match_controller)
- 状態表示(print_state)
pick_9
以下の入力から、9マス分の盤面情報(一打を中心に前後4個の計9マス)を抽出する関数
- 現在の盤面
- 新たな一打の位置
- 影響範囲抽出方向(縦・横・斜め1・斜め2の計4方向)
match_controller
以下の入力から、定義済み各パターンにマッチする並びを探す
定義済み各パターン
- *は何でもいい
- −は空白
- ★は新たな一打(中心)
- ●は自分の石
- 各、裏返しの逆パターンもある
三になるパターン |
**−●★●−−* |
*−−●★●−** |
**−●★−●−* |
***−★●●−− |
**−−★●●−* |
***−★−●●− |
四になるパターン |
**−●★●●** |
***●★●●−* |
**●−★●●** |
***●★●−●* |
***●★−●●* |
***−★●●●* |
****★●●●− |
****★●●−● |
****★−●●● |
達四になるパターン |
**−●★●●−* |
***−★●●●− |
五になるパターン |
****★●●●● |
***●★●●●* |
**●●★●●** |
コード
注意:整形の為、全角文字を含んでいる
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define NG 0
#define BMAX 8
#define SPACE '-'
#define WHITE 'O'
#define BLACK 'X'
#define NUL 'N'
#define BTWN(i) 0 <= i && i < BMAX
typedef struct struct_state {
int three;
int four;
int comp_four;
int five;
} state;
int xy(int x, int y){
return x * BMAX + y;
}
void print_board(char *board){
int i, j;
printf(" ");
for(j=0;j<BMAX;j++)printf("%1d",j);
printf("\n");
for(i=0;i<BMAX;i++){
printf("%2d ",i);
for(j=0;j<BMAX;j++)
printf("%c", board[i * BMAX + j]);
printf("\n");
}
}
void copy_board(char *from, char *to){
int i;
for(i=0;i<BMAX * BMAX ;i++)
to[i] = from[i];
}
int init_board(char *board){
int i, j;
for(i=0;i<BMAX;i++){
for(j=0;j<BMAX;j++)
board[i * BMAX + j] = SPACE;
}
}
void print_state(state state_board){
printf("*** STATE ***\n");
printf("FIVE: %d\n", state_board.five);
printf("COMP-FOUR: %d\n", state_board.comp_four);
printf("FOUR: %d\n", state_board.four);
printf("THREE: %d\n", state_board.three);
printf("\n");
}
/* 前後4個分のボードを抜き出す */
void pick_9(char *board, char *pick_board, int x, int y, int dx, int dy){
int i;
int tmpx,tmpy;
int cnt = 0;
for(i=-4; i <= 4; i++){
tmpx = x + dx*i;
tmpy = y + dy*i;
if(BTWN(tmpx) && BTWN(tmpy)){
pick_board[cnt] = board[xy(tmpx, tmpy)];
} else {
pick_board[cnt] = NUL;
}
cnt++ ;
}
pick_board[cnt] = '\0';
// printf("(distX,distY)=(%d,%d):(%s)\n",dx, dy,pick_board);
}
/*文字列の大きさを得る*/
int size_of_str(char *str){
int cnt = 0;
while(str[cnt] != '\0'){
cnt++;
}
return cnt;
}
/*文字列の並びを反転させる*/
void reverse_char(char *str,char *result){
int i = 0;
int size = size_of_str(str);
while(size){
//str[size] は '\0'
result[i] = str[size-1];
i++;
size--;
}
result[i] = '\0';
}
int match(char *pattern,char *pick9,char bw){
int i = 0;
while(i < 9){
switch(pattern[i]){
case '-':
if (pick9[i] != '-'){ return (NG); }
break;
case '1':
if (pick9[i] != bw){ return (NG); }
break;
case '?':
break;
}
i++;
}
return (OK);
}
int match_builder(char pattern[][10], char *pick9, char bw){
int i = 0;
char reverse[10];
while(pattern[i][0]){
reverse_char(pattern[i],reverse);
if (match(pattern[i],pick9,bw)){return (OK);}
if (match(reverse,pick9,bw)){return (OK);}
i++;
}
return (NG);
}
state match_controller(char *pick9, state state_board, char bw){
char five[4][10] = {
"????11111",
"???11111?",
"??11111??",
'\0'
};
char comp_four[3][10] = {
"??-1111-?",
"???-1111-",
'\0'
};
char four[10][10] = {
"??-1111??",
"???1111-?",
"??1-111??",
"???111-1?",
"???11-11?",
"???-1111?",
"????1111-",
"????111-1",
"????1-111",
'\0'
};
char three[7][10] = {
"??-111--?",
"?--111-??",
"??-11-1-?",
"???-111--",
"??--111-?",
"???-1-11-",
'\0'
};
if (match_builder(five,pick9,bw)){state_board.five++;}
if (match_builder(comp_four,pick9,bw)){state_board.comp_four++;}
if (match_builder(four,pick9,bw)){state_board.four++;}
if (match_builder(three,pick9,bw)){state_board.three++;}
return state_board;
}
state check_board(char *board, int x, int y, int bw){
state state_board;
char result[10];
state_board.three = 0;
state_board.four = 0;
state_board.comp_four = 0;
state_board.five = 0;
pick_9(board, result, x, y, 1, 0);
state_board = match_controller(result, state_board, bw);
pick_9(board, result, x, y, 0, 1);
state_board = match_controller(result, state_board, bw);
pick_9(board, result, x, y, 1, 1);
state_board = match_controller(result, state_board, bw);
pick_9(board, result, x, y,-1, 1);
state_board = match_controller(result, state_board, bw);
return state_board;
}
int put_board(char *board, char *result, int x, int y, char bw){
copy_board(board, result);
if(0 <= x && x < BMAX && 0 <= y && y < BMAX
&& result[x * BMAX + y] == SPACE) {
result[xy(x,y)] = bw;
return(OK);
} else {
return(NG);
}
}
int read_position(int *x, int *y){
if(scanf("%d %d", x, y)==EOF){
exit(OK);
}
return OK;
}
/**************************************************
Main
**************************************************/
main(){
int tmpx, tmpy;
char board[BMAX * BMAX];
int turn = 0;
char borw[2] = {WHITE, BLACK};
char message[2][10]={"First","Second"};
state state_board;
init_board(board);
print_board(board);
while(1){
read_position(&tmpx, &tmpy);
if(put_board(board, board, tmpx, tmpy, borw[turn])){
printf("%s(%c): %d %d \n",
message[turn], borw[turn], tmpx, tmpy);
state_board = check_board(board, tmpx, tmpy, borw[turn]);
if(turn) turn=0; else turn=1;
} else {
printf("%s(%c): %d %d is not put!!\n",
message[turn], borw[turn], tmpx, tmpy);
}
print_board(board);
print_state(state_board);
if(state_board.five){
goto END;
}
}
END:
printf("%s(%c) win \n",
message[turn], borw[turn]);
exit(OK);
}