|
/*========================================================*/ <<<あゆしゃのC言語プログラミング>>> /*========================================================*/ 第530回 2次元配列の行を代入・削除 発行 2005年1月21日(水曜日) 発行数 約2600 {magclick} /*========================================================*/ はじめに ( 決り文句 ) /*========================================================*/ ・このメールマガジンは、主にまぐまぐさんから発行しています。 ・ジャンルは、マルチメディアのプログラム、C言語です。 ・横60文字で作成し、インデントは大抵半角スペース4つです。 ・ここで扱うプログラムは、C言語と半光年以内のものです。 ・登録解除は、メルマガのホームページでお願いします。 ・過去ログはバックナンバー(下欄参照)を活用して下さい。 ・内容は私が感じたもので、最新の技術も、へたれもあります。 ・わかりやすさを優先させる為、たまに嘘があるかもしれません。 ・セキュリティ突破のため、暗号化された単語があります。 /*========================================================*/ ご挨拶 /*========================================================*/ こんにちは。あゆしゃです。 現在、暇があるとGIBSを作っています。 以前紹介した状態遷移図についてデバッグを進めているのです。 ユニットの移動やマップの制圧が完成し、ファーストコンタクト (両軍のユニットが始めて接触し戦闘を行う)のデバッグ中です。 ★とんでもない動きをしたりして、少し面白いのですが、 ブレークポイントやステップ実行が使えないので、少々苦戦して います。 変数の書き間違えなども良くやるので、Perlの文法チェックを やってくれるツールでもないものかと思いましたが、良くわかりま せんでした。 {magclick} /*========================================================*/ 今回のお題 << 2次元配列の行を代入・削除 >> /*========================================================*/ それを踏まえて今回は、Perlのお話です。 GIBSのシステム上、ターン終了処理の1回のアクセスで、最大 1000ユニットを処理しなければなりません。 これは100ユニット*5ラウンド*2プレイヤーという計算 ですが、原作は200ユニットなので、所要時間に余裕があれば 2000ユニットを処理したいところです。 そこで、Perlでポインタを使用する技をいろいろと考えて きました。 今回、また新しい技に気がつきました。 # 2次元配列の初期化 @data = ([]); # 2次元配列の0行目のポインタを取得 *pd0 = $data; # 2次元配列の0行目の5列目に代入 $pd0[ 5 ] = 2; こういうポインタの使い方を、前回までに紹介しました。 今回、困ったのは、破壊されたユニットの情報を消す処理と、 マップにいるユニットをカウントする処理です。 /*========================================================*/ ユニットが破壊された場合、そのユニットの情報を持つ行を 1行削除します。 この1行削除を、ループをはってちまちまと””を代入して いては、日が暮れます。 そこで、 @data[ 35 ] = (); みたいな処理ができないものかと、いろいろ工夫していました。 これをそのまま実行させると死ぬのですが、以下のようにすると 思惑通りに動きました。 @{ $data[ 35 ] } = (); これで data の35行目をすべて消しています。 @{}については、2次元配列のファイル入出力処理で紹介した ポインタから配列へキャストする方法です。 そして配列に対して空の配列()を代入することにより、行が ばっさりと消える、というスンポーです。 /*========================================================*/ もう1つ困ったのが、ユニットのカウントです。 ジャブローに5ユニットいるという場合、各ユニットの処理で ジャブローのユニット数にあたる変数をインクリメントすればOK です。 しかし。 そのユニット数は、1ラウンド分のユニット数でなければ なりません。 さらに。 ラウンドごとの処理で、前のラウンドのユニット数を使用したい のです、制圧や撤退の条件として。 前のラウンドのユニット数は保持しつつ、今回のラウンドの ユニット数を0からカウントするには、バッファを2種類持つほか ありません。 でも。 ラウンドの終了時に、前回のユニット数を消し、今回のユニット 数を反映しなければなりませんが、これをループをはってちまちま とやっていては、日が暮れます。 ここで行コピーを使いたいのです。 しかし行コピーを行う方法を知りませんでした。 しかも敵は2次元配列です。良くわかりませんでした。 そこで、ユニット削除です。 @{ $data[ 35 ] } = (); これと同じことをしようと考えました。つまり、 # ラウンドの最初にカウンタ(バッファ)をゼロクリア @num = ([]); # ユニットループ for( $i = 1; $i <= 100; $i++ ) { # 勢力ループ foreach $now_side ( $e_side, $side ) { # ポインタを取得 *data = $now_side == $side ? *fd_data : *fd_e_data; *udd = $data[ $fi_data_unitdata_top + $i ]; # 現在の勢力・マップのユニット数をインクリメント $mapno = $udd[ $fi_data_unitdata_map ]; $num[ $now_side ][ $mapno ]++ if( $mapno ); } } # 今回カウントした内容をメインデータに反映 @{ $data[ 5 ] } = @{ $num[ $side ] }; # 自分用自分分 @{ $data[ 6 ] } = @{ $num[ $e_side ] }; # 自分用相手分 @{ $e_data[ 5 ] } = @{ $num[ $e_side ] }; # 相手用相手分 @{ $e_data[ 6 ] } = @{ $num[ $side ] }; # 相手用自分分 という感じでカウンタ処理を組みました。 2次元配列の1行から2次元配列の1行へコピーしています。 ギgレrンの野望に登場するマップの数は78です。 78のループをまわすより、行コピーのほうが早い(かなぁ?) ということに加えて、この方が気持ちがいいです。 /*========================================================*/ 現在、通常の画面処理が150msであり、16ユニットが存在 する状態でのターン終了時が200msです。 つまり、16ユニット*5*2を処理するのに、約50ms かかっています。 これはデスクトップ上のアパッチ(デバッグソフト)の処理速度 であり、実際のサーバは5倍〜10倍ぐらい早いです。 このmsという単位は、ミリ秒ですが、SOLDOUT で表示される CPUs と同じようなものです。 SOGの画面の CPUs が約 0.1 CPUs ですので、100msほど かかっている、ということになります。 負荷が大きいとサーバを追い出されてしまいますが、300ミリ 秒ぐらいまでなら、大丈夫かと思っています。 本当でしょうか? {magclick} /*========================================================*/ さいごに /*========================================================*/ 自分で作るとしても、派手なものは製作に時間がかかるので ちょっといやです。 しかし、変数のチェックだけなら、簡単なツールとして作成 できるかもしれません。 {magclick} /*========================================================*/ 次回予告 /*========================================================*/ 次回は1月21日(金曜日)に、第531回をお送りします。 お題は「GIBS 0.5 先行試作版」 現状、どのようになっているのか、少し公開してみましょう。 ただし、ユーザの新規登録処理が動かないようにしておきます。 お楽しみに! /*========================================================*/ 最後の決り文句 /*========================================================*/ このメールマガジンは、まぐまぐさんから発行しています。 このメールマガジンを解除したい場合は、まぐまぐさんをご利用 ください。このメルマガのまぐまぐアイディーは最後にあります。 このメールマガジンには広告が挿入されていますか? このメールマガジンの内容に文面の引用はありませんか? めーらっくすの場合はめーらっくすの利用方に従ってください。 このメールマガジンの内容の、転用、流用、宣伝、リンク、 少しだけよ? なんて大歓迎です。 {magclick} /*========================================================*/ /*========================================================*/ 発行者 あゆしゃ ホームページ::あゆしゃの世界 http://ayusya.hp.infoseek.co.jp/ ご意見・ご感想・ご質問メール mailto:ayusya@flamenco.plala.or.jp まぐまぐ::アイディー 0000020674 まぐまぐ::登録と解除 http://www.mag2.com/m/0000020674.htm まぐまぐ::バックナンバー http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674 めーらっくす::アイディー MM3E1AEE285AB4F めーらっくす::登録と解除 http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F めーらっくす::バックナンバー★最近のものならこちらが便利★ http://www.mailux.com/mm_bno_list.php?mm_id=MM3E1AEE285AB4F |