連珠のコード書く

  1. プログラム概要
    1. 各状態の名称と説明
  2. 全体の処理と対応する関数
    1. 関数解説
    2. パターン
  3. コード


プログラム概要

  • 新たに置かれた石がどのような状態を作り出すか判定する
  • 評価関数を実装することで、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

以下の入力から、定義済み各パターンにマッチする並びを探す
  • 9マス分の盤面情報
  • 置かれた石の色

定義済み各パターン

  • *は何でもいい
  • −は空白
  • ★は新たな一打(中心)
  • ●は自分の石
  • 各、裏返しの逆パターンもある

三になるパターン
**−●★●−−*
*−−●★●−**
**−●★−●−*
***−★●●−−
**−−★●●−*
***−★−●●−

四になるパターン
**−●★●●**
***●★●●−*
**●−★●●**
***●★●−●*
***●★−●●*
***−★●●●*
****★●●●−
****★●●−●
****★−●●●

達四になるパターン
**−●★●●−*
***−★●●●−

五になるパターン
****★●●●●
***●★●●●*
**●●★●●**

コード 

注意:整形の為、全角文字を含んでいる
#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);

}
2006年02月17日(金) 16:15:16 Modified by hacking_dubby




スマートフォン版で見る