首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扑克牌洗牌和交易程序

扑克牌洗牌和交易程序
EN

Code Review用户
提问于 2018-11-28 19:47:53
回答 4查看 11.5K关注 0票数 5

这个程序在卡片和四个玩家之间进行交互,其中卡片是要分发的。

该程序具有以下功能

  • 创造一副牌。
  • 洗牌。
  • 展示甲板。
  • 四位玩家平分牌。
  • 显示每个玩家的牌。

请提出一些更好的方法来做这个节目。

还建议在这个程序中新的功能和修改。

代码语言:javascript
复制
package cardgame;

public class Card {

    String suit;
    String rank;

    public Card(String cardSuit, String cardRank){
        this.suit = cardSuit;
        this.rank = cardRank;
    }
}
代码语言:javascript
复制
package cardgame;

import java.util.*;

public class DeckOfCards {

    final int size = 52;
    Card[] deckOfCards = new Card[size];


    public DeckOfCards(){

        int count=0;

        String[] suits = {"Diamonds","Clubs","Hearts","Spades"};
        String[] ranks ={"King","Queen","Jack","Ten","Nine","Eight","Seven","Six","Five","Four","Three","Deuce","Ace",};

        for (String s:suits){
            for (String r:ranks){

                Card card = new Card(s, r);
                this.deckOfCards[count] = card;
                count++;
            }
        }

    }
    public void ShuffleCards(){
        Random rand = new Random();
        int j;
        for(int i=0; i<size; i++){
            j = rand.nextInt(52);
            Card temp = deckOfCards[i];
            deckOfCards[i]=deckOfCards[j];
            deckOfCards[j]= temp;
        }
    }
    public void showCards(){
        System.out.println("---------------------------------------------");
        int count =0;
        for (Card card : deckOfCards){
            System.out.print(card.rank + " of " + card.suit + "     ");
            count++;
            if(count%4==0)
                System.out.println("");
        }
        System.out.println("---------------------------------------------");
    }
    public void dealCards(Players player1,Players player2,Players player3,Players player4){

        int count = 0;

        for (Card card : deckOfCards){

            if (count>38){
                player1.playCards[count%13] = card;
                //System.out.println(player1.playCards[count/12].rank+"   "+player1.playCards[count/12].suit);
            }
            else if (count>25){
                player2.playCards[count%13] = card;
            }
            else if (count>12){
                player3.playCards[count%13] = card;
            }
            else{
                player4.playCards[count%13] = card;
            } 
            count++;
        }
    }


}
代码语言:javascript
复制
package cardgame;

public class Players {
    String name;
    Card[] playCards = new Card[13];


    public Players(String name){
        this.name = name;
    }
    public void ShowPlayerCards(){
        System.out.println("---------------------------------------------");
        for (Card card : playCards){
            if(card!=null)
                System.out.println(card.rank + "  of  " + card.suit);
        }
        System.out.println("---------------------------------------------");
    }
    public String getName(){
        return name;
    }

}
代码语言:javascript
复制
package cardgame;

import java.util.*;


public class CardGame {

    public static void main(String[] args) {
        DeckOfCards deck = new DeckOfCards();
        System.out.println("UnShuffeled Cards.");
        deck.showCards();
        deck.ShuffleCards();
        System.out.println("Shuffeled Cards.");
        deck.showCards();

        Scanner input = new Scanner(System.in);
        System.out.println("Player One...\nEnter Name:");
        Players player1 = new Players(input.nextLine());
        System.out.println("Player Two...\nEnter Name:");
        Players player2 = new Players(input.nextLine());
        System.out.println("Player Three...\nEnter Name:");
        Players player3 = new Players(input.nextLine());
        System.out.println("Player Four...\nEnter Name:");
        Players player4 = new Players(input.nextLine());

        deck.dealCards(player1, player2, player3, player4);
        System.out.println("---------------------------------------------");
        System.out.println(player1.getName());
        player1.ShowPlayerCards();
        System.out.println(player2.getName());
        player2.ShowPlayerCards();
        System.out.println(player3.getName());
        player3.ShowPlayerCards();
        System.out.println(player4.getName());
        player4.ShowPlayerCards();
    }

}
EN

回答 4

Code Review用户

回答已采纳

发布于 2018-11-28 22:06:06

好的..。我不知道如何以一种有意义的方式向您展示我所做的所有重构,所以我将发布重构类并从那里开始。

Main:

代码语言:javascript
复制
public static void main(String[] args) {

    Scanner input = new Scanner(System.in);
    Players[] players = new Players[4];
    Card[] deck = Dealer.getDeckOfCards();

    System.out.println("Un-shuffled Cards.");
    Dealer.showCards(deck);
    Card[] shuffledCards = Dealer.shuffleCards(deck);
    System.out.println("Shuffled Cards.");
    Dealer.showCards(shuffledCards);

    for(int i = 0; i < players.length; i++) {
        System.out.println("Enter Player Name: ");
        players[i] = new Players(input.nextLine());
    }

    Players[] playersWithCards = Dealer.dealCards(players, shuffledCards);

    System.out.println("---------------------------------------------");

    for(Players player : playersWithCards) {
        System.out.println(player.getName());
        player.showPlayerCards();
    }

}

