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

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

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

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

584閲覧

C++ else文の内容が勝手に実行される

ijuhs

総合スコア13

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/01/26 12:36

編集2019/01/27 03:41

#C++ else文がおかしい?
c++の完全初心者なんですが、
https://www.youtube.com/watch?v=JLQLxrgygKk
を見て同じプログラムを書いています。
動画の42:00ごろのeraseConnectedBlocks関数を実装したところ、セルを選択しようとしただけでelse内の処理まで実行され、次のwhileループへ移ってしまいます。
別の場面でも同じバグが起こりましたが、その時はelseとその後ろの{の間にスペースを入れたら解決しました。今回はそれでは解決せず、困っています。回答よろしくお願いします。
##状況
セルを選択しただけでブロックの消去がされ、矢印は一瞬しか表示されない
##試したこと
elseをelse if(selectedX >=0 )にする
##該当部分のコード

C++

1#include<stdio.h> 2#include<stdlib.h> 3#include<time.h> 4#include <string.h> 5#include<conio.h> 6 7//マップ縦横幅 8#define FIELD_WIDTH 8 9#define FIELD_HEIGHT 8 10 //ブロックの種類 11#define BLOCK_TYPE_MAX 7 12 13//セルの状態 14enum{ 15 CELL_TYPE_NONE,//0 16 CELL_TYPE_BLOCK_0,//1 17 CELL_TYPE_BLOCK_1,//2 18 CELL_TYPE_BLOCK_2,//3 19 CELL_TYPE_BLOCK_3,//4 20 CELL_TYPE_BLOCK_4,//5 21 CELL_TYPE_BLOCK_5,//6 22 CELL_TYPE_BLOCK_6,//7 23 CELL_TYPE_BLOCK_MAX//8 24}; 25 26//セルAA情報 27char cellAA[][3+1] = { 28 "・",//CELL_TYPE_NONE 29 "〇",//CELL_TYPE_BLOCK_0 30 "△",//CELL_TYPE_BLOCK_1 31 "□",//CELL_TYPE_BLOCK_2 32 "●",//CELL_TYPE_BLOCK_3 33 "▲",//CELL_TYPE_BLOCK_4 34 "■",//CELL_TYPE_BLOCK_5 35 "☆",//CELL_TYPE_BLOCK_6 36}; 37 38//セル(0,0)~(7,7) 39int cells[FIELD_HEIGHT][FIELD_WIDTH]; 40 41//連結チェックされたか 42int ischecked[FIELD_HEIGHT][FIELD_WIDTH]; 43 44//カーソル位置 45int cursorX, cursorY; 46 47//選択されたセル 48int selectedX = -1, selectedY = -1; 49 50/* 51 連結判定関数 52 x:対象のx座標 53 y:対象のy座標 54 cellType:ブロックの種類 55 count:つながっている数 56*/ 57int getConnectedBlockCount(int _x, int _y, int _cellType, int _count){ 58 //判定対象か否か 59 if ((_x < 0) || (_x >= FIELD_WIDTH) || (_y < 0 ) || (_y >= FIELD_HEIGHT) || ischecked[_y][_x] || (cells[_y][_x] == CELL_TYPE_NONE) || (cells[_y][_x] != _cellType)) 60 return _count; 61 _count++; 62 ischecked[_y][_x] = true; 63 64 //再帰処理 65 //上 66 _count = getConnectedBlockCount(_x, _y-1, _cellType, _count); 67 //下 68 _count = getConnectedBlockCount(_x, _y+1, _cellType, _count); 69 //左 70 _count = getConnectedBlockCount(_x-1, _y, _cellType, _count); 71 //右 72 _count = getConnectedBlockCount(_x+1, _y, _cellType, _count); 73 74 return _count; 75} 76 77//連結したブロックを消す関数 78void eraseConnectedBlocks(int _x, int _y, int _cellType){ 79 //対象か否か 80 if ((_x < 0) || (_x >= FIELD_WIDTH) || (_y < 0 ) || (_y >= FIELD_HEIGHT) || (cells[_y][_x] == CELL_TYPE_NONE) || (cells[_y][_x] != _cellType)) 81 return; 82 //自身を消す 83 cells[_y][_x] = CELL_TYPE_NONE; 84 //上下左右も判定し消す 85 eraseConnectedBlocks(_x, _y-1, _cellType); 86 eraseConnectedBlocks(_x, _y+1, _cellType); 87 eraseConnectedBlocks(_x-1, _y, _cellType); 88 eraseConnectedBlocks(_x+1, _y, _cellType); 89} 90//main 91int main() { 92 //ブロックのランダム化 93 srand((unsigned int)time(NULL)); 94 for (int y = 0; y < FIELD_HEIGHT; y++){ 95 for(int x = 0; x < FIELD_WIDTH; x++){ 96 //1 + 0...6 =1...7 97 cells[y][x] = CELL_TYPE_BLOCK_0 + rand() % BLOCK_TYPE_MAX; 98 } 99 } 100 //描画とか 101 while (1) { 102 system("cls"); 103 for (int y = 0; y < FIELD_HEIGHT; y++) { 104 105 for (int x = 0; x < FIELD_WIDTH; x++) { 106 if ((x == cursorX) && (y == cursorY)) { 107 //カーソル 108 printf("◎"); 109 } 110 else { 111 //ブロック 112 printf("%s", cellAA[cells[y][x]]); 113 } 114 } 115 //y座標選択位置 116 if (y == selectedY){ 117 printf("←"); 118 } 119 //行移動 120 printf("\n"); 121 } 122 //最後の行に追加 123 for(int x = 0; x < FIELD_WIDTH; x++){ 124 //選択されていたら矢印を描画 125 printf("%s",(x == selectedX)?"↑":" " ); 126 } 127 128 //キー入力に対応 129 switch (_getch()){ 130 //カーソル移動 131 case 'w':(cursorY == 0)? : cursorY--; break; 132 case 's':(cursorY == FIELD_HEIGHT-1)? : cursorY++; break; 133 case 'a':(cursorX == 0)? : cursorX--; break; 134 case 'd':(cursorX == FIELD_WIDTH-1)? : cursorX++; break; 135 default: 136 if (selectedX < 0){ 137 //選択 138 selectedX = cursorX; 139 selectedY = cursorY; 140 141 }else{ 142 //入れ替え 143 int tmp = cells[cursorY][cursorX]; 144 cells[cursorY][cursorX] = cells[selectedY][selectedX]; 145 cells[selectedY][selectedX] = tmp; 146 147 //判定フラグクリア 148 memset(ischecked, 0, sizeof ischecked); 149 150 //連結判定&ブロック消去 151 for (int y = 0; y < FIELD_HEIGHT; y++){ 152 for(int x = 0; x < FIELD_WIDTH; x++){ 153 int n = getConnectedBlockCount(x, y, cells[y][x], 0); 154 if(n >= 3) { 155 eraseConnectedBlocks(x, y, cells[y][x]); 156 } 157 } 158 } 159 160 //選択解除 161 selectedX = 162 selectedY = -1; 163 } 164 break; 165 } 166 } 167} 168

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

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

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

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

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

pepperleaf

2019/01/27 12:44 編集

本当に問題の発生したコードですか? > selectedX = ~~このコード(最後から、6行目あたり)ではエラーですね。~~ ここはエラーじゃなかった。 thkanaさんの指摘箇所がエラー
y_waiwai

2019/01/26 22:32

コードの一部だけじゃなく、全体を提示しましょう バグはあなたの思っているところに発生しているとは限りません
thkana

2019/01/26 23:12

> セルを選択しようとしただけでelse内の処理まで実行され、次のwhileループへ移ってしまいます。 これはあなたの判断です。その判断に至った、観測できる「事実」を示して下さい。 実際のところ、「初心者」を自称する方が「プログラムが文法通り動かない」とおっしゃる場合、プログラムが間違っているか文法の理解が間違っているかのどちらかなのです。書かれている過去の対応や「試したこと」から考えるに文法の理解が十分ではないことは明らかです。そのあなたの判断は、申し訳ありませんが信頼できるものではありません。 「事実」を示してください。
thkana

2019/01/27 10:35

キー入力の三項演算子のところでコンパイル通らない...ということは、あなたが実際に試しているソースとは別のものということです。 違うソースコードを貼ってもあなたの問題の解決の役には立たないかも、というのはおわかりですね。 それと、「矢印は一瞬しか表示されない」という症状は、私のてもとでは「いわゆる全角(日本語)文字を入力する」という操作以外では発生しません。動画も結局見ちゃいましたけど、動画中で言っているようにEnterキーとかで操作してみたらどうなりますか。
pepperleaf

2019/01/27 12:49

thkanaさん>私のてもとでは「いわゆる全角(日本語)文字を入力する」 矢印キー等の特殊キー (内部複数バイト)でも発生。(三項演算子は、適当に設定) もしかしたら、常に漢字入力(で、Ascii変換)になっているかも。 とすると、aswdでも動かないとか。 直接入力で、スペースキーで普通に動作(と言っても、動画見てませんが)
ijuhs

2019/01/28 12:04 編集

すみません。確認不足で、スペースキーでやってみたら成功しました・・・ どうやら、選択を矢印キーですると質問の症状が起きるようです。なぜ矢印キーではこのようなバグが発生するのでしょうか?
thkana

2019/01/28 14:37

それが「バグ」かどうかは微妙です。 なぜ、というなら"Windowsがそうなるように作られている"からだし、プログラムを組む人はそれについて知らなきゃいけません。動画中では"位置の移動はFPSと同様wsadで、Enterを押して選択/交換出来るようにしましょう、まぁ他のキーでもいいことにしましょうか"みたいなことを言っているのですから、単にあなたの使い方が間違っていただけ、とも言えます。 そんなことより、今回は「ソースコードを載せて、起こった現象をそのまま書いたら話が進展した」ということをしっかり覚えておいていただきたいです。
guest

回答1

0

ベストアンサー

なぜ矢印キーではこのようなバグが発生するのでしょうか?

矢印キーは、内部で発生しているコードが 2バイト(だったか) だからです。
_getch()関数は、字面だけ見れば、文字読込みですが、実体は、1バイトの読込みとなっているからです。(英語圏から、見れば、1文字 = 1バイト)

矢印キーとかのコードは、MSのサイトとかで調べると分かりますが、とりあえず回答まで。

投稿2019/01/28 12:11

pepperleaf

総合スコア6383

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

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

ijuhs

2019/01/29 07:06

詳しい解説ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問