CHaser2009step3

全国高校生プログラミングコンテスト

CHaser2009
ステップアップヒント３【競技サーバを起動するバッチファイル】
競技サーバを起動するには、バッチファイル（CHaser2009.bat）をダブルクリックして「java edu.procon.Server2009」とコマンドを打たなければなりません。
競技をするたびにコマンドを打つのは面倒なので、サーバを起動するバッチファイ
ルを作りましょう。
program フォルダに、CHaser2009ServerStart.bat というファイルを作り、メモ帳などで以下のプログラムを入力します。

【画面 19】競技サーバ起動用のバッチファイル
こうすれば、バッチファイルをダブルクリックするだけで競技サーバが起動します。
同様に、対戦プログラムを起動するバッチファイルも作ってみましょう。

【画面 20】サンプルプログラム起動用のバッチファイル
このバッチファイルは、プログラムが保存されているフォルダまで移動して、コンパイルをした後、プログラムを実行します。もし、プログラムにエラーがあれば、コンパイラがエラーメッセージを出力し、バッチファイルを終了します。
「sample2009_02」の部分を変更すれば別のプログラムでも使用できます。

- 17 -CHaser2009step3【サンプルプログラム３】アイテム回収処理と相手への対応を追加したプログラム
program フォルダの下に「sample2009_03」という名前のフォルダを作り、次のプログラムを入力します。プログラム名は「sample2009_03.java」です。
【動作】・相手が上下左右にいた場合、その方向にブロックを put します。
・アイテムが上下左右にあった場合、その方向に walk してアイテムを回収します。
・その他は、sample2009_02.java と同じです。
・old_mode という変数を使用して、1 つ前のモード番号を格納します。
【sample2009_03.java】
12345678910111213141516171819202122232425262728
2930
31323334353637383940

public class sample2009_03 {public static void main(String[] args) {int[] value;
value = new int[10];int mode = 1,/* 現在のモード */old_mode = 1; /* 前のモード *//********** 競技サーバに接続する **********/
edu.procon.Connect2009 target;
target = new edu.procon.Connect2009("全プロ３" );while (true) {value = target.getReady( );if (value[0] == 0) break;/********** 周囲（上下左右）に相手がいるかチェック **********/
if(value[2]==1 || value[4]==1 || value[6]==1 || value[8]==1){
mode = 90; /* mode を 90 に変更する */}/********** 周囲（上下左右）にアイテムがあるかチェック **********/
if(value[2]==3 || value[4]==3 || value[6]==3 || value[8]==3){
old_mode = mode; /* 現在のモードを old_mode に保存する */mode = 20; /* mode を 20 に変更する */}/********** mode で分岐する **********/
switch (mode){case 1: /* 壁にぶつかるまで上に移動する */if(value[2] == 2){/* 上にブロックがあったら */value = target.walkRight( ); /* 右に移動し */mode = 2;/* mode を 2 に変更する */}else{/* そうでなければ、上に移動する */value = target.walkUp( );}break;
case 2: /* ブロックにぶつかるまで右に移動する */if(value[6] == 2){- 18 -CHaser2009step3

414243444546
4748
4950
515253
54
55
5657
58
5960
61626364
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

value = target.walkDown( );mode = 3;}
else{value = target.walkRight( );}break;
case 3: /* ブロックにぶつかるまで下に移動する */if(value[8] == 2){
value = target.walkLeft( );mode = 4;}
else{value = target.walkDown( );}break;
case 4: /* ブロックにぶつかるまで左に移動する */if(value[4] == 2){
value = target.walkUp( );mode = 1;}
else{
value = target.walkLeft( );}break;
case 20: /* 周囲にアイテムがあったら、取りに行く *//* 上にアイテムがあったら、上に walk する */if(value[2] == 3)
value = target.walkUp();/* 左にアイテムがあったら、左に walk する */else if(value[4] == 3) value = target.walkLeft();/* 右にアイテムがあったら、右に walk する */else if(value[6] == 3) value = target.walkRight();/* 下にアイテムがあったら、下に walk する */elsevalue = target.walkDown();mode = old_mode; /* モードを元に戻す */break;
case 90: /* 周囲に相手がいたら、put する *//* 上に相手がいたら、上に put する */if(value[2] == 1)
value = target.putUp();/* 左に相手がいたら、左に put する */else if(value[4] == 1) value = target.putLeft();/* 右に相手がいたら、右に put する */else if(value[6] == 1) value = target.putRight();/* 下に相手がいたら、下に put する */elsevalue = target.putDown();
break;}/********** 制御情報が 0 だったら終了する **********/
if(value[0] == 0) break;}/********** 競技サーバから切断する **********/
target.exit( );}}- 19 -

