So-net無料ブログ作成
検索選択

Android SDK で,ゲームを作る (2) [プログラム三昧]このエントリーを含むはてなブックマーク#

WS000944.png

前回は,ひとつのファイルに何もかもゴチャマゼに入れてしまいました.今回は, Model 部分を切りだします.

ゲームロジック(Model オブジェクト)

/*
 * $Id$
 * --------------------------------------------
 * File         : SeekNumberModel.java
 * Package      : org.noritan.seeknumber
 * Copyright    : Copyright (c) 2010 noritan.org
 * Organization : noritan.org
 * Created      : 2010/03/12
 * --------------------------------------------
 */
package org.noritan.seeknumber;

import java.util.ArrayList;

/**
 * This <code>SeekNumberModel</code> class is a game logic
 * of the Seek Number Game.
 * 
 * @author noritan
 * @see {@link SeekNumberListener}
 */
public class SeekNumberModel {
    private int buttonCount;
    private int[] indexOrdered; // position to id table
    private int expected;
    private ArrayList<SeekNumberListener> listeners = new ArrayList<SeekNumberListener>();
    
    /**
     * Construct a <code>SeekNumberModel</code> object.
     * It is assumed that the game has a number of buttons
     * indicated by the parameter <code>buttonCount</code>
     * The <code>indexOrdered</code> table and
     * the <code>expected</code> variable are initialized.  
     *
     * @param buttonCount The number of buttons to be handled by this object.
     */
    public SeekNumberModel(int buttonCount) {
        this.buttonCount = buttonCount;
        indexOrdered = new int[buttonCount];
        for (int i = 0; i < buttonCount; i++) {
            indexOrdered[i] = i;
        }
        expected = Integer.MAX_VALUE;
    }
    
    /**
     * Reorder the <code>indexOrdered</code> table with a random
     * number generator of <code>Math</code> class.
     * In addition, the <code>expected</code> variable is
     * initialized too.
     * A {@link #notifyInitialize(int[])} event is issued when
     * the table is initialized.
     */
    public void reorder() {
        ArrayList<Integer> buttonLeft = new ArrayList<Integer>();
        for (int i = 0; i < buttonCount; i++) {
            buttonLeft.add(i);
        }
        for (int i = 0; i < buttonCount; i++) {
            int k = (int)(Math.random() * (buttonCount - i));
            int index = buttonLeft.get(k);
            indexOrdered[i] = index;
            buttonLeft.remove(k);
        }
        notifyInitialize(indexOrdered);
        expected = 0;
    }
    /**
     * This method notifies a click event is occurred on a button.
     * The position of the clicked button is indicated by the
     * parameter <code>position</code>.
     * This method cause a {@link #notifyHit(int)} event when
     * the hit button is an expected one indicated by
     * the variable <code>expected</code>. 
     * Whe clicked button is the last one, an additional event
     * {@link #notifyFinish()} is issued too. 
     * 
     * @param position The position of the hit button.
     */
    public void click(int position) {
        if (expected >= buttonCount) {
            // Nothing is expected.
            return;
        }
        // Is the button an expected one ?
        if (indexOrdered[position] == expected) {
            // Right selection.
            notifyHit(position);
            // point next button to be expected.
            expected++;
            if (expected >= buttonCount) {
                // All buttons are clicked.
                notifyFinish();
            }
        }            
    }
    /**
     * Add a {@link SeekNumberListener} object as an event listener
     * of this object.
     * 
     * @param listener An event listener to accept events issued by
     * this object.
     */
    public void addListener(SeekNumberListener listener) {
        listeners.add(listener);
    }
    /**
     * Notify all event listeners that this object is initialized.
     * The {@link SeekNumberListener#initialized(int[])} method is
     * used to issue the event.
     * The parameter <code>assignment</code> is cloned prior to
     * issue the event not to modify the assignment map of this
     * object. 
     * 
     * @param assignment An assignment map from button's position
     * to the button's order.
     */
    protected void notifyInitialize(int[] assignment) {
        assignment = assignment.clone(); 
        for (SeekNumberListener listener:listeners) {
            listener.initialized(assignment);
        }
    }
    /**
     * Notify all event listeners that this object recognizes
     * an expected button is clicked at the position.
     * 
     * @param position The position of the hit button.
     */
    protected void notifyHit(int position) {
        for (SeekNumberListener listener:listeners) {
            listener.hit(position);
        }
    }
    /**
     * Notify all event listeners that this object detects the end
     * of a game when all buttons are hit.
     */
    protected void notifyFinish() {
        for (SeekNumberListener listener:listeners ) {
            listener.finished();
        }
    }
}

View に依存する部分を取り去って,ゲームロジックとして独立させました.このオブジェクトは,どのユーザ・インターフェイスにも使用することができます.

このモデルに対してメッセージを伝えるのは, public メソッド reorder() と click(int) です.それぞれ,ユーザがゲームを開始した時とユーザがボタンをクリックした時に呼び出されます.

public メソッドには,もう一つ addListener(SeekNumberListener) というものがあります.このメソッドは,モデルオブジェクトから発生られるメッセージを受け取るオブジェクト(Listener)を登録するために使用されます.

SeekNumberListener インターフェイス

/*
 * $Id$
 * --------------------------------------------
 * File         : SeekNumberListener.java
 * Package      : org.noritan.seeknumber
 * Copyright    : Copyright (c) 2010 noritan.org
 * Organization : noritan.org
 * Created      : 2010/03/12
 * --------------------------------------------
 */
package org.noritan.seeknumber;

/**
 * Objects implementing this <code>SeekNumberListener</code> interface
 * accepts events issued by a {@link SeekNumberModel}
 * class instance.
 * The <code>SeekNumberListener</code> interface is used to be
 * registered with the
 * {@link SeekNumberModel#addListener(SeekNumberListener)}
 * method.
 * 
 * @author noritan
 * @see SeekNumberModel
 * @see SeekNumberModel#addListener(SeekNumberListener)
 */
public interface SeekNumberListener {
    /**
     * Notify the listener that new labels are assigned to the buttons.
     * 
     * @param assignment An assignment map from the position of
     * a button to the label corresponding to the button.
     */
    void initialized(int[] assignment);
    /**
     * Notify the listener that a button at a <code>position</code>
     * is hit correctly.
     * 
     * @param position The position of the hit button.
     */
    void hit(int position);
    /**
     * Notify the listener that all buttons are hit and a game
     * has finished.
     */
    void finished();
}

SeekNumberListener インターフェイスは, Model オブジェクトから発せられたメッセージを受け取ります.三つのメソッド initialized(int[]) hit(int) finished() を装備しており,それぞれ,ゲームの開始を知らせる,当たりボタンが押されたことを示す,ゲームの終了を知らせる,という役割があります.

GUI 関連のコードは,後日.


nice!(0)  コメント(0)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この記事のトラックバックURL:
※言及リンクのないトラックバックは受信されません。