ページ 11

ターン制について

Posted: 2010年7月16日(金) 20:02
by gyt
オセロや将棋などのボードゲームに使われているターン制をプログラムで書くにはどのように考えればいいのでしょうか?
自分が駒を置く(動かす)と相手の番になるようなプログラムを書きたいです。
が、考え方が分かりません(T.T)

int junban=0;のようにして自分が操作し終わったらjunban=1;のようにし、junbanが1なら相手、0なら自分のような考え方でいいのでしょうか?

もし、もっと楽でスマートな考え方があったら教えてください。
できれば簡単な例なども教えてくださると嬉しいです

ご指南お願いします。

Re:ターン制について

Posted: 2010年7月16日(金) 21:54
by Justy
>junbanが1なら相手、0なら自分のような考え方でいいのでしょうか?
 それでいいと思います。
 intじゃなくて enumを使って明示的に誰の手番かを表せば判りやすくてもっといいですね。

Re:ターン制について

Posted: 2010年7月16日(金) 21:59
by gyt
Justyさん、回答ありがとうございます。


そこで質問なのですが、enumを使うとintを使ったときとどう変わるのでしょうか?
いまいちenumについて理解できてないので、教えてくださると助かります。

Re:ターン制について

Posted: 2010年7月16日(金) 22:18
by Justy
>enumを使うとintを使ったときとどう変わるのでしょうか?
 よく読み直してみたら、対戦相手も人間で交互に操作するくらいで、特に処理的に分岐することが
ないようであればintのままでもいいのかもしれません。

 ただ自分と相手とで処理を分けなければならないようなケース……例えば相手が CPUだったり、
ネットワーク先の対戦相手だったりしたのなら、
[color=#d0d0ff" face="monospace]
enum Turn
{
Turn_Player,
Turn_CPU
};
[/color]

とかしておいてソースコード上で
[color=#d0d0ff" face="monospace] if(junban == Turn_Player)
[/color]
とすれば見ただけでプレイヤーの番だと判ります。

[color=#d0d0ff" face="monospace] if(junban == 0)
[/color]
とするよりは判りやすいはずです。

 又、デバッガで変数の値を参照するとき、多くの環境で enumの値はその名前で表示されます。
 Playerと CPUの2つくらいしか無い場合はあまり影響はないかもしれませんが、
種類が増えてきたとき見ただけでそれが何なのかわかるので、デバッグの効率も上がると思います。

Re:ターン制について

Posted: 2010年7月16日(金) 22:27
by gyt
なるほど...
後々のことを考えるとenumを使ったほうが効率が良くなりそうですね。
例まで使っての説明、ありがとうございます。

参考にさせていただきます。

Re:ターン制について

Posted: 2010年7月16日(金) 22:45
by Lbfuvab
ここではオセロの話題とし、手を
typedef struct{
    int x,y;
}MOVE;
で表すものとすると

MOVE PlayerTurn(int Color);
MOVE ComTurn(int Color);

MOVE (*Turns[2])(void);

のようにしておくと、プレイヤー同士やCOM同士の実装が楽になるのでお勧めです。

ターンの切り替えは
Turn ^= 1;で良いんじゃないですか(0,1のみなら)

Re:ターン制について

Posted: 2010年7月16日(金) 23:53
by gyt
>
typedef struct{
>     int x,y;
> }MOVE;
>
> で表すものとすると
>
> MOVE PlayerTurn(int Color);
> MOVE ComTurn(int Color);
>
> MOVE (*Turns[2])(void);
>
> のようにしておくと、プレイヤー同士やCOM同士の実装が楽になるのでお勧めです。

このようにおくと、どのように楽になるのでしょうか?

また
> MOVE PlayerTurn(int Color);
> MOVE ComTurn(int Color);

のint Colorにはどのような意味があるのでしょうか?


> ターンの切り替えは
> Turn ^= 1;で良いんじゃないですか(0,1のみなら)

Turn ^=1;
の ^の意味が分かりません。orz
どのように使われていて、どのような意味を持つのでしょうか?

質問ばかりでスミマセン。
初歩的な質問だったらごめんなさい。

Re:ターン制について

Posted: 2010年7月17日(土) 17:55
by KEYONN_
Turn^=1;
の意味は、0と1を繰り返すという事です。
1とのXOR(排他的論理和)ですので、

XORを表を書いて説明すると

XOR
|0 0|→0
|1 0|→1
|0 1|→1
|1 1|→0
となります。

とここで、Turn=Turn XOR 1;として、Turnが初期値0だとすると、
どうなるでしょうか?

0 XOR 1なので、結果は1です。それをまたTurnに代入します。
今度は、1 XOR 1ですね?結果は、0です。それをまたTurnに代入します。
これを繰り返していく訳です。

Re:ターン制について

Posted: 2010年7月17日(土) 21:07
by lbfuvab
プレイヤー対COMのみの実装ならあまりメリットはないですが、
プレイヤー対プレイヤーやCOM対COMや過去対戦の読み込みを考えると結構メリットがありますよ。

Re:ターン制について

Posted: 2010年7月17日(土) 22:11
by gyt
TKOZさん、
Turn^=1;
の意味を教えていただきありがとうございます。
XORは授業で習ったので、理解しました。

lbfuvadさん、
>プレイヤー対プレイヤーやCOM対 COMや過去対戦の読み込みを考えると結構メリットがありますよ。
どのようなメリットなのでしょうか?
今作っているのはプレイヤー対COMなのですが、完成したら実装を増やすかもしれないので教えてくださると助かります(-人-)

質問ばかりでスミマセン。

皆さん、回答ありがとうございました。

Re:ターン制について

Posted: 2010年7月20日(火) 02:00
by lbfuvab
おお、続いてた。

私は

typedef MOVE (*ChoiceFunc_t)(int);

int Game(ChoiceFunc_t White,ChoiceFunc_t Black);

みたいなのを実体にしようと考えていました。

ええと、メリットとしては
1.構造が分かりやすくなるのでバグが減る(よりブラックボックス化出来る)
2.ブラックボックス化のメリットとして少ない労力でモード追加ができる

デメリットは
1.基本的に制御をとりっぱなし構造なのでGUIにするならマルチスレッド化がほぼ必須
2.そんなに機能追加しないなら無駄が多い

Re:ターン制について

Posted: 2010年7月20日(火) 02:02
by lbfuvab
追記です。

GUIなソフトでしっかりしたAIを組み込むならどっちにしてもマルチスレッドになります(一応プロセス間通信もありですが・・・