📄 board.java
字号:
*/ public boolean contains(int x, int y) { return x >= 0 && y >= 0 && x < width && y < height; } /** * Determines whether this Board "contains" the specified * Coords. * * @param c the Coords. */ public boolean contains(Coords c) { if ( c == null ) return false; return contains(c.x, c.y); } /** * Returns the Hex at the specified Coords. * * @param c the Coords. */ public IHex getHex(Coords c) { if (c == null) return null; return getHex(c.x, c.y); } /** * Determines if this Board contains the (x, y) Coords, * and if so, sets the specified Hex into that position * and initializes it. * * @param x the x Coords. * @param y the y Coords. * @param hex the hex to be set into position. */ public void setHex(int x, int y, IHex hex) { data[y * width + x] = hex; initializeAround(x, y); } /** * Sets the hex into the location specified by the * Coords. * * @param c the Coords. * @param hex the hex to be set into position. */ public void setHex(Coords c, IHex hex) { setHex(c.x, c.y, hex); } /** * Checks if a file in data/boards is the specified size */ public static boolean boardIsSize(String filename, int x, int y) { int boardx = 0; int boardy = 0; try { // make inpustream for board Reader r = new BufferedReader(new FileReader("data/boards" + File.separator + filename)); // read board, looking for "size" StreamTokenizer st = new StreamTokenizer(r); st.eolIsSignificant(true); st.commentChar('#'); st.quoteChar('"'); st.wordChars('_', '_'); while(st.nextToken() != StreamTokenizer.TT_EOF) { if(st.ttype == StreamTokenizer.TT_WORD && st.sval.equalsIgnoreCase("size")) { st.nextToken(); boardx = (int)st.nval; st.nextToken(); boardy = (int)st.nval; break; } } r.close(); } catch (IOException ex) { return false; } // check and return return boardx == x && boardy == y; } /** * Can the player deploy an entity here? * There are no canon rules for the deployment phase (?!). I'm using * 3 hexes from map edge. */ public boolean isLegalDeployment(Coords c, Player p) { if (c == null || p == null || !contains(c)) return false; int nLimit = 3; int nDir = p.getStartingPos(); int minx = 0; int maxx = width; int miny = 0; int maxy = height; if(nDir > 10) { //Deep deployment, the board is effectively smaller nDir -= 10; minx = width / 5; maxx -= width / 5; miny = height / 5; maxy -= height / 5; if(c.x < minx || c.y < miny || c.x >=maxx || c.y >= maxy) return false; } switch (nDir) { case 0 : // Any return true; case 1 : // NW return (c.x < minx+nLimit && c.x >= minx && c.y < height / 2) || (c.y < miny+nLimit && c.y >= miny && c.x < width / 2); case 2 : // N return c.y < miny+nLimit && c.y >= miny; case 3 : // NE return (c.x > (maxx - nLimit) && c.x < maxx && c.y < height / 2) || (c.y < miny+nLimit && c.y >= miny && c.x > width / 2); case 4 : // E return c.x >= (maxx - nLimit) && c.x < maxx; case 5 : // SE return (c.x >= (maxx - nLimit) && c.x < maxx && c.y > height / 2) || (c.y >= (maxy - nLimit) && c.y < maxy && c.x > width / 2); case 6 : // S return c.y >= (maxy - nLimit) && c.y < maxy; case 7 : // SW return (c.x < minx+nLimit && c.x >= minx && c.y > height / 2) || (c.y >= (maxy - nLimit) && c.y < maxy && c.x < width / 2); case 8 : // W return c.x < minx+nLimit && c.x >= minx; case 9: // Edge return (c.x < minx+nLimit && c.x >= minx) || (c.y < miny+nLimit && c.y >= miny) || (c.x >= (maxx - nLimit) && c.x < maxx) || (c.y >= (maxy - nLimit) && c.y < maxy); case 10: // Centre return c.x >= width / 3 && c.x <= 2 * width / 3 && c.y >= height / 3 && c.y <= 2 * height / 3; default : // ummm. . return false; } } /** * Loads this board from a filename in data/boards */ public void load(String filename) { // load a board try { java.io.InputStream is = new java.io.FileInputStream(new java.io.File("data/boards", filename)); // tell the board to load! load(is); // okay, done! is.close(); } catch(java.io.IOException ex) { System.err.println("error opening file to load board!"); System.err.println(ex); } } /** * Loads this board from an InputStream */ public void load(InputStream is) { int nw = 0, nh = 0, di = 0; IHex[] nd = new IHex[0]; try { Reader r = new BufferedReader(new InputStreamReader(is)); StreamTokenizer st = new StreamTokenizer(r); st.eolIsSignificant(true); st.commentChar('#'); st.quoteChar('"'); st.wordChars('_', '_'); int count1 = 1; int count2 = 1; while(st.nextToken() != StreamTokenizer.TT_EOF) { if(st.ttype == StreamTokenizer.TT_WORD && st.sval.equalsIgnoreCase("size")) { // read rest of line String[] args = {"0", "0"}; int i = 0; while(st.nextToken() == StreamTokenizer.TT_WORD || st.ttype == '"' || st.ttype == StreamTokenizer.TT_NUMBER) { args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int)st.nval + "" : st.sval; } nw = Integer.parseInt(args[0]); nh = Integer.parseInt(args[1]); nd = new IHex[nw * nh]; di = 0; } else if(st.ttype == StreamTokenizer.TT_WORD && st.sval.equalsIgnoreCase("option")) { // read rest of line String[] args = {"", ""}; int i = 0; while(st.nextToken() == StreamTokenizer.TT_WORD || st.ttype == '"' || st.ttype == StreamTokenizer.TT_NUMBER) { args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int)st.nval + "" : st.sval; } // Only expect certain options. if ( args[0].equalsIgnoreCase("exit_roads_to_pavement") ) { if ( args[1].equalsIgnoreCase("false") ) { this.roadsAutoExit = false; } else { this.roadsAutoExit = true; } } // End exit_roads_to_pavement-option } else if(st.ttype == StreamTokenizer.TT_WORD && st.sval.equalsIgnoreCase("hex")) { // read rest of line String[] args = {"", "0", "", ""}; int i = 0; while(st.nextToken() == StreamTokenizer.TT_WORD || st.ttype == '"' || st.ttype == StreamTokenizer.TT_NUMBER) { args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int)st.nval + "" : st.sval; } int elevation = Integer.parseInt(args[1]); int newIndex = indexFor(args[0], nw, count2); nd[newIndex] = new Hex(elevation, args[2], args[3]); count1++; if (count1 > nw) { count2++; count1 = 1; } } else if(st.ttype == StreamTokenizer.TT_WORD && st.sval.equalsIgnoreCase("end")) { break; } } } catch(IOException ex) { System.err.println("i/o error reading board"); System.err.println(ex); } // fill nulls with blank hexes for (int i = 0; i < nd.length; i++) { if (nd[i] == null) { nd[i] = new Hex(); } } // check data integrity if(nw > 1 || nh > 1 || di == nw * nh) { newData(nw, nh, nd); } else { System.err.println("board data invalid"); } } private int indexFor(String hexNum, int width, int row) { int substringDiff = 2; if (row > 99) substringDiff = Integer.toString(width).length(); int x = Integer.parseInt(hexNum.substring(0, hexNum.length() - substringDiff)) - 1; int y = Integer.parseInt(hexNum.substring(hexNum.length() - substringDiff)) - 1; return y * width + x; } /** * Writes data for the board, as text to the OutputStream */ public void save(OutputStream os) { try { Writer w = new OutputStreamWriter(os); // write w.write("size " + width + " " + height + "\r\n"); if ( !this.roadsAutoExit ) { w.write( "option exit_roads_to_pavement false\r\n" ); } for (int i = 0; i < data.length; i++) { IHex hex = data[i]; boolean firstTerrain = true; StringBuffer hexBuff = new StringBuffer("hex "); hexBuff.append(new Coords(i % width, i / width).getBoardNum()); hexBuff.append(" "); hexBuff.append(hex.getElevation()); hexBuff.append(" \""); for (int j = 0; j < Terrains.SIZE; j++) { ITerrain terrain = hex.getTerrain(j); if (terrain != null) { if (!firstTerrain) { hexBuff.append(";"); } hexBuff.append(terrain.toString()); // Do something funky to save building exits. if (((Terrains.BUILDING == j) || (j == Terrains.FUEL_TANK)) && !terrain.hasExitsSpecified() && terrain.getExits() != 0) { hexBuff.append(":").append(terrain.getExits()); } firstTerrain = false; } } hexBuff.append("\" \""); if (hex.getTheme() != null) { hexBuff.append(hex.getTheme()); } hexBuff.append("\"\r\n"); w.write(hexBuff.toString()); // w.write("hex \"" + hex.getTerrain().name + "\" " + Terrain.TERRAIN_NAMES[hex.getTerrainType()] + " \"" + hex.getTerrain().picfile + "\" " + hex.getElevation() + "\r\n"); } w.write("end\r\n"); // make sure it's written w.flush(); } catch(IOException ex) { System.err.println("i/o error writing board"); System.err.println(ex); } } /** * Writes data for the board, as serialization, to the OutputStream */ public void save2(OutputStream os) { try { ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(this); oos.flush(); } catch(IOException ex) { System.err.println("i/o error writing board"); System.err.println(ex); } } /** * Record that the given coordinates have recieved a hit from an inferno. * * @param coords - the <code>Coords</code> of the hit. * @param round - the kind of round that hit the hex. * @param hits - the <code>int</code> number of rounds that hit. * If a negative number is passed, then an * <code>IllegalArgumentException</code> will be thrown. */ public void addInfernoTo( Coords coords, InfernoTracker.Inferno round, int hits ) { // Declare local variables. InfernoTracker tracker = null; // Make sure the # of hits is valid. if ( hits < 0 ) { throw new IllegalArgumentException ( "Board can't track negative hits. " ); } // Do nothing if the coords aren't on this board. if ( !this.contains( coords ) ) { return; } // Do we already have a tracker for those coords? tracker = (InfernoTracker) this.infernos.get( coords ); if ( null == tracker ) { // Nope. Make one. tracker = new InfernoTracker(); this.infernos.put( coords, tracker ); } // Update the tracker. tracker.add( round, hits ); } public void removeInfernoFrom(Coords coords) { // Do nothing if the coords aren't on this board. if ( !this.contains( coords ) ) { return; } infernos.remove(coords); } /** * Determine if the given coordinates has a burning inferno. * * @param coords - the <code>Coords</code> being checked. * @return <code>true</code> if those coordinates have a burning * inferno round. <code>false</code> if no inferno has hit * those coordinates or if it has burned out. */ public boolean isInfernoBurning( Coords coords ) { boolean result = false; InfernoTracker tracker = null; // Get the tracker for those coordinates
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -