SSブログ

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

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。