private TileUsage[,] BuildTileUsageByMap(ref string[] layout) { var result = new TileUsage[this.WorldSize.X, this.WorldSize.Y]; foreach (var tdc in this._tileDefinitionCollections) { foreach (TilePos tp in tdc.Area.PointsInside()) { char symbol = layout[tp.Y][tp.X]; var tileDefinition = tdc[symbol]; TileUsage tu; switch (tileDefinition) { case TileWallDefinition _: tu = TileUsage.Wall(symbol); break; case TileFloorDefinition _: tu = TileUsage.Floor(symbol); break; case TileObjectDefinition objectDef: tu = TileUsage.Object(symbol, objectDef.Description); break; default: throw new InvalidOperationException(); } result[tp.X, tp.Y] = tu; } } return(result); }
private void ValidateGameState(ref string[] layout, GameState gameState) { var tileUsage = BuildTileUsageByMap(ref layout); var issues = new List <string>(); var cy = this.WorldSize.Y; var cx = this.WorldSize.X; for (int y = 0; y < cy; y++) { for (int x = 0; x < cx; x++) { var tp = new TilePos(x, y); var hasItems = gameState.GetItemsOnTile(tp).Any(); TileUsage t = tileUsage[x, y]; if (t.TileTypeByMap == TileTypeByMap.Object && !hasItems) { issues.Add(tp + ": Map had tile marked as occupied by an object '" + t.Description + "', but nothing is there."); } else if (t.TileTypeByMap == TileTypeByMap.Floor && hasItems) { var items = gameState.GetItemsOnTile(tp).ToList(); issues.Add(tp + ": Map had tile marked as unoccupied, but contains " + items.Count + " item(s): " + string.Join(", ", items.Select(item => item.GetType().Name)) + "."); } } } if (issues.Count == 0) { return; } var message = string.Join("\r\n", issues); Trace.WriteLine(message); var dr = MessageBox.Show(message, "Warnings", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); if (dr == DialogResult.Cancel) { throw new InvalidOperationException(message); } }