播放器:

代码语言:javascript
复制
class Players {

    private String name;
    private Card[] cards = new Card[13];

    Players(String name){
        this.name = name;
    }
    void showPlayerCards(){
        System.out.println("---------------------------------------------");
        for (Card card : cards){
            //you had been checking here if this was null, but there was no need for that check
            System.out.printf("%s  of %s\n", card.rank, card.suit);
        }
        System.out.println("---------------------------------------------");
    }
    void receiveCard(Card card, int position){
        cards[position] = card;
    }
    String getName(){
        return name;
    }

}

Dealer (前DeckOfCards)

代码语言:javascript
复制
class Dealer {
    private static final int SIZE = 52;
    private static Card[] deckOfCards = new Card[SIZE];

    static Card[] getDeckOfCards() {

        int count = 0;

        String[] suits = {"Diamonds", "Clubs", "Hearts", "Spades"};
        String[] ranks = {"King", "Queen", "Jack", "Ten", "Nine", "Eight", "Seven", "Six", "Five", "Four", "Three", "Deuce", "Ace"};

        for (String s : suits) {
            for (String r : ranks) {

                Card card = new Card(s, r);
                deckOfCards[count] = card;
                count++;
            }
        }

        return deckOfCards;

    }

    static Card[] shuffleCards(Card[] deckOfCards) {
        Random rand = new Random();
        int j;
        for (int i = 0; i < SIZE; i++) {
            j = rand.nextInt(SIZE);
            Card temp = deckOfCards[i];
            deckOfCards[i] = deckOfCards[j];
            deckOfCards[j] = temp;
        }
        return deckOfCards;
    }

    static void showCards(Card[] deckOfCards) {
        System.out.println("---------------------------------------------");
        int count = 0;
        for (Card card : deckOfCards) {
            System.out.printf("%s of %s\t", card.rank, card.suit); //use print f with \t (tab character)
            count++;
            if (count % 4 == 0)
                System.out.println();
        }
        System.out.println("---------------------------------------------");
    }

    static Players[] dealCards(Players[] players, Card[] deck) {
        int numOfCardsPerPlayer = deck.length / players.length;
        for (int i = 0; i < deck.length; i++) {
            int positionInHand = i % numOfCardsPerPlayer;
            players[i % players.length].receiveCard(deck[i], positionInHand);
        }

        return players;
    }
}

和Card:

代码语言:javascript
复制
class Card {
    String suit;
    String rank;

    Card(String cardSuit, String cardRank){
        this.suit = cardSuit;
        this.rank = cardRank;
    }
}
  1. 在将Main重构为尽可能使用循环之后,我做的第一件事就是确保您没有不必要地编写代码public。您的所有classes都位于同一个package中,因此可以通过删除public修饰符使它们成为package-private。这通常被认为是一个很好的实践,因此当您开始使用许多类(其中一些类可能具有相同的名称)处理项目时,您将限制冲突。
  2. 您的代码和重构它的方式之间最大的区别可能是我将DeckOfCards更改为Dealer,并使其成为静态的。在编程中,DeckOfCards的抽象实际上只是一组卡片,就像Card[] deck = Dealer.getDeckOfCards();一样。在我看来,您从DeckOfCards调用的大部分任务实际上都是Dealer的工作,因此我更改了代码以反映这一点,并在程序进行过程中传递在驱动程序类中创建的值。(例如,在行Card[] shuffledCards = Dealer.shuffleCards(deck);中)如果您查看这个类,您将看到它的所有方法都是静态的,这实际上只是一个首选项。如果您想为经销商创建一个像Dealer dealer = new Dealer();这样的构造函数,并且更多地将它看作一个实体而不是一个实干家,那么您可以。

我肯定我漏掉了一些东西所以如果你有什么问题告诉我。总之,我认为你为一个新开发人员做了很好的工作。

票数 6
EN

Code Review用户

发布于 2018-11-29 02:24:11

我有以下建议:

  1. 做西装和排名,因为他们是固定的,不会被改变。
  2. 让所有实例变量都是私有的,并拥有getter和setter方法来访问它们,这通常是一种很好的做法。
  3. 使大小最终静态,因为它是一个常量值,不会被更改。

以下是完整的代码:

套装enum

代码语言:javascript
复制
package cardGame;

enum Suit {
    DIAMONDS,
    CLUBS,
    SPADES,
    HEARTS;
}

秩enum

代码语言:javascript
复制
package cardGame;

enum Rank {
    ACE,
    DEUCE,
    THREE,
    FOUR,
    FIVE,
    SIX,
    SEVEN,
    EIGHT,
    NINE,
    TEN,
    JACK,
    QUEEN,
    KING;
}

卡类

代码语言:javascript
复制
package cardGame;

class Card {
    private final Suit suit;
    private final Rank rank;

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

    Rank getRank() {
        return rank;
    }

