diff options
-rw-r--r-- | Main.java | 39 | ||||
-rw-r--r-- | aux/Card.java | 140 | ||||
-rw-r--r-- | aux/Environ.java | 7 | ||||
-rw-r--r-- | aux/Hand.java | 28 | ||||
-rw-r--r-- | aux/set/CardSet.java | 199 | ||||
-rw-r--r-- | aux/set/Hand.java | 26 | ||||
-rw-r--r-- | aux/set/Set.java | 75 | ||||
-rw-r--r-- | tools/Deck.java | 19 | ||||
-rw-r--r-- | tools/Timer.java | 23 |
9 files changed, 556 insertions, 0 deletions
diff --git a/Main.java b/Main.java new file mode 100644 index 0000000..6319ea6 --- /dev/null +++ b/Main.java @@ -0,0 +1,39 @@ +package mahjong; + +import mahjong.aux.set.CardSet; +import mahjong.aux.set.Set; +import mahjong.tools.Timer; + +public class Main { + + public static void main(String[] args) { + // write your code here +// Set hand = Deck.generateDeck(); +// +// hand.print(); +// +// System.out.println(new Card("wu tiao").getNormalName()); +// System.out.println(new Card("hong wu tiao").getNormalName()); + + String[] names={ + // ":3M",":4M",":6M",":7M",":2S",":4S",":5S",":8S",":9S",":7S",":8P","dong feng","nan feng","bei feng"}; + // ":3M",":4M",":6M",":7M",":2S",":4S",":5S",":8S",":9S",":7S",":8P","dong feng","nan feng"}; + ":4M",":6M",":7M",":2S",":4S",":5S",":5S",":8S",":9S",":7S",":8P","dong feng","nan feng"}; + // ":4M",":6M",":7M",":2S",":4S",":5S",":5S",":5S",":7S",":8S",":9S",":8P","dong feng"};//,"nan feng"}; + // ":1M",":3M",":6M",":8M",":8M",":9M",":1S",":3S",":5S",":1P",":3P",":7P",":9P"}; + // ":2M",":4M",":6M",":8M",":3P",":4P",":5P",":1S",":1S",":2S",":2S",":3S",":1Z"}; + // ":1M",":3M",":3M",":4M",":5M",":6M",":7M",":2S",":2S","dong feng","nan feng","xi feng","bei feng"}; + // ":2M",":3M",":4M",":8M",":3P",":4P",":5P",":1S",":2S",":3S",":2S",":3S",":4S"}; + + Set hand = new Set(names); + hand.print(); + System.out.println("++++++++++++++++++++++++++++++++++++"); + CardSet cardSet = new CardSet(0); + cardSet.add(hand,1); + Timer timer=new Timer(); + timer.tick(); + System.out.println(cardSet.ameliorate().size()); + timer.tock(); + System.out.println(timer.elapse()); + } +} diff --git a/aux/Card.java b/aux/Card.java new file mode 100644 index 0000000..cabd2d9 --- /dev/null +++ b/aux/Card.java @@ -0,0 +1,140 @@ +package mahjong.aux; + +/** + * Created by joe on 12/1/14. + */ +public class Card { + int id = 0; + static final String[] typeName = {"Wan","Tong","Tiao","Feng","Yuan"}; + static final String[] typeSuffix = {"Wan","Tong","Tiao","Feng",""}; + static final String[] shuName = {"Guard","Guard","Yi","Er","San","Si","Wu","Liu","Qi","Ba","Jiu","Guard","Guard"}; + static final String[] fengName = {"Guard","Guard","Dong","Guard","Guard","Nan","Guard","Guard","Xi","Guard","Guard","Bei","Guard","Guard"}; + static final String[] yuanName = {"Guard","Guard","Fa","Guard","Guard","Zhong","Guard","Guard","Bai","Guard","Guard"}; + static final String exName = "Hong"; + static final String errName = "ERROR"; + + static public int parseSuffixNameId(String str) + { + int id; + for (int i=0;i<typeSuffix.length;++i) + if (str.compareToIgnoreCase(typeSuffix[i])==0) + return i; + return 0; + } + static public int parseOrdNameId(String str) + { + int id; + for (int i=0;i<shuName.length;++i) + if (str.compareToIgnoreCase(shuName[i])==0) + return i; + for (int i=0;i<fengName.length;++i) + if (str.compareToIgnoreCase(fengName[i])==0) + return i; + for (int i=0;i<yuanName.length;++i) + if (str.compareToIgnoreCase(yuanName[i])==0) + return i; + return 0; + } + static public int parseExId(String str) + { + if (str.compareToIgnoreCase(exName)==0) + return 1; + return 0; + } + + // Various Constructor + public Card(){} + public Card(int id) + { + this.id=id; + } + public Card(String name) + { + int type = 4; + int ord = 0; + int ex = 0; + if (name.charAt(0)==':') + { + ord = name.charAt(1)-47; + switch (name.charAt(2)) + { + case 'M': + type=0;break; + case 'P': + type=1;break; + case 'S': + type=2;break; + case 'F': + type=3;break; + case 'Z': + type=4;break; + } + if (name.length()>3) + ex=1; + id = (((type<<4)+ord)<<1)+ex; + return; + } + String[] res = name.split("\\s"); + + ex=parseExId(res[0]); + + ord = parseOrdNameId(res[ex]); + if (res.length > ex+1) + type = parseSuffixNameId(res[ex+1]); + id = (((type<<4)+ord)<<1)+ex; + } + + // Some Getters + public int getId() { + return id; + } + public int getStdId() {return id&0xFFFE;} + public int getTypeId() + { + return id>>5; + } + public int getOrdId() + { + return (id>>1)&0xF; + } + public int getExId() + { + return id&1; + } + public String getTypeName() {return typeName[getTypeId()];} + public String getTypeSuffix() {return typeSuffix[getTypeId()];} + public String getOrdName() + { + int type = getTypeId(); + int ord = getOrdId(); + if (isShu()) + return shuName[ord]; + if (isFeng()) + return fengName[ord]; + if (isYuan()) + return yuanName[ord]; + return errName; + } + public String getBaoName() + { + if ( getExId() > 0) + return exName; + return ""; + } + public String getNormalName() + { + return getBaoName().concat(" ") + .concat(getOrdName()).concat(" ") + .concat(getTypeSuffix()) + .trim(); + } + + // Some Testers + public boolean isShu() { return getTypeId()<3; } + public boolean isFeng() { return getTypeId() == 3; } + public boolean isYuan() { return getTypeId() == 4; } + public boolean isLaoTou() { return isShu()&& (getOrdId()&7) == 0; } + public boolean isZi() { return isFeng() || isYuan(); } + public boolean is19() { return isLaoTou() || isZi();} + public boolean isZhongZhang(){ return !is19(); } +}
\ No newline at end of file diff --git a/aux/Environ.java b/aux/Environ.java new file mode 100644 index 0000000..701f220 --- /dev/null +++ b/aux/Environ.java @@ -0,0 +1,7 @@ +package mahjong.aux; + +/** + * Created by joe on 12/1/14. + */ +public class Environ { +} diff --git a/aux/Hand.java b/aux/Hand.java new file mode 100644 index 0000000..ef8da6c --- /dev/null +++ b/aux/Hand.java @@ -0,0 +1,28 @@ +package mahjong.aux; + +/** + * Created by joe on 12/1/14. + */ + +public class Hand { + static final int total = 13; + Card[] cards = new Card[13]; + + // Constructors + Hand(){} + Hand(String[] cardNames) + { + for (int i = 0; i<total;++i) + cards[i] = new Card(cardNames[i]); + } + Hand(Card[] cards) + { + this.cards = cards; + } + + // Some operation + int calTing() + { + return 0; + } +} diff --git a/aux/set/CardSet.java b/aux/set/CardSet.java new file mode 100644 index 0000000..8df6055 --- /dev/null +++ b/aux/set/CardSet.java @@ -0,0 +1,199 @@ +package mahjong.aux.set; + +import mahjong.aux.Card; + +import java.util.Vector; + +/** + * Created by joe on 12/2/14. + */ +public class CardSet { + public static final int cardTypeTotal = 34; + public static final int[] deckIds = new int[] + { + 4, 6, 8, 10, 12, 14, 16, 18, 20, + 36, 38, 40, 42, 44, 46, 48, 50, 52, + 68, 70, 72, 74, 76, 78, 80, 82, 84, + 100,106,112,118, + 132,138,144,146 + }; + private static final int[] id2OrdLut = new int[] + { + 34, 34, 0, 1, 2, 3, 4, 5, 6, 7, 8, 34, 34, 34, 34, 34, + 34, 34, 9, 10, 11, 12, 13, 14, 15, 16, 17,34, 34, 34, 34, 34, + 34, 34, 18, 19, 20, 21, 22, 23, 24, 25, 26,34, 34, 34, 34, 34, + 34, 34, 27,34, 34, 28,34, 34, 29,34, 34, 30,34, 34, 34, 34, + 34, 34, 31,34, 34, 32,34, 34, 33,34, 34, 34, 34, 34, 34, 34, + }; + + protected int[] cardRem = new int[cardTypeTotal+1]; + + public void init(int cnt) + { + for (int i=0;i<cardTypeTotal; ++i) + cardRem[i]=cnt; + } + public CardSet(int cnt) + { + init(cnt); + } + + public void add(Set cards,int mult) + { + for (Object card:cards.getCards()) + add((Card)card,mult); + } + + public void add(Card card,int mult) + { + cardRem[getOrd(card.getStdId())]+=mult; + } + + protected int std2Id(int std) + { + return std>>1; + } + protected int getOrd(int id) + { + return id2OrdLut[std2Id(id)]; + } + + public boolean validify() + { + for (int i:cardRem) + if (i<0||i>4) + return false; + return true; + } + + private int cnt=0; + + public int calTing() + { + //cnt=0; + int res=calTing(0,cardRem[0],0,0,0); + //System.out.println(cnt); + return res; + } + + private int nextCardOrd(int i) + { + return getOrd(deckIds[i]+2); + } + + private int next2CardOrd(int i) + { + return nextCardOrd(nextCardOrd(i)); + } + + private int calTing(int pos,int rems,int shoupai,int ting, int mian) + { + //++cnt; + int res=6; + switch (rems) + { + case 0: + if (pos == cardTypeTotal) + return st2T(shoupai,ting,mian); + else + res = Math.min(res,calTing(pos+1, cardRem[pos+1], shoupai, ting, mian)); + break; + case 1: + case 2: + if (cardRem[nextCardOrd(pos)]>0) { + if (cardRem[next2CardOrd(pos)] > 0) { + if (cardRem[nextCardOrd(pos)] > 3) + res = Math.min(res,calTing(next2CardOrd(pos), cardRem[next2CardOrd(pos)] - 1, shoupai, ting, mian + 2)); + else if (cardRem[nextCardOrd(pos)] > 2) + res = Math.min(res,calTing(next2CardOrd(pos), cardRem[next2CardOrd(pos)] - 1, shoupai + 1, ting, mian + 1)); + else + res = Math.min(res,calTing(next2CardOrd(pos), cardRem[next2CardOrd(pos)] - 1, shoupai, ting, mian + 1)); + } else + res = Math.min(res,calTing(nextCardOrd(pos), cardRem[nextCardOrd(pos)]-1, shoupai, ting + 1, mian)); + } + else + if (cardRem[next2CardOrd(pos)] > 0) + res = Math.min(res,calTing(next2CardOrd(pos), cardRem[next2CardOrd(pos)]-1, shoupai, ting + 1, mian)); + if (rems>1) + res = Math.min(res,calTing(pos, rems-2, shoupai + 1, ting, mian)); + else + res = Math.min(res,calTing(pos, 0, shoupai, ting, mian)); + break; + case 3: + case 4: + res = Math.min(res,calTing(pos, rems-3, shoupai, ting, mian+1)); + break; + } + return res; + } + + private int st2T(int shoupai,int ting, int mian) + { + int res=0; + if (shoupai==0) + res=1; + else + ting+=shoupai-1; + res+=Math.min(4,ting)+Math.max(0,4-ting-mian)*2; + + //System.out.println("S".concat(Integer.toString(shoupai)).concat("T").concat(Integer.toString(ting)).concat("M").concat(Integer.toString(mian))); + //System.out.println(Math.min(6 - shoupai, res)); + return Math.min(6-shoupai,res); + } + + public Vector<Card> jinZhang() + { + Vector<Card> cards = new Vector<Card>(); + int res=0; + int ref=calTing(); + for (int i=0;i<cardTypeTotal;++i) + if (cardRem[i]<3) + { + Card card=new Card(deckIds[i]); + add(card,1); + if (calTing()<ref) { + ++res; + cards.add(card); + } + add(card, -1); + } + return cards; + } + + public Vector<Card> ameliorate() + { + Vector<Card> cards = new Vector<Card>(); + int res=0; + int ref=calTing(); + int jinref=jinZhang().size(); + for (int i=0;i<cardTypeTotal;++i) + if (cardRem[i]<3) + { + Card card=new Card(deckIds[i]); + add(card,1); + if (calTing()==ref) { + if (maxJinZhang(ref)>jinref) { + ++res; + cards.add(card); + //System.out.println(card.getNormalName()); + } + } + add(card, -1); + } + return cards; + } + + public int maxJinZhang(int xt) + { + int res=0; + for (int i=0;i<cardTypeTotal;++i) + if (cardRem[i]>0) + { + --cardRem[i]; + if (calTing()==xt) + res=Math.max(res,jinZhang().size()); + ++cardRem[i]; + } + return res; + } +} diff --git a/aux/set/Hand.java b/aux/set/Hand.java new file mode 100644 index 0000000..b715e54 --- /dev/null +++ b/aux/set/Hand.java @@ -0,0 +1,26 @@ +package mahjong.aux.set; + +import mahjong.aux.Card; + +/** + * Created by joe on 12/1/14. + */ +public class Hand extends Set { + public Hand() + { + super(); + } + public Hand(String[] cardNames) + { + super(cardNames); + } + public Hand(Card[] cards) + { + super(cards); + } + + public Set[] generateEnds() + { + return null; + } +} diff --git a/aux/set/Set.java b/aux/set/Set.java new file mode 100644 index 0000000..d087955 --- /dev/null +++ b/aux/set/Set.java @@ -0,0 +1,75 @@ +package mahjong.aux.set; + +import mahjong.aux.Card; + +import java.util.Random; +import java.util.Vector; + +/** + * Created by joe on 12/1/14. + */ +public class Set { + static protected final Random rand = new Random(); + protected Vector<Card> cards = new Vector<Card>(); + + public Set(){} + public Set(String[] cardNames) + { + for (String name:cardNames) + add(new Card(name)); + } + public Set(Card[] cards) + { + for (Card card:cards) + add(card); + } + + public void sort() + { + cards.sort((Card x,Card y) -> x.getExId()-y.getExId()); + } + public void add(Card in) + { + cards.add(in); + } + public void remove(Card out) + { + for (int i=0; i<cards.size();++i) + if (cards.elementAt(i).getId() == out.getId()) + { + cards.remove(i); + break; + } + } + public void replace(Card out, Card in) + { + remove(out); + add(in); + } + public Card draw() + { + int ord = rand.nextInt(getSize()); + Card card = cards.elementAt(ord); + remove(card); + return card; + } + + public Object[] getCards() + { + return cards.toArray(); + } + public String getTypeName() + { + return "Misc"; + } + public int getSize() + { + return cards.size(); + } + + public void print() + { + for (Card card:cards) + System.out.println(card.getNormalName()); + } +} diff --git a/tools/Deck.java b/tools/Deck.java new file mode 100644 index 0000000..d2e4d0c --- /dev/null +++ b/tools/Deck.java @@ -0,0 +1,19 @@ +package mahjong.tools; + +import mahjong.aux.Card; +import mahjong.aux.set.CardSet; +import mahjong.aux.set.Set; + +/** + * Created by joe on 12/1/14. + */ +public class Deck { + static public Set generateDeck() + { + Set deck = new Set(); + for (int i=0; i<CardSet.cardTypeTotal;++i) + for (int cnt=0; cnt<4; ++cnt) + deck.add(new Card(CardSet.deckIds[i])); + return deck; + } +} diff --git a/tools/Timer.java b/tools/Timer.java new file mode 100644 index 0000000..08d8829 --- /dev/null +++ b/tools/Timer.java @@ -0,0 +1,23 @@ +package mahjong.tools; + +/** + * Created by joe on 12/2/14. + */ +public class Timer { + long st,ed; + + public void tick() + { + st=System.currentTimeMillis(); + } + + public void tock() + { + ed=System.currentTimeMillis(); + } + + public long elapse() + { + return ed-st; + } +} |