/// <summary> /// Apply a texture to the terrain using the specified TerrainTester. /// </summary> /// <param name="position">Top left position of the texture relative to the terrain.</param> public void ApplyData(sbyte[,] data, Vector2 position) { for (int y = (int)position.Y; y < data.GetUpperBound(1) + (int)position.Y; y++) { for (int x = (int)position.X; x < data.GetUpperBound(0) + (int)position.X; x++) { if (x >= 0 && x < _localWidth && y >= 0 && y < _localHeight) { _terrainMap[x, y] = data[x, y]; } } } // generate terrain for (int gy = 0; gy < _ynum; gy++) { for (int gx = 0; gx < _xnum; gx++) { //remove old terrain object at grid cell if (_bodyMap[gx, gy] != null) { for (int i = 0; i < _bodyMap[gx, gy].Count; i++) { World.RemoveBody(_bodyMap[gx, gy][i]); } } _bodyMap[gx, gy] = null; //generate new one GenerateTerrain(gx, gy); } } }
private sbyte[,] ForceFall(sbyte[,] source, int pxStart, int pxMax) { int width = source.GetUpperBound(0) + 1; int height = source.GetUpperBound(1) + 1; // Do the fall checks from bot to top for (int px = Mathf.Max(0, pxStart); px <= Mathf.Min(width - 1, pxMax); px++) { for (int py = 0; py < height; py++) { var block = source[px, py]; // Ignore garbage if (block > 0 && block < 99) { for (int yFall = py - 1; yFall >= 0; yFall--) { if (source[px, yFall] == 0) { source[px, yFall] = block; source[px, yFall + 1] = 0; } } } } } return(source); }
public Model() { gameField = new sbyte[height, width]; playGroundImage = new Bitmap(width * 20, height * 20); createNewTetro(); Debug.Print(string.Format("height: {0} width: {1}", gameField.GetUpperBound(0), gameField.GetUpperBound(1))); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (j == height - 1) { gameField[gameField.GetUpperBound(0), i] = 0; } else { gameField[j, i] = -1; } } } gfx = Graphics.FromImage(playGroundImage); drawGame(); }
/// <summary> /// Compute a list of possible moves from a given grid /// </summary> /// <param name="level">Depth</param> /// <param name="n">Branch index</param> /// <param name="g"></param> /// <param name="minX">Left bound</param> /// <param name="maxX">Right bound</param> /// <param name="parent"></param> /// <returns></returns> public List <AIMove> GetWeightedMoves(int level, int n, sbyte[,] g, int minX, int maxX, AIMove parent) { int width = g.GetUpperBound(0) + 1; int height = g.GetUpperBound(1) + 1; var moves = GetMoves(level, g, minX, maxX, parent); if (moves.Count > 0) { foreach (var m in moves) { m.gridAfterMove = GetGridWithMove(g, m); var weightData = heuristic.WeightMove(m, width, height, level); m.weight = weightData.total + (parent?.weight ?? 0); m.depthLevel = level; m.comboCount = weightData.combosCount + (parent?.comboCount ?? 0); m.gridAfterMove = RemoveCombos(m.gridAfterMove, weightData.blocksInCombo); } } return(moves); }
static public byte[,] GaussianMasking(sbyte[,] Mask_2D, byte[,] Array_Input) { int maskXLength = Mask_2D.GetUpperBound(0) + 1, maskYLength = Mask_2D.GetUpperBound(1) + 1; byte[,] Array_GaussianBlurred = new byte[Array_Input.GetUpperBound(0) + 1, Array_Input.GetUpperBound(1) + 1]; int totalMask = 0; for (int y = 0; y < maskYLength; y++) { for (int x = 0; x < maskXLength; x++) { totalMask += Mask_2D[x, y]; } } for (int y = ((maskYLength - 1) >> 1); y < Array_Input.GetUpperBound(1) + 1 - ((maskYLength - 1) >> 1); y++) { for (int x = ((maskXLength - 1) >> 1); x < Array_Input.GetUpperBound(0) + 1 - ((maskXLength - 1) >> 1); x++) { float accumulator = 0; for (int j = 0; j < maskYLength; j++) { for (int i = 0; i < maskXLength; i++) { accumulator += Mask_2D[i, j] * Array_Input[x - ((maskXLength - 1) >> 1) + i, y - ((maskYLength - 1) >> 1) + j]; } } Array_GaussianBlurred[x, y] = (byte)Math.Round((accumulator / totalMask), MidpointRounding.AwayFromZero); } } return(Array_GaussianBlurred); }
/// <summary> /// Apply the specified texture data to the terrain. /// </summary> /// <param name="data"></param> /// <param name="offset"></param> public void ApplyData(sbyte[,] data, Vector2 offset = default(Vector2)) { for (int x = 0; x < data.GetUpperBound(0); x++) { for (int y = 0; y < data.GetUpperBound(1); y++) { if (x + offset.X >= 0 && x + offset.X < _localWidth && y + offset.Y >= 0 && y + offset.Y < _localHeight) { _terrainMap[(int)(x + offset.X), (int)(y + offset.Y)] = data[x, y]; } } } RemoveOldData(0, _xnum, 0, _ynum); }
public void ApplyData(sbyte[,] data, TSVector2 offset = default(TSVector2)) { for (int i = 0; i < data.GetUpperBound(0); i++) { for (int j = 0; j < data.GetUpperBound(1); j++) { bool flag = i + offset.x >= 0 && i + offset.x < this._localWidth && j + offset.y >= 0 && j + offset.y < this._localHeight; if (flag) { this._terrainMap[(int)((long)(i + offset.x)), (int)((long)(j + offset.y))] = data[i, j]; } } } this.RemoveOldData(0, this._xnum, 0, this._ynum); }
public Tetro(sbyte[,] gameField, TetroType type) { this.Type = type; this.gameField = gameField; setTetroField(); y = 0; x = gameField.GetUpperBound(1) / 2 - tetroField.GetUpperBound(1) / 2; Fill(); }
static public byte[,] EdgeDetectionMasking(sbyte[,] Mask_X, sbyte[,] Mask_Y, byte[,] Array_Input) { byte[,] Array_Convolved = new byte[Array_Input.GetUpperBound(0) + 1, Array_Input.GetUpperBound(1) + 1]; for (int y = ((Mask_Y.GetUpperBound(1) + 1 - 1) >> 1); y < Array_Input.GetUpperBound(1) + 1 - ((Mask_Y.GetUpperBound(1) + 1 - 1) >> 1); y++) { for (int x = ((Mask_X.GetUpperBound(0) + 1 - 1) >> 1); x < Array_Input.GetUpperBound(0) + 1 - ((Mask_X.GetUpperBound(0) + 1 - 1) >> 1); x++) { float accumulatorX = 0f; float accumulatorY = 0f; for (int j = 0; j < Mask_Y.GetUpperBound(1) + 1; j++) { for (int i = 0; i < (Mask_X.GetUpperBound(0) + 1); i++) { accumulatorX += Mask_X[i, j] * Array_Input[x - ((Mask_X.GetUpperBound(0) + 1 - 1) >> 1) + i, y - ((Mask_X.GetUpperBound(1) + 1 - 1) >> 1) + j]; accumulatorY += Mask_Y[i, j] * Array_Input[x - ((Mask_Y.GetUpperBound(0) + 1 - 1) >> 1) + i, y - ((Mask_Y.GetUpperBound(1) + 1 - 1) >> 1) + j]; } } Array_Convolved[x, y] = (byte)Math.Sqrt(accumulatorX * accumulatorX + accumulatorY * accumulatorY); } } return(Array_Convolved); }
public Vector2 GetHighest(sbyte[,] g) { int width = g.GetUpperBound(0) + 1; int height = g.GetUpperBound(1) + 1; var highestBlock = Vector2.zero; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { sbyte block = g[x, y]; if (block > 0) { if (y > highestBlock.y) { highestBlock = new Vector2(x, y); } } } } return(highestBlock); }
/// <summary> /// Writes a 2D array of sbytes to the output. /// </summary> /// <param name="name">Name of the value</param> /// <param name="value">2D array of sbytes</param> public void Write(string name, sbyte[,] value) { if (value == null) { _output.Write(NULL_OBJECT); return; } else { _output.Write(A_OK); } int row = value.GetUpperBound(0); int col = value.GetUpperBound(1); _output.Write(row); _output.Write(col); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { _output.Write(value[i, j]); } } }
/// <summary> /// Check if clerance zone is available for base node. /// Return true if it is availavle and false if not. /// </summary> /// <param name="baseNode">base node</param> /// <returns></returns> public bool CheckNode(int baseNodeX, int baseNodeY, int baseNodeZ, int gridX, int gridY, int gridZ) { bool checker = true; for (int i = 0; i <= CLZPoints.GetUpperBound(0); i++) { int mgridX = CLZPoints[i, 0] + baseNodeX; int mgridY = CLZPoints[i, 1] + baseNodeY; int mgridZ = CLZPoints[i, 2] + baseNodeZ; if (mgridX < 0 || mgridY < 0 || mgridZ < 0 || mgridX >= gridX || mgridY >= gridY || mgridZ >= gridZ) { continue; } if (MGrid[mgridX, mgridY, mgridZ] == 1) { return(false); } } return(checker); }
public void Rotate() { if (this.Type != TetroType.O) { int center = 2; if (this.type == TetroType.I) { center = 3; } sbyte[,] temp = new sbyte[TetroField.GetUpperBound(0) + 1, TetroField.GetUpperBound(0) + 1]; for (int y = 0; y < TetroField.GetUpperBound(0) + 1; y++) { for (int x = 0; x < TetroField.GetUpperBound(1) + 1; x++) { if (-y + center >= 0) { temp[-y + center, x] = TetroField[x, y]; } } } for (int y = 0; y < TetroField.GetUpperBound(0) + 1; y++) { for (int x = 0; x < TetroField.GetUpperBound(1) + 1; x++) { if (temp[y, x] != -1) { if (this.X < 0) { if (CheckRight()) { MoveRight(); } else { return; } } else if (this.X + this.tetroField.GetUpperBound(1) + 1 > gameField.GetUpperBound(1) + 1) { if (CheckLeft()) { MoveLeft(); } else { return; } } } } } Clear(); TetroField = temp; Fill(); } }
/// <summary> /// Get all possible moves from the simplified grid /// </summary> public List <AIMove> GetMoves(int level, sbyte[,] g, int minX, int maxX, AIMove parent) { // Explore the grid! int width = g.GetUpperBound(0) + 1; int height = g.GetUpperBound(1) + 1; // Find the moves var moves = new List <AIMove>(); int currentCount = 0; int limit = settings.movesLimits.Length > level ? settings.movesLimits[level] : int.MaxValue; // Look left only on the first step. Then right only. int start = minX + 1; for (int x = start; x < maxX; x++) { // Be sure we're in the grid if (x < 0 || x >= width) { continue; } for (int y = 0; y < height; y++) { int block = g[x, y]; if (block >= 0 && block < 99) // Not empty & not garbage { // Check left if (x > 0 && x == start) { if (block != 0 || g[x - 1, y] != 0) { if (parent == null || (parent.x != (x - 1) && parent.y != y && parent.direction != -1)) { moves.Add(new AIMove(x, y, -1, parent)); currentCount++; } } } // Check right if (x < width - 1) { if (block != 0 || g[x + 1, y] != 0) { if (parent == null || (parent.x != (x + 1) && parent.y != y && parent.direction != 1)) { moves.Add(new AIMove(x, y, 1, parent)); currentCount++; } } } } if (level > 0 && currentCount > limit) { return(moves); } } } // First depth = randomize please if (level == 0 && limit > 0) { return(moves.OrderBy(m => Random.Range(0f, 1f)).Take(limit).ToList()); } return(moves); }
public List <PathFinderNode> FindPath(Location start, Location end, sbyte[,] direction) { PathFinderNode parentNode; bool found = false; int gridX = mGrid.GetUpperBound(0) + 1; int gridY = mGrid.GetUpperBound(1) + 1; int gridZ = mGrid.GetUpperBound(2) + 1; mStop = false; mStopped = false; mOpen.Clear(); mClose.Clear(); parentNode.G = 0; parentNode.H = mHEstimate; parentNode.F = parentNode.G + parentNode.H; parentNode.X = start.X; parentNode.Y = start.Y; parentNode.Z = start.Z; parentNode.PX = parentNode.X; parentNode.PY = parentNode.Y; parentNode.PZ = parentNode.Z; parentNode.Id = 0; parentNode.ANX = start.X; parentNode.ANY = start.Y; parentNode.ANZ = start.Z; //Clearance zone creation CLZChecker cLZChecker = null; if (mCLZdist != 0) { //Clearance zone creation RefCLZCreator refCLZCreator = new RefCLZCreator(mCLZdist); mClearanceZone = refCLZCreator.Create(); cLZChecker = new CLZChecker(mGrid, mClearanceZone); } mOpen.Push(parentNode); while (mOpen.Count > 0 && !mStop) { parentNode = mOpen.Pop(); if (parentNode.X == end.X && parentNode.Y == end.Y && parentNode.Z == end.Z) { mClose.Add(parentNode); found = true; break; } if (mClose.Count > mSearchLimit) { mStopped = true; return(null); } if (mPunishChangeDirection) { mHoriz = (parentNode.X - parentNode.PX); } //Lets calculate each successors for (int i = 0; i <= (mDiagonals ? 8 : direction.GetUpperBound(0)); i++) { PathFinderNode newNode; newNode.X = parentNode.X + direction[i, 0]; newNode.Y = parentNode.Y + direction[i, 1]; newNode.Z = parentNode.Z + direction[i, 2]; newNode.Id = 0; if (newNode.X < 0 || newNode.Y < 0 || newNode.Z < 0 || newNode.X >= gridX || newNode.Y >= gridY || newNode.Z >= gridZ) { continue; } int newG; if (mHeavyDiagonals && i > 3) { newG = parentNode.G + (int)(mGrid[newNode.X, newNode.Y, newNode.Z] * 2.41); } else { newG = parentNode.G + mGrid[newNode.X, newNode.Y, newNode.Z]; } //check point by obstacles and clerance zone if (cLZChecker != null) { if (!cLZChecker.CheckNode(newNode.X, newNode.Y, newNode.Z, gridX, gridY, gridZ)) { continue; } } else { if (mGrid[newNode.X, newNode.Y, newNode.Z] == 1) { continue; } } if (mCompactPath) { int cost = 2; if ((start.X == end.X) && (newNode.X - start.X) != 0) { if ((newNode.Y - parentNode.Y) != 0) { newG += cost; } } if (start.Y == end.Y && (newNode.Y - start.Y) != 0) { if ((newNode.X - parentNode.X) != 0) { newG += cost; } } if (start.Z == end.Z && (newNode.Z - start.Z) != 0) { if ((newNode.X - parentNode.X) != 0 || (newNode.Y - parentNode.Y) != 0) { newG += cost; } } } if (mPunishChangeDirection) { newG += PunishChangeDirectionChecker.GetNewG(newNode.X, newNode.Y, newNode.Z, parentNode, start, newG); } int foundInOpenIndex = -1; for (int j = 0; j < mOpen.Count; j++) { if (mOpen[j].X == newNode.X && mOpen[j].Y == newNode.Y && mOpen[j].Z == newNode.Z) { foundInOpenIndex = j; break; } } if (foundInOpenIndex != -1 && mOpen[foundInOpenIndex].G <= newG) { continue; } int foundInCloseIndex = -1; for (int j = 0; j < mClose.Count; j++) { if (mClose[j].X == newNode.X && mClose[j].Y == newNode.Y && mClose[j].Z == newNode.Z) { foundInCloseIndex = j; break; } } if (foundInCloseIndex != -1 && (mReopenCloseNodes || mClose[foundInCloseIndex].G <= newG)) { continue; } newNode.PX = parentNode.X; newNode.PY = parentNode.Y; newNode.PZ = parentNode.Z; newNode.G = newG; newNode.ANX = 0; newNode.ANY = 0; newNode.ANZ = 0; if (mANGlength != 0) { if (!NodesCheker.IfMinLength(mANGlength, parentNode, newNode.X, newNode.Y, newNode.Z)) { continue; } else { newNode.ANX = NodesCheker.newNodeANX; newNode.ANY = NodesCheker.newNodeANY; newNode.ANZ = NodesCheker.newNodeANZ; } } switch (mFormula) { default: case HeuristicFormula.Manhattan: newNode.H = mHEstimate * (Math.Abs(newNode.X - end.X) + Math.Abs(newNode.Y - end.Y) + Math.Abs(newNode.Z - end.Z)); break; case HeuristicFormula.MaxDXDY: newNode.H = mHEstimate * (Math.Max(Math.Abs(newNode.X - end.X), Math.Abs(newNode.Y - end.Y))); break; case HeuristicFormula.DiagonalShortCut: int h_diagonal = Math.Min(Math.Abs(newNode.X - end.X), Math.Abs(newNode.Y - end.Y)); int h_straight = (Math.Abs(newNode.X - end.X) + Math.Abs(newNode.Y - end.Y)); newNode.H = (mHEstimate * 2) * h_diagonal + mHEstimate * (h_straight - 2 * h_diagonal); break; case HeuristicFormula.Euclidean: newNode.H = (int)(mHEstimate * Math.Sqrt(Math.Pow((newNode.X - end.X), 2) + Math.Pow((newNode.Y - end.Y), 2))); break; case HeuristicFormula.EuclideanNoSQR: newNode.H = (int)(mHEstimate * (Math.Pow((newNode.X - end.X), 2) + Math.Pow((newNode.Y - end.Y), 2))); break; case HeuristicFormula.Custom1: Point dxy = new Point(Math.Abs(end.X - newNode.X), Math.Abs(end.Y - newNode.Y)); int Orthogonal = Math.Abs(dxy.X - dxy.Y); int Diagonal = Math.Abs(((dxy.X + dxy.Y) - Orthogonal) / 2); newNode.H = mHEstimate * (Diagonal + Orthogonal + dxy.X + dxy.Y); break; } if (mTieBreaker) { int dx1 = parentNode.X - end.X; int dy1 = parentNode.Y - end.Y; int dz1 = parentNode.Z - end.Z; int dx2 = start.X - end.X; int dy2 = start.Y - end.Y; int dz2 = start.Z - end.Z; int cross = Math.Abs(dx1 * dy2 - dx2 * dy1); //fix z here newNode.H = (int)(newNode.H + cross * 0.001); } newNode.F = newNode.G + newNode.H; mOpen.Push(newNode); } mClose.Add(parentNode); } if (found) { PathFinderNode fNode = mClose[mClose.Count - 1]; for (int i = mClose.Count - 1; i >= 0; i--) { if (fNode.PX == mClose[i].X && fNode.PY == mClose[i].Y && fNode.PZ == mClose[i].Z || i == mClose.Count - 1) { fNode = mClose[i]; } else { mClose.RemoveAt(i); } } mStopped = true; return(mClose); } mStopped = true; return(null); }
public void findPath() { Node currentNode; openList.Add(startingNode.GetHashCode(), startingNode); while (openList.Count > 0) { //lowest F value int minF = openList.Min(byF => byF.Value.F); //finds a new node to explore var check = openList.Where(nextNode => nextNode.Value.F == minF).OrderBy(nextNode => nextNode.Value.H).ToList(); currentNode = check.First().Value; //directions to search; sbyte[,] direction = new sbyte[8, 2] { { 0, -1 }, { 1, 1 }, { 0, 1 }, { 1, -1 }, { 1, 0 }, { -1, 1 }, { -1, 0 }, { -1, -1 } }; if (closedList.ContainsKey(endNode.GetHashCode())) { endNode = closedList[endNode.GetHashCode()]; grid[endNode.position.X, endNode.position.Y] = 2; displayPath(endNode); return; } for (int i = 0; i < 8; i++) { Point newNodePos = new Point(currentNode.position.X + direction[i, 0], currentNode.position.Y + direction[i, 1]); Node newNode = new Node(newNodePos, currentNode, travelCost[i % 2]); //outside the grid if (newNodePos.X < 0 || newNodePos.Y < 0 || newNodePos.X > grid.GetUpperBound(0) || newNodePos.Y > grid.GetUpperBound(1)) { continue; } //A wall(not walkable) if (grid[newNodePos.X, newNodePos.Y] == -1) { continue; } //fount the parent node if (currentNode.parentNode != null && newNodePos.Equals(currentNode.parentNode.position)) { continue; } //node already checked and closed if (closedList.ContainsKey(newNode.GetHashCode())) { continue; } //Checks the open list for nodes with the same position and returns null if nothing is found if (openList.ContainsKey(newNode.GetHashCode())) { //Changes an old node(if G > this.G) Node t = openList[newNode.GetHashCode()]; if (t.G > newNode.G) { openList[newNode.GetHashCode()] = newNode; } } else { //Adds a new node grid[newNode.position.X, newNode.position.Y] = 4; openList.Add(newNode.GetHashCode(), newNode); } if (!newNode.position.Equals(endNode.position)) { PathFinderDebug(newNode.position.X, newNode.position.Y, PathFinderNodeType.Open); } } closedList.Add(currentNode.GetHashCode(), currentNode); openList.Remove(currentNode.GetHashCode()); if (!(currentNode.position.Equals(startingNode.position) || currentNode.position.Equals(endNode.position))) { grid[currentNode.position.X, currentNode.position.Y] = 8; PathFinderDebug(currentNode.position.X, currentNode.position.Y, PathFinderNodeType.Close); } } }