Javaでトランプを1枚ずつ配るっていう実装を考えてみた

f:id:ts0818:20191027140435j:plain

くばられた5枚のカードを一度だけ交換して、相手よりいい役をそろえようとするゲーム
しかし、ゲームに「賭け」の魅力が加わると、一変して複雑な心理戦が始まるゲームでもある!ポーカーフェイスとは、相手に気持ちを読まれないための表情なのだ!!

ジョジョの奇妙な冒険』第23巻(1991)

⇧  ご存知「ジョジョの奇妙な冒険 - 第3部 」の 「ダービー・ザ・ギャンブラー」の回での解説ですね、はい、どうもボクです。

で、

wired.jp

⇧  まさかの、AI圧勝...ポーカーフェイスとか関係ないやん...

 

ちなみに「ポーカー」で検索したら、

www.nintendo.co.jp

⇧  任天堂がトップに来るっていうね、流石です。

Wikipedia さんによりますと、

ポーカー(poker)は、トランプを使って行うゲームのジャンルである。コントラクトブリッジジン・ラミーと並ぶ世界三大カードゲームの一つで、心理戦を特徴とする。主にアメリカ合衆国でプレイされているゲームである。プレイヤー達は5枚の札でハンド(役、手役)を作って役の強さを競う。

ポーカー - Wikipedia

⇧  世界三大カードゲームの1つであると。

そんな、「ポーカー」に限らないんだけど、カードゲームで複数人数で遊ぶ場合に1枚ずつカード配るじゃないっすか?

それって、プログラミングだとどう実装すんのかな~、って、ふと思ったので。そんでは、レッツトライ~。

 

カード1枚ずつ配る

っていう実装の情報がなかなか見つからんので、独自に考えてみました。

とりあえず、Eclipse を起動で。Javaプロジェクトを作成で、以下のような「.java」ファイルを用意。

f:id:ts0818:20191027144811p:plain

「PokerHands.java」はポーカーの役の判定用のクラスとしようと思ったんだけど、どう実装するか定まってないので、割愛。

あと、あくまで、ゲームの始めの状態(プレイヤーの手元に初期のカードが配置されるとこまで)までしか実装できてません(涙)。

んで、ソースコードを編集。

Card.java

package game;

import java.util.ArrayList;
import java.util.List;

/**
 * トランプクラス
 */
public class Card {
  /** トランプの数字 */
  public enum Rank {
    DEUCE("2"), THREE("3"), FOUR("4"), FIVE("5"), SIX("6"), SEVEN("7"), EIGHT("8"),
    NINE("9"),TEN("10"), JACK("J"), QUEEN("Q"), KING("K"), ACE("A");

    private String rankNumber;

    private Rank(String rankNumber) {
      this.rankNumber = rankNumber;
    }

    public String getRankNumber() {
      return this.rankNumber;
    }

  }

  /** トランプの絵柄 */
  public enum Suit {
    CLUBS("♣"), DIAMONDS("♦"), HEARTS("♥"), SPADES("♠");

    private String suitMark;

    private Suit(String suitMark) {
      this.suitMark = suitMark;
    }

    public String getSuitMark() {
      return this.suitMark;
    }

  }

  private final Rank rank;
  private final Suit suit;

  private Card(Rank rank, Suit suit) {
    this.rank = rank;
    this.suit = suit;
  }

  public Rank rank() {
    return rank;
  }

  public Suit suit() {
    return suit;
  }

  private static final List<Card> protoDeck = new ArrayList<Card>();

  // Initialize prototype deck
  static {
    for (Suit suit : Suit.values())
      for (Rank rank : Rank.values())
        protoDeck.add(new Card(rank, suit));
  }

  public static ArrayList<Card> newDeck() {
    return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
  }
}

Player.java

package game;

import java.util.ArrayList;
import java.util.List;

/**
 * プレイヤークラス
 */
public class Player {
  private int id;
  private String name;
  private List<Card> cards = new ArrayList<>();

  private Player(int id, String name) {
    this.id = id;
    this.name = name;
  }
  
  public static Player fuctoryPlayer(int id, String name) {
    return new Player(id, name);
  }
  
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public List<Card> getCards() {
    return cards;
  }
  public void setCards(List<Card> cards) {
    this.cards = cards;
  } 
}

PlayPoker.java

package main;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import game.Card;
import game.Player;

public class PlayPoker {
  
  private static final int maxCards = 5; // 手札の最大枚数

  public static void main(String[] args) throws IOException {
    // TODO 自動生成されたメソッド・スタブ      
    List<Card> cards = Card.newDeck();
    Collections.shuffle(cards);
    // プレイヤー人数
    int players = 3;
    // プレイヤーの名前
    String[] names = { "Tom", "Bob", "Joe" };

    List<Card> playCards = new ArrayList<>(cards.subList(0, maxCards * players));
    List<Player> playersList = new ArrayList<>();
    for (int index = 0; index < players; index++) {
      playersList.add(Player.fuctoryPlayer(index, names[index]));
    }

    handOutCrad(playersList, playCards);
    for (Player player : playersList) {
      System.out.println(player.getName() + "さんの手持ちカード");
      for (Card card : player.getCards()) {
        System.out.println(card.suit().getSuitMark() + "" + card.rank().getRankNumber());
      }
    }
  }

  /**
   * プレイヤーに初期カードを配布するメソッド
   * @param playersList プレイヤーのリスト
   * @param playCards カード枚数(プレイヤー数×5枚)
   */
  public static void handOutCrad(List<Player> playersList, List<Card> playCards) {
    // プレイヤーの数だけ繰り返し
    for (int index = 0; index < playersList.size(); index++) {
      int i = 0;
      // 5枚配る
      while (playersList.get(index).getCards().size() < maxCards) {
        // 1枚ずつ配る
        for (int j = index; j < playCards.size(); j += playersList.size()) {
          playersList.get(index).getCards().add(i++, playCards.get(j));
        }
      }
    }
  }
  
//  public static void takeCard(List<Player> playersList, int changeCard, List<Card> cards) {
//    
//  }
}

んで、実行してみる。

f:id:ts0818:20191027145952p:plain

f:id:ts0818:20191027150255p:plain

⇧  とりあえず、1枚ずつ配れたかな。まぁ、全員のカードが表示されてしまってるから、ゲームとしては全く成り立たないわけだけど。

時間がある時に、ポーカーゲーム完成させたいな~、って言ってもクラス構成とかをどうするかがなかなか難しそうですかね、他にも分からんことだらけですが(涙)

ちなみに、トランプクラスは、

docs.oracle.com

⇧  Oracleさんのサイトを参考にさせていただきました。

そして、

www.mag2.com

⇧  上記サイト様が詳しいですが、「ずつ」「づつ」って混乱しますよね。

今回はこのへんで。