質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

2016閲覧

詰め将棋の詰みを判定させたい

aiueo4561167

総合スコア4

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2019/01/08 12:19

ある特定の駒を用いて,1手詰め将棋問題を列挙しようと考えています.
攻め手は,金2枚,受け手は玉1枚と残りの駒を持駒としています.
下記のプログラムでは,バックトラック法を用いて,4×4マスに利きを考えずに,駒を並べました.
ある盤面が詰んでいるのか詰んでいないのかを判定して,詰んでいる状態のみを表示したいと考えています.

c

1#include <stdio.h> 2#include <stdlib.h> 3enum KomaN {GYO, KYO, KEI, GIN, KIN, HSH, KAK, FU}; 4enum Dir {A_DIR, B_DIR, OWNED_A, OWNED_B}; 5 6 7 8typedef struct Koma { 9 enum KomaN nam; 10 int x; 11 int y; 12 enum Dir dir; 13} Koma; 14 15#define BOARD_SIZE 9 16#define MAX_KOMA 38 //最大の持ち駒 17 18int hantei(int dep); 19Koma * make_koma(enum KomaN nam, int x, int y, enum Dir dir); 20void init(); 21void printBoard(); 22int searchTsumi(int dep); 23 24 25Koma * board[BOARD_SIZE * BOARD_SIZE]; //盤の大きさ 26Koma * playerA[MAX_KOMA]; //先手の最大駒 27int NkomaA; //先手の持ち駒 28Koma * playerB[MAX_KOMA+1]; //後手の最大駒 29int NkomaB; //後手の持ち駒 30char *kname[] = {"GY", "KY", "KE", "GI", "KI", "HS", "KA", "FU"}; 31 32Koma * make_koma(enum KomaN nam, int x, int y, enum Dir dir){ 33 Koma *pt = malloc(sizeof(Koma)); 34 pt->nam = nam; 35 pt->x = x; 36 pt->y = y; 37 pt->dir = dir; 38 return pt; 39} 40 41void init() { 42 int i, j; 43 for (i = 0; i < BOARD_SIZE; i++){ 44 for (j = 0; j < BOARD_SIZE; j++){ 45 board[BOARD_SIZE * i + j] = NULL; //最初はNULLを埋めておく 46 } 47 } 48 NkomaA = 0; 49 NkomaB = 37; 50} 51 52//表示する 53void printBoard() { 54 int i, j; 55 char *shikiri = " +--+--+--+--+--+--+--+--+--+"; 56 printf("  0 1 2 3 4 5 6 7 8\n"); 57 printf("%s\n", shikiri); 58 for (i = 0; i < BOARD_SIZE; i++) { 59 printf("%2d ", i); 60 for (j = 0; j< BOARD_SIZE; j++) { 61 Koma *pt = board[i * BOARD_SIZE + j]; 62 if (pt != NULL){ 63 printf("|%s", kname[pt->nam]); 64 } else { 65 printf("| "); 66 } 67 } 68 printf("|\n"); 69 printf("%s\n", shikiri); 70 } 71 printf("\n"); 72} 73 74int searchTsumi(int dep) { 75 int i, j; 76 int kk[] = {KIN, KIN, GYO}; 77 78 79 80 //深さが3になったら 81 if (dep >= 3){ 82 printBoard(); 83 } else { 84 for (i = 0; i < 4; i++) { 85 for (j = 5; j < 9; j++) { 86 if (board[i * BOARD_SIZE + j] != NULL) continue; 87 Koma *k = make_koma(kk[dep], i, j, A_DIR); 88 board[i * BOARD_SIZE + j] = k; 89 searchTsumi(dep + 1); 90 board[i * BOARD_SIZE + j] = NULL; 91 } 92 } 93 } 94} 95 96/* 詰んでいるかどうかの判定 */ 97int hantei(int dep) { 98 99 //玉の位置を特定 100 for (int i = 0; i < 4; i++) { 101 for (int j = 5; j < 9; j++) { 102 if(board[i * BOARD_SIZE + j]==GYO){ 103 kingE = i * BOARD_SIZE + j; 104 } 105 } 106 } 107} 108 109int main() { 110 init(); 111 searchTsumi(0); 112 return 0; 113}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/01/08 12:31

で、しつもんはなんでしょうか
izmktr

2019/01/08 22:32

メモリリークがひどいコードですね… 学校の課題でないのならC言語使わないほうがいいのでは…
guest

回答3

0

詰みの状態とは、

  1. 王の現在位置と周囲8マス中で空いているマスのすべてで、敵方の駒が移動可能である(筋が効いている)
  2. 現在王に対して王手をかけている駒を取ることのできる味方の駒(王自身も含む)がないか、あってもその駒を動かした場合に別の王手が発生する
  3. 王に対して王手をかけている駒が香車・飛車・角行の場合、味方の駒を移動させて筋を殺すことができない。もしくは合駒を打つことができない

になるでしょうか。
1は純粋に移動させた局面を構成して(高々9局面です)やればよいですね。
2と3が面倒ですね。どこになら駒が移動できるか、そしてその駒が移動したことによって別の王手が発生しないか、をそれぞれ局面構成して調べる必要があるでしょう。
※ルール上、「盤面上になく、攻め手側の持ち駒でない駒は、すべて受け手側の持ち駒である」ので、合駒が足りなくなることはなさそうですが

投稿2019/01/09 07:00

編集2019/01/09 07:38
tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ある盤面が詰んでいるのか詰んでいないのかを判定

詰んでいる=玉側に打つ手がない なので
ルール上やれる防衛手段(?)が有効か否かを順に調べればよいのでは.

  1. とりあえず王手がかかっていなければ詰んでない
  2. 王手をかけている駒が1個だけの場合は以下を判定

2-1. 玉ではない味方の駒でそれを取れるなら詰んでない
2-2. 間駒を打てる状態(相手が特定の駒種類であって且つ玉に隣接してない)なら詰んでない
3. 玉が移動できる範囲に,敵の駒が利いてない場所があれば詰んでない

みたいな.

(コード見てないけど,盤面をてきとーに作ってるなら,二歩とかになってないことの判定も別途要るかも?)

投稿2019/01/09 06:32

fana

総合スコア11673

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

詰みとは、玉がどう動いても次に必ず取られてしまう状態にあることです。
玉の周りの8マスを調べて、味方の駒や敵駒の利きで全て埋まっていた場合詰み、
一ヶ所でも移動可能なら詰みではないという処理で出来ると思います。

投稿2019/01/09 00:57

asobinin

総合スコア69

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問