using System; using System.Collections; using System.Collections.Generic; using System.Text; namespace BattleForAllenCreek { class Los { int originX, originY; int endPointX, endPointY; int range; int bearing; int maxIndex; int losType; int[] sectors = new int[] { 0, 0, 16, 17, 14, 15, 13, 0, 18, 20, 19, 22, 21, 23, 12, 0, 8, 7, 10, 9, 11, 0, 6, 4, 5, 2, 3, 1}; public Los() { this.originX = 0; this.originY = 0; this.endPointX = 0; this.endPointY = 0; } public Los(int originX, int originY, int endPointX, int endPointY) { this.originX = originX; this.originY = originY; this.endPointX = endPointX; this.endPointY = endPointY; this.setBearing(); this.setRange(); } public void setOrigin(int originX, int originY) { this.originX = originX; this.originY = originY; this.setBearing(); this.setRange(); } public void setEndPoint(int endPointX, int endPointY) { this.endPointX = endPointX; this.endPointY = endPointY; this.setBearing(); this.setRange(); } private void setRange() { int absX = Math.Abs(this.endPointX - this.originX); int absY = Math.Abs(this.endPointY - this.originY); if (absX > absY) { this.range = absX / 2; } else { this.range = (absX + absY) / 4; } this.maxIndex = this.range * 2; } public int getRange() { return this.range; } private void setBearing() { // returns number 0-23 // even numbers are lines, odd numbers are areas between lines // 0=N, 6=E, 12=S, 18=W // 4 = 60 degrees, 8 = 120 degrees, 16 = 240 degrees, 20 = 300 degrees // 2 = 30 degrees, 10 = 150 degrees, 14 = 210 degrees, 22 = 330 degrees // odd numbers are anywhere in between the even lines int delta_x, delta_y; int absolute_x, absolute_y; int x3times, sector, quadrant; sector = 0; quadrant = 0; // step 1. find the delta delta_x = this.endPointX - this.originX; delta_y = this.endPointY - this.originY; // step 2. check if at the origin if( delta_x == 0 && delta_y == 0 ) { this.bearing = -1; } else { // step 3. find the sector absolute_x = Math.Abs(delta_x); absolute_y = Math.Abs(delta_y); x3times = 3 * absolute_x; if( delta_x == 0 ) sector = 0; else { if(delta_y == 0) sector = 1; else { if( absolute_x == absolute_y) sector = 2; else { if(absolute_x > absolute_y) sector = 3; else { if( x3times == absolute_y) sector = 4; else { if( x3times > absolute_y) sector = 5; else sector = 6; } } } } } } // step 4. find the quadrant if( delta_x < 0 ) { if( delta_y > 0) quadrant = 0; else quadrant = 1; } else { if( delta_y > 0) quadrant = 2; else quadrant = 3; } this.bearing = this.sectors[ ( quadrant * 7 ) + sector ]; if (( this.bearing % 2) == 0 ) { if ((this.bearing % 4) == 0) { this.losType = 1; // straight } else { this.losType = 2; // corner } } else { this.losType = 3; // zig-zag } } public int getBearing() { return this.bearing; } public int getFacingNumber() { // returns 1=N, 2=NE, 3=SE, 4=S, 5=SW, 6=NW return (int)Math.Floor((double)(this.getBearing() / 4) + 1); } public ArrayList getHexpartList() { int stepIndex, losIndex; int[] stepX = { 0, 2, 2, 4, 2, 2, 0, -2, -2, -4, -2, -2, 0 }; int[] stepY = { -4, -6, -2, 0, 2, 6, 4, 6, 2, 0, -2, -6, -4 }; int hexagonX; int hexagonY; int hexsideX; int hexsideY; ArrayList hexpartList = new ArrayList(); losIndex = 0; this.maxIndex = this.range * 2; // if bearing is even number if (this.losType == 2) { // straight LOS if (this.losType == 1) { stepIndex = (int)Math.Floor((double)bearing / 2); hexagonX = this.originX; hexagonY = this.originY; hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "straight")); losIndex++; do { hexsideX = hexagonX + (stepX[stepIndex] / 2); hexsideY = hexagonY + (stepY[stepIndex] / 2); // add hexside hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex, (this.maxIndex - losIndex), "straight")); losIndex++; // go to next hexagon in LOS hexagonX += stepX[stepIndex]; hexagonY += stepY[stepIndex]; // add hexagon hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "straight")); losIndex++; } while (losIndex <= this.maxIndex); } else { // corner LOS stepIndex = (int)Math.Floor((double)this.bearing / 2); hexagonX = this.originX; hexagonY = this.originY; hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "straight")); do { hexsideX = hexagonX + (stepX[stepIndex] / 2); hexsideY = hexagonY + (stepY[stepIndex] / 2); switch (this.bearing) { case 2: hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY + 2, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY + 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex + 2, (this.maxIndex - losIndex - 2), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY - 2, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY - 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); break; case 6: hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY + 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY - 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex + 2, (this.maxIndex - losIndex - 2), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY + 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY - 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); break; case 10: hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY - 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY - 2, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex + 2, (this.maxIndex - losIndex - 2), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY + 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY + 2, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); break; case 14: hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY - 2, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY - 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex + 2, (this.maxIndex - losIndex - 2), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY + 2, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY + 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); break; case 18: hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY + 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY - 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex + 2, (this.maxIndex - losIndex - 2), "corner")); hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY + 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY - 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); break; case 22: hexpartList.Add(new HexpartLos(hexsideX + 1, hexsideY + 1, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY + 2, losIndex + 1, (this.maxIndex - losIndex - 3), "corner")); hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex + 2, (this.maxIndex - losIndex - 2), "corner")); hexpartList.Add(new HexpartLos(hexsideX - 1, hexsideY - 1, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); hexpartList.Add(new HexpartLos(hexsideX + 0, hexsideY - 2, losIndex + 3, (this.maxIndex - losIndex - 1), "corner")); break; } losIndex += 4; // go to next hexagon in LOS hexagonX += stepX[stepIndex]; hexagonY += stepY[stepIndex]; hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "corner")); } while (losIndex < this.maxIndex); } } else { // bearing is odd number // zig-zag LOS stepIndex = ((int)Math.Floor((double)this.bearing / 4)) * 2; hexagonX = this.originX; hexagonY = this.originY; int hexagon1X, hexagon1Y, hexagon2X, hexagon2Y; int offset1, offset2; hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; do { hexagon1X = hexagonX + stepX[stepIndex]; hexagon1Y = hexagonY + stepY[stepIndex]; hexagon2X = hexagonX + stepX[stepIndex + 2]; hexagon2Y = hexagonY + stepY[stepIndex + 2]; offset1 = (int)Math.Abs( (this.originX * this.endPointY) - (this.originX * hexagon1Y) - (this.endPointX * this.originY) + (this.endPointX * hexagon1Y) + (hexagon1X * this.originY) - (hexagon1X * this.endPointY)); offset2 = (int)Math.Abs( (this.originX * this.endPointY) - (this.originX * hexagon2Y) - (this.endPointX * this.originY) + (this.endPointX * hexagon2Y) + (hexagon2X * this.originY) - (hexagon2X * this.endPointY)); if (offset1 == offset2) { // double hexagon traverse // first near hexagon hexpartList.Add(new HexpartLos(hexagon1X, hexagon1Y, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; // second near hexagon hexpartList.Add(new HexpartLos(hexagon2X, hexagon2Y, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; // hexside between to two above hexsideX = hexagonX + ((stepX[stepIndex] + stepX[stepIndex + 2]) / 2); hexsideY = hexagonY + ((stepY[stepIndex] + stepY[stepIndex + 2]) / 2); hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; // add last hexagon which at range of 2 hexagonX = hexagonX + stepX[stepIndex] + stepX[stepIndex + 2]; hexagonY = hexagonY + stepY[stepIndex] + stepY[stepIndex + 2]; hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; } else { if (offset1 < offset2) { hexsideX = (hexagonX + hexagon1X) / 2; hexsideY = (hexagonY + hexagon1Y) / 2; hexagonX = hexagon1X; hexagonY = hexagon1Y; hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; } else { hexsideX = (hexagonX + hexagon2X) / 2; hexsideY = (hexagonY + hexagon2Y) / 2; hexagonX = hexagon2X; hexagonY = hexagon2Y; hexpartList.Add(new HexpartLos(hexsideX, hexsideY, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; hexpartList.Add(new HexpartLos(hexagonX, hexagonY, losIndex, (this.maxIndex - losIndex), "zig-zag")); losIndex++; } } } while (hexagonX != this.endPointX || hexagonY != this.endPointY); } return hexpartList; } } }