001 package core; 002 003 import java.util.*; 004 005 /** 006 * Position on the board. 007 * 008 * @specfield x : int // x location of piece 009 * @specfield y : int // y location of piece 010 * 011 * Abstract Invariant: 0 <= x <= 7 0 <= y <= 7 012 */ 013 public class Position 014 { 015 // Positions are numbered from 0 016 // For a1, x=0 and y=0 017 // For a8, x=0 and y=7 018 // For h8, x=7 and y=7 019 final private int x, y; 020 public static final Position[][] pos = ALLarray(); 021 public static final Collection<Position> ALL = ALLfn(); 022 023 public static Position[][] ALLarray(){ 024 Position[][] ans = new Position[8][8]; 025 for(int x = 0; x < 8; x++){ 026 for(int y = 0; y < 8; y++){ 027 ans[x][y] = new Position(x, y); 028 } 029 } 030 return ans; 031 } 032 public static Collection<Position> ALLfn(){ 033 Collection<Position> ans = new ArrayList<Position>(); 034 for(int x = 0; x < 8; x++){ 035 for(int y = 0; y < 8; y++){ 036 ans.add(get(x, y)); 037 } 038 } 039 return ans; 040 } 041 042 043 public static boolean isValid(int x, int y){ 044 return ((x >= 0 && x < 8) && 045 (y >= 0 && y < 8)); 046 } 047 public boolean isValid(){ 048 return Position.isValid(x, y); 049 } 050 051 public static Position get(int x, int y){ 052 //return new Position(x, y); 053 return pos[x][y]; 054 } 055 /** 056 * Gives a postion in term of x and y coordinates. 057 */ 058 private Position(int x, int y) { 059 this.x = x; 060 this.y = y; 061 } 062 063 /** 064 * @returns x of this position 065 */ 066 public int getX() { 067 return x; 068 } 069 070 /** 071 * @returns y of this position 072 */ 073 public int getY() 074 { 075 return y; 076 } 077 078 /** 079 * @see Object 080 */ 081 public boolean equals(Object o) 082 { 083 if (o != null && o instanceof Position) 084 { 085 Position p = (Position) o; 086 return (p.x == x && p.y == y); 087 } 088 return false; 089 } 090 091 /** 092 * @see Object 093 */ 094 public int hashCode() 095 { 096 return x * 8 + y; 097 } 098 099 /** 100 * @param s 101 * is a String representing a chess position 102 * @requires s is of the form [row][column], where the row is a character 103 * from a to h and the column is a number from 1 to 8. For 104 * example, c7 is a legal argument to this method, as is h4. 105 * @returns a Position corresponding to the String s. Its toString method 106 * will return a String equal to s. 107 */ 108 public static Position fromString(String s) 109 { 110 int x; 111 int y; 112 113 if (!Position.validPosition(s)) 114 { 115 throw new RuntimeException("'" + s + "' is not a valid position."); 116 } 117 118 // Determine the column (x) 119 char colChar = s.charAt(0); 120 x = ((int) colChar) - ((int) 'a'); 121 if (x < 0 || x >= 8) { 122 // Shouldn't be reached because we already ran validPosition 123 throw new RuntimeException("'" + s + "' is not a valid position."); 124 } 125 126 // Determine the row (y) 127 y = Integer.parseInt(s.substring(1)) - 1; 128 129 // Make a new position at (x, y) and return it 130 assert(x >= 0 && x < 8 && y >= 0 && y < 8); 131 return get(x, y); 132 } 133 134 /** 135 * @returns true if s is of the form [row][column], where the row is a 136 * character from a to h and the column is a number from 1 to 8. 137 * For example, c7 is a valid position String, as is h4. 138 */ 139 public static boolean validPosition(String s) 140 { 141 142 // First, validate the input length 143 if (s.length() != 2) 144 { 145 return false; 146 } 147 148 // Check the column (x) 149 char colChar = s.charAt(0); 150 if (colChar < 'a' || colChar > 'h') 151 { 152 153 // colChar isn't a character from a to h 154 return false; 155 } 156 157 // Check the row (y) 158 try 159 { 160 int y = Integer.parseInt(s.substring(1)); 161 if (y < 1 || y > 8) 162 { 163 return false; 164 } 165 } catch (NumberFormatException ex) 166 { 167 return false; 168 } 169 170 // x and y are both valid 171 return true; 172 } 173 174 /** 175 * @returns a String representation of this, of the form [column][row]. The 176 * columns are represented by letters from a to h, where a 177 * corresponds to a column argument of 1 to the constructor. The 178 * rows are numbered from 1 to 8. Thus, from White's perspective, 179 * the lower-left corner is a1, the lower-right corner is h1, and 180 * the upper-right corner is h8. 181 */ 182 public String toString() 183 { 184 return "abcdefgh".charAt(x) + "" + (y+1); 185 } 186 }