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

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

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

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

Q&A

2回答

2227閲覧

はさみ将棋の囲み判定

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2018/07/07 07:16

編集2018/07/08 05:35

はさみ将棋をc言語で作っており、囲まれた時の判定をどのように判定したらいいのかわからずに困ってます。

はさみ将棋をc言語で作っており、挟まれた時の判定はできたのですが、囲まれた時の判定をどのように判定したらいいのかわからずに困ってます。
盤の配列は11x11で定義していますが、ゲームの盤自体はは9x9で考えていて、盤の一番上下左右の端は壁として設定しています。

発生している問題・エラーメッセージ

囲まれた時の判定をどのように判定したらいいのかわからない。

該当のソースコード

二次元配列を使って、盤を保存しています。 #define HORIZONTAL_LINE 11//横 #define VERTICAL_LINE 11//縦 #define EMPTY 0 #define FU 1 #define TO 2 #define KABE 3 //グローバル変数 int table[VERTICAL_LINE][HORIZONTAL_LINE];//[縦][横] int counta, countb; //駒と碁盤の壁を定義 for (counta = 0; counta < VERTICAL_LINE; counta++) { for (countb = 0; countb < HORIZONTAL_LINE; countb++) { table[counta][countb] = EMPTY; } } for (counta = 0; counta < VERTICAL_LINE; counta++) { for (countb = 0; countb < HORIZONTAL_LINE; countb++) { if (counta == 1) { table[counta][countb] = TO; } if (counta == VERTICAL_LINE - 2) { table[counta][countb] = FU; } if (counta == 0 || counta == VERTICAL_LINE - 1 || countb == 0 || countb == HORIZONTAL_LINE - 1) { table[counta][countb] = KABE; } }

試したこと

移動した駒の左右上下を確認していく。
それぞれで壁の値が出るまで、相手の駒が連続で続いているかをチェックして、続いていたらその続いている駒の上下を確認していく?
自分でもよくわかりません。

補足情報(FW/ツールのバージョンなど)

はさみ将棋のルール(公益社団法人 日本将棋連盟)
https://www.shogi.or.jp/knowledge/hasami_shogi/

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

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

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

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

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

guest

回答2

0

2018/07/09 追記しました

追記ここから

is_siege関数が囲まれているかを判定する関数となっています。

c

1#include <stdio.h> 2 3#define HORIZONTAL_LINE 11 //横 4#define VERTICAL_LINE 11 //縦 5#define EMPTY 0 6#define FU 1 7#define TO 2 8#define KABE 3 9 10 11#define UE 0 12#define SHITA 1 13#define HIDARI 2 14#define MIGI 3 15 16 17//グローバル変数 18int table[VERTICAL_LINE][HORIZONTAL_LINE] = { 19{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 20{ 3, 0, 1, 0, 0, 0, 0, 0, 1, 2, 3 }, 21{ 3, 0, 2, 0, 1, 2, 1, 0, 1, 2, 3 }, 22{ 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3 }, 23{ 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, 24{ 3, 2, 1, 0, 0, 1, 1, 0, 0, 0, 3 }, 25{ 3, 1, 0, 0, 0, 2, 2, 1, 0, 0, 3 }, 26{ 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3 }, 27{ 3, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3 }, 28{ 3, 0, 1, 2, 1, 0, 1, 2, 2, 2, 3 }, 29{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 30}; 31 32struct stack { 33 int koma; 34 int x; 35 int y; 36}; 37 38#define STACK_SIZE 9 39static struct stack s_stack[STACK_SIZE]; 40static int s_stack_top; 41 42 43void init_stack(void) { 44 s_stack_top = 0; 45} 46 47void push(int koma, int x, int y) { 48 if (s_stack_top >= STACK_SIZE) { 49 return; 50 } 51 s_stack[s_stack_top].koma = koma; 52 s_stack[s_stack_top].x = x; 53 s_stack[s_stack_top].y = y; 54 s_stack_top++; 55} 56 57int pop(struct stack* s) 58{ 59 if (s_stack_top < 1) { 60 return 0; 61 } 62 63 s_stack_top--; 64 s->koma = s_stack[s_stack_top].koma; 65 s->x = s_stack[s_stack_top].x; 66 s->y = s_stack[s_stack_top].y; 67 return 1; 68} 69 70 71 72void disp_table(void) 73{ 74 int i, j; 75 putchar(' '); 76 for (i = 0; i < HORIZONTAL_LINE; i++) 77 { 78 putchar(i + 0x30); 79 } 80 putchar('\n'); 81 for (j = 0; j < VERTICAL_LINE; j++) 82 { 83 putchar(j + 0x30); 84 for (i = 0; i < HORIZONTAL_LINE; i++) 85 { 86 switch (table[j][i]) 87 { 88 case KABE: 89 putchar('*'); 90 break; 91 case FU: 92 putchar('F'); 93 break; 94 case TO: 95 putchar('T'); 96 break; 97 default: 98 putchar(' '); 99 break; 100 } 101 } 102 putchar('\n'); 103 } 104} 105 106// 駒のつながりが途切れた先にあるものを調べる 107int koma_probe(int koma, int x, int y, int d) 108{ 109 int placed; 110 if (table[y][x] == EMPTY) 111 { 112 return EMPTY; 113 } 114 if (table[y][x] == KABE) 115 { 116 return KABE; 117 } 118 if (table[y][x] != koma) 119 { 120 return table[y][x]; 121 } 122 123 placed = 0; 124 switch (d) 125 { 126 case UE: 127 placed = koma_probe(koma, x, y - 1, d); 128 break; 129 case SHITA: 130 placed = koma_probe(koma, x, y + 1, d); 131 break; 132 case HIDARI: 133 placed = koma_probe(koma, x - 1, y, d); 134 break; 135 case MIGI: 136 placed = koma_probe(koma, x + 1, y, d); 137 break; 138 } 139 return placed; 140} 141 142 143// komaをたどりながらEMPTYを探す 144// EMPTYを検出した=囲まれてないので取れない 145// 0 - EMPTYが無かった 146// 1 - EMPTYを見つけた 147int empty_probe(int ff_table[][HORIZONTAL_LINE], int koma, int x, int y) { 148 if (ff_table[y][x] == koma) { 149 push(koma, x, y); 150 ff_table[y][x] = -1; //検査済み 151 152 } 153 else if (ff_table[y][x] == EMPTY) { 154 // EMPTYを見つけたので探査を打ち切る 155 return 1; 156 } 157 else { 158 // EMPTYではない何かがあったので探査を打ち切る 159 return 0; 160 } 161 162 // 上下左右方向に探査を続ける 163 if (empty_probe(ff_table, koma, x, y - 1)) { 164 return 1; 165 } 166 else if (empty_probe(ff_table, koma, x, y + 1)) { 167 return 1; 168 } 169 else if (empty_probe(ff_table, koma, x - 1, y)) { 170 return 1; 171 } 172 else if (empty_probe(ff_table, koma, x + 1, y)) { 173 return 1; 174 } 175 return 0; 176} 177 178 179// 囲まれているか調べる 180int is_siege(int koma, int x, int y) 181{ 182 int i, j; 183 184 // 作業用にコピーする 185 int ff_table[VERTICAL_LINE][HORIZONTAL_LINE]; 186 for (j = 0;j < VERTICAL_LINE;j++) { 187 for (i = 0;i < HORIZONTAL_LINE;i++) { 188 ff_table[j][i] = table[j][i]; 189 } 190 } 191 192 init_stack(); 193 return !empty_probe(ff_table, koma, x, y); 194} 195 196 197//x,yの位置にある駒が取れるか? 198// 0 - とれない 199// 1 - 取れる 200int is_capture(int x, int y) 201{ 202 int koma = table[y][x]; 203 int ue = koma_probe(koma, x, y - 1, UE); 204 int shita = koma_probe(koma, x, y + 1, SHITA); 205 int hidari = koma_probe(koma, x - 1, y, HIDARI); 206 int migi = koma_probe(koma, x + 1, y, MIGI); 207 208 int aite; 209 if (koma == FU) 210 { 211 aite = TO; 212 } 213 else 214 { 215 aite = FU; 216 } 217 218 //上下左右方向にaiteで挟まれてたら取れる 219 if (ue == aite && shita == aite) 220 { 221 return 1; 222 } 223 if (hidari == aite && migi == aite) 224 { 225 return 1; 226 } 227 228 // コマが囲まれてたら取れる 229 if (is_siege(koma, x, y)) { 230 return 1; 231 } 232 233 return 0; 234} 235 236void disp_result(int x, int y) 237{ 238 int koma = table[y][x]; 239 char *name[2] = { "FU", "TO" }; 240 if (is_capture(x, y)) 241 { 242 printf("%d,%dの%sは取れる\n", x, y, name[koma - 1]); 243 } 244 else 245 { 246 printf("%d,%dの%sは取れない\n", x, y, name[koma - 1]); 247 } 248} 249 250int main(void) 251{ 252 disp_table(); 253 disp_result(2, 2); 254 disp_result(5, 2); 255 disp_result(1, 5); 256 disp_result(3, 9); 257 disp_result(5, 6); 258 disp_result(6, 6); 259 disp_result(8, 9); 260 disp_result(9, 1); 261} 262