CHaser2009step3【プログラム説明】①変数の宣言6
7

int mode = 1,/* 現在のモード */old_mode = 1; /* 前のモード */動作の種類を記憶させる mode を宣言します。old_mode はアイテム回収処理をした後に元のモードに戻るために必要で、1 つ前のモード番号を記憶させておきます。
②チーム名
11

target = new edu.procon.Connect2009("全プロ３" );edu.procon.Connect2009 クラスを使って競技サーバに接続します。「サンプルプログラム３」なので、チーム名を「全プロ３」にしました（変更しても構いません）。
③周囲（上下左右）に相手がいるかチェック
171819/********** 周囲（上下左右）に相手がいるかチェック **********/
if(value[2]==1 || value[4]==1 || value[6]==1 || value[8]==1){
mode = 90; /* mode を 90 に変更する */CHaser2009 は、相手にブロックを put して勝利することが一番の目的です。サーバから戻り値で相手は「1」なので、if 文を使って判断します。
「value[2]==1」は上に相手がいるか？という意味です。同様に「value[4]==1」は左に相手がいるか？という意味になります。
「||」は論理和（OR）をする演算子で、上（value[2]）または左（value[4]）または右（value[6]）または下（value[8]）に相手がいるか？という意味になります。
もし、相手がいたら mode を 90 にします。
上value value value
[1]
[2]
[3]

左value value value
右[6]
[4]
[5]
value value value
[7]
[8]
[9]

下
【図 6】サーバの戻り値の格納先④mode=90 の処理
7778
7980
818283848586

case 90: /* 周囲に相手がいたら、put する *//* 上に相手がいたら、上に put する */if(value[2] == 1)
value = target.putUp();/* 左に相手がいたら、左に put する */else if(value[4] == 1) value = target.putLeft();/* 右に相手がいたら、右に put する */else if(value[6] == 1) value = target.putRight();/* 下に相手がいたら、下に put する */elsevalue = target.putDown();
break;- 20 -CHaser2009step3

switch 文を使って mode の値で分岐処理を行います。mode=90 の場合、上下左右に相手がいるので、相手のいる方向に put し勝利となります。
⑤周囲（上下左右）にアイテムがあるかチェック
22
23
24
25
26

/********** 周囲（上下左右）にアイテムがあるかチェック **********/
if(value[2]==3 || value[4]==3 || value[6]==3 || value[8]==3){
old_mode = mode; /* 現在のモードを old_mode に保存する */mode = 20; /* mode を 20 に変更する */}相手への処理と同様で if 文を使用して周囲にアイテムがあるか判断します。アイテ
ムは「3」です。アイテムを回収したあと元のモードに戻らなければならないのでold_mode に現在のモード番号を格納してから、mode に 20 を格納します。
⑥mode=20 の処理
66
67
68
69
70
71
72
73
74
75
76

case 20: /* 周囲にアイテムがあったら、取りに行く *//* 上にアイテムがあったら、上に walk する */if(value[2] == 3)
value = target.walkUp();/* 左にアイテムがあったら、左に walk する */else if(value[4] == 3) value = target.walkLeft();/* 右にアイテムがあったら、右に walk する */else if(value[6] == 3) value = target.walkRight();/* 下にアイテムがあったら、下に walk する */elsevalue = target.walkDown();mode = old_mode; /* モードを元に戻す */break;

mode=20 の場合、上下左右にアイテムがあるので、その方向に walk します。アイ
テムを回収したあと、元のモードに戻らなければならないので old_mode の値を modeに代入します。
現在、使用しているモードは表 4 の通りです。
【表 4】モードの種類と動作
mode

動作

1

ブロックにぶつかるまで上に移動する

2

ブロックにぶつかるまで右に移動する

3

ブロックにぶつかるまで下に移動する

4

ブロックにぶつかるまで左に移動する

20（新規）周囲（上下左右）のアイテムを回収する

90（新規）周囲（上下左右）の相手に put する【発展】
今回追加したプログラムは上下左右しか対応していないので、斜め方向（右上、右下、左上、左下）に対応できるモードを新たに作らないといけません。

- 21 -