public void TestWinningCondition() { // 1x1 map int w = 1; int h = 1; IMapGenerator mapGenerator = MapGeneratorFactory.CreateOpenMapGenerator(); Map map = mapGenerator.GenerateMap(w, h, IMapGeneratorConstants.NO_SEED); // place player AbstractPlayer player = AIPlayerFactory.CreateEmptyAIPlayer("Test empty AI", map.Grid[0, 0]); // create game instance Game game = new Game() { GameMap = map }; game.AddAIPlayer(player); // perform one game loop step game.GameLoopStep(); // check winner Assert.IsTrue(game.IsWinner, "No winner after game loop step!"); Assert.IsNotNull(game.Winner, "Winner is null!"); }
/// <summary> /// Generates new game with given parameters. If aiCount+1 (1 for human player) is greater than width*heght, exception is thrown. /// </summary> /// <param name="width">Width of the map.</param> /// <param name="height">Height of the map.</param> /// <param name="mapSeed">Map seed.</param> /// <param name="aiCount">Number of AIs (simple AI is used).</param> /// <param name="monsterDensity">Density of monsters 0..1</param> /// <param name="itemDensity">Density of items 0..1</param> /// <param name="humanPlayerName">Name of the human player.</param> /// <returns>Generated game instance.</returns> public static Game GenerateGame(int width, int height, int mapSeed, int aiCount, double monsterDensity, double itemDensity, string humanPlayerName) { // check if (aiCount + 1 > width * height) { throw new Exception($"Počet protihráčů {aiCount} je na plochu {width}x{height} moc velký!"); } Map.Map gameMap = MapGeneratorFactory.CreateSimpleMapGenerator().GenerateMap(width, height, mapSeed); Game game = new Game() { GameMap = gameMap }; Random r = new Random(); // sets of occupied position for creatures and items, '{x}:{y}' HashSet <String> creatureOccupiedPositions = new HashSet <string>(); HashSet <string> itemsOccupiedPositions = new HashSet <string>(); // place human player int x = r.Next(width); int y = r.Next(height); AbstractPlayer player = new HumanPlayer(humanPlayerName, gameMap.Grid[x, y]); game.AddHumanPlayer(player); creatureOccupiedPositions.Add($"{x}:{y}"); // place AI players int pCount = 1; AddObjectsToGame(width, height, aiCount, 20, (ox, oy) => { if (!creatureOccupiedPositions.Contains($"{ox}:{oy}")) { game.AddAIPlayer(AIPlayerFactory.CreateSimpleAIPLayer($"Simple AI Player {pCount}", gameMap.Grid[ox, oy])); creatureOccupiedPositions.Add(($"{ox}:{oy}")); pCount++; return(true); } else { return(false); } }); // monster count from density: // density is expected to be in range 0..1 and will be mapped to the count of remaining free map blocks // this number is then lowered to 2/3 and this result is used as a base // then monsterCount = base + random.next(base/3) double monsterCountBase = 2 * (monsterDensity * (width * height - aiCount)) / 3; int monsterCount = (int)(monsterCountBase + r.NextDouble() * (monsterCountBase / 3)); // place monsters AddObjectsToGame(width, height, monsterCount, 20, (ox, oy) => { if (!creatureOccupiedPositions.Contains($"{ox}:{oy}")) { game.AddMonster(MonsterFactory.CreateRandomMonster(gameMap.Grid[ox, oy])); creatureOccupiedPositions.Add(($"{ox}:{oy}")); return(true); } else { return(false); } }); // item count is calculated the same way as monster count is double itemCountBase = 2 * (itemDensity * (width * height - aiCount)) / 3; int itemCount = (int)(itemCountBase + r.NextDouble() * (itemCountBase / 3)); // place items AddObjectsToGame(width, height, itemCount, 20, (ox, oy) => { if (!itemsOccupiedPositions.Contains($"{ox}:{oy}")) { game.AddItem(ItemFactory.CreateRandomItem(gameMap.Grid[ox, oy])); itemsOccupiedPositions.Add(($"{ox}:{oy}")); return(true); } else { return(false); } }); return(game); }
/// <summary> /// Places SelectedToolboxItem to the map. If no item is selected, nothing happnes. /// /// If the map block is occupied, coordinates are out of range, map is null or item type is unknown, exception is raised. /// /// </summary> /// <param name="mapX">X coordinate of map block to place this item.</param> /// <param name="mapY">Y coordinate of map block to place this item.</param> public void PlaceSelectedToolboxItem(int mapX, int mapY) { EditorToolboxItem item = SelectedToolboxItem; // no item selected => do nothing if (item == null) { return; } if (GameMap == null) { throw new Exception("Není herní mapa!"); } else if (mapX < 0 || mapX >= GameMap.Width || mapY < 0 || mapY >= GameMap.Height) { throw new Exception($"[{mapX},{mapY}] není v rozsahu mapy!"); } else if ((item.ItemType == EditorToolboxItemType.AI_PLAYER || item.ItemType == EditorToolboxItemType.MONSTER) && GameMap.Grid[mapX, mapY].Occupied) { throw new Exception($"Na pozici [{mapX},{mapY}] už je umístěn hráč, nebo monstrum!"); } else if ((item.ItemType == EditorToolboxItemType.ITEM || item.ItemType == EditorToolboxItemType.ARMOR || item.ItemType == EditorToolboxItemType.WEAPON) && GameMap.Grid[mapX, mapY].Item != null) { throw new Exception($"Na pozici [{mapX},{mapY}] už je umístěn předmět!"); } int uid = -1; switch (item.ItemType) { case EditorToolboxItemType.HUMAN_PLAYER: if (HumanPlayerPlaced) { throw new Exception("Na hrací plochu lze umístit pouze jednoho lidského hráče!"); } GameMap.Grid[mapX, mapY].Creature = new HumanPlayer("Human player", GameMap.Grid[mapX, mapY]); uid = GameMap.Grid[mapX, mapY].Creature.UniqueId; HumanPlayerPlaced = true; break; case EditorToolboxItemType.AI_PLAYER: GameMap.Grid[mapX, mapY].Creature = AIPlayerFactory.CreateSimpleAIPLayer("Simple AI Player", GameMap.Grid[mapX, mapY]); uid = GameMap.Grid[mapX, mapY].Creature.UniqueId; break; case EditorToolboxItemType.MONSTER: GameMap.Grid[mapX, mapY].Creature = MonsterFactory.CreateRandomMonster(GameMap.Grid[mapX, mapY]); uid = GameMap.Grid[mapX, mapY].Creature.UniqueId; break; case EditorToolboxItemType.ITEM: GameMap.Grid[mapX, mapY].Item = ItemFactory.CreateBasicItem(GameMap.Grid[mapX, mapY]); uid = GameMap.Grid[mapX, mapY].Item.UniqueId; break; case EditorToolboxItemType.ARMOR: GameMap.Grid[mapX, mapY].Item = ItemFactory.CreateLeatherArmor(GameMap.Grid[mapX, mapY]); uid = GameMap.Grid[mapX, mapY].Item.UniqueId; break; case EditorToolboxItemType.WEAPON: GameMap.Grid[mapX, mapY].Item = ItemFactory.CreateAxe(GameMap.Grid[mapX, mapY]); uid = GameMap.Grid[mapX, mapY].Item.UniqueId; break; default: throw new Exception($"Neznámý typ umisťovaného předmětu: {item.ItemType}!"); } EditorToolboxItem placedItem = item.Clone(); placedItem.UID = uid; PlacedItems.Add(placedItem); OnPropertyChanged("PlacedItems"); }