1 名前:まだ初心者なの [02/06/27 02:02 ID:HvMYma0g] 比較的規模の小さい ゲームやアルゴリズムをUPしたり 語り合ったりするスレッドです。 勉強用ですので、言語の選択についてや ゲームが面白いかどうかの議論は禁止の方向で。 UPする方は使用言語を明記してください。 どうか盛り上がってください。おながいします。おながいします。
43 名前:名前は開発中のものです。 [02/06/27 23:49 ID:mqIF8vG.] モード切替機能がすごすぎるですね! 配列の勉強中。理想は式を打ち込んだら構文を解析して勝手に計算してくる奴作りたいdeath!
44 名前:名前は開発中のものです。 [02/06/28 00:56 ID:xUNqH2JY] ごめん、漏れ1に萌えちゃった。
45 名前:名前は開発中のものです。 [02/06/28 01:26 ID:81Hj0kfA] モード切替機能最高にかっこよすぎです。参考にさせていただきます
46 名前:名前は開発中のものです。 mailto:sage [02/06/28 01:29 ID:???] 異次元スレ
47 名前:名前は開発中のものです。 mailto:sage [02/06/28 13:31 ID:???] 異次元配列の勉強中です!
48 名前:名前は開発中のものです。 mailto:sage [02/06/28 19:24 ID:???] >>43 の式の構文解析って逆ポーランド記法だっけ? y=ax+bが yax*b+=に変換して計算するやつ。
49 名前:名前は開発中のものです。 mailto:sage [02/06/28 19:56 ID:???] 再帰下降じゃないのかなぁ・・・内部で式を逆ポーランドにするけども。
50 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/06/28 21:00 ID:???] ポーカーclassが形になりました。 変な入力をするとバグるのは相変わらずです… カードの交換操作は>>41 と同じです。 C++です。 ソースのみ www.geocities.co.jp/SiliconValley-Cupertino/8770/poker.txt 実行ファイル込み www.geocities.co.jp/SiliconValley-Cupertino/8770/poker.zip 相変わらず見難いソースですが… 他のテーブルゲームのclassをいくつか作れば カジノになりますねー。
51 名前:名前は開発中のものです。 [02/06/28 21:11 ID:tpZVIR7w] >>48-49 イヤ、なんと呼ばれるのかは知らないが、そんな高級なのじゃないと思う。 入力を配列に入れて、その配列の要素が数字か文字か判定していくニダ たとえば「15*3」と入力する。プログラムはそれを配列に入れ、まず変数aに15を入れ、*を読み込んで掛け算モードにして、 3を読み込んで変数bにいれて計算。配列の中身を一つずつ調べてそれが数字か文字か判定するって感じかな! しかし、「{(10+3)*5}/5」とかはどうやってやるのかなあとか思うので、みんな考えてチョ まあコンピュータにやらせるなら逆ポーランドは便利な記述法なのかなと思う
52 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/06/28 21:23 ID:???] >>51 僕はまだ、クイックソートやマージソートが 何をやっているのか、ってのがやっと解りはじめた 程度のヘタレなんですが… 難しいですね。 全くと言っていいほど、やり方が思いつかないです。 ()内の式を再帰で渡す形でバラバラにしていくのかなぁ? 頭の体操になりそうなので、毎日ちょっとずつ考えよう…
53 名前:名前は開発中のものです。 [02/06/28 21:39 ID:tpZVIR7w] 俺は51だが、俺のレベルもそのくらいだYo!>52 のほほんと頑張ろうぜ
54 名前:名前は開発中のものです。 mailto:sage [02/06/29 09:50 ID:???] 逆ポーランド記法は、スタックを使って実現。 まず、逆ポーランド記法に数式をなおす。 {(10+3)*5}/5 → 10 3 + 5 * 5 / と言うようになる。 まずは、数式を逆ポーランド記法になおす関数をつくり、結果を配列A[]にいれる。 次に、逆ポーランド記法の計算をする関数を作る。 A[]から一つずつ要素を取り出して、演算子かどうかを判断しながらスタックに格納していく。演算子だった場合は、計算を行う。 動作1:数字がきているので、そのままスタックに積む。 |10| 動作2:数字がきているので、そのままスタックに積む。 |10| 3| 動作3:演算子"+"がきているので、A[0] + A[1] をして、A[0]に代入。 |13| 動作4:数字がきているので、そのままスタックに積む。 |13| 5| 動作5:演算子"*"がきているので、A[0] * A[1] をして、A[0]に代入。 |65| 動作6:数字がきているので、そのままスタックに積む。 |65| 5| 動作7:演算子"/"がきているので、A[0] / A[1] をして、A[0]に代入。 |13| 動作8:要素がなくなったので、A[0]を出力して終了。
55 名前:名前は開発中のものです。 mailto:sage [02/06/29 13:34 ID:???] 勉強になりますた
56 名前:名前は開発中のものです。 mailto:age [02/06/29 14:26 ID:???] >>50 不覚にもハマッタよ。>>ポーカー でも、もしかしたら ロイヤルストレートってところで 入力をミスってオジャンにナターヨ。 入力ミスのチェックはしないのかな?
57 名前:50 mailto:まだ初心者なのsage [02/06/29 16:08 ID:???] すいません、ポーカーclassにバグがありました。 >>56 さんの書き込みを見て、何となくソースを 見直してみたんですけど、Flashの判定でバカなミスをかましてました。 コッソリ修正しておきましたので報告です。URLは>>50 と同じです。 >>56 僕がヘタレだからエラーチェックが入っていないってのも あるんですけど、後で再利用したり、手を加えることを考えて、余計な コードは書かないようにしています。暇があったら改良してやって下さい。 あと、すいませんが遊ぶ時は修正版をダウンロードし直して下さい…
58 名前:50 mailto:まだ初心者なのsage [02/06/29 16:13 ID:???] >>54 >逆ポーランド記法に数式をなおす。 これがえらい難しいですね… 難しいというか、ただ面倒くさいだけなのかもしれませんが。 検索すれば答えはあるんでしょうけど、なんとか 自分で作ってみたいなぁ。
59 名前:名前は開発中のものです。 mailto:sage [02/06/29 20:37 ID:???] 逆ポーランドに直すのはかなり簡単だろ。 構文解析でも基礎中の基礎じゃないか。 優先順位と括弧にだけ気をつければ良いんだから。
60 名前:名前は開発中のものです。 mailto:sage [02/06/29 23:23 ID:???] とりあえずここまで… 残りは後で考えます #! /usr/bin/env ruby def infix_to_postfix(expr) stack = ['('] result = [] operator_priority = { '*' => 50, '/' => 50, '+' => 20, '-' => 20, '(' => 10, ')' => 10, } expr.each{ |x| if '+ - * /'.split.include?(x) # operator while operator_priority[stack.last] >= operator_priority[x] result.push(stack.pop) end stack.push(x) else result.push(x) # operand はそのまま出力 end } while not stack.empty? and operator_priority[stack.last] >= operator_priority[')'] result.push(stack.pop) end result.pop # 最後は'('が入ってるので捨てる result end puts infix_to_postfix(ARGV[0].split).join
61 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/07/01 04:10 ID:???] 逆ポーランドへの変換プログラムです。 + - * / 演算に対応しています。小数の使用可です。 ()は使えません。入力時にスペースとタブを入れても大丈夫です。 今回はC言語です。 ソース www.geocities.co.jp/SiliconValley-Cupertino/8770/MtoB.txt 実行ファイル込み www.geocities.co.jp/SiliconValley-Cupertino/8770/MtoB.zip なんか、ソースのコメントからして駄目さがにじみ出ていますが。 >>59 とりあえず、自分の理解した範囲で挑戦しました。 いずれ、完璧なものが出来たらUPさせていただきます。 >>60 rubyなのですか?僕には読めません…スマソ
62 名前:名前は開発中のものです。 mailto:sage [02/07/01 05:21 ID:???] 逆ポーランドが終わったら正規表現をやると良い。 たぶん、コレも興味が持てるだろう
63 名前:名前は開発中のものです。 mailto:age [02/07/01 14:52 ID:???] 期待age 上にあるのは糞スレばっかり。 健闘を祈ります。
64 名前:名前は開発中のものです。 mailto:sage [02/07/01 16:47 ID:???] kusosure washo-i
65 名前:名前は開発中のものです。 mailto:sage [02/07/04 13:25 ID:???] プログラマの卵がんがれー
66 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/07/05 01:55 ID:???] 最近はアルゴリズムより言語の仕様の勉強中心なので UPする(意味がある)ものが少ないです。というわけで >>3 をFLASHに移植してみることに。 www.geocities.co.jp/SiliconValley-Cupertino/8770/Maze.swf (IEならF5で)リロードしてみてください。 毎回違った迷路が作成されるはずです。今はこれだけです。 これをもとに、ちょっとしたミニゲームを作る予定…(未定ですが) ソース(ファイルを開くのにFLASH5が必要です) www.geocities.co.jp/SiliconValley-Cupertino/8770/Maze.zip なんか、FLASHだと(C/C++と比べて)混沌としてしまいますね。 でも、ActionScriptが分かる人なら簡単に改造できると思います。 ソースの80%ほどは、>>3 のC++のソースからのコピペで済みました。 次回のUPまでに、もう少しコメントをしっかりと書いておきます。
67 名前:名前は開発中のものです。 mailto:age [02/07/05 14:32 ID:???] メタセコイアっぽいマウスによるカメラの制御方法です。 回転にはクォータニオンを使ってます。 void CMouseListener::RotateCameraPosition() { int dx = mouseoldx - mousex; int dy = mouseoldy - mousey; float dtheta1 = dx*D3DXToRadian(1)/2; float dtheta2 = dy*D3DXToRadian(1)/2; D3DXVECTOR3 axis1 = D3DXVECTOR3(0.0f,1.0f,0.0f); //x-z平面上で見たときの角度を取得 float thetaaxis2 = (float)atan2(-vCameraPos.x,-vCameraPos.z); //π/4回転させる D3DXVECTOR3 axis2 = D3DXVECTOR3(cosf(thetaaxis2),0,-sinf(thetaaxis2)); //続く
68 名前:名前は開発中のものです。 mailto:sage [02/07/05 14:37 ID:???] D3DXQUATERNION q1,q2, qi1,qi2;//逆クオータニオン //dthetaだけaxisに対して回転 D3DXQuaternionRotationAxis(&q1,&axis1,dtheta1); D3DXQuaternionRotationAxis(&q2,&axis2,dtheta2); //逆クォータニオンを設定 D3DXQuaternionInverse(&qi1,&q1); D3DXQuaternionInverse(&qi2,&q2); //元のカメラの位置ベクトル成分を持つクォータニオン D3DXQUATERNION qPos = D3DXQUATERNION(vCameraPos.x,vCameraPos.y,vCameraPos.z,0.0f); D3DXVECTOR3 vNewPos1,vNewPos2; //それぞれの軸についてカメラの位置を回転させたものを求めて D3DXQUATERNION qNewPos1 = q1*qPos*qi1; D3DXQUATERNION qNewPos2 = q2*qPos*qi2; //ベクトルとして合成 vNewPos1 = D3DXVECTOR3(qNewPos1.x,qNewPos1.y,qNewPos1.z); vNewPos2 = D3DXVECTOR3(qNewPos2.x,qNewPos2.y,qNewPos2.z); //正規化 D3DXVec3Normalize(&vCameraPos,&(vNewPos2 + vNewPos1)); //元の大きさを持たせる vCameraPos*= Dist; //変換行列を作成、IDirect3DDeviceに与える ApplyNewCameraPosition(); }
69 名前:68 mailto:sage [02/07/05 14:43 ID:???] ゴメソ訂正 ×//ベクトルとして合成 ○//ベクトルとする です。んでは学校行ってきます
70 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/07/06 13:05 ID:???] ポインタの勉強をしたので >>3 の迷路生成クラスを、少し改良しました。 コンストラクタに二つの仮引数を渡すことで、迷路の大きさを自由に決定できます。 ソース www.geocities.co.jp/SiliconValley-Cupertino/8770/newMEIRO.txt 実行ファイル込み www.geocities.co.jp/SiliconValley-Cupertino/8770/newMEIRO.zip 変数名、コメントなども少しだけ改めました…精進します。
71 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/06 13:12 ID:???] >>67-69 3Dですか〜。ゲーム製作の香りがしますねぇ。 僕は、どちらかというとゲームのルール自体は 2D前提で考えますね。(表示には3Dも使ってみたいですが) ローグみたいなゲームを製作中です。 細かいデータをチマチマといじるのが好きなので。 あと、書き忘れましたが>>70 はC++です。
72 名前:名前は開発中のものです。 mailto:sage [02/07/06 15:12 ID:???] >>71 実行してないから分からないんだが、生成した迷路データで 3D迷路を探索するゲーム作ったら? Wizとか女神転生とかみたいな感じの。
73 名前:67 mailto:sage [02/07/06 22:09 ID:???] >>71 どうもです。一人でちまちまコード打ってると気分が滅入ってくるので これからもちょくちょく貼り付けさせてもらいにくるかもしれません。
74 名前:名前は開発中のものです。 mailto:sage [02/07/07 10:11 ID:???] 役立たずかも template<typename T, typename U> T co_interface_cast(U from) { T ret; HRESULT result; result = from->QueryInterface( __uuidof(T), reinterpret_cast<void**>( &ret ) ); if ( FAILED( result ) ) { ret = NULL; } return ret; }
75 名前:名前は開発中のものです。 mailto:sage [02/07/07 17:29 ID:???] >>74 ゲーム作るのにCOM使うのってどんなときですか? xファイルを読み込むのぐらいにしか使ったことないyo
76 名前:名前は開発中のものです。 mailto:sage [02/07/09 14:54 ID:???] >>70 少しソースを見たけど #include<iostream> #include<cstdlib> #include<ctime> #include<new> は良くない無いなぁ、拡張子はきちんとつけようよ。
77 名前:名前は開発中のものです。 mailto:sage [02/07/09 16:07 ID:???] >>76 ネタはageて書こうぜ
78 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/07/11 17:40 ID:???] あまり上げるネタがないですねぇ… 迷路ばっかりいじくっててナンですが www.geocities.co.jp/SiliconValley-Cupertino/8770/mimiMaze.html ↑↓←→キーで移動できます。ミミズです。壁(固い土)も掘り進めます。 スクリプトの処理が多少重いので、環境によっては動きが悪いかもしれません。 これから、どんなゲームにしようか考えます。 >>78 大体は本で読んだとおりに書いているのですが… ヘッダーファイルの拡張子は付けた方がいいのでしょうか? ちょっと、検索してみます。すみませんが、まだ言語の理解が足りてないので…
79 名前:名前は開発中のものです。 mailto:sage [02/07/11 18:18 ID:???] >>76 最近、 #include<hoge> ってくっつけて書くのが流行ってるのかなぁ?
80 名前:名前は開発中のものです。 mailto:sage [02/07/11 18:25 ID:???] 関数呼び出しと同じ感覚なんじゃない? include が関数名で(笑)。
81 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/11 18:37 ID:???] × #include<hoge> ○ #include <hoge> ですか? コンパイラによっては正しく認識されなかったり するのでしょうか…(僕はVC++6.0しか使ってないです)
82 名前:名前は開発中のものです。 mailto:sage [02/07/11 19:07 ID:???] #inluce<hege> でも問題なしなんだろうけど、気になるね。 #include <hoge.cpp> とか #include <hoge.c> で直接コンパイルしちゃう方法もあるから、ヘッダーファイルって事を明らかにする為にも #include <hoge.h> の方がいいとおもうよ。
83 名前:名前は開発中のものです。 mailto:sage [02/07/11 19:59 ID:???] #include<iostream> #include<cstdlib> #include<ctime> #include<new> でもコレはC++標準じゃねーか
84 名前:名前は開発中のものです。 mailto:sage [02/07/11 20:28 ID:???] >>83 スマン、俺の知識が古かったのかもしれん。「C++標準」って言葉の意味が分からん。 VC++ではそうなるってこと? それとも全てのC++で共通ってことなのか? 余計なこと言ったかもしれんな、逝ってくるよ・・・。
85 名前:名前は開発中のものです。 mailto:sage [02/07/11 20:39 ID:???] すべてのC++で共通。 Standard C++規格のライブラリで規定されている
86 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/11 21:14 ID:???] >>84 調べてみましたが、C++ではファイル名の 重複を避ける為、拡張子を付けない形になっている とのことでした。(違うのかもしれませんが) ちなみに、conio.hはcconioってのが無いみたいなので 適当に#includeしちゃいました。 >>72 遅レスですが 実際にRPGみたいなゲームを作るときは 僕はランダムマップにはしないと思います。 出現する敵、アイテムに加えてマップまでランダムだと バランスを取るのが大変ですし、1000回遊べる〜とかには興味がないので… 1〜2回でも満足できるゲームにするつもりです。
87 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/11 21:16 ID:???] あと、>>78 はFLASH5です。書き忘れでした。
88 名前:名前は開発中のものです。 [02/07/12 10:58 ID:3cFLSzxg] よくわかんないけどSTGの弾幕の数式書き出すプログラム作ってよ。おながいします。
89 名前:名前は開発中のものです。 mailto:sage [02/07/12 11:06 ID:???] while(1) { printf("88逝ってよし\n"); }
90 名前:名前は開発中のものです。 mailto:sage [02/07/12 12:06 ID:???] >>88 数式じゃなくて、書き出すプログラム? 余り関係ないが、参考になるかも。 www.asahi-net.or.jp/~cs8k-cyu/bulletml/index.html
91 名前:名前は開発中のものです。 mailto:sage [02/07/12 12:08 ID:???] 今… 88が… … 逝 く ! ! ! ! ! ! !
92 名前:名前は開発中のものです。 mailto:sage [02/07/12 13:11 ID:???] >>90 ギャー!! これじゃー!! たぶん… サンクスコーヽ(´д`)ノ いやね、当方プログラマじゃないしなる気もないのでなんかスクリプトっぽいので ミーシューでSTGを作ろうと思ってたのですよ。そしたら逝ってよしとか言われてるんです。 もうね、逝くかと、死ぬかと。 ごめんなさい。
93 名前:3D太郎 [02/07/12 20:37 ID:0q0E/8gY] ぷよぷよ消しアルゴリズムです。2回再帰しなくても良いようお知恵をお貸し下さい。 #define BX 6 #define BY 10 for( int x = 0; x < BX; x ++){ for( int y = 0; y < BY; y ++){ if( block[ x][ y].getActived()){ int cnt = checkEraseBlock( x, y, block[ x][ y].getColor()); if( cnt > 4) EraseBlock( x, y, block[ x][ y].getColor()); } } } int checkEraseBlock( int x, int y, int color, int cnt) { if( color == block[ x][ y].getColor() && block[ x][ y].getActived()){ cnt ++; cnt = checkEraseBlock( x - 1, y + 1, color, cnt); cnt = checkEraseBlock( x - 1, y - 1, color, cnt); cnt = checkEraseBlock( x + 1, y + 1, color, cnt); cnt = checkEraseBlock( x + 1, y - 1, color, cnt); } return cnt; } void eraseBlock( int x, int y, int color) { if( color == block[ x][ y].getColor() && block[ x][ y].getActived()){ eraseBlock( x - 1, y + 1, color); eraseBlock( x - 1, y - 1, color); eraseBlock( x + 1, y + 1, color); eraseBlock( x + 1, y - 1, color); block[ x][ y].setErase(); } }
94 名前:名前は開発中のものです。 [02/07/12 20:57 ID:ta2l.s0c] すいませんgetActived()ってなんですか? で,分岐してからcolor調べずに分岐する前に調べたらどうでしょう?
95 名前:名前は開発中のものです。 mailto:sage [02/07/12 21:08 ID:???] フィールドと同じ配列を用意して、 状態を保存しておけば?
96 名前:名前は開発中のものです。 mailto:sage [02/07/12 21:25 ID:???] そう。 > int cnt = checkEraseBlock( x, y, block[ x][ y].getColor()); > if( cnt > 4) EraseBlock( x, y, block[ x][ y].getColor()); つながってる個数を調べるのと消すのを同時にやってるのが悪い。 cntは、各ブロックに覚えさせておいて、全ブロックのcntを計算してから 4以上のブロックのぷよを消せば、2回目の再帰は要らない。 再帰を使わないやり方もあるけど、ぷよぷよの場合は、返って効率悪いかな。
97 名前:名前は開発中のものです。 mailto:sage [02/07/12 21:29 ID:???] ちなみに、配列で状態を保存しておけば一度捜査したところの無駄な再帰は無くなる
98 名前:3D太郎 [02/07/12 22:33 ID:0q0E/8gY] >>94 各blockにstateflgを記録し、Actived(存在する)ならtrueを返します。 isActivedに変えました^^;colorを調べる順番変更させていただきました。 >>95 >>97 blockの中に状態保持フラグがあり、そこで同動作を実現しております。 >>96 再帰の途中では、cnt<4の状態があり、この状態で2度と訪れない場合が 存在します。cnt>4条件で消していると、これらが消されないように思うのですが、 どうでしょうか?
99 名前:名前は開発中のものです。 mailto:sage [02/07/12 22:40 ID:???] 再帰なんだけど、末尾再帰ではなく、 関数から戻るフェーズで一番下の層からの戻り値(カウント)をセットすれば?
100 名前:名前は開発中のものです。 mailto:sage [02/07/12 22:53 ID:???] というか、このコードって動いてるの? 斜めにつながるぷよぷよ? 無限再帰してるようにも見える。 get*()関数はもしかして内部状態を変化させていますか?
101 名前:3D太郎 [02/07/12 23:11 ID:0q0E/8gY] >>100 cnt = checkEraseBlockの下に状態変化関数を入れ忘れておりました。 上記は妄想関数です。アルゴリズムだけでも伝わればと思ったのですが、 本末転倒しております。 いくつか落ちゲーに必要なアルゴリズムがそろったらきちんと コーディングしたいと思っております。
102 名前:名前は開発中のものです。 mailto:sage [02/07/12 23:47 ID:???] >>98 だから、 > int cnt = checkEraseBlock( x, y, block[ x][ y].getColor()); > if( cnt > 4) EraseBlock( x, y, block[ x][ y].getColor()); をそれぞれ別のループの中で行えということ。 こんな風に。 for(...) { for (...) { block[x][y].setCnt(checkEraceBlock(x, y, ...)); } } for(...) { for (...) { if (block[x][y].getCnt() >= 4) { block[x][y].setErace(); } } } これだと前半のループが効率悪いから、>>97 みたいなことをすると良い。
103 名前:名前は開発中のものです。 [02/07/13 01:01 ID:.X0DkgxQ] ちょうど3D太郎さんと同じような処理を作ってたんで、 自分のものっけてみようかと。 分けわかんない型や関数があると思いますが、 そのへんは想像か、見なかったことにしてもらう方向で。 こんなもんのっけるんじゃねーって人は無視してください。
104 名前:大学1年生 [02/07/13 01:02 ID:.X0DkgxQ] ちょうど3D太郎さんと同じような処理を作ってたんで、 自分のものっけてみようかと。 分けわかんない型や関数があると思いますが、 そのへんは想像か、見なかったことにしてもらう方向で。 こんなもんのっけるんじゃねーって人は無視してください。
105 名前:大学1年生 [02/07/13 01:03 ID:.X0DkgxQ] Sint32 CBoard::EraseBall() { Sint32 point = 0; Sint32 i, erasenum, eraseline = CGameInfo::GetInstance()->GetEraseLine(); Sint32 idxbox[SELLNUM]; for(i=0; i<SELLNUM; i++) { if(Table[i] != NULL) { Table[i]->SetSearchFlag(False); Table[i]->SetEraseFlag(False); } }
106 名前:大学1年生 [02/07/13 01:04 ID:.X0DkgxQ] for(i=0; i<SELLNUM; i++) { if(!Table[i]) continue; erasenum = EraseSearch(i % RETU, i / RETU, Table[i]->GetElement(), 0, idxbox); if(erasenum >= eraseline) { //#得点処理 point += erasenum * 10; for(Sint32 j=0; j<erasenum; j++) { Table[idxbox[j]]->SetEraseFlag(True); Table[idxbox[j]] = NULL; //#消去処理 } } } return point; }
107 名前:大学1年生 [02/07/13 01:05 ID:.X0DkgxQ] Sint32 CBoard::EraseSearch(Sint32 x, Sint32 y, const CElement &element, Sint32 num, Sint32 idxbox[]) { Sint32 idx = y * RETU + x; if(!Table[idx] || Table[idx]->GetSearchFlag() || Table[idx]->GetElement() != element) return num; Table[idx]->SetSearchFlag(True); if(x < RETU - 1) num = EraseSearch(x + 1, y, element, num, idxbox); if(x > 0) num = EraseSearch(x - 1, y, element, num, idxbox); if(y < GYOU - 1) num = EraseSearch(x, y + 1, element, num, idxbox); if(y > 0) num = EraseSearch(x, y - 1, element, num, idxbox); idxbox[num] = idx; return num + 1; } 2重カキコすいませんでした。
108 名前:名前は開発中のものです。 mailto:sage [02/07/13 12:20 ID:???] 処理の流れやアルゴリズムの簡単な説明くらい 書いてホスィね。作ろうとしているものがイマイチ分からんです。 もしくは、一部だけじゃなくて全部を上げるとか。もちろん動く形でね。
109 名前:名前は開発中のものです。 mailto:sage [02/07/13 20:17 ID:???] 再帰させないアルゴリズムってどうするの?
110 名前:名前は開発中のものです。 mailto:sage [02/07/13 20:40 ID:???] >>109 スタックとwhileでどうよ?
111 名前:>>109 mailto:sage [02/07/13 22:57 ID:???] #include <list> struct group { int _num, *num, color; group(int c) { num = &_num; color = c; } void link(group *g) { if (g != this) { int n = *num; num = g->num; *num += n; } } } *block_g[6][6]; int block[6][6] = { {1, 1, 1, 4, 4, 0}, {1, 0, 1, 0, 4, 4}, {1, 1, 1, 2, 2, 4}, {0, 3, 3, 0, 2, 2}, {3, 3, 1, 2, 2, 4}, {3, 1, 1, 1, 0, 4} }; void erace() { std::list<group*> glist; for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) { if (j > 0 && block_g[i][j-1]->color == block[i][j]) (*(block_g[i][j] = block_g[i][j-1])->num)++; if (i > 0 && block_g[i-1][j]->color == block[i][j]) { if (block_g[i][j]) block_g[i][j]->link(block_g[i-1][j]); else (*(block_g[i][j] = block_g[i-1][j])->num)++; } if (!block_g[i][j]) { (*(block_g[i][j] = new group(block[i][j]))->num)++; glist.push_back(block_g[i][j]); } } for (std::list<group*>::iterator i = glist.begin(); i != glist.end(); ++i) delete *i; } int main() { memset(block_g, 0, sizeof(block_g)); erace(); for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) printf("%02d,", *block_g[i][j]->num); printf("\n"); } }
112 名前:111 mailto:sage [02/07/13 23:00 ID:???] おっと、#include <stdio.h> がないとだめかも。 gccで動作確認しますた。
113 名前:大学1年生 [02/07/14 01:47 ID:6shM2PBs] >>108 すいませんでした。 Bool == bool, True == true, False == false, Sint32 == int Table[] == 消える対象(CElementのポインタ)がはいってるテーブル RETU == 列, GYOU == 行, SELLNUM = Table[]のサイズ == RETU * GYOU ぷよぷよみたいな感じで。 処理の流れ EraseBall() idxbox[] == 削除予定のTable[]のIndexを保存するための配列 SetSearchFlagとSetEraseFlagで検索したか、削除対象かのフラグをFalseで初期化 Table[]をすべてEraseSearchで何個つながってるか数を検索 つながってた個数が一定数(eraseline)以上なら削除決定 idxbox[]を使い削除対象のインデックスを習得 SetEraseFlagを使いTrueに設定 Table[] = NULLでテーブルから削除 EraseSearch(列の座標,行の座標,ぷよの色みたいな感じ,何個つながってるか,検索したIndexを入れる配列) テーブルに存在するか、検索済みか、同じ属性かの判定 SetSearchFlag(True)で検索済みに設定 上下左右で再帰して検索 idxbox[]に検索したアイテムのTableのIndexを設定 自分がつながってたことを表すようにnumに1つ足してreturn つまり3D太郎さんと同じアルゴリズムです。 動く形で全部(一部でも)アップするのはいっぱいファイルがいるので無理です。 かなりわかりにくい説明だと思いますけど、これが限界なんで。 分からなかったらすいません。
114 名前:名前は開発中のものです。 mailto:sage [02/07/14 02:08 ID:???] ぷよぷよとかテトリスは(タイトルを変えても) 実行可能な状態でUPすると著作権侵害に触れるんだっけ? 確か、ブロック崩しはOKだったよね。
115 名前:名前は開発中のものです。 mailto:sage [02/07/14 02:23 ID:???] >>114 ほんと?著作権なの? 意匠権とか、特許じゃなくて??
116 名前:名前は開発中のものです。 [02/07/14 09:55 ID:fsyX9X4c] >>114 でも著作権って、アイデアは保護されないはず。 ソースコードには著作権があるので、 1から作れば問題ないとかあるとか…。 結局のところどうなんだ? >>114 の話もよく聞くし・・・
117 名前:114 mailto:sage [02/07/14 10:36 ID:???] >>115-116 「アルゴリズム」自体には著作権は 認められていないと思うけど、ゲームの ルール自体には認められているから… 普通に考えて、商用のゲームのコピーを勝手にUPするのはNGかな、と。 2chでは、「ぷよぷよ作ろう」みたいなスレッドが普通に立って 普通にUPされているからちょっと気になった。 でも、このスレには関係の無いことだったかな。汚してスマソ。
118 名前:名前はデバッグ中のものです。 mailto:sage [02/07/14 11:06 ID:???] >>116 なるほど。 |2chでは、「ぷよぷよ作ろう」みたいなスレッドが普通に立って |普通にUPされているからちょっと気になった。 同意。なんか、違和感を覚えた。 誰もスレで指摘していなかったような感じで。
119 名前:名前は開発中のものです。 mailto:sage [02/07/14 11:51 ID:???] ルールに著作権が認められてるって本当? 判例とかあるのかな?
120 名前:114 mailto:sage [02/07/14 12:11 ID:???] すいません、これで最後にします。 >>119 ゲーム関係の裁判は様々な主張が入り乱れていて 絶対的な判例ってのは、まだ無いと思います。 ルールって表現はマズかった。 だが、ぷよぷよのルール(ゲーム)はプログラムと 何らかの視覚表現があって成立するものだから プログラムに視覚表現を含めてUPするのは危険だと思う。
121 名前:名前は開発中のものです。 mailto:sage [02/07/14 12:45 ID:???] というか、著作権云々じゃなくて、製作者としての姿勢的にとか道義的にまずいだろ。
122 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/18 01:13 ID:???] ちょっと旅行に行ってました。 山に登ろうとした日に台風が来て、もうアホかと。 では、気持ちを新たにUPさせていただきます。 以前話題に出た、逆ポーランド記法への変換アルゴリズムです。 >>61 のプログラムが少し進化しました。 ()に対応しました。 また、 (-(47 + 12) / 8) のように括弧の前のマイナス記号にも対応してます。 それ以外は>>61 と同じです。 + - * / の四則演算ができます。 C言語です。 ソース www.geocities.co.jp/SiliconValley-Cupertino/8770/newMtoB.txt 実行ファイル www.geocities.co.jp/SiliconValley-Cupertino/8770/newMtoB.zip ソースは見るに値しない状態(きたない)ですが一応あげさせていただきます。 <<続きます>>
123 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/07/18 01:15 ID:???] <<続きです>> アルゴリズムは () 内の式を再帰で渡していく というものです。括弧の前のマイナスは -(8 + 7) → -1 * (8 + 7) という風に変換して渡してます。 自力で無理やり作ったものなので、無駄が多いと思います。 誰か、より完璧なアルゴリズムをご存知でしたら教えていただきたいです。 どちらかと言えば、マ板向きの話題なのかもしれませんが… また、>>122 のプログラムの動作について指摘がありましたらお願いします。 ぷよぷよの話題に関しては、僕の効率の悪い、初心者気合アルゴリズムで 場を荒らしてしまうような気がするので、ROMさせていただきます。口惜しや…
124 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/18 01:27 ID:???] >どちらかと言えば、マ板向きの話題なのかもしれませんが… ム板に訂正… しかも>>78 で自爆レスしてる… >>76 に訂正です。
125 名前:名前は開発中のものです。 [02/07/18 02:25 ID:VUqV/Vc.] >>117 ほか 同人誌と同じようなものだし、別に責められるほどのものではないんでは? ただ、ぷよぷよアルゴリズムの権利者(って今どこが持ってるんだ?)から クレームがあるかもしれないことを認識しておく必要があるとは思うが。
126 名前:名前は開発中のものです。 mailto:sage [02/07/18 09:24 ID:???] 今はセガがもってるんだっけ?
127 名前:名前は開発中のものです。 mailto:sage [02/07/18 09:39 ID:???] アルゴリズムに認められるのは特許権。 しかも、プログラムをただ公開しただけじゃ、特許権侵害にはならないんじゃなかったっけ?
128 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/07/18 14:04 ID:???] >>122 のプログラムに大きなバグがありました。 ()に付いているマイナス記号の判定、スペースやタブで 区切って式を入力した際の不具合を修正しました。 修正した実行ファイル www.geocities.co.jp/SiliconValley-Cupertino/8770/newMtoB2.zip 例えば (9+8*7)/6-(-((5-4)*(3+2))) という式を与えた場合の出力は… (修正前)9 8 7 * + 6 /-1 -1 5 4 - 3 2 + * * * - (修正後)9 8 7 * + 6 / -1 5 4 - 3 2 + * * - と、なっています。 まだバグがありそうですし、汚いのでソースのUPは今回は見送ります…
129 名前:>>128 mailto:sage [02/07/18 16:25 ID:???] いろいろと入力してみたけどコンピューターで 計算できる形になってるみたいだしいいんじゃない? ソースについてのコメントは控える。(w
130 名前:名前は開発中のものです。 [02/07/18 21:01 ID:eG1jD3wM] merosuke.tripod.co.jp/project1.zip
131 名前:名前は開発中のものです。 mailto:まだ初心者なの [02/07/18 21:29 ID:???] >>129 コメントありがとうございます。少しだけ自信がつきました… 今のところはバグが見当たらないので 逆ポーランド記法の式を計算する関数も作ってみました。 入力された式を逆ポーランド記法に変換して表示し、計算結果も表示されます。 C言語です。 ソース www.geocities.co.jp/SiliconValley-Cupertino/8770/calculation.txt 実行ファイル www.geocities.co.jp/SiliconValley-Cupertino/8770/calculation.zip 動作などに関する意見や質問があったらよろしくお願いします。
132 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/18 21:32 ID:???] >>130 落としてみたのですが、エラーが出て実行できませんでした。 あと、何かを貼り付ける時は簡単なコメント・説明を添えるように してください…おねがいします。
133 名前:名前は開発中のものです。 [02/07/18 23:33 ID:KrSipdXM] ちょっとソースが汚いかも。 GetPriorityOperator関数でcase文使っているけど、この使い方だったら、 if文使った方がまとまると思うよ。あと、再起してる関数じゃないなら、 部分部分にreturn入れないで、retとかいう変数つくって、 そこに戻り値入れて最後に返してやるようにする。 int GetPriorityOperator(char op) { int ret = 0; if(op == '*') ret = 10; else if(op == '/') ret = 10; else if(op == '+') ret = 8; else if(op == '-') ret = 8; else if(op == '\0') ret = 0; else if(op == ')') {printf(")"); ret = 0;} else printf("GetPriorityOperator(char op); 不正な引数\n"); return ret; }
134 名前:名前は開発中のものです。 mailto:sage [02/07/18 23:37 ID:???] 生成されるコードを考えると、そこのソースは元のままでいい。 出来れば、defaultは除去してその前の段階でキャラクタ検査をした方が良い。
135 名前:名前は開発中のものです。 mailto:まだ初心者なのsage [02/07/19 08:47 ID:???] >>133-134 レスありがとうございます。 まずは、見やすいプログラムを書くように心がけます。 僕は、まだ生成されるコードの効率とかを 考えるレベルには至っていないのかもしれません… 効率について検索してみたのですが、 >switchは if - elseif …のチェイン(cmp xx jz xx ...)に展開されることもしばしばで、 >こんなものになってしまったらジャンプテーブルに比べて圧倒的に速度が低がするのは想像に硬くありません。 >例えば、switch文の最後に > default: > __assume(0); // (VCの拡張機能、ここに来ることは有り得ないと言う事) >等としてやるとVCに於いてはほぼ確実にジャンプテーブルに展開されるようになります(なるそうです…)。 というのがありました。
136 名前:名前は開発中のものです。 mailto:sage [02/07/19 09:45 ID:???] というか、生成されるコードならテーブルに展開するのが一番速いけどな
137 名前:名前は開発中のものです。 mailto:sage [02/07/20 14:19 ID:???] C言語。オセロ。某所より。見て氏ね。 #include <stdio.h> int*i,p,t,a,d,v,m[91]={-10,-9,-8,-1,1,8,9,10},s;void k(){if(m[p]==0)for(i=m;*i ;i++){for(v=p+*i;m[v]==9-t;v+=*i);if(v-p-*i&&m[v]==t&&(s=a=v=p,d))do m[v]=t,v +=*i;while(m[v]-t);}}main(){for(m[40]=m[50]=s=t=3,m[41]=m[49]=6;s-1;a=d=0){for (p=8;++p<82;printf("・\0○\0●\0\n"+m[p]))p%9?k():m[p]=9;for(a?d=a=p=9:s?s=0, puts("pass"):s++;a==9;k())t-6?scanf("%d%d",&p,&v),p+=v*9:++p;t=9-t;}return 0;}
138 名前:名前は開発中のものです。 mailto:sage [02/07/20 20:43 ID:???] >>137 すごいですね。 俺が授業で書いたオセロは200行ちょい。 このプログラムを改行とかしたら40行弱。 ・・・あと4年間で何とかしないとな。
139 名前:名前は開発中のものです。 mailto:sage [02/07/20 23:29 ID:???] つーか、このオセロはかなり上級者の書いた物だろ 7行スレでも有名な人が書いた物。
140 名前:名前は開発中のものです。 [02/07/21 00:04 ID:VfOHqT.A] 言語の仕様を熟知していれば ある程度は可能だと思うが。 別にレベルがどうこうじゃないような。 >>137 みたいなのはオジさん同士で見せ合うのは たのしいんだけど、若い人は興味無いんじゃないか? 基本的に「実用テクニック」にはなり得ないから。
141 名前:名前は開発中のものです。 mailto:sage [02/07/21 00:12 ID:???] >>140 勝手に言ってくれるなー 俺もいいかげんおじさんなのか。
142 名前:名前は開発中のものです。 mailto:sage [02/07/21 00:26 ID:???] sou desu YO!
143 名前:名前は開発中のものです。 mailto:sage [02/07/21 00:34 ID:???] あのオセロは割り切り方が凄いんだよ。 実装範囲を選んで、機能を限定してそれ専用にチューニングしてる。 こういうことは結構重要で、出来ない奴は結局ここの技術にこだわりすぎて 全体的に効率悪い物しか作れない。 小手先のテクニックも使ってるけど、それだけだと思ったら大間違いだよ。