001    /*
002     * Created on Feb 15, 2005
003     *
004     */
005    package aima.games;
006    
007    import java.util.ArrayList;
008    import java.util.List;
009    
010    import aima.basic.XYLocation;
011    
012    /**
013     * @author Ravi Mohan
014     * 
015     */
016    public class TicTacToeBoard {
017            private static final String O = "O";
018    
019            private static final String X = "X";
020    
021            String[] topRow = { " ", " ", " " };
022    
023            String[] midRow = { " ", " ", " " };
024    
025            String[] bottomRow = { " ", " ", " " };
026    
027            private String[] whichRow(int rowNumber) {
028                    String[] whichRow = null;
029                    if (rowNumber == 0) {
030                            whichRow = topRow;
031                    } else if (rowNumber == 1) {
032                            whichRow = midRow;
033                    } else if (rowNumber == 2) {
034                            whichRow = bottomRow;
035                    }
036                    return whichRow;
037    
038            }
039    
040            public boolean isEmpty(int row, int col) {
041                    String[] whichRow = whichRow(row);
042    
043                    return (whichRow[col] == " ");
044            }
045    
046            public void markX(int row, int col) {
047                    mark(row, col, X);
048            }
049    
050            public void markO(int row, int col) {
051                    mark(row, col, O);
052            }
053    
054            public void mark(int row, int col, String symbol) {
055                    String[] whichRow = null;
056                    whichRow = whichRow(row);
057                    whichRow[col] = symbol;
058            }
059    
060            public boolean isAnyRowComplete() {
061                    boolean retVal = false;
062                    for (int i = 0; i < 3; i++) {
063                            String[] whichRow = whichRow(i);
064                            if ((whichRow[0] != " ") && (whichRow[0] == whichRow[1])
065                                            && (whichRow[1] == whichRow[2])) {
066                                    retVal = true;
067                                    break;
068                            }
069                    }
070                    return retVal;
071            }
072    
073            public boolean isAnyColumnComplete() {
074                    boolean retVal = false;
075                    for (int i = 0; i < 3; i++) {
076    
077                            if ((topRow[i] != " ") && (topRow[i] == midRow[i])
078                                            && (midRow[i] == bottomRow[i])) {
079                                    retVal = true;
080                                    break;
081                            }
082                    }
083                    return retVal;
084            }
085    
086            public boolean isAnyDiagonalComplete() {
087                    boolean retVal = false;
088                    // check diagonal 1
089                    if ((topRow[0] != " ") && (topRow[0] == midRow[1])
090                                    && (midRow[1] == bottomRow[2])) {
091                            retVal = true;
092                    } else if ((topRow[2] != " ") && (topRow[2] == midRow[1])
093                                    && (midRow[1] == bottomRow[0])) {
094                            retVal = true;
095                    }
096    
097                    return retVal;
098            }
099    
100            public boolean lineThroughBoard() {
101                    return ((isAnyRowComplete()) || (isAnyColumnComplete()) || (isAnyDiagonalComplete()));
102            }
103    
104            public String getValue(int row, int col) {
105                    String[] whichRow = whichRow(row);
106                    return whichRow[col];
107            }
108    
109            private void setValue(int row, int col, String val) {
110                    String[] whichRow = whichRow(row);
111                    whichRow[col] = val;
112            }
113    
114            public void print() {
115                    for (int i = 0; i < 3; i++) {
116                            for (int j = 0; j < 3; j++) {
117                                    String value = getValue(i, j);
118                                    String printValue;
119                                    if (value == " ") {
120                                            printValue = "-";
121                                    } else {
122                                            printValue = value;
123                                    }
124                                    System.out.print(printValue + " ");
125                            }
126                            System.out.println();
127                    }
128            }
129    
130            @Override
131            public String toString() {
132                    StringBuffer buf = new StringBuffer();
133                    for (int i = 0; i < 3; i++) {
134                            for (int j = 0; j < 3; j++) {
135                                    String value = getValue(i, j);
136                                    String printValue;
137                                    if (value == " ") {
138                                            printValue = "-";
139                                    } else {
140                                            printValue = value;
141                                    }
142                                    buf.append(printValue + " ");
143                            }
144                            buf.append("\n");
145                    }
146                    return buf.toString();
147            }
148    
149            public TicTacToeBoard cloneBoard() {
150                    return (TicTacToeBoard) clone();
151            }
152    
153            @Override
154            public Object clone() {
155                    TicTacToeBoard newBoard = new TicTacToeBoard();
156                    for (int i = 0; i < 3; i++) {
157                            for (int j = 0; j < 3; j++) {
158                                    String s = getValue(i, j);
159                                    newBoard.setValue(i, j, s);
160                            }
161                    }
162                    return newBoard;
163            }
164    
165            public int getNumberOfMarkedPositions() {
166                    int retVal = 0;
167                    for (int i = 0; i < 3; i++) {
168                            for (int j = 0; j < 3; j++) {
169                                    if (!(isEmpty(i, j))) {
170                                            retVal++;
171                                    }
172                            }
173    
174                    }
175                    return retVal;
176            }
177    
178            public List getUnMarkedPositions() {
179                    List<XYLocation> retVal = new ArrayList<XYLocation>();
180                    for (int i = 0; i < 3; i++) {
181                            for (int j = 0; j < 3; j++) {
182                                    if (isEmpty(i, j)) {
183                                            retVal.add(new XYLocation(i, j));
184                                    }
185                            }
186    
187                    }
188                    return retVal;
189            }
190    
191            @Override
192            public boolean equals(Object anObj) {
193                    boolean retVal = true;
194                    TicTacToeBoard anotherBoard = (TicTacToeBoard) anObj;
195                    boolean secondBreak = false;
196                    for (int i = 0; i < 3; i++) {
197                            for (int j = 0; j < 3; j++) {
198                                    if (anotherBoard.getValue(i, j) != getValue(i, j)) {
199                                            retVal = false;
200                                            secondBreak = true;
201                                            break;
202                                    }
203    
204                            }
205                            if (secondBreak == false) {
206                                    break;
207                            }
208    
209                    }
210                    return retVal;
211            }
212    
213            public boolean isMarked(String string, int i, int j) {
214                    return getValue(i, j).equals(string);
215            }
216    }