実行結果

0123456789: 0*********** 1* F FT* 2* T FTF FT* 3* F * 4*F * 5*TF FF * 6*F TTF * 7* F * 8* F F * 9* FTF FTTT* :*********** 2,2のTOは取れる 5,2のTOは取れる 1,5のTOは取れる 3,9のTOは取れる 5,6のTOは取れる 6,6のTOは取れない 8,9のTOは取れない 9,1のTOは取れない

追記ここまで


is_capture関数で指定位置の駒を取れるか調べます。

c

1#include <stdio.h> 2 3#define HORIZONTAL_LINE 11 //横 4#define VERTICAL_LINE 11 //縦 5#define EMPTY 0 6#define FU 1 7#define TO 2 8#define KABE 3 9 10//グローバル変数 11int table[VERTICAL_LINE][HORIZONTAL_LINE] = { 12{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 13{ 3, 0, 1, 0, 0, 0, 0, 0, 1, 2, 3 }, 14{ 3, 0, 2, 0, 1, 2, 1, 0, 1, 2, 3 }, 15{ 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3 }, 16{ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, 17{ 3, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3 }, 18{ 3, 0, 0, 0, 0, 2, 2, 1, 0, 0, 3 }, 19{ 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3 }, 20{ 3, 1, 0, 0, 0, 0, 0, 1, 1, 1, 3 }, 21{ 3, 2, 1, 0, 0, 0, 0, 2, 2, 2, 3 }, 22{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 23}; 24 25void disp_table(void) 26{ 27 int i, j; 28 putchar(' '); 29 for (i = 0; i < HORIZONTAL_LINE; i++) 30 { 31 putchar(i + 0x30); 32 } 33 putchar('\n'); 34 for (j = 0; j < VERTICAL_LINE; j++) 35 { 36 putchar(j + 0x30); 37 for (i = 0; i < HORIZONTAL_LINE; i++) 38 { 39 switch (table[j][i]) 40 { 41 case KABE: 42 putchar('*'); 43 break; 44 case FU: 45 putchar('F'); 46 break; 47 case TO: 48 putchar('T'); 49 break; 50 default: 51 putchar(' '); 52 break; 53 } 54 } 55 putchar('\n'); 56 } 57} 58 59// 駒のつながりが途切れた先にあるものを調べる 60int probe(int koma, int x, int y, int d) 61{ 62 int placed; 63 if (table[y][x] == EMPTY) 64 { 65 return EMPTY; 66 } 67 if (table[y][x] == KABE) 68 { 69 return KABE; 70 } 71 if (table[y][x] != koma) 72 { 73 return table[y][x]; 74 } 75 76 placed = 0; 77 switch (d) 78 { 79 case 0: 80 placed = probe(koma, x, y - 1, d); 81 break; 82 case 1: 83 placed = probe(koma, x, y + 1, d); 84 break; 85 case 2: 86 placed = probe(koma, x - 1, y, d); 87 break; 88 case 3: 89 placed = probe(koma, x + 1, y, d); 90 break; 91 } 92 return placed; 93} 94 95//x,yの位置にある駒が取れるか? 96// 0 - とれない 97// 1 - 取れる 98int is_capture(int x, int y) 99{ 100 int koma = table[y][x]; 101 int ue = probe(koma, x, y - 1, 0); 102 int shita = probe(koma, x, y + 1, 1); 103 int hidari = probe(koma, x - 1, y, 2); 104 int migi = probe(koma, x + 1, y, 3); 105 106 int aite; 107 if (koma == FU) 108 { 109 aite = TO; 110 } 111 else 112 { 113 aite = FU; 114 } 115 116 if (ue == aite && shita == aite) 117 { 118 return 1; 119 } 120 if (ue == aite && shita == KABE) 121 { 122 if (hidari != EMPTY && migi != EMPTY) 123 { 124 return 1; 125 } 126 } 127 if (ue == KABE && shita == aite) 128 { 129 if (hidari != EMPTY && migi != EMPTY) 130 { 131 return 1; 132 } 133 } 134 135 if (hidari == aite && migi == aite) 136 { 137 return 1; 138 } 139 if (hidari == aite && migi == KABE) 140 { 141 if (ue != EMPTY && shita != EMPTY) 142 { 143 return 1; 144 } 145 } 146 if (hidari == KABE && migi == aite) 147 { 148 if (ue != EMPTY && shita != EMPTY) 149 { 150 return 1; 151 } 152 } 153 154 return 0; 155} 156 157void disp_result(int x, int y) 158{ 159 int koma = table[y][x]; 160 char *name[2] = { "FU", "TO" }; 161 if (is_capture(x, y)) 162 { 163 printf("%d,%dの%sは取れる\n", x, y, name[koma - 1]); 164 } 165 else 166 { 167 printf("%d,%dの%sは取れない\n", x, y, name[koma - 1]); 168 } 169} 170 171int main(void) 172{ 173 174 disp_table(); 175 disp_result(2, 2); 176 disp_result(5, 2); 177 disp_result(1, 9); 178 disp_result(5, 6); 179 disp_result(6, 6); 180 disp_result(9, 9); 181 disp_result(9, 1); 182}

実行結果

./a.out 0123456789: 0*********** 1* F FT* 2* T FTF FT* 3* F * 4* * 5* FF * 6* TTF * 7* F * 8*F FFF* 9*TF TTT* :*********** 2,2のTOは取れる 5,2のTOは取れる 1,9のTOは取れる 5,6のTOは取れる 6,6のTOは取れない 9,9のTOは取れない 9,1のTOは取れない

投稿2018/07/07 12:08

編集2018/07/09 06:05
tatamyiwathy

総合スコア1039

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

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

退会済みユーザー

退会済みユーザー

2018/07/08 05:51 編集

回答ありがとうございます。tatamyiwathyさんの回答で考えさせていただいたのですが、この判定方法だとはさみ判定しかうまくできませんでした。囲み判定を対象の駒の上と下。そして左右の連続する駒の端しか確認しておらず。 例えば、下のような場合も取れると判定してしまいます。(とは完全に囲まれてはいない) 0123456789: 0*********** 1* * 2* * 3* * 4* * 5* * 6* * 7* * 8* F * 9* FTTTTT* :.*********** 6,9のTOは取れる ↑の状況    歩 歩ととトとと壁 壁壁壁壁壁壁壁 トについてチェック 私のルール説明不足だったのですが、囲む場合は相手の駒を完全に囲み連続している相手の駒がすべて移動できない状態でないと、相手の駒を取れません。私の説明では、少しわかりにくいので、質問文の補足情報にはさみ将棋のルールが説明されているサイトのリンクを張っておきましたので参考にしてください。 もし、よろしければ、これらを考慮して教えていただければ、ありがたいです。
PineMatsu

2018/07/09 08:13

横から失礼します。 はさみ将棋は、基本的にははさめば駒を取れますが、壁に接している場合は動きを封じないと取れないというルールなのですよね。 なら、判定する駒が壁に接しているかどうかで分岐させて、壁に接していなければtatamyiwathyさんの判定を使い、壁に接していたら、動けるかどうかで判定すれば良いのではないでしょうか?
guest

0

tatamyiwathyさん。PineMatsuさん。いろいろと教えていただきありがとうございました。

投稿2020/12/14 11:41

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

fiveHundred

2020/12/14 11:56

ベストアンサーとして不適切です。 これは解決に役に立った回答を選択するものです。 もし自力で解決したため該当するものがない、というのであればその解決した方法を記載してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問