001    package org.dllearner.examples;
002    
003    import java.io.BufferedReader;
004    import java.io.FileNotFoundException;
005    import java.io.FileOutputStream;
006    import java.io.FileReader;
007    import java.io.IOException;
008    import java.util.LinkedList;
009    import java.util.List;
010    import java.util.StringTokenizer;
011    
012    /**
013     * Transforms UCI-ML-Repository Poker example to a conf file.
014     * 
015     * @author jl
016     *
017     */
018    public class PokerTransformer {
019    
020            public static void main(String[] args) {
021                    PokerTransformer pt = new PokerTransformer();
022                    pt.transform();
023            }
024                    
025            public void transform() {
026                    
027                    String learningGoal = "pair";           
028                    // String learningGoal = "straight";
029                    
030                    String fileIn = "files/examples/poker/poker-hand-training-true.data";
031                    // String fileOut = "files/examples/poker/poker.preconf";
032                    String fileOut = "release_test/dllearner-2007-04-08/examples/poker/poker_"+learningGoal+".conf";
033                    
034                    String yinyangPosFile = "release_test/dllearner-2007-04-08/examples/poker/"+learningGoal+"Positives.txt";
035                    String yinyangNegFile = "release_test/dllearner-2007-04-08/examples/poker/"+learningGoal+"Negatives.txt";
036                    String dllExamplesFile = "release_test/dllearner-2007-04-08/examples/poker/"+learningGoal+"_examples.txt";
037                    
038                    // Datei öffnen
039                    BufferedReader in = null;
040                    try {
041                            in = new BufferedReader(new FileReader(fileIn));
042                    } catch (FileNotFoundException e) {
043                            e.printStackTrace();
044                    }
045                    
046                    // Datei in eine String-Array einlesen 
047                    List<String> pokerExamples = new LinkedList<String>();
048                    String line = "";
049                    int lineNumber = 0;
050                    while(line!=null && lineNumber<50) {
051                            try {
052                                    line = in.readLine();
053                            } catch (IOException e) {
054                                    // TODO Auto-generated catch block
055                                    e.printStackTrace();
056                            }
057                            if(line!=null)
058                                    pokerExamples.add(line);
059                            
060                            lineNumber++;
061                    }
062                    
063                    List<PokerHand> hands = new LinkedList<PokerHand>();
064                    for(String s : pokerExamples) {
065                            // System.out.println(s);
066                            StringTokenizer st = new StringTokenizer(s,",");
067                            
068                            // 5 Karten einlesen
069                            PokerCard[] cards = new PokerCard[5];
070                            for(int i=0; i<=4; i++) {
071                                    String suit = st.nextToken();
072                                    String rank = st.nextToken();
073                                    cards[i] = new PokerCard(new Integer(suit),new Integer(rank));
074                            }
075                            
076                            // Klasse auslesen
077                            String handType = st.nextToken();
078                            PokerHand hand = new PokerHand(cards, new Integer(handType));
079                            
080                            // prüfen, ob Deck schon existiert (nicht gerade effizient,
081                            // aber OK)
082                            boolean handExists = false;
083                            for(PokerHand d : hands) {
084                                    if(equalDecks(d,hand)) {
085                                            handExists = true;
086                                            break;
087                                    }
088                            }
089                            
090                            if(!handExists) {
091                                    // besondere Bedingungen um mehr straights zu bekommen
092                                    if(learningGoal.equals("straight")) {
093                                            // oversampling um mehr richtige straights zu bekommen
094                                            // (am anfang stehen royal flushes, die auch nicht so
095                                            // ideal zum lernen sind)
096                                            if(hand.getHandType()==4 || Math.random()<0.05) {
097                                                    hands.add(hand);
098                                            } 
099                                            
100                                    } else 
101                                            hands.add(hand);
102                            }
103                                    
104                    }
105                    
106                    // Ausgabe in Datei
107                    try {
108                            FileOutputStream fos = new FileOutputStream(fileOut);
109                            FileOutputStream yyPos = new FileOutputStream(yinyangPosFile);
110                            FileOutputStream yyNeg = new FileOutputStream(yinyangNegFile);  
111                            FileOutputStream ex = new FileOutputStream(dllExamplesFile);
112                            
113                            // für jede Karte die entsprechende Ausgabe machen
114                            int handNumber = 0;
115                            for(PokerHand deck : hands) {
116                                    String handID = "hand" + handNumber;
117                                    
118                                    // Ausgabe der Hand (damit für Reasoner klar ist, dass es
119                                    // sich um Individuen handelt)
120                                    write(fos, "deck("+handID+").");
121                                    
122                                    int cardNumber = handNumber*5;
123                                    PokerCard[] cards = deck.getCards();
124                                    // for(Card card : deck.getCards()) {
125                                    for(int i=0; i<5; i++) {
126                                            PokerCard card = cards[i];
127                                            String cardID = "card" + cardNumber;
128                                            
129                                            // Ausgabe der Karte (damit klar ist, dass es sich um ein
130                                            // Individual handelt)
131                                            write(fos, "card("+cardID+").");
132                                            
133                                            // hasCard-Ausgabe
134                                            write(fos, "hasCard("+handID+"," + cardID + ").");
135                                            
136                                            // suit und rank ausgeben
137                                            write(fos, "hasSuit("+cardID+"," + card.getSuitString()+").");
138                                            write(fos, "hasRank("+cardID+"," + card.getRankString()+").");
139                                            
140                                            // sameSuit, nextRank und sameRank ausgeben
141                                            for(int j=i+1; j<5; j++) {
142                                                    PokerCard otherCard = cards[j];
143                                                    String otherCardID = "card" + (handNumber*5+j);
144                                                    if(card.hasSameSuit(otherCard))
145                                                            write(fos, "sameSuit("+cardID+","+otherCardID+").");
146                                                    if(card.hasSameRank(otherCard))
147                                                            write(fos, "sameRank("+cardID+","+otherCardID+").");    
148                                            }
149                                            
150                                            // nextRank ist nicht symmetrisch, deshalb müssen alle 
151                                            // 4 anderen Karten geprüft werden
152                                            for(int j=0; j<5; j++) {
153                                                    PokerCard otherCard = cards[j];
154                                                    String otherCardID = "card" + (handNumber*5+j);
155                                                    if(card.hasNextRank(otherCard)) {
156                                                            // Spezialfall: Ass
157                                                            if(card.getRank()==1) {
158                                                                    // Regel: falls es keinen König gibt, dann darf
159                                                                    // nextRank geschrieben werden
160                                                                    if(!hasKing(deck))
161                                                                            write(fos, "nextRank("+cardID+","+otherCardID+").");
162                                                            } else
163                                                                    write(fos, "nextRank("+cardID+","+otherCardID+").");
164                                                    }
165                                            }
166                                            
167                                            write(fos,"");
168                                            
169                                            cardNumber++;
170                                    }
171                                    
172                                    // Lernziel ausgeben (hier: Paar, behinhaltet auch 2 Paar etc.)
173                                    int hand = deck.getHandType();
174                                    
175                                    if(learningGoal.equals("pair")) {
176                                            if(hand==1 || hand==2 || hand==3 || hand==6 || hand==7) { 
177                                                    write(fos, "+pair("+handID+").");
178                                                    write(yyPos, "http://localhost/foo#"+handID);
179                                                    write(ex, "+pair(\"http://localhost/foo#"+handID+"\").");
180                                            } else {
181                                                    write(fos, "-pair("+handID+").");
182                                                    write(yyNeg, "http://localhost/foo#"+handID);
183                                                    write(ex, "-pair(\"http://localhost/foo#"+handID+"\").");
184                                            }
185                                    } else if(learningGoal.equals("straight")) {
186                                            if(hand==4 || hand==8 || hand==9) { 
187                                                    write(fos, "+straight("+handID+").");
188                                                    write(yyPos, "http://localhost/foo#"+handID);
189                                                    write(ex, "+straight(\"http://localhost/foo#"+handID+"\").");
190                                            } else {
191                                                    write(fos, "-straight("+handID+").");
192                                                    write(yyNeg, "http://localhost/foo#"+handID);
193                                                    write(ex, "-straight(\"http://localhost/foo#"+handID+"\").");
194                                            }
195                                    }
196                                    
197                                    write(fos,"");
198                                    
199                                    handNumber++;
200                            }
201                            
202                            // fos.write(content.getBytes());
203                            fos.close();
204                    } catch (Exception e) {
205                            System.out.println(e);
206                            System.exit(0);
207                    }
208                    
209            }
210            
211            private void write(FileOutputStream fos, String content) {
212                    content += "\n";
213                    try {
214                            fos.write(content.getBytes());
215                    } catch (IOException e) {
216                            e.printStackTrace();
217                    }
218            }
219                    
220            public boolean equalDecks(PokerHand deck1, PokerHand deck2) {
221                    PokerCard[] deck1Cards = deck1.getCards();
222                    for(int i=0; i<5; i++) {
223                            if(!isInCards(deck1Cards[i],deck2))
224                                    return false;
225                    }
226                    return true;
227            }
228            
229            public boolean isInCards(PokerCard card, PokerHand deck) {
230                    PokerCard[] cards = deck.getCards();
231                    for(int j=0; j<5; j++) {
232                            // Test auf Gleichheit
233                            if(card.getSuit()==cards[j].getSuit() && card.getRank()==cards[j].getRank())
234                                    return true;
235                    }
236                    return false;
237            }
238            
239            public boolean hasKing(PokerHand deck) {
240                    PokerCard[] cards = deck.getCards();
241                    for(int j=0; j<5; j++) {
242                            if(cards[j].getRank()==13)
243                                    return true;
244                    }
245                    return false;           
246            }
247    }