全国高校生プログラミングコンテスト
CHaserOnline
ステップアップヒント２
8 コマンドについて□コマンドについて説明します。ＣやＨなどのプレイヤ（以下プレイヤ）の制御をおこな
うにはコマンドを使用します。コマンドには以下のものがあります（2014.6.12 現在）。説
明中のプレイヤはＣと表記します。また、戻り値が入る変数は整数型の一次元配列
returnNumber[10]とします。
一連のコマンド発行後に「user=」メッセージを受け取った場合はゲーム終了となりますので、クライアントプログラムを終了してください。
Ａ 準備コマンド（サーバに接続し、プレイヤの周囲情報を得る）
コマンド名
機能
サーバに接続し、自分のターンであればプレイヤの周囲情報grを得る。
0
1
2

3

6

Ｃ
7

5

8

マス目にある数字は returnNumber[]の添え字と一致する。

1

Ｂ 動作コマンド walk 系（指定した方向へ 1 マス移動する）
コマンド名
機能
指定した方向へ 1 マス移動する。
wu
wu・・・上wd
wd・・・下wl
wl・・・左wrwr・・・右wr の例
0361Ｃ7258

マス目にある数字は returnNumber[]の添え字と一致する。
また、数字の並びは wu, wd, wl の場合も移動先の周囲 9 マスの左上が 0 となる。
wl の例
0361Ｃ72582

Ｂ 動作コマンド look 系（指定した方向の周囲９マスの情報を得る）
コマンド名機能
指定した方向の周囲９マスの情報を得る。
lulu・・・上
ld
ld・・・下llll・・・左
lrlr・・・右
lr の例

Ｃ012345678

マス目にある数字は returnNumber[]の添え字と一致する。
また、数字の並びは lu, ld, ll の場合も探査範囲の左上が 0 となる。
ld の例

Ｃ0123456783Ｂ 動作コマンド search 系（指定した方向、真っすぐ 9 マスの情報を得る）
コマンド名
機能
指定した方向、真っすぐ 9 マスの情報を得る。
susu・・・上sd
sd・・・下slsl・・・左
srsr・・・右sr の例
Ｃ 01234567

8マス目にある数字は returnNumber[]の添え字と一致する。
また、数字の並びは左上のマスが 0 となる。
sd の例

su の例
0Ｃ

102

1324354657687Ｃ84

Ｂ 動作コマンド put 系（指定した方向へブロックを置く）
コマンド名
機能
指定した方向へブロックを置く。
pu2
pu2・・・上
pd2
pd2・・・下
pl2
pl2・・・左pr2
pr2・・・右pr2 の例
013Ｃ6※

2

78は壁マス目にある数字は returnNumber[]の添え字と一致する。

5

Ｂ 動作コマンド put&walk 系（指定した方向へブロックを置き、逆向きに１マス移動する）
コマンド名
機能
指定した方向へブロックを置き、逆向きに１マス移動する。
pu2wd
pu2wd・・・上にブロックを置き、下へ移動
pd2wu
pd2wu・・・下にブロックを置き、上へ移動
pl2wr
pl2wr・・・左にブロックを置き、右へ移動
pr2wl
pr2wl・・・右にブロックを置き、左へ移動
pru2wld
pru2wld・・・右上にブロックを置き、左下へ移動
plu2wrdplu2wrd・・・左上にブロックを置き、右下へ移動
prd2wlu
prd2wlu・・・右下にブロックを置き、左上へ移動
pld2wru
pld2wru・・・左下にブロックを置き、右上へ移動
pld2wru の例
036※

1Ｃ7258は壁

マス目にある数字は returnNumber[]の添え字と一致する。

6

Ｂ 動作コマンド kei 系（桂馬に似た動き）
コマンド名
機能
指定した方向へ桂馬に似た動きをする。
keiru
keiru・・・右上へ桂馬のような動きをする
keird
keird・・・右下へ桂馬のような動きをする
keilu
keilu・・・左上へ桂馬のような動きをする
keild
keild・・・左下へ桂馬のような動きをする
keird の例

0

3

6

1

Ｃ
7

2

5

8

マス目にある数字は returnNumber[]の添え字と一致する。

Ｃ 終了コマンド（自分のターンを終了させる）
コマンド名
機能
#

自分のターンを終了させる※周囲情報なし

7

9 プログラムの流れについて□みなさんが作るクライアントプログラムと競技サーバのやりとりは次のようになります。
まず WEB の仕組みとしてサーバへの接続、WEB コマンドの送信、サーバからのリターンメッセージの受信とサーバからの切断がひとつのセットとなります。複数のセットを連携させる仕組みとして「セッション」を利用します。
準備コマンドのｇｒをサーバへ送信して周囲情報を取得するセット、動作コマンドを選んで送信して周囲情報を取得するセット、ターンを終了させるセットの３つのセットをひとつのパッケージとします。このパッケージをターン終了まで繰り返します。クライアン
トプログラムは図 1 のフローチャートのようになります。
みなさんは、サーバから得た周囲情報をもとにコマンドを選んで送信する部分を考えます。
【フローチャート】【プログラム】(途中省略あり)

send_cmd("GetReadyCheck", "command1=gr", ReturnCode);}while(strchr(ReturnCode, ',')==NULL);

if(returnNumber[5]==2){mode = 7;}
else{
mode = 5;}

switch(mode){中略}
send_cmd("CommandCheck", param, ReturnCode);}while(strchr(ReturnCode, ',')==NULL&&strcmp(ReturnCode, "user=")!=0);

