質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

2回答

15068閲覧

【カードゲーム】カードを引く(or配る)メソッドはどこに実装すべきか。

Jake

総合スコア289

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

2クリップ

投稿2015/08/17 18:51

はじめまして、java教材向けに簡単なカードゲームを制作しました。制作後、もうすこしリファクタリング&拡張性のあるコードにできないものかと思い、この場を借りて質問させて頂くことにしました。

ざっとですが、下のようなクラスがあります。

  • Cardクラス(カード)
    -カードの数値
    -カードのスート(ダイヤ、スペードなど)
    -カードの表示値 (数値は1でも表示はAなど)
  • Deckクラス(カードの山)
    -Card52
    -shuffle() カードをシャッフル
  • Playerクラス (プレイヤー)
    -Card[](手札分)
    -cardCount (手持ちカード枚数)
    -addCound()(手持ちカード枚数カウンタを増やす)
  • Gameクラス (ベースクラス:main()があります)
    -Deck mainDeck (カードの山)
    -cardMax (現在の山の枚数)
    -hitCard() (カードを引く)

【カードを引く】というメソッドは、main()のあるGameクラス内に記載し、ゲームループから呼び出しました。

static void hitCard(Player p) { //山の一番最後からカードを一枚取って、プレイヤーのカード配列に入れる p.cards[p.cardCount]=mainDeck.cards[cardMax - 1]; //手持ちカード枚数カウンタを増やす p.addCount(); //山の枚数を減らす cardMax--; }

と、こんな感じです。
上記コード&記載場所で動作的には何ら問題はないです。

ここからが質問なのですが、Gameクラスに【カードを引く】というメソッドを書くのはどうなんでしょう?

例えば、複数のカードゲームを選択してプレイできるように今後プロジェクトを改造する場合を想定したら、【カードを引く】メソッドはどこに実装すべきだと思いますか?

今考えているのは、Gameクラスをmain()持ちではないクラスに変更し、各ゲームはGameクラスを継承した物にするという作りに。スーパークラスのGameクラスの中に【カードを引く】メソッドを実装するのが妥当なのかな?と考えています。

皆さんの思考をお聞かせ頂きたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

僕はオブジェクト指向を使う主な目的は、コードの書き方を現実世界の表現に近づけるためのモノと考えています。(DDDで言うユビキタス言語です)そういう意味で、Gameカードを引くメソッドを持っているとゲームがカードを引くとコード上は表現されます。コード上現実世界を表現できていますか?これをコードにすると

java

1// ゲームはプレイヤーのためにカードを引く(Game hits card for player) 2game.hitCard(player);

と表現されるはずです。

これよりは、カードを引くプレイヤーがカードを引くの方がそれっぽいですよね。現実世界でカードを引くのはプレイヤーですから。Gameにはカードを配るメソッドが定義されており、そこでカードの配り方が定義されていたら下記のように実装されるでしょう。

java

1public class Game { 2 3 public void deal(){ 4 Card card = drawFromDeck(); 5 player.hand(card); // Gameがカードを配る 6 } 7 8 private Card drawFromDeck() { 9 // デッキからカードを選ぶ実装例 10 return deck.cards[random]; 11 } 12 13}

ところで、プレイヤーに配るカードは、カードゲームのルール毎に異なりませんか?例えばポーカーと七並べのルールで遊べたとして、1枚ずつ配るのか、数枚まとめて配るのか、はカードゲームのルールに定義します。Gameにカードを配るを実装するよりも、Ruleにカードを配るを実装した方がそれらしくなります。

こうしていくことで、コードにドメインの知識を語らせる事ができるでしょう。

投稿2015/08/17 23:32

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jake

2015/08/18 03:11

コメントありがとうございます。 書かれている通り、「Gameがカードを引く(配る)」というカタチになっている、というのも懸念点の1つでした。 まとめて配る場合や順に配る場合といろいろパターンがありますが、基本的には1枚ずつ配ることの繰り返しですので、仮想ゲームマスターに配ってもらう、という感覚で作っていたのですが、書かれている内容を見ると、方向性がクリアになってきたような気がします。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2015/08/18 04:46

GameMasterは良いクラス名ですね。Ruleがカードを配るのもあとになって変な気がしました。GameMasterがRuleを知っていて、そのRuleに合わせてカードを配るんですね。
guest

0

質問に対するリファクタリングを考えてみました。
1-Gameクラスを抽象クラス化
2-抽象メソッドdoTurnを追加→ゲーム内の状態を変化させるメソッド、今回のカードを引く等の行為など
3-抽象メソッドjudgeを追加→ゲーム状態変化に伴う勝敗判定
4-Gameクラスのmain内で2.3を呼ぶ
5-Gameを実装したCardGameを実装

投稿2015/08/17 23:44

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jake

2015/08/18 03:13

コメントありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問