[Java]文字版傷心小棧
程式碼
Card.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
package pokerGames; import java.util.*; /** * @author 幻冽(Magic Lea) */ public class Card { //花色:梅花0,方塊1,愛心2,黑桃3 private CardPattern patternForCard; private int numberForCard; public final int offset;//最大的牌是2,那麼offset=2(依此類推) public Card() { this(CardPattern.CLUB, 3, 1);//預設給梅花二,offset=1 } public Card(int code, int offset) {//輸入代碼的建構式 this(CardPattern.codeToPattern((code - offset - 1) / 13), ((code - offset - 1) % 13) + 1 + offset, offset); } public Card(String patternForCard, int numberForCard, int offset) {//輸入牌花色(字串)和數字的建構式 this(CardPattern.valueOf(patternForCard), numberForCard, offset); } public Card(CardPattern patternForCard, int numberForCard, int offset) {//主要的建構式 this.patternForCard = patternForCard; this.numberForCard = numberForCard; this.offset = offset; } public CardPattern getPatternForCard() {//取得牌的花色 return patternForCard; } public void setPatternForCard(CardPattern patternForCard) {//設定牌的花色 this.patternForCard = patternForCard; } public int getNumberForCard() {//取得牌位移後的數字 return this.numberForCard; } public void setNumberForCard(int numberForCard) {//設定牌為位移的數字 this.numberForCard = numberForCard; } public boolean equals(Card card) {//比較兩張牌是否同發色同數字同位移 if (this.offset == card.offset) { if (this.numberForCard == card.getNumberForCard()) { if (this.patternForCard == card.getPatternForCard()) { return true; } } } return false; } public int toCode() {//卡片轉代碼 return this.patternForCard.ordinal() * 13 + this.getNumberForCard(); } public String toString() {//卡片轉成文字 String numberForDisplay; int realNumber = this.numberForCard; if (realNumber > 13) {//把位移過的卡片位移回來 realNumber -= 13; } switch (realNumber) {//用通俗的說法輸出 case 1: numberForDisplay = " A"; break; case 11: numberForDisplay = " J"; break; case 12: numberForDisplay = " Q"; break; case 13: numberForDisplay = " K"; break; default: numberForDisplay = String.format("%2d", this.numberForCard); } return this.getPatternForCard().getDescription() + numberForDisplay; } } enum CardPattern {//牌的花色 CLUB, DIAMOND, HEART, SPADE, NULL; public String getDescription() {//獲得牌組的中文 switch (this.ordinal()) { //梅花0,方塊1,愛心2,黑桃3 case 0: return "梅花"; case 1: return "方塊"; case 2: return "愛心"; case 3: return "黑桃"; default: return null; } } public static CardPattern codeToPattern(int code) {//代號轉花色 switch (code) { case 0: return Enum.valueOf(CardPattern.class, "CLUB"); case 1: return Enum.valueOf(CardPattern.class, "DIAMOND"); case 2: return Enum.valueOf(CardPattern.class, "HEART"); case 3: return Enum.valueOf(CardPattern.class, "SPADE"); default: return Enum.valueOf(CardPattern.class, "NULL"); } } } class CardComparator implements Comparator { //給TreeSet用的排序 @Override public int compare(T c1, T c2) { return c1.toCode() - c2.toCode(); } } |
Hearts.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
package pokerGames; /** * @author 幻冽(Magic Lea) */ public class Hearts { static int offset = 1;//此遊戲用到的位移 private int game;//局 private HeartsPlayer playerOne;//第一位玩家 private boolean heartBreak;//紅心破碎 private int patternOfRound;//這回合的花色 private HeartsPlayer firstPlayerOfRound;//這回合先出牌的玩家 private int round;//回合 private Card[] cardsOfRound;//這回合已經出的牌 public Hearts() { game = 0; playerOne = new HumanHeartPlayer(new ComAHeartsPlayer("王老虎", new ComAHeartsPlayer("謝老闆", new ComAHeartsPlayer("派大猩")))); heartBreak = false; patternOfRound = CardPattern.NULL.ordinal(); firstPlayerOfRound = null; round = 0; Player.circularize(playerOne); } public Card[] getCardsOfRound() { return cardsOfRound; } private HeartsPlayer startByWho(Card card) {//有梅花2的先開始 HeartsPlayer tempPlayer = playerOne; do { if (tempPlayer.haveThisCard(card)) { return tempPlayer; } tempPlayer = tempPlayer.getNextPlayer(); } while (tempPlayer != playerOne); System.err.println("看到鬼!大家都沒有這張牌!"); return null; } private void transferCard(HeartsPlayer playerOne) {//傳牌 //右傳,左傳,對傳,不傳 System.out.println("開始傳牌"); if (this.game % 4 == 0) {//4的倍數不傳牌 System.out.println("這次不傳牌"); return; } Card transferedCard[][] = new Card[4][3];//暫存大家要傳的牌 for (int counter = 0; counter < 4; counter++) {//各個詢問傳什麼牌 transferedCard[counter] = playerOne.transferWhatCard(); playerOne = playerOne.getNextPlayer(); } HeartsPlayer tempPlayer = playerOne; int counter = 0; do { HeartsPlayer transferedPlayer = null; switch (this.game % 4) {//設定傳牌對象 case 1: transferedPlayer = tempPlayer.getNextPlayer();//右傳 break; case 2: transferedPlayer = tempPlayer.getLastPlayer();//左傳 break; case 3: transferedPlayer = tempPlayer.getNextPlayer().getNextPlayer();//對傳 break; case 0: System.err.println("不該進入這裡"); return; } for (Card card : transferedCard[counter]) {//開始傳牌 try { tempPlayer.removeCard(card); transferedPlayer.addCard(card); } catch (NullPointerException e) { System.err.println("怎麼會沒有牌呢?"); } } tempPlayer = tempPlayer.getNextPlayer(); ++counter; } while (tempPlayer != playerOne); } private HeartsPlayer whoWinTheRound() {//判斷此回合誰吃牌 //輸出這回合出的卡片 System.out.print("這回合出的牌:"); for (Card card : getCardsOfRound()) { System.out.print("[" + card + "] "); } //開始判斷 HeartsPlayer tempPlayer = firstPlayerOfRound.getNextPlayer(); HeartsPlayer winner = firstPlayerOfRound; Card CardForWinner = cardsOfRound[0]; int counter = 1; while (tempPlayer != firstPlayerOfRound) {//一張一張比大小 if (cardsOfRound[counter].getPatternForCard() == CardForWinner.getPatternForCard()) { if (cardsOfRound[counter].getNumberForCard() > CardForWinner.getNumberForCard()) { winner = tempPlayer; CardForWinner = cardsOfRound[counter]; } } tempPlayer = tempPlayer.getNextPlayer(); counter++; } for (Card card : cardsOfRound) {//吃到點牌便計分 if (card.toCode() >= 28) { if (card.toCode() <= 40) {//愛心1~13 tempPlayer.addScoreCard(card); tempPlayer.addScoreCard(card); tempPlayer.addScoreForPlayer(1); } if (card.toCode() == 51) {//黑桃Q tempPlayer.addScoreCard(card); tempPlayer.addScoreCard(card); tempPlayer.addScoreForPlayer(13); } } } System.out.println("," + winner + "得牌"); return winner; } private HeartsPlayer discard() {//開始出牌 HeartsPlayer tempPlayer = firstPlayerOfRound; cardsOfRound = new Card[4]; int counter = 0; do { while (!isLegally(tempPlayer, cardsOfRound[counter])) { cardsOfRound[counter] = tempPlayer.discardWhatCard(getCardsOfRound()); if (!isLegally(tempPlayer, cardsOfRound[counter])) { cardsOfRound[counter] = null; } } tempPlayer.removeCard(cardsOfRound[counter]);//出牌後移除牌 tempPlayer = tempPlayer.getNextPlayer(); counter++; } while (tempPlayer != firstPlayerOfRound); return whoWinTheRound(); } private void finalThisGame(HeartsPlayer playerOne) {//結束這場傷心小棧 int[] scores = new int[4]; int counter = 0; HeartsPlayer tempPlayer = playerOne; HeartsPlayer[] players = playerOne.toArray(); do { scores[counter] = tempPlayer.getScoreForPlayer(); tempPlayer = tempPlayer.getNextPlayer(); counter++; } while (tempPlayer != playerOne); for (int i = 0; i < 3; i++) {//氣泡排序名次 for (int j = i + 1; j < 4; j++) { if (scores[i] > scores[j]) { int tempScore = scores[i]; tempPlayer = players[i]; scores[i] = scores[j]; players[i] = players[j]; scores[j] = tempScore; players[j] = tempPlayer; } } } for (int n = 0; n < 4; n++) {//輸出名次 System.out.println("第" + (n + 1) + "名:分數 " + scores[n] + " 的玩家 " + players[n]); } } private void setPatternOfRound(CardPattern pattern) { this.patternOfRound = pattern.ordinal(); } private void setFirstPlayerOfRound(HeartsPlayer firstPlayer) { this.firstPlayerOfRound = firstPlayer; } private boolean isLegally(HeartsPlayer player, Card card) {//判斷出牌的合法性 if (card == null) { return false; } else if (player == firstPlayerOfRound) { if (round == 1) { if (card.equals(new Card("CLUB", 2, Hearts.offset))) { } else { if (player.errorHint) { System.err.println("你必須出梅花2"); } return false; } } if (card.getPatternForCard() == CardPattern.HEART) { if (this.heartBreak == true) { } else { if (player.errorHint) { System.err.println("尚未心碎,不得出愛心"); } return false; } } setPatternOfRound(card.getPatternForCard()); return true; } else { if (player.haveThisPattern(CardPattern.codeToPattern(patternOfRound))) { if (CardPattern.codeToPattern(patternOfRound) == card.getPatternForCard()) { return true; } else { if (player.errorHint) { System.err.println("你必須跟牌,請出一張 " + CardPattern.codeToPattern(patternOfRound).getDescription()); } return false; } } else { if (card.getPatternForCard() == CardPattern.HEART) { heartBreak = true; } return true; } } } private void nextGame() {//換下一局 firstPlayerOfRound = null; game++; heartBreak = false; patternOfRound = CardPattern.NULL.ordinal(); HeartsPlayer tempPlayer = playerOne; //清除上一回合的吃到的牌 do { tempPlayer.clearScoreCard(); tempPlayer = tempPlayer.getNextPlayer(); } while (tempPlayer != playerOne); //建立牌 int[] codeForCards = new int[52]; for (int number = 0; number < 52; number++) { codeForCards[number] = number + Hearts.offset + 1; } //洗牌5000次 for (int times = 1; times <= 5000; times++) { int rand1 = (int) (Math.random() * 100000) % 52; int rand2 = (int) (Math.random() * 100000) % 52; int temp = codeForCards[rand1]; codeForCards[rand1] = codeForCards[rand2]; codeForCards[rand2] = temp; } //發牌 tempPlayer = playerOne; for (int element = 0; element < 52; element++) { int codeForCard = codeForCards[element]; tempPlayer.addCard(new Card(codeForCard, Hearts.offset)); tempPlayer = tempPlayer.getNextPlayer(); } } public void newMoon() {//豬羊變色 for (HeartsPlayer player : playerOne.toArray()) { if (player.getScoreCards().size() == 14) { System.out.println("豬~羊~變~色~"); player.addScoreForPlayer(-26); HeartsPlayer tempPlayer = player.getNextPlayer(); while (tempPlayer != player) { tempPlayer.addScoreForPlayer(26); tempPlayer = tempPlayer.getNextPlayer(); } } } } public void play() { while (true) { HeartsPlayer tempPlayer = null; nextGame(); //換牌 transferCard(playerOne); //由誰開始 setFirstPlayerOfRound(startByWho(new Card("CLUB", 2, Hearts.offset))); //出牌 for (round = 1; round <= 13; round++) { setFirstPlayerOfRound(discard()); } //豬羊變色 newMoon(); //展示分數 tempPlayer = playerOne; int counter = 0; int[] scores = new int[4]; do { tempPlayer.showAllScoreCard(); scores[counter] = tempPlayer.getScoreForPlayer(); System.out.println("目前分數是:" + scores[counter]); System.out.println("--------------------------------------------------"); tempPlayer = tempPlayer.getNextPlayer(); counter++; } while (tempPlayer != playerOne); //判斷結局 for (int score : scores) { if (score >= 100) { finalThisGame(playerOne); return; } } } } } |