send_cmd("EndCommandCheck", "command3=%23", ReturnCode);}while(strcmp(ReturnCode, "command1=")!=0&&strcmp(ReturnCode, "user=")!=0);【図 1】プログラムの大まかな流れ

810 サンプルプログラム２（フィールド端を捉える）□① 場外についてクライアントがフィールド外に近づく、または出てしまうと周囲情報が減少します。この仕組みを利用してフィールド外へ出ないようにします。
フィールド外に近づいた場合の例
フィールド内右上にいる場合
search down の範囲がはみ出してしまった場合
0

Ｃ

2

3

10

122

3

450

1

Ｃ0

フィールド右端にいる場合

Ｃ

45Ｃ
場外に出てしまった場合

マス目にある数字は returnNumber[]の添え字と一致する
9② プログラムの保存
サンプルプログラム２をダウンロードするか、アクション部分を打ち直します。
プログラム名は「CHaserOnlineClient009-3FieldRelease.c」です。
③ プログラムの動作
・まず右へ移動します。
・右端までたどり着いたら下へ移動します。
・右下までたどり着いたら左へ移動します。
・左下までたどり着いたら上へ移動します。
・左上までたどり着いたら右へ移動します。以降はフィールドの内側を時計回りに制限ターンになるまで移動を繰り返します。
・mode(モード)という変数を作り、動作の種類を記憶させています。
④ 対戦(１台のパソコンで二つのクライアントを起動する場合)
・端末を二つ起動させる。
・二つの画面でそれぞれのコマンドを入力し、対戦させる。
ひとつは自分の ID で起動させ、もうひとつは cool や hot などの公開されている ID で起動する。
起動コマンドの例(自分の ID)./CHaserOnlineClient009-3FieldRelease.o⊔http://www7019ug.sakura.ne.jp:80/
CHaserOnline003/user/⊔-u⊔Jibun⊔–p⊔Watashi⊔-r⊔1⊔-x⊔192.168.30.251:8080

起動コマンドの例(もうひとつの ID)./CHaserOnlineClient009-3FieldRelease.o⊔http://www7019ug.sakura.ne.jp:80/
CHaserOnline003/user/⊔-u⊔cool⊔–p⊔cool⊔-r⊔1⊔-x⊔192.168.30.251:8080※先に接続したクライアントから順に C、H のキャラクタが割振られます。また、戻り値はそれぞれ 1000、2000 となります。

10⑤ サンプルプログラム/*----------------------Action を発行する-------------------------*/do{if(beforeCount != count){if(beforeCount > count){
switch(mode){case
1:mode = 5;
break;//上なら//右へ

case

5:
mode = 7;
break;//右なら//下へ

case

7:
mode = 3;
break;//下なら//左へ

case

3:
mode = 1;
break;//左なら//上へ

default:
mode = 5;//それ以外なら//右へ}}
beforeCount = count;}strcpy(param, "command2=");switch(mode){中略}
send_cmd("CommandCheck", param, ReturnCode);}while(strchr(ReturnCode,',')==NULL&&strcmp(ReturnCode,"user=")!=0);11

⑥ プログラム説明
if(beforeCount != count){・・・
beforeCount = count;}
前回の戻り値の数と変化があったら処理をします。
変化があった場合は次回のために戻り値の数を記録します。

if(beforeCount > count){
switch(mode){・・・}}
もしも、前回よりも戻り値の数が減少した場合は処理をします。

switch(mode){case1:mode = 5;
break;・・・//上なら//右へ}
右回りになるように方向を変化させます。
上記の処理を組み合わせることで、フィールド端を察知して場外へ出なくすることができます。

⑦ 注意
このクライアントは一度フィールド端を見つけると、ターン終了までフィールド端を右回りになぞり続けます。進行方向に壁があってもよけることなく進みますので、減点が増えてしまいます。うまく回避できるように判断を追加してみてください。

12

11 新アイテム、新コマンドについて□
ワープや put&walk 系コマンド、kei 系コマンドについて、使い方のヒントや注意点について説明します。
まずワープについて説明します。
このワープはコマンドではなくアイテム類であることに注意してください。
ステップアップヒント 1 の８ページでも触れましたが、このワープを取ろうとすると上下左右１０マス分移動することができます。左右への移動で考えると walk や put&walk の１０ターン分を１ターンで移動することができます。
違うエリアに移動したいときに使うと良いでしょう。ただし、移動先に他クライアントがいる可能性も考えられますので注意が必要となります。
次に put&walk 系コマンドについて説明します。
このコマンドは１ターンで put と walk の二つの動作を組み合わせて実行できる効率のよいコマンドです。CHaserOnline では相手に Put をしてもゲームは終了せずにターン終了まで進みます。相手に Put したらその逆に動くことができるこのコマンドは活用の場が多くありそうです。また、上下左右の動きに加えて斜め方向にも動くことができますのでwalk のみでの移動よりも早く動くことができます。
しかし必ず Put してから、その逆方向に動きますのでアイテムをつぶしてしまう危険性もあります。
最後に kei 系コマンドについて説明します。
このコマンドは walk の３ターン分を１ターンで移動することができます。うまく活用すれば少ないターン数で広範囲の移動や探査が可能になります。ブロックに囲まれてしまい身動きがとれないときにも効果を発揮するでしょう。しかし移動先はゲットレディでは見えない場所ですので注意が必要です。

13