演算子について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
サム
記事: 2
登録日時: 4年前

演算子について

#1

投稿記事 by サム » 4年前

Youtubeのプログラミング実況のオセロゲーム制作で、次のようなソースーコードがあります。

コード:

include<stdio.h>
#include<conio.h>
#include<stdlib.h>

#define BOARD_WIDTH 8
#define BOARD_HEIGHT 8
int cursorX=0, cursorY=0;

int turn;
int cells[BOARD_HEIGHT][BOARD_WIDTH] = {};
enum {
	COLOR_NONE=-1,
	COLOR_BLACK=0,
	COLOR_WHITE=1,
	COLOR_MAX
};
char colorNames[][5 + 1]{
	"Black",
	"White"
};

bool checkCanPut(int _color, int _x, int _y) {
	return false;
}

void drawBoard() {
	system("cls");
	for (int y = 0; y < BOARD_HEIGHT; y++) {
		for (int x = 0; x < BOARD_WIDTH; x++)
			if ((x == cursorX) && (y == cursorY))
				printf("◎");
			else {
				switch (cells[y][x]) {
				case COLOR_NONE:printf("・"); break;
				case COLOR_BLACK:printf("●"); break;
				case COLOR_WHITE:printf("〇"); break;
				}
			}
		printf("\n");
	}
}

int  main() {
	for (int y = 0; y < BOARD_HEIGHT; y++)
		for (int x = 0; x < BOARD_WIDTH; x++)
			cells[y][x] = COLOR_NONE;
	cells[3][3] = cells[4][4] = COLOR_WHITE;
	cells[4][3] = cells[3][4] = COLOR_BLACK;
	drawBoard();

	bool cantPut = false;

	while (1) {
		switch (_getch()) {
		case 'w':cursorY--; break;
		case 's':cursorY++; break;
		case 'a':cursorX--; break;
		case 'd':cursorX++; break;
		default:
			if (!checkCanPut(turn, cursorX, cursorY)) {
				cantPut = true;
				break;
			}
			cells[cursorY][cursorX] = turn;
			turn ^= 1;
			break;
		}
		drawBoard();
		if (cantPut)
			printf("Can't put!\n");
		else
			printf("%s turn.\n", colorNames[turn]);
	}
}
if (!checkCanPut(turn, cursorX, cursorY))の!の意味がいまいち理解できません。
!は真なら偽、偽なら真ということはわかっているんですが、上のソースコードではどのような条件で cantPut = true; の処理になるのでしょうか?
bool cantPut = false;と関係はあるのでしょうか?
もう一つ
turn ^= 1; なんですが、Youtubeでは0だったら1,1だったら0に切り替えると仰っているのですが、
定義でint turn;//turn=0//で turn ^= 1; ^=演算子で1と0を入れ替える。
つまり^=演算子は数字の入れ替えができるという考えでいいのでしょうか?
長文ですみません<(_ _)>

アバター
asd
記事: 319
登録日時: 13年前

Re: 演算子について

#2

投稿記事 by asd » 4年前

サム さんが書きました:
4年前
if (!checkCanPut(turn, cursorX, cursorY))の!の意味がいまいち理解できません。
!は真なら偽、偽なら真ということはわかっているんですが、上のソースコードではどのような条件で cantPut = true; の処理になるのでしょうか?
bool cantPut = false;と関係はあるのでしょうか?
checkCanPut関数の戻り値の否定(Not)を取るので、
この関数が真を返せば偽に、偽を返せば真になります。

で、checkCanPut関数の実体を見ていただくと以下の通り現状では常に偽を返しますので、
現状では常にこのif文は真になります。
(今後指定座標にコマが置けるかを判定して返すようになるものと思います)

コード:

bool checkCanPut(int _color, int _x, int _y) {
	return false;
}
cantPutは名前から推測できる通り、指定した場所にコマが置けないかを保存しておく変数かと思います。
途中でcheckCanPut関数により指定した場所にコマが置けなかった場合の処理を行うために、
コマが置けなかったかどうかを変数に保存して後に利用しています。
(当該箇所にコメント付きで解説入れてみました)

コード:

	bool cantPut = false;//指定場所に置けないかどうかのフラグ変数。初期値は偽なので置ける(置けないcan'tPutが偽なので)

	while (1) {
		//~略~
		default:
			if (!checkCanPut(turn, cursorX, cursorY)) {	//指定場所にコマが置けなかったら
				cantPut = true;					//置けないフラグを真に
				break;
			}
			cells[cursorY][cursorX] = turn;
			turn ^= 1;
			break;
		}
		drawBoard();
		if (cantPut)						//置けないフラグが真だったら
			printf("Can't put!\n");
		else
			printf("%s turn.\n", colorNames[turn]);
	}
サム さんが書きました:
4年前
もう一つ
turn ^= 1; なんですが、Youtubeでは0だったら1,1だったら0に切り替えると仰っているのですが、
定義でint turn;//turn=0//で turn ^= 1; ^=演算子で1と0を入れ替える。
つまり^=演算子は数字の入れ替えができるという考えでいいのでしょうか?
数字の入れ替えというと語弊があるのですが、ビット演算で1との排他的論理和(XOR)をとっています。
排他的論理和というのは二つのビットにおいて同じビットは0に、異なるビットは1になります。
ビットやビット演算にサムさんがどの程度詳しいのかわからないのですが、
数値を二進数にして各桁ごとに上記の計算を行います。

たとえば13と3のXORは以下の通り14になります(一番下位のビットだけ同じなので0、それ以外は異なるので1になる)
1101…13の二進数
0011…3の二進数
1110…13と3のXOR

これを念頭に置いてturnの演算を見てみると1とのXORなので、
turnが0だったら0と1のXORで1
turnが1だったら1と1のXORで0
になるのでビットが反転する形になります。
(1ビットで表していますが、int型なので上位にもっとビットがありますが全部0なので表記を省略しています)

分かりにくい箇所があれば遠慮なく聞いてくださいね(*´ヮ`)
Advanced Supporting Developer
無理やりこじつけ(ぉ

サム
記事: 2
登録日時: 4年前

Re: 演算子について

#3

投稿記事 by サム » 4年前

なるほど!!
とてもわかりやすく助かりました!
(人''▽`)ありがとうございました。

アバター
asd
記事: 319
登録日時: 13年前

Re: 演算子について

#4

投稿記事 by asd » 4年前

どういたしまして(*´ヮ`)r
解決したようでよかったです!
Advanced Supporting Developer
無理やりこじつけ(ぉ

返信

“C言語何でも質問掲示板” へ戻る