洗牌程式
程式主要包含三個部分:
- 通用牌類 Card,沒有特殊花色的牌,像撲克裡的“跑得快”可直接使用;
- 撲克 Poker,繼承自 Card,加入大小王兩張牌,像“鬥地主”可使用;
- 麻将 Mahjong,繼承自 Card,加入特殊花色的牌,如東風、北風、紅中、白闆等。
以下為代碼:
package org.iword.card;
/**
* @檔案名: org.iword.Main.java
* @作者 : iword
* @日期 : 2014年6月25日 上午2:17:56
* @版本 : 1.0
* @描術 :
*
* ALL RIGHTS RESERVED,COPYRIGHT(C) FCH LIMITED 2014
*/
public class Main {
public static void main(String[] args)
{
String[] num = { "A ", "2 ", "3 ", "4 ", "5 ", "6 ", "7 ", "8 ", "9 ",
"10", "J ", "Q ", "K " };
String[] suits = { "紅桃", "黑桃", "方塊", "梅花" };
String[] otherCards = { "大王 ", "小王 " };
Poker poker = new Poker(suits, num, otherCards);
String[] numMj = { "一", "二", "三", "四", "五", "六", "七", "八", "九" };
String[] suitsMj = { "條", "餅", "萬" };
String[] otherCardsMj = { "東風", "西風", "南風", "北風", "發财", "紅中", "白闆" };
Mahjong mahjong = new Mahjong(suitsMj, numMj, otherCardsMj);
// 顯示洗好的撲克牌
shuffle(poker);
// 顯示洗好的麻将牌
shuffle(mahjong);
}
// 洗牌
private static void shuffle(Card card)
{
card.start();
}
}
// 通用牌類
package org.iword.card;
import java.util.Random;
/**
* @檔案名: org.iword.Card.java
* @作者 : iword
* @日期 : 2014年6月25日 上午1:16:23
* @版本 : 1.0
* @描術 : 定義一般的牌,如撲克裡的“跑得快”,不包含特殊的花色牌,如撲克裡的“鬥地主”所需要的大小王。
*
* ALL RIGHTS RESERVED,COPYRIGHT(C) FCH LIMITED 2014
*/
public class Card {
private String[] suits; // 牌的花色,如黑桃、紅桃等
private String[] num; // 牌的編号,如A, 2, 3等
protected String[] cards; // 将牌的花色和牌的編号組合存儲形成一副牌
protected int length; // 牌的張數,cards 的長度
// 構造函數
public Card(String[] suits, String[] num)
{
this.suits = suits;
this.num = num;
this.length = suits.length * num.length;
}
// 初始化牌,如果繼承此類,應視情況覆寫此方法
protected void initialize()
{
this.cards = new String[this.length];
int index = 0;
for (int i = 0; i < num.length; i++) {
for (int j = 0; j < suits.length; j++) {
// 将花色和編号組合成一張牌進行存儲
cards[index++] = suits[j] + num[i];
}
}
}
// 交換 arr[i] 與 arr[j] 的值
private void swap(String[] arr, int i, int j)
{
String temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 洗牌
private void shuffle()
{
Random random = new Random(); // 生成生機數
for (int i = 0; i < this.length; i++) {
swap(this.cards, i, random.nextInt(this.length));
}
}
// 顯示牌
private void show()
{
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < this.length; i++) {
if (0 == i % 10) {
stringBuilder.append("\n");
}
stringBuilder.append(this.cards[i]).append(" ");
}
System.out.println(stringBuilder.toString());
}
// 供調用的入口
public void start()
{
initialize();
shuffle();
show();
}
}
// 撲克
package org.iword.card;
/**
* @檔案名: org.iword.Poker.java
* @作者 : iword
* @日期 : 2014年6月25日 上午2:26:28
* @版本 : 1.0
* @描術 : 繼承 Card 類定義包含大小王的撲克牌
*
* ALL RIGHTS RESERVED,COPYRIGHT(C) FCH LIMITED 2014
*/
public class Poker extends Card {
private String[] otherCards; // 撲克中的特殊花色牌,大王和小王
public Poker(String[] suits, String[] num, String[] otherCards)
{
super(suits, num);
this.otherCards = otherCards;
this.length += otherCards.length; // 加上特殊花色牌的數量
}
// 初始化
@Override
protected void initialize()
{
super.initialize();
int index = 0;
while (null != this.cards[index]) {
index++;
}
// 加入特殊花色的牌
for (int i = 0; i < this.otherCards.length; i++) {
this.cards[index++] = this.otherCards[i];
}
}
}
// 麻将
package org.iword.card;
/**
* @檔案名: org.iword.Mahjong.java
* @作者 : iword
* @日期 : 2014年6月25日 上午2:47:11
* @版本 : 1.0
* @描術 : 繼承 Card 類定義麻将牌
*
* ALL RIGHTS RESERVED,COPYRIGHT(C) FCH LIMITED 2014
*/
public class Mahjong extends Card {
private String[] otherCards; // 特殊花色牌,如東風、白闆等
private static final int NUM_PER_CARD = 4; // 麻将每種牌有4張
public Mahjong(String[] suits, String[] num, String[] otherCards)
{
super(suits, num);
this.otherCards = otherCards;
// 每一張牌有 4 個,加上特殊牌的數量之後,總數量要乘以 4
this.length = (this.length + otherCards.length) * NUM_PER_CARD;
}
// 初始化麻将牌
@Override
protected void initialize()
{
super.initialize();
int index = 0;
while (null != this.cards[index]) {
index++;
}
// 加入特殊花色的牌
for (int i = 0; i < this.otherCards.length; i++) {
this.cards[index++] = this.otherCards[i];
}
int length = index;
for (int i = 1; i < NUM_PER_CARD; i++) {
System.arraycopy(this.cards, 0, this.cards, i * index, length);
}
}
}
以前看書記得有這麼有一道洗牌的題,今天有空再寫一遍,發在這裡。