OOD - blackjack design
2016-03-20 23:38
447 查看
How
is my BlackJack game design?
up vote7down votefavorite | This is a command line BlackJack game created in Java as my final project for an advanced programming class. What do you think about it? Have I used OOP correctly? What grade should I get for this? :D Any concept in game that could be improved? I used JRE 1.7. And to make Unicode characters work you must use Unicode in Eclipse. This is my Class Diagram: ![]() BlackJack.java import java.io.*; public class BlackJack { private static int BLACKJACK = 21; private static int DECKSIZE = 52; private static boolean isPlayerDone; public static void main(String[] args) throws IOException { Deck deck = null; Hand playersHand = null; Hand splitHand = null; Hand dealersHand = null; System.out.println("--------------------------------------------------------"); System.out.println("- BLACK JACK -"); System.out.println("--------------------------------------------------------\n"); boolean runGame = true; while(runGame) switch(options()) { case "deal": dealersHand = new Hand("Dealer"); playersHand = new Hand("Player"); splitHand = null; isPlayerDone = false; deck = initialDraw(deck, playersHand, splitHand, dealersHand); if (playersHand.getHandTotal() == BLACKJACK) { System.out.print("Player has BLACKJACK!\n\n"); isPlayerDone = true; System.out.print("Dealer uncovers card...\n\n"); showHands(playersHand, splitHand, dealersHand); System.out.print("Dealer's move...\n\n"); deck = dealerDraw(deck, playersHand, splitHand, dealersHand); showHands(playersHand, splitHand, dealersHand); compareHands(playersHand, splitHand, dealersHand); } // end if() break; // end case "deal" case "hit": if(!isPlayerDone) deck = hit(deck, playersHand, splitHand, dealersHand); else System.out.print("You must deal cards first!\n\n"); break; // end case "hit" case "stand": if(!isPlayerDone) { isPlayerDone = true; deck = stand(deck, playersHand, splitHand, dealersHand); } // end if() else System.out.print("You must deal cards first!\n\n"); break; // end case "stand" case "split": if(!isPlayerDone) splitHand = split(playersHand, splitHand, dealersHand); else System.out.print("You must deal cards first!\n\n"); break; // end case "split" case "exit": runGame = false; System.out.print("Game ended.\n\n"); break; // end case "exit" default: System.out.print("Invalid entry\n\n"); } // end switch() } // end main() private static Hand split(Hand player, Hand split, Hand dealer) { if(player == null) System.out.print("You must deal cards first!\n\n"); else if(player.getHandSize() == 2 && player.bothEqual()) { split = new Hand("Player"); split.insert(player.deleteFirst()); showHands(player, split, dealer); compareHands(player, split, dealer); } // end else if() else if(!player.bothEqual()) System.out.print("Both card values must be the same!\n\n"); else System.out.print("You must have no more than 2 cards to split!\n\n"); return split; } // end split() private static Deck stand(Deck deck, Hand player, Hand split, Hand dealer) { if(player == null) System.out.print("You must deal cards first!\n\n"); else { isPlayerDone = true; System.out.print("Dealer uncovers card...\n\n"); showHands(player, split, dealer); System.out.print("Dealer's move...\n\n"); deck = dealerDraw(deck, player, split, dealer); showHands(player, split, dealer); compareHands(player, split, dealer); } // end else return deck; } // end stay() private static Deck hit(Deck deck, Hand player, Hand split, Hand dealer) { if(player == null) System.out.print("You must deal cards first!\n\n"); else { deck = drawFromDeck(deck, player); System.out.print("\n"); if(split != null) { deck = drawFromDeck(deck, split); System.out.print("\n"); } // end if() showHands(player, split, dealer); compareHands(player, split, dealer); if (player.getHandTotal() == BLACKJACK) { System.out.print("Player has BLACKJACK!\n\n"); isPlayerDone = true; System.out.print("Dealer uncovers card...\n\n"); showHands(player, split, dealer); System.out.print("Dealer's move...\n\n"); deck = dealerDraw(deck, player, split, dealer); showHands(player, split, dealer); compareHands(player, split, dealer); } // end if() else if(player.getHandTotal() > BLACKJACK) { System.out.print("Player Busted!\n\n"); isPlayerDone = true; System.out.print("Dealer uncovers card...\n\n"); showHands(player, split, dealer); compareHands(player, split, dealer); } } // end else return deck; } // end hit() private static Deck dealerDraw(Deck deck, Hand player, Hand split, Hand dealer) { if(player.getHandTotal() <= BLACKJACK) { // Dealer takes a precaution and only draws // if hand total is less than or equal to 16. while(dealer.getHandTotal() <= 16 && (dealer.getHandTotal() <= player.getHandTotal() || (split != null && dealer.getHandTotal() <= split.getHandTotal()))) deck = drawFromDeck(deck, dealer); // Player has reached BLACKJACK! // There's no or little chance to win, // dealer risks and draws even if total is high. if (player.getHandTotal() == BLACKJACK || (split != null && split.getHandTotal() == BLACKJACK)) while(dealer.getHandTotal() < BLACKJACK) deck = drawFromDeck(deck, dealer); } // end if() return deck; } // dealerDraw() private static Deck drawFromDeck(Deck deck, Hand hand) { deck = checkDeck(deck); Card temp = new Card(deck.pop()); if (hand.getName().equals("Dealer") && !isPlayerDone) { if(hand.getHandSize() < 1) System.out.print("Drawing Dealer's card... X_X"); else System.out.print("Drawing Dealer's card... " + temp.toString()); } // end if() else { if(hand.getName().equals("Dealer")) System.out.print("Drawing Dealer's card... " + temp.toString() + "\n"); else System.out.print("Drawing Player's card... " + temp.toString()); } // end else System.out.print("\n"); hand.insert(temp); return deck; } // end drawFromDeck() private static void compareHands(Hand player, Hand split, Hand dealer) { if (isPlayerDone) { if(player.getHandTotal() > BLACKJACK || (split != null && split.getHandTotal() > BLACKJACK)) { System.out.print("Player Busted!\n"); if(dealer.getHandTotal() <= BLACKJACK) System.out.print("Dealer Wins!\n\n"); } // end if() else if(dealer.getHandTotal() > BLACKJACK) { System.out.print("Dealer Busted!\n"); if(player.getHandTotal() <= BLACKJACK || (split != null && split.getHandTotal() <= BLACKJACK)) System.out.print("Player Wins!\n\n"); } // end else if() else if(dealer.getHandTotal() > BLACKJACK && (player.getHandTotal() > BLACKJACK || (split != null && split.getHandTotal() > BLACKJACK))) { System.out.print("Both Busted!\n"); } // end else if() else { if((player.getHandTotal() > dealer.getHandTotal() && player.getHandTotal() <= BLACKJACK) || (split != null && (split.getHandTotal() > dealer.getHandTotal() && player.getHandTotal() <= BLACKJACK))) System.out.print("Player Wins!\n\n"); else if((player.getHandTotal() < dealer.getHandTotal() && dealer.getHandTotal() <= BLACKJACK) || (split != null && (split.getHandTotal() < dealer.getHandTotal() && dealer.getHandTotal() <= BLACKJACK))) System.out.print("Dealer Wins!\n\n"); if(player.getHandTotal() == BLACKJACK || (split != null && split.getHandTotal() == BLACKJACK)) System.out.print("Player has BLACKJACK!\n\n"); if(dealer.getHandTotal() == BLACKJACK) System.out.print("Dealer has BLACKJACK!\n\n"); } // end else } // end if() } // end compareHands() private static Deck checkDeck(Deck deck) { if(deck == null) deck = createDeck(); else if(deck.isEmpty()) { System.out.print("\nDeck is empty! You must create and shuffle new deck of cards!\n\n"); deck = createDeck(); } // end else if() return deck; } // end checkDeck() private static Deck createDeck() { System.out.println("Creating deck..."); Deck deck = new Deck(DECKSIZE); deck.createDeck(); System.out.println("Shuffling deck..."); deck.shuffleDeck(); System.out.print("\n"); return deck; } // end createDeck() private static Deck initialDraw(Deck deck, Hand player, Hand split, Hand dealer) { deck = drawFromDeck(deck, player); deck = drawFromDeck(deck, dealer); deck = drawFromDeck(deck, player); deck = drawFromDeck(deck, dealer); System.out.print("\n"); showHands(player, split, dealer); compareHands(player, split, dealer); return deck; } // end initialDraw() private static void showHands(Hand player, Hand split, Hand dealer) { System.out.print("Dealers Hand:"); if(!isPlayerDone) { dealer.peek(); System.out.print(" X_X = " + dealer.peekValue() + "\n"); } // end if() else { dealer.displayHand(); System.out.print(" = " + (dealer.getHandTotal() == BLACKJACK ? dealer.getHandTotal() + " : BLACKJACK!" : ((dealer.getHandTotal() > BLACKJACK) ? dealer.getHandTotal() + " : BUSTED!" : dealer.getHandTotal())) + "\n"); } // end else System.out.print("Players Hand:"); player.displayHand(); System.out.print(" = " + (player.getHandTotal() == BLACKJACK ? player.getHandTotal() + " : BLACKJACK!" : ((player.getHandTotal() > BLACKJACK) ? player.getHandTotal() + " : BUSTED!" : player.getHandTotal())) + "\n"); if (split != null) { System.out.print("Players Hand:"); split.displayHand(); System.out.print(" = " + (split.getHandTotal() == BLACKJACK ? split.getHandTotal() + " : BLACKJACK!" : ((split.getHandTotal() > BLACKJACK) ? split.getHandTotal() + " : BUSTED!" : split.getHandTotal())) + "\n\n"); } // end if() else System.out.print("\n"); } // end showHands() private static String options() throws IOException { System.out.print("deal, hit, split, stand, exit: "); InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = br.readLine(); System.out.print("\n"); return s; } // end options() } // end BlackJack Hand.java class Hand { private Card first; private int cardTotal; private String name; private int handSize; public Hand(String name) { first = null; this.name = name; cardTotal = 0; handSize = 0; } // end Hand() public void insert(Card card) { Card newLink = new Card(card); newLink.next = first; if (card.getRank() == 1 && cardTotal + card.getValue() > 21) cardTotal = cardTotal + (card.getValue() - 10); else cardTotal = cardTotal + card.getValue(); handSize = handSize + 1; first = newLink; } // end insert() public Card deleteFirst() { Card temp = first; first = first.next; cardTotal = cardTotal - temp.getValue(); handSize = handSize - 1; return temp; } // end deleteFirst() public void displayHand() { Card current = first; while(current != null) { current.showCard(); current = current.next; } // end while() } // end displayHand() public boolean isEmpty() { return first == null; } // end isEmpty() public boolean bothEqual() { Card temp = first; return temp != null && (temp.getValue() == temp.next.getValue()); } // end bothEqual() public void peek() { first.showCard(); } // end peek() public int peekValue() { return first.getValue(); } // end peekValue() public int getHandSize() { return handSize; } // end getHandSize() public String getName() { return name; } // end getName() public int getHandTotal() { return cardTotal; } // end getHandTotal() } // end Hand Deck.java class Deck { private int maxSize; private Card[] stackArray; private int top; public Deck(int s) { maxSize = s; stackArray = new Card[maxSize]; top = -1; } // end Deck() private void push(Card card) { stackArray[++top] = new Card(card); } // end push() public Card pop() { return stackArray[top--]; } // end pop() public boolean isEmpty() { return top == -1; } // end isEmpty() public void shuffleDeck() { Card swap; for (int i = 0; i < stackArray.length; i++) { int r = i + (int) (Math.random() * (stackArray.length - i)); swap = stackArray[i]; stackArray[i] = stackArray[r]; stackArray[r] = swap; } // end for() } // end shuffleDeck() public void createDeck() { String[] suit = {"\u2663", "\u2666", "\u2665", "\u2660"}; int[] rank = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; for (int i = 0; i < rank.length; i ++) { for (int j = 0; j < suit.length; j++) { push(new Card(suit[j], rank[i])); } // end for() } // end for() } // end createDeck() } // end Deck Card.java class Card { public Card next; private String suit; private int rank; Card(String suit, int rank) { this.suit = suit; this.rank = rank; } // end Card() Card(Card card) { suit = card.suit; rank = card.rank; } // end Card() private String getRankName() { if (rank == 1) return "A"; else if (rank == 11) return "J"; else if (rank == 12) return "Q"; else if (rank == 13) return "K"; else return String.valueOf(rank); } // end getRankName() public int getValue() { if (rank == 1) return 11; else if (rank == 11 || rank == 12 || rank == 13) return 10; return rank; } // end getValue() public String getSuit() { return suit; } // end getSuit() public int getRank() { return rank; } // end getRank() public void showCard() { System.out.print(" " + getRankName() + "_" + suit); } // end showCard() @Override public String toString() { return getRankName() + "_" + suit; } // end toString() } // end Card java oop game playing-cards
| ||||||||||||||||
a comment |
2 Answers
activeoldestvotesup vote8down voteaccepted +50 | A few notes: I don't think you're utilizing OOP to its full potential in your BlackJackclass; all its methods are static and you're passing around too many variables. A cleaner alternative would be to make deck, playersHand, splitHand, and dealersHandclass-level variables, change the methods to be non-static, and then you won't have to pass them all around. So something like this: public class BlackJack { ... private Deck deck; private Hand splitHand; private Hand playersHand; private Hand dealersHand; private boolean isPlayerDone; public static void main(String[] args) throws IOException { BlackJack blackjack = new BlackJack(); blackjack.start(); } public void start() { while(runGame) { switch(options()) { case "deal": deal(); break; case "hit": hit(); break; case "stand": stand(); break; ... } } } public void deal() { playersHand = new Hand("Player"); dealersHand = new Hand("Dealer"); splitHand = null; isPlayerDone = false; ... } ... } The Handclass doesn't really need a namebecause there are only 2 types of hands: dealer and player. So you can just pass in a booleanfor drawFromDeck(): private Deck drawFromDeck(boolean drawForPlayer) { Hand hand = drawForPlayer ? playersHand : dealersHand; ... } You have several different places where you're checking for blackjack, and I can't easily follow the logic. compareHands()checks for blackjack, but there are a couple other places with some checks too. These might be necessary (I don't know the rules of Blackjack that well), but you should try to minimize duplicate logic as much as possible. For example, this block of code is in both main()and hit(): if (player.getHandTotal() == BLACKJACK) { System.out.print("Player has BLACKJACK!\n\n"); isPlayerDone = true; System.out.print("Dealer uncovers card...\n\n"); showHands(player, split, dealer); System.out.print("Dealer's move...\n\n"); deck = dealerDraw(deck, player, split, dealer); showHands(player, split, dealer); compareHands(player, split, dealer); } // end if() I think fixing those (mostly points 1 & 3) would go a long way to making the code easier to read and maintain. I skimmed over your other classes and they seemed fine at a glance, having good separation of concerns.
| ||||||||
a comment |
up vote3down vote | Some remarks: Your main method is HUGE, consider splitting it This code: deck = drawFromDeck(deck, player); deck = drawFromDeck(deck, dealer); deck = drawFromDeck(deck, player); deck = drawFromDeck(deck, dealer); can be reduced to this: for(int i = 0; i < 4; i++) deck = drawFromDeck(deck, dealer); This code: System.out.print(" = " + (player.getHandTotal() == BLACKJACK ? player.getHandTotal() + " : BLACKJACK!" : ((player.getHandTotal() > BLACKJACK) ? player.getHandTotal() + " : BUSTED!" : player.getHandTotal())) + "\n"); is duplicated the lines below, you can create a method that accepts an Handand does its calculations getRankName() in Card.java could be rewritten more cleanly with a switch
| ||||||||||||||||
|
相关文章推荐
- timer invalidate
- CF_2B_TheLeastRoundWay
- linux设备驱动归纳总结
- SDL学习(3)图像运动处理
- Android网络编程之HttpURLConnection
- Partition List
- C++智能指针auto_ptr详解
- OOD - blackjack
- 圣思园张龙-Java SE 第三讲(原生数据类型使用陷阱 Pitfall of Primitive Data Type)
- 浅析 eval 解析json
- OSChina 周一乱弹 ——生活不止眼前的苟且
- RPM管理工具
- yum程序包管理和程序包编译安装
- R语言中的逐步回归函数
- FZU 2218 Simple String Problem(状态压缩DP)
- Ubuntu 安装 chrome 32/64 方法
- python 的常用时间操作,取得当前时间等
- socket编程
- Problem B: 小数计算——结构体
- 【自考】毕设-保定之行