    Suit getSuit() {
        return suit;
    }

    @Override
    public String toString() {
        return rank + " of " + suit;
    }
}

DeckOfCards类

代码语言:javascript
复制
package cardGame;

import java.util.Random;

class DeckOfCards {
    public static final int SIZE = 52;
    private final Card[] cards = new Card[SIZE];

    DeckOfCards() {
        int currentCardIndex = 0;

        for (Suit suit : Suit.values()) {
            for (Rank rank : Rank.values()) {
                cards[currentCardIndex++] = new Card(suit, rank);
            }
        }
    }

    Card[] getCards() {
        return cards;
    }

    Card getCard(int index) {
        return cards[index];
    }

    void shuffleDeck() {
        Random rand = new Random();

        for (int i = 0; i < SIZE; i++) {
            int j = rand.nextInt(SIZE);
            swapCards(i, j);
        }
    }

    void swapCards(int i, int j) {
        Card temp = cards[i];
        cards[i] = cards[j];
        cards[j] = temp;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append("Current Deck:\n");

        for (int i = 0; i < DeckOfCards.SIZE; i++) {
            stringBuilder.append("Card #" + (i + 1) + ": " + getCard(i) + "\n");
        }

        return stringBuilder.toString();
    }
}

播放器类

代码语言:javascript
复制
package cardGame;

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

class Player {
    private String name;
    private List<Card> cards = new ArrayList<>();

    Player(String name) {
        this.name = name;
    }

    void giveCard(Card card) {
        cards.add(card);
    }

    List<Card> getCards() {
        return cards;
    }

    String printPlayerCards() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(name + " has the following cards:\n");

        for (Card card : cards) {
            stringBuilder.append(card + "\n");
        }

        return stringBuilder.toString();
    }

    @Override
    public String toString() {
        return name;
    }
}

CardGame类

代码语言:javascript
复制
package cardGame;

import java.util.Scanner;

public class CardGame {
    private static final int NO_OF_PLAYERS = 4;
    private final Player[] players = new Player[NO_OF_PLAYERS];
    private final DeckOfCards deckOfCards = new DeckOfCards();

    public static void main(String[] args) {
        CardGame cardGame = new CardGame();

        System.out.println("WELCOME TO THE CARD GAME\n");
        System.out.println("Enter the four players' name below");

        Scanner scan = new Scanner(System.in);
        for (int i = 0; i < NO_OF_PLAYERS; i++) {
            cardGame.players[i] = new Player(scan.next());
        }

        cardGame.deckOfCards.shuffleDeck();

        System.out.println(cardGame.deckOfCards);

        cardGame.dealCards();

        cardGame.displayCardsForAllPlayers();
    }


    private void dealCards() {
        for (int i = 0; i < DeckOfCards.SIZE; i++) {
            players[i % NO_OF_PLAYERS].giveCard(deckOfCards.getCard(i));
        }
    }

    private void displayCardsForAllPlayers() {
        for (int i = 0; i < NO_OF_PLAYERS; i++) {
            System.out.println(players[i].printPlayerCards());
        }
    }
}
票数 6
EN

Code Review用户

发布于 2018-11-29 13:24:48

欢迎收看代码评审!

其他人所说的增编:

命名

单数&复数名词

玩家是Player而不是Players,当你谈论一件事时,你应该用单数的名字,当你谈论很多事情时,你应该用复数。ie:

代码语言:javascript
复制
Player[] players = new Player[4];

避免冗余

尽量避免命名过程中的冗余,所以不要有:

代码语言:javascript
复制
DeckOfCards.shuffleDeck()

你可以写:

代码语言:javascript
复制
DeckOfCards.shuffle()

让他们保持简单的

如果您简单地将类命名为Deck,那么读者在这里考虑装载甲板的可能性就不大。在这种情况下,很明显这是一张牌牌。

MISC

如果可能的话,

是通用的,

尽量通用,避免神奇的值。如果您的甲板的大小,如果所有可能的组合之和,所以,例如,再次使用枚举的建议在另一个答案:

代码语言:javascript
复制
private static final int SIZE = Suit.values().length * Rank.values().length;

就像这样,如果你后来决定改变甲板的类型,例如删除aces或数字,更改将自动反映在您的代码的其余部分。而且你知道..。减少重构代码使开发人员更快乐。

考虑底层类型

您可以只存储卡片的索引,只需一个简单的int。卡片可以用相对于其在新甲板中的位置的索引来表示。范围0-51。

从索引中检索西服和等级,取决于牌在甲板上的订购方式。

如果按秩排序(A♡,A♢,A♠,A♣,2♡,2♢,.,K♡,K♢,K♠,K♣):

代码语言:javascript
复制
Rank r = Rank.values()[i / 4];
Suit s = Suit.values()[i % 4];

(A♡,2♡,3♡,.,J♣,Q♣,K♣):

代码语言:javascript
复制
Rank r = Rank.values()[i % 13];
Suit s = Suit.values()[i / 13];

(要想更快/更好地将int转换为enum,请检查这是如此的帖子)

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/208644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档