■掲示板に戻る■ 全部 1- 101- 最新50

プログラム言語で会話するスレ

48 : ◆zFEditKho2 :02/10/15 00:26 ID:JcMaByFU
☆ エロゲで学ぶデザインパターン ☆

【 Iterator : イテレータ 】
 構成要素を順番になめまわします。

 ArrayList エロゲ棚 = new ArrayList{ 君望, はじるす, 水月, みずいろ };
                             // 悲惨な棚があります。
 Iterator 俺の目 = エロゲ棚.getIterator();   // マイコレクションをCheck it!

 while ( 俺の目.次がある==true ){ // 目先に何かある間、ループします。
   if. ( 俺の目.次==はじるす ){   // ロリハケーン!
      (;´Д`)ハァハァ              // ハァハァ
   }
 }

49 : ◆zFEditKho2 :02/10/17 01:37 ID:YTGlnVnQ
☆ エロゲーで学ぶデザインパターン ☆

【 Adaptor : アダプター 】
 型が合わなくても、一皮かぶせて再利用。

 エロゲCD ねこねこソフト(){.  // 古い関数
    return new みずいろ(); // エロゲCD「みずいろ」を生成
 }
 
 エロゲDVD ねこねこソフト再販(){     // アダプターです
    return DVD化( ねこねこソフト() );  // DVD版を再販します
 }

50 : ◆zFEditKho2 :02/10/19 03:01 ID:afoAuzYY
☆ エロゲーで学ぶデザインパターン ☆

【 Template Method : テンプレート 】
 似た機能をまとめることで、ロジックを共通化します。

 abstract class はじるす{         // これがテンプレ
   public   int   年齢.  = 18;    // 祖父倫対策
   public   Image 見た目 = ロリ;    // お兄ちゃん直撃
   public abstruct String なまえ;  // キャラクターの名前
 }

 class しおりちゃん extends はじるす{         // はじるすを継承
   public String なまえ = new String(”しおり”);// しおりちゃん実装
 }
 class さおりちゃん extends はじるす{         // はじるすを継承
   public String なまえ = new String(”さおり”);// さおりちゃん実装
 }

51 :名無しさん@初回限定 :02/10/21 19:47 ID:xAh+opT1
俺クラスのメンバー変数
final static boolean DOUTEI = true;

52 : ◆zFEditKho2 :02/10/22 02:36 ID:eoRoqRcg
☆ エロゲーで学ぶデザインパターン ☆

【 Factory Method : ファクトリー 】
 TemplateMethod(テンプレート)の応用です。ヤヤコシイ
 枠組みとして"作成者"と"製品"、(工場と製品仕様)
 実装部として"具体的作成者"と"具体的製品"(作業員と完成品)
 の4つに分け、枠組み(フレームワーク)の再利用を目指します。

 abstruct class アリスソフト {               // 作成者です
   public abstruct SYSTEM3.9 create(); // SYSTEM3.9な
 }                          // ゲームを作ります
 abstruct class SYSTEM3.9 {        // 製品です
   public abstruct ハァハァ えちシーン();. // エロゲ必須要素
 }
 class 社員 extends アリスソフト {      // 具体的作成者(作成者を継承)
   public SYSTEM3.9 create(){     // SYSTEM3.9なゲームを
     return new SYSTEM3.9();   .// "実際に"作ります。
   }
 }
 class 妻みぐい extends SYSTEM3.9 { // 具体的製品(製品を継承)
   public ハァハァ えちシーン(){       // えちシーンを"実装"します。
     return new 人妻();        // 人妻で(;´Д`)ハァハァ
   }
 }

---
>>51 俺クラスメンバ変数(C版)
static const bool DOUTEI = true; // ダメフラグ立ちっぱなし(;´Д⊂)

53 : ◆zFEditKho2 :02/10/24 02:02 ID:ti2zAlLe
☆ エロゲーで学ぶデザインパターン ☆

【 Singleton : シングルトン 】
 staticとprivateを使った、ある意味テクニック。1つであることを保証します。
 複数スレッドからの同時アクセス時に威力を発揮。

 public class シナリオ { // これがsingletonなクラス。某エロゲ会社を想定。
   private static シナリオ ライター = new シナリオ();
    // static、つまり1回しか生成されないのがミソ。
   public static シナリオ getInstance(){  // 実体を取得します。
     return ライター;             // シナリオライターを返却。
   }
   private シナリオ(){ // 普通の確保(new)をされないように、
   }           // privateです(=自分自身にしか使えない)
 }
 public class Main{                // 使い方。
   シナリオライター 阿鼻巣暴徒,誰彼;    // 2本のソフトがあります
   阿鼻巣暴徒 = シナリオ.getInstance();// シナリオ取得その1
   誰彼       = シナリオ.getInstance();// シナリオ取得その2
     // この時点で、阿鼻巣暴徒==誰彼が成立します。
 }

54 :名無しさん@初回限定 :02/10/26 01:43 ID:fpYh0ljk
横レススマソですがガンガレ!

Mementoをどうカマしてくれるのか…(・∀・)ウズウズ

55 : ◆zFEditKho2 :02/10/26 03:51 ID:9Ezv8nq6
☆ エロゲーで学ぶデザインパターン ☆

【 Prototype : プロトタイプ 】
 わざわざデータを新しく作らず、既存データのコピーつまりクローンで済ませます。
 クラス数が多いとか、クラスから組み上げるのが面倒なときに適用。

 public interface ロリ extends Cloneable {   // クローン可能を継承。
   public abstruct ロリ createClone();   . // クローン作成を宣言。
 }
 public class ZERO {          // 昔、『密猟者』とか作ってた会社
   private ロリ キャラ = new ロリ(); // 最近は、これで名を馳せますた
   public ロリ create (){         // ロリを産み出します
     return キャラ.createClone(); // キャラ(のコピー)を返却
   } // いつものような new なんとか() で作っていないことに注意。
 }
 public class しおりちゃん implements ロリ {// 例によってしおりタン+ロリ
   public ロリ createClone(){           // クローン作成を実装します
      ロリ 自分自身 = null;           // はじめは何もないけれど
     try{
       自分自身 = (ロリ) (this.clone());// 自分自身をクローン化。
     }catch( CloneNotSupportedException e ){
       // try〜catch間で、クローンに失敗したらここに来ます。
     }
     return 自分自身;          // 自分自身のコピーを返却。
   }
 }           // 同様にさおりタンも作成可能。当然ロリ標準装備。
---
>>54 なんとか完走できるようにガンガリマス。
Mementoはおそらく、御想像とおりのネタになると思います(;´ー`)

56 :名無しさん@初回限定 :02/10/27 10:23 ID:3ssAZtNG
23パターン後にスレッド型のやつよろ

57 : ◆zFEditKho2 :02/10/28 01:19 ID:OTgH54UY
☆ エロゲーで学ぶデザインパターン ☆

【 Builder : ビルダー 】
 複雑な構造は一気に作らず、少しずつ順番に。
 組立方法に従って、部品を組み立てます。

 public abstruct class Builder {      // たくましくなる方法
   public abstruct マッスル 海でガッツ(); // 筋力up宣言 その1
   public abstruct マッスル 山でガッツ(); // 筋力up宣言 その2
 }
 public class 主人公 {                // 筋力upを組立
   public マッスル ガッツ( Builder ヒロイン ){ // 鍛えます。
     マッスル 筋肉;
     筋肉 += ヒロイン.海でガッツ();    // マッシヴ!
     筋肉 += ヒロイン.山でガッツ();    // モア マッシヴ!!
     return 筋肉;
   }
 }
 public class タカさん extends Builder {       // 筋力up実装
   public マッスル 海でガッツ(){ return マッシヴ!! ;. }// 実装その1
   public マッスル 山でガッツ(){ return マッシヴ!!!!; }// 実装その2
 }
 // 使い方 // タカさんにシゴかれる主人公の図
   マッスル 筋肉 = 主人公.ガッツ( new タカさん() );

---
>>56 ス、スレッドデザパタ…ドナタカ オナガイシマス(;;;´ー`)

58 :名無しさん@初回限定 :02/10/28 03:27 ID:CjGQ7rNS
'デザパタ厨必死だな

59 :名無しさん@初回限定 :02/10/29 23:43 ID:mFTZhsoD
そこでC++版の登場だ。

       ∧_∧
  ∧__∧ (´<_` ) これってGoFじゃないだろ兄者。
  ( ´_ゝ`)/  ⌒i
_(__つ/ ̄ ̄ ̄/i |_
  \/___/ ヽ⊃


const int BSF = 1;
const int Wind=2;
const int AT=3;



CString genericMinoriUser(int opus)
{
 switch (opus){
 case BSF:
  return "少女崇拝";

 case Wind:
  return "わたし、>1にとって、なんなのよっ!! ねえ? >1にとって、わたしはなん";//以下略

 case AT:
  ASSERT(0);
  return "";
}
return "nbkzvxZE/w : #nDIzサV/p";//ここには絶対に来ないが、

}


60 : ◆zFEditKho2 :02/10/30 02:02 ID:PrWhtk5G
☆ エロゲーで学ぶデザインパターン ☆

【 Abstruct Factory : アブストラクト ファクトリー 】
 (以下、抽象工場と略します)
 前述、Factory(工場)の拡張版です。比較するとこんな感じ?

          <枠組み>        <実装部>
          (abstructにします)   (extendsで対応する枠組みを継承)
  通常工場 : 工場→仕様         / 作業員→完成品
  抽象工場 : 工場→仕様1仕様2… / 作業員→完成品1完成品2…

 で、エロゲナイズするとこんな感じ。

  通常工場 枠組み: ヒロインがひとりのエロゲ  → ヒロイン
           実装部: / 『あゆみちゃん物語』 → あゆみ
  抽象工場 枠組み: Keyのエロゲ         → ヒロイン、先輩、リストカッター
           実装部: / 『Kanon』           → あゆ.、 舞 、   栞
           実装部: / 『Air』             → 観鈴.、美凪、 佳乃

  枠組みの再利用で、新たな実装部を追加しやすくすることが特徴です。

// コード無くてスマソ(;´ー`) //  >>58 REM アト15パタン ユルシテ…

61 :名無しさん@初回限定 :02/10/31 04:43 ID:3uuMr7E2
/*
AngelTypeって、抽象クラスだったんじゃないかな?

Aerisスレの住民の頭のなかには、
住民一人一人が継承したprivateなコンクリートクラスが存在した。
そして今回、minoriが別のpublicなコンクリートクラスを
リリースすることになった。

そんな感じがする。

当然、継承の上で姉妹関係にあるクラスなのだから
代入はできないので、
スレが多少「期待と違う」とか「シナリオが〜」といった
話題になるのは仕方ないだろうけど。

まずは、publicなコンクリートクラスが現れたことに乾杯。
*/

62 :名無しさん@初回限定 :02/10/31 07:09 ID:zVh6HUrA
意表をついてWebプログラムで書いてみようかな
PHPあたりで

63 : ◆zFEditKho2 :02/11/01 01:57 ID:rofPd1yi
☆ エロゲーで学ぶデザインパターン ☆

【 Bridge : ブリッジ 】
 Factory系は、機能追加が苦手。(前述の例では、ヒロイン種の追加)
 そこでBridgeパタンの登場。実装部を継承することでパワーアップさせます。

 public abstruct class ロリゲー {           // ロリゲ必須要素を列挙
   public abstruct void コスプレ();     // コスプレがあることを宣言
   public abstruct void しーしー();     // シーシーがあることを宣言
 }
 public class 双子 extends ロリゲー {      // 上記要素を実装
   public void コスプレ(){ いろいろ(); } // コスプレを実装
   public void しーしー(){ にょ();    } // シーシーを実装
 }
 public class はじるす {       // ロリゲを核とするエロゲ
   private ロリゲー x ;        // 核。
   public はじるす( ロリゲー x ){ // コンストラクタ:初期化するトコ
     this.x = x ;           // 核に双子要素をセット。
   }
   public void コスプレH(){ x.コスプレ(); } // コスプレイベントです
   public void しーしー(){ x.しーしー(); } // しーしーイベントです
 }
 // 使い方 // はじるす( new 双子() ).コスプレH(); // コスプレでハァハァ
  // ところが、「はじめて」がなかったことに非難轟々。
  // そこで、はじいしゃには追加実装されることに。
 public class はじいしゃ extends はじるす { // 前作機能を再利用。
   public はじいしゃ( ロリゲー x ){ // ある意味、一種のおまじない?
     super ( x ); // クラス"はじるす"版の初期化を行います。
   }
   public void はじめて(){ ハカシーン(); } // 待望の追加機能
 }
 // 使い方 // はじいしゃ( new 双子() ).はじめて(); // ハァハァ

64 :名無しさん@初回限定 :02/11/01 07:54 ID:+i8OTm77
そろそろそのネタ飽きてきた…

65 :名無しさん@初回限定 :02/11/01 14:21 ID:OGcF8F/N
>>61

基底クラス

住民がprivateに継承

minoriがpublicに継承

上記2クラスを住民が継承

名前解決をめぐって住民が逆ギレ祭り

「ダイヤモンド型継承」とMeyers先生に怒られる

(´・ω・‘)

コード無いや。

66 :名無しさん@初回限定 :02/11/06 05:27 ID:HenN0oUp
あれ?デザパタ終わっちゃった?
結構楽しみだったのに。
中途半端にするぐらいなら、最初からやるなゴルァ!ってことで。

67 :名無しさん@初回限定 :02/11/07 03:30 ID:zkKFQ5i5
C++よりCでやってくれ。
++はわからん。

68 :名無しさん@初回限定 :02/11/07 05:14 ID:Mu2xNzk7
>68 GOTO 69

69 :名無しさん@初回限定 :02/11/07 05:16 ID:Mu2xNzk7
69 GOTO >68
RUN


70 :名無しさん@初回限定 :02/11/07 07:02 ID:FsrpKYKQ
while( 1 )
{
  system.out.println( ">>1さん、助けて〜<br>" ) ;
}

71 :名無しさん@初回限定 :02/11/07 21:26 ID:E0cVJJ4s
:loop
echo 飽きてきたぞ
goto loop


72 :[9.5/23] ◆zFEditKho2 :02/11/12 21:47 ID:DBfOtK9d
エロゲでデザパタ、残り14パタンを最後まで一気にやります。
あまり興味のないかたは、goto >>88 でお願いします。

……その前に、お詫びしたいことがあります。
今までのコード中にabstructとありましたら、
それはabstractの間違いです。
申し訳ありません、ついCのくせが……。

73 :[10/23] ◆zFEditKho2 :02/11/12 21:51 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Strategy : ストラテジー 】
戦略部分を切り離すことで、動作をごっそり切り替えたりできます。
 public interface システム動作 {   // 戦略切換用の宣言集
   public abstract void メニュー(); // メニュー宣言
 }
 public class 通常メニュー implement システム動作{// 製品用のメニュー
   public void メニュー(){ // 製品版では、CGモード=クリア後のお楽しみ。
     ゲーム開始を選択可能にする();
     if( シナリオクリア == true ) CGモードを選択可能にする();
   }            // シナリオを1回クリアしていたら、CGモードオープン。
 }
 public class デバッグメニュー implement システム動作{// デバッグ用メニュー
   public void メニュー(){ // デバッグ用なので、CGモードフルオープン。
     ゲーム開始を選択可能にする();
     CGモードを選択可能にする();
   }
 }
 public class エロゲ製品版 {
   private boolean シナリオクリア;   // 1回クリアしたかどうかのフラグ
   public void タイトル画面(){    // タイトル画面の動作
     メニュー メニュー表示 = new 通常メニュー(); // 製品版なので……
     メニュー表示.メニュー();     // 通常メニューを表示します
   }
   public void ゲーム開始(){…(省略)…}.// 実際のゲーム
   public void CGモード(){…(省略)…}  // ハァハァ
 }
こうやって作っておくと、タイトル画面()内で
    メニュー メニュー表示 = new 通常メニュー();.   を
    メニュー メニュー表示 = new デバッグメニュー(); に書き換えるだけで
手軽にテストすることができます。

74 :[11/23] ◆zFEditKho2 :02/11/12 21:53 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Composite : コンポジット 】
ファイルとフォルダの関係のように、入れ物と中身を同一種として取り扱います。

1.入れ物&中身の共通クラス(宣言)
 public abstract class アイテム {
   public abstract アイテム add( アイテム item ); // 持ち物追加(宣言)
 }
2.中身クラス (アイテムを継承して実装)
 public class 中身 extends アイテム{
   public アイテム add( アイテム item ){   // 持ち物追加(中身Ver)
   }   // 中身には何も追加できないので、なにもしません。
 }     // 他に、例外をthrowして失敗を伝える方法もあります。
3.入れ物クラス (アイテムを継承して実装)
 public class 入れ物 extends アイテム{
   private LinkedList 一覧 = new LinkedList(); // 一覧を確保
   public アイテム add( アイテム item ){   // 一覧に追加(入れ物Ver)
     一覧.add( item );             // 一覧にアイテムを追加
   }
 }
4.こんな感じでツリーを構築
  入れ物 箱.      = new 入れ物(); 入れ物 CDケース  = new 入れ物();
  内容 ゲームCD   = new 内容();  内容 マニュアル   = new 内容();
  内容 アンケートハガキ = new 内容();  内容 くまシャーペン = new 内容();
                   // 箱
  箱.add ( CDケース ); .     // ├ CDケース
  CDケース.add ( ゲームCD ); // │ └ ゲームCD
  箱.add ( マニュアル );.    // ├ マニュアル
  箱.add ( アンケートハガキ );.  //.├ アンケートハガキ
  箱.add ( くまシャーペン );.  //.└ くまシャーペン

75 :[12/23] ◆zFEditKho2 :02/11/12 21:54 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Decorator : デコレーター 】
引数と戻り値を同じ型にすると、飾りつけができます。
詳しくは中身(宣言)・中身(実装)・装飾(宣言)・装飾(実装)
の4つで構成するのですが、このようなイメージてことで……

1.
 Image 着替え関数( Image body ){ // 入と出が同じ型の関数
   bodyにワンピースを着せる作業;  // 飾りつけ部分
   return body;            // 飾りつけ後を返却
 }
 にそった形の関数群、
 Image ワンピ( Image body ); とか
 Image ニーソ( Image body ); とか用意します。

2.
 Image ヒロイン = ハダカ( new Image( ) ); // ヒロインのハァハァ画像
 を土台として、

 Image ヒロイン = エプロンドレス( ワンピ ( シャツ ( ブラ ( ショーツ (
           ガーターベルト ( ニーソ ( カチューシャ (
             ハダカ( new Image( ) ) ) ) ) ) ) ) ) );
 のように、Imageに次々と服を着せる。

3.
 結果、ヒロインはメイドさん。

76 :[13/23] ◆zFEditKho2 :02/11/12 21:58 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Visitor : ビジター 】 受入先を訪問者が渡り歩く……と思いこんだらハマルかも。
それぞれの受入先での振る舞いを訪問者に集中させることで、処理と構造を分離。
1.訪問者と受入先の宣言
 public abstract class Visitor {
   public abstract void visit( Acceptor a );} // 問合(宣言)
 public interface Acceptor {
   public abstract void accept( Visitor v );} // 受諾(宣言)
2.訪問者クラス (訪問者宣言を実装) : 処理はここにまとめる
 public class エロゲオタ extends Visitor {
   public int 所持エロゲ本数 = 0; // 所持エロゲ本数、最初は0。
   public void visit( 一般家電店 a ){ // 問合その1(実装)
   }             // エロゲが無くて(´・ω・`)ショボーン
   public void visit( エロゲショップ a ){ // 問合その2(実装)
     所持エロゲ本数++;       // エロゲいっこ増やす。
   }
 }
3.受入先クラス (受入先宣言の実装) : 構造はここにまとめる
  具体的な処理は訪問者で記述したので、こっちは簡潔に。
 public class エロゲショップ implements Acceptor {
   public void accept( Visitor v ){ v.visit( this ); }
 }            // エロゲオタのvisit(問合その1)を実行
 public class 一般家電店 implements Acceptor {
   public void accept( Visitor v ){ v.visit( this ); }
 }            // エロゲオタのvisit(問合その2)を実行
4.使用例
 エロゲショップ getchu = new エロゲショップ( ); 一般家電店 コジマ. = new 一般家電店( ) ;
 エロゲオタ 漏れ     = new エロゲオタ( );
 getchu.accept( 漏れ );  // エロゲ+1 → 所持 1 本
 コジマ.accept( 漏れ );   // エロゲ±0 → 所持 1 本

77 :[14/23] ◆zFEditKho2 :02/11/12 22:08 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Chain of Responsibility : チェイン オブ レスポンシビリティ 】
責任のたらい回し。こなせるなら自分で処理、ダメなら次の人に丸投げ。
処理クラスを数珠繋ぎにします……線形リストの構造に似てるような?
 public abstract class ショップ {
   private ショップ 次の店;   // たらい回し先。
   public ショップ setNext( ショップ next ){
     次の店 = next;  // 次の店を設定。
     return next;   // 数珠繋ぎにします (実はDecorator)
   }
   public final boolean getエロゲ( ){ // エロゲが欲しい
     if ( エロゲがある( )==true ){ // ハケーン
       return true;           // good job!
     } else if ( 次の店 != null ){   // 他に店がまだある
       次の店.getエロゲ( );    // 隣の店へGo
     } else {                 // 全部探したのに
       return false;         // 見つからなかった……
     }
 } }
 public class 近所の店 extends ショップ{
   public boolean エロゲがある( ){ return false; } }
 public class ソフマップ extends ショップ{
   public boolean エロゲがある( ){ return true; } }
 public class getchu extends ショップ{
   public boolean エロゲがある( ){ return true; } }

使い方: ルートを設定して、たらい回し開始。
 ショップ 巡回ルート = 近所の店.setNext(ソフマップ).setNext(getchu);
 boolean 巡回結果 = 巡回ルート.getエロゲ( );
 // 近所の店は×だがソフマップは○。よって、巡回結果==true。

78 :[15/23] ◆zFEditKho2 :02/11/12 22:09 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Facade : ファサード 】
ゴチャゴチャした処理を、たった一つの関数にまとめます。すっきり。

1.ごちゃごちゃしたクラス
 public class 裏画面処理{
   public void drawBackGround ( ){ 背景表示 }
   public void drawCharacter ( ){ 立ち絵表示 }
   public void drawWindow ( ){ メッセージウィンドウ表示 }
   public void drawString ( ){ 文字列表示 }
 }

2.たった1つにまとめたクラス
 public class 表示{
   public void 描画( ){// いろいろとややこしい処理です。
     裏画面確保
     裏画面処理.drawBackGround();
     if ( Hシーン中 != true ){      // Hシーン中は、立ち絵必要なし。
       裏画面.drawChatacter();
     }
     裏画面処理.drawWindow();
     裏画面処理.drawString();
     表画面に裏画面を上書き
   } // 余談:裏画面で作業して最後に表画面に転写。
 }   //     アニメーションさせるのに必須です。

3.使い方
 表示.描画( ); // 表示はたったこの1行でOK。

79 :[16/23] ◆zFEditKho2 :02/11/12 22:12 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Observer : オブザーバー 】
なにかあったら全ての観察者に報告。Javaには同名クラスObserverがあるので注意の事。
1.報告者/観察者の宣言
 public interface Subject {  // 報告する人(報告者)
   public abstract void setObserver( Observer o ); // 観察者の場所を記憶(宣言)
   public abstract void notify( String str ); }     // 観察者に更新を報告(宣言)
 public interface Observer { // 受信する人(観察者)
   public abstract void update ( Subject s ); }   // 子に変更があった時(宣言)
2.報告者の実装
 public class エロゲマ implements Subject {
   private LinkedList BBS = new LinkedList();    // 観察者一覧
   public String カキコ;
   public void setObserver( Observer o ){ BBS.add( o ); }// 観察者を記憶(実装)
   public void notify( String str ){                   // 報告する(実装)
     カキコ = str;
     一覧に登録されている観察者全てに、BBS.update( this );
 } }
3.観察者の実装
 public class 2chBBS implements Observer {
   private LinkedList ログ = new LinkedList();
   public void update ( Subject s ){       // 報告者に変更があった時(実装)
     ログ.add( c.カキコ ) );           // 書き込みをログに保存
 } }

4.使い方
 エロゲマ エロゲオタ. = new エロゲマ();  // とあるオタ
 2chBBS エロゲ板 = new 2chBBS(); エロゲオタ.setObserver( エロゲ板 );
 2chBBS 葱板  = new 2chBBS(); エロゲオタ.setObserver( 葱板 );
 エロゲオタ.notify("エロゲオタキモイ");  // マルチポスト(・A・)イクナイ!

80 :[17/23] ◆zFEditKho2 :02/11/12 22:15 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Mediator : メディエーター 】
たったひとりの相談役。親がすべての子供の状態を管理します。
 public interface Child {   // 相談する人(子)   (※一般名称はColleague:同僚)
   public abstract void setMother( Mother m );   // 親のいる場所を記憶(宣言)
   public abstract void setEnabled( boolean enabled ); // 親の言うことを聞く(宣言)
 }
 public interface Mother { // 相談される人(親) (※一般名称はMediator:相談役)
   public abstract void childChanged ( Child c ); // 子に変更があった時(宣言)
 }
 public class ヒロイン implements Child {           //子の実装
   private Mother system;
   private int 好感度 = 0 ;   public boolean Hシーン = false ;
   public void setMother( Mother m ){ system = m; } // 親を記憶(実装)
   public void setEnabled( boolean b ){ Hシーン=b; }   // 親の言うことを聞く(実装)
   public void 好感度上昇( ){
     好感度++;
     system.childChanged( this ); // 自分自身に変更があったことを親に伝える
    }           // この部分は前述のObserverパターン。子供が親に報告します。
 }
 public class エロゲシステム implements Mother {// 親の実装
   public Child 委員長 = new Child();
   public Child あかり = new Child();
   public void childChanged ( Child c ){   // 子に変更があった時(実装)
     if ( 委員長.好感度>90 ){
       委員長.setEnabled( true );    // 委員長はストーキングで攻略できるが、
     }else if ( 委員長.好感度>50 && あかり.好感度>90 ){
         あかり.setEnabled( true );  // あかりは、他キャラの好感度も
 }  }  }  }                     // 高くないと攻略不可。
// エロゲシステムが各ヒロインの攻略可能判定を司る図……ちょっと萎える(;´ー`)

81 :[18/23] ◆zFEditKho2 :02/11/12 22:18 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Memento : メメント 】
状態をまるまる保存することで、作業履歴を取り扱います。
 public class セーブデータ implements Serializable{          // 状態保持クラス
   private String シナリオ現在位置 = new String("title");
   public void set位置( String pos ){ シナリオ現在位置 = pos; } //現在位置Set
   public String get位置( ){ return シナリオ現在位置; }      //現在位置Get
 }
 public class エロゲシステム {           // 上記状態をやりくりするクラス
   private Stack history = new Stack(); // いわゆるスタック。履歴管理に最適。
   public void save( ){                   // データを書き込み
     (history.peek())をファイルに保存 // 一番最新のデータを保存します
   }
   public String load( ){                   // データを読み込み
     セーブデータ dataをファイルから読込
     historyを一旦クリアしてdataを追加
     return data.get現在位置( );
   }
   public String undo( ){                  // 一つ前にもどす。
     return ( history.pop( ) ).get現在位置( );
   }
   public void next( String pos ){            // 履歴一つ覚える。
     セーブデータ data = new セーブデータ( pos );
     history.push( data ); // クラスごとまるまる保存…この辺がMemento
 } }
3.使い方
 先に進むには   エロゲシステム.next( 次シーン );        // 次のシーンへ
 Hシーン直前で    エロゲシステム.save( );            // 保存
 CG回収できたら String 現在位置 = エロゲシステム.load( ); // 読込なおし
 巻き戻すには.   String 現在位置 = エロゲシステム.undo( ); // 一つ前に戻る

82 :[19/23] ◆zFEditKho2 :02/11/12 22:19 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 State : ステート 】
クラス内の if 文で分けず、各状態ごとにクラスを作る方法。意外に説明が難しい。

例えば次のようなクラスは、
 public class エロゲ {
   public void エロゲ評価( ){
     if.    ( 良作 ){ とりあえずコンプリート }
     else if ( 地雷 ){ 2chに地雷報告   }
   }
 }

Stateパターンで書くと、1つのinterfaceと2つのクラスになります。
 public interface エロゲState {
   public abstract void エロゲ評価( ); // 宣言します
 }
 public class 良作エロゲ implements エロゲState {
   public void エロゲ評価( ){ とりあえずコンプリート }// 宣言を実装
 }
 public class 地雷エロゲ implements エロゲState {
   public void エロゲ評価( ){ 2chに地雷報告 }  // 宣言を実装
 }

で、2つのクラスは必要に応じてif文で切換えます。
……結局 if は使います(苦笑) ただし、
 public class 凡作エロゲ implements エロゲState {
   public void エロゲ評価( ){ 2chで愚痴ってみる }// 宣言を実装
 }
のような、新しい状態の追加が簡単です。

83 :[20/23] ◆zFEditKho2 :02/11/12 22:21 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Flyweight : フライウェイト 】
管理対象に同じ物があるのなら、余分に作るより共有。
// VCLのAnsiStringやSTLのstring等の実装で、この仕組みが使われています。

 public class ImageFactory {                  // 画像管理クラス
   private static ImageFactory singleton = new ImageFactory( );
   private ImageFactory (){ }
   public static ImageFactory getInstance(){ return singleton; }
                // 以上の3行は前述Singletonパターン。同期ミスを防ぎます。
   private HashMap CG記憶 = new HashMap( ); // 名前と画像の組合せを管理
   public synchronized Image getImage( String ヒロイン ){. // 画像取得
     Image img = (Image)CG記憶.get( ヒロイン );    // 登録済みの中にある?
     if( img == null ){                     // なかったので……
       imgをファイルから読み込む              // 読み込んで
       CG記憶.put( ヒロイン,img );            // 組合せごと保存します。
     }
     return img;                        // 要求された画像を返却。
   }
 }
 
 // こうやって作っておけば、例えば同一画像を何度も呼ばれる時、
 ImageFactory CG管理 = ImageFactory.getInstance( );// Singletonでがっちり管理
 Image img1 = CG管理.getImage( "..'´/^Y^ヽ" );. // a
 Image img2 = CG管理.getImage( "i !l|.    |" ); // b
 Image img3 = CG管理.getImage( "i !l|.    |" ); // b
 Image img4 = CG管理.getImage( "i !l|.    |" ); // b
 Image img5 = CG管理.getImage( ">(|-[ ] []ノ" ); // c
 // 画像メモリの消費量は、a と b と c の3つ分で済みます。

84 :[21/23] ◆zFEditKho2 :02/11/12 22:23 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Proxy : プロキシー 】
一見、普通のクラスだけど……内部では、ないなら作成&あるなら再利用。
必要になってはじめて new (確保) する、それがProxy。

1.共通宣言
 public interface メーカー {
   public abstract Date 新作発売日( );   // 予告  (宣言)
   public abstract void 新作制作( );     // 実作業(宣言)
 }
2.時間のかからない作業……この役がProxy(代理人)
 public class エロゲメーカー implements メーカー {
   public 開発 開発陣;         // (取り込んで、外に見せない)
   public Date 新作発売日( ){ return 予定している発売日; }
   public void 新作制作( ){ // 実作業(宣言)
     if ( 開発陣==null ){      
       開発陣 = new 開発( );
     }
   }
 }
3.重たい作業
 public class 開発 implements メーカー {
   public Date 新作発売日( ){ return 予測される発売日; }
   public void 新作制作( ){ エロゲ制作実作業 (※とても時間がかかる) }
 }
4.使い方
 エロゲメーカー maker = new エロゲメーカー( );
 Date 発売予定日 = maker.新作発売日( ); // ここまでは2.のクラスが担当。
 maker.新作制作();                 // このタイミングで初めて3.が起動。
 // 納期のズレは……気にしちゃダメ。

85 :[22/23] ◆zFEditKho2 :02/11/12 22:24 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Command : コマンド 】
操作ごとに関数を一つ……ではなく、操作ごとにクラスを一つ作ります。

1.共通のインターフェイス
 public interface Command {
   public abstract void execute( ); // コマンドを「実行」(宣言)
 }

2.上記インターフェイスを組み込んだ各種操作(例)
 public class Look implements Command {
   public void execute( ){ 「眼鏡の看護婦さんがいる」 }
 }
 public class Talk implements Command {
   public void execute( ){ 『嘘……ついたんですね。』 }
 }
 public class Action implements Command {
   public void execute( ){ 「逃げることができない!」 }
 }

3.こうやって作っておけば、それぞれの操作をコマンドとして
  取り扱うことができます。また、複数のコマンドをまとめて実行する
  ……いわゆるマクロも実現できます。
 public class EscapeMacro implements Command {
   public void execute( ){
     new Action().execute(); // 逃げる → 失敗
     new Action().execute(); // 逃げる → やはり失敗
   }
 }

86 :[22/23] ◆zFEditKho2 :02/11/12 22:27 ID:DBfOtK9d
☆ エロゲーで学ぶデザインパターン ☆
【 Interpreter : インタープリター 】 // アドベンチャーやビジュアルノベルも、インタープリタです。
前述Commandを発展。簡易文法解析を組み込んで、ミニ言語を実現します。

こんなミニ言語を考えてみます……12月購入リスト。
 1| 人妻麻雀2 [rouge] http://pinktower.com/www.will-japan.co.jp/
 2| 彼女はメイドRot 〜悠久の小夜曲〜 [BELL-DA] http://pinktower.com/www.media-box.ne.jp/
 3| 妹汁 (アトリエかぐや) http://pinktower.com/www.alpha-net.ne.jp/users2/kaguya21/
そしてここに3人のエロゲオタが。
 ・タイトルに "妻" が含まれていたら購入する 「ひとづまにあ」クラス
 ・タイトルに "メイド"が含まれていたら購入する 「御主人様」クラス
 ・タイトルに "妹" が含まれていたら購入する 「お兄ちゃん」クラス

 ところが上記リストでは、何処から何処までがタイトルにあたるのか、わかりにくいです。
 そこで文脈分割マシンを用意。各行を"("や")"で区切ってバラバラにします。

 例えば3行めだと、次の3つ。
   "妹汁" と "アトリエかぐや" と "http://pinktower.com/www.alpha-net.ne.jp/users2/kaguya21/"
 1つ目がタイトルにあたるので、それを調べればよい……こんな感じで解釈します。

 結果としては、次の順に実行されることになります。
  1| ひとづまにあが"人妻麻雀2"を購入
  2| 御主人様が"彼女はメイドRot"を購入
  3| お兄ちゃんが"妹汁"を購入

まとめ : 特に重要なのは次の2つ。
 1.文脈分割マシンクラス  ファイルから読み込んだ1行を単語に分割して解釈しやすくします。
   // Javaの場合、分割にはStringTokenizerかPatternのsplit()を使うとよいです。
 2.コマンドクラス       自分の事を意味していたら、コマンドを実行します。
   // 単純にswitch使ったり他クラスに投げたり木を構築したりそりゃもういろいろ方法が。

87 :[last] ◆zFEditKho2 :02/11/12 22:32 ID:DBfOtK9d
1パタン1発言内に納めるべく、相当削ぎ落としましたが、
それでも張り付ける段になって、30行制限に遭遇。ウカツでした。
そして、最後の最後で通し番号が……(´・ω・`)ショボーン


気付いてるかたは気付いてると思いますが……以上の23パタン、
http://pinktower.com/www.hyuki.com/dp/ 結城さんの本を手本としてエロゲナイズしました。

デザインパターンは、プログラマ達がよく使う手法をまとめたものです。
私はJavaで書きましたが、考え方自体はC++等他言語でも応用可能です。

順番に覚えるのは難しいですが、今まで組んできた経験を振りかえれば、
きっとあてはまるものがあるはず。どれかひとつでも役立てば、これ幸い。

「エロゲーで学ぶデザインパターン」でした。

88 :名無しさん@初回限定 :02/11/13 00:21 ID:ks3hX8bA
>87
すばらしい、感動した

89 :名無しさん@初回限定 :02/11/13 00:48 ID:e3o2GEEd
Transcript show: '>>87乙〜。次はスレッドパターンだなw'

90 :名無しさん@初回限定 :02/11/13 06:20 ID:jkGCig+e
<?php

ob_start() ;

/* HTML構文略 */

echo( ">87<br>\n" ) ;
echo( "スレッドパターンは時間がかかりそうだな・・・<br>\n" ) ;
for( i=0 ; i<100 ; i++ )
  echo( "まぁがんばれ<br>\n" ) ;

ob_end_flush() ;
?>

91 :名無しさん@初回限定 :02/11/13 20:11 ID:edNiJBjM
>>87乙カレーです。

saveファイルいっこ遡ったくらいではBad直行な漏れとしては
Memento、リングバッファのほうがよかね?とか思いマスタ。
まあ勝手な話しでスマソ

92 : ◆zFEditKho2 :02/11/14 02:52 ID:jGqGtAj0
>>88 ’サンクスです。
>>89 >>90
実はスレッドパターン、まだ本すら手に入れてない状態なので……すが、
なんとか、頑張る所存です。イツニナルヤラ;

>>91 リングバッファ : Queueの実装手法の一つ、ですよね?(さっき調べたw)
確かに、エロゲセーブデータにぴったりの仕様です。件数制限あるし (w

// 本当は花の記憶シリーズのように、好きな位置から再開できたらいいんですけど…

93 :補[7/23] ◆zFEditKho2 :02/11/14 22:30 ID:kImQmxEV
今さらですが、チョト修正します……>>57 のBuilderですが、やっぱり、
getResult(最終結果の取出)がないのはマズーなのかなぁ、と(;~ー~)

【 Builder : ビルダー 】
 複雑な構造は一気に作らず、少しずつ順番に。
 組み終わったらgetResult()で取り出します。

 public abstract class Builder {      // たくましくなる方法
   public abstract マッスル 海でガッツ(); // 筋力up宣言 その1
   public abstract マッスル 山でガッツ(); // 筋力up宣言 その2
 }
 public class 主人公 {                // 筋力upを組立
   private マッスル 筋肉;           // 主人公の筋肉
   public void ガッツ( Builder ヒロイン ){  // 鍛えます。
     筋肉 += ヒロイン.海でガッツ();    // マッシヴ!
     筋肉 += ヒロイン.山でガッツ();    // モア マッシヴ!!
   }
   public マッスル getResult( ){       // 仕上がりを返します
     return 筋肉;
   }
 }
 public class タカさん extends Builder {       // 筋力up実装
   public マッスル 海でガッツ(){ return マッシヴ!! ;. }// 実装その1
   public マッスル 山でガッツ(){ return マッシヴ!!!!; }// 実装その2
 }
 // 使い方 //
  主人公.ガッツ( new タカさん() );  // タカさんにシゴかれる主人公の図
  マッスル 筋肉 = 主人公.getResult(); // 鍛えられたキンニクをポージング

73 KB  [ video.15pink.com サンプルはここ ]
続きを読む

掲示板に戻る 全部 前100 次100 最新50
名前: E-mail (省略可) :

read.cgi ver7.09p (03/01/29)