Make room system generic

This commit is contained in:
Stone_Red
2024-02-04 20:25:30 +01:00
parent 8096f95f04
commit 6734d64e99
9 changed files with 68 additions and 29 deletions
+4 -2
View File
@@ -302,8 +302,6 @@ node_modules/
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
@@ -396,3 +394,7 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
# SQLite
/src/TextLore/games.sqlite-shm
/src/TextLore/games.sqlite-wal
@@ -4,5 +4,5 @@ namespace TextLore.Database;
public class GamesDatabaseContext(DbContextOptions<GamesDatabaseContext> options) : DbContext(options)
{
public DbSet<Games.Roguelike.Models.RoomDefinition> RoguelikeRooms { get; set; }
public DbSet<Games.Roguelike.Models.RoomDefinition> Rooms { get; set; }
}
@@ -19,12 +19,12 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
Level level = new Level(size, seed);
Queue<Room> generationQueue = new Queue<Room>();
RoomDefinition startRoomDefinition = await GetRandomRoomDefinition() ?? throw new InvalidOperationException("No rooms found in the database.");
RoomDefinition startRoomDefinition = await GetRandomRoomDefinition(level) ?? throw new InvalidOperationException("No rooms found in the database.");
Position startRoomPosition = new Position(seed.Next(0, size.Width), seed.Next(0, size.Height));
Room startRoom = new Room(startRoomPosition, startRoomDefinition);
level.AddRoom(startRoom);
_ = level.AddRoom(startRoom);
generationQueue.Enqueue(startRoom);
while (generationQueue.Count > 0)
@@ -43,11 +43,11 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
if (level.IsPositionInBounds(newPosition) && level.GetRoom(newPosition) is null)
{
RoomDefinition? newRoomDefinition = await GetRandomRoomDefinition();
RoomDefinition? newRoomDefinition = await GetRandomRoomDefinition(level);
Room newRoom = new Room(newPosition, newRoomDefinition ?? throw new InvalidOperationException("No rooms found in the database."));
level.AddRoom(newRoom);
_ = level.AddRoom(newRoom);
generationQueue.Enqueue(newRoom);
}
}
@@ -74,7 +74,7 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
return level;
}
private async Task<RoomDefinition?> GetRandomRoomDefinition()
private async Task<RoomDefinition?> GetRandomRoomDefinition(Level level)
{
RoomDefinition? room = null;
int randomRoomIndex = seed.Next();
@@ -87,6 +87,11 @@ public class LevelGenerator(DeterministicRandom seed, IQueryable<RoomDefinition>
{
room = await rooms.FirstOrDefaultAsync(x => x.Id == randomRoomIndex);
if (room?.Tag == RoomTag.Unique && level.RoomExists(room))
{
room = null;
}
if (room is not null)
{
break;
+19 -2
View File
@@ -22,14 +22,26 @@ public class Level(Size size, DeterministicRandom seed)
return rooms;
}
public void AddRoom(Room room)
public bool AddRoom(Room room)
{
if (!IsRoomInBounds(room))
{
throw new InvalidOperationException("Room is out of bounds.");
return false;
}
if (room.Definition.Tag == RoomTag.Unique && RoomExists(room.Definition))
{
return false;
}
if (room.Definition.Tag == RoomTag.Start && rooms.Values.Any(r => r.Definition.Tag == RoomTag.Start))
{
return false;
}
rooms[room.Position] = room;
return true;
}
public bool IsPositionInBounds(Position point)
@@ -47,6 +59,11 @@ public class Level(Size size, DeterministicRandom seed)
return rooms.ContainsKey(point);
}
public bool RoomExists(RoomDefinition definition)
{
return rooms.Values.Any(r => r.Definition.Id == definition.Id);
}
public void ClearRoom(Position point)
{
_ = rooms.Remove(point);
@@ -1,14 +1,22 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace TextLore.Games.Roguelike.Models;
public class RoomDefinition(string name)
[PrimaryKey(nameof(Id), nameof(Tag), nameof(Game))]
public class RoomDefinition(int id, RoomTag tag, string game)
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
[Column(Order = 0)]
public int Id { get; } = id;
[Required]
public string Name { get; set; } = name;
[Column(Order = 1)]
public RoomTag Tag { get; } = tag;
[Column(Order = 2)]
public string Game { get; } = game;
public required string Name { get; set; }
public string Script { get; set; } = string.Empty;
}
@@ -0,0 +1,9 @@
namespace TextLore.Games.Roguelike.Models;
public enum RoomTag
{
None = 0,
Start = 1,
End = 2,
Unique = 3
}
@@ -37,7 +37,7 @@ public partial class RoguelikePage
{
if (firstRender)
{
await console.Execute(new GenerateLevelCommand(DatabaseContext.RoguelikeRooms, NavigationManager, OnLevelGenerated), Seed);
await console.Execute(new GenerateLevelCommand(DatabaseContext.Rooms, NavigationManager, OnLevelGenerated), Seed);
}
}
}
+9 -11
View File
@@ -28,17 +28,15 @@ GamesDatabaseContext databaseContext = serviceScope.ServiceProvider.GetRequiredS
if (await databaseContext.Database.EnsureCreatedAsync())
{
databaseContext.RoguelikeRooms.AddRange(
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 1"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 2"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 3"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 4"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 5"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 6"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 7"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 8"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 9"),
new TextLore.Games.Roguelike.Models.RoomDefinition("Room 10")
databaseContext.Rooms.AddRange(
new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.Start, "rogelike") { Name = "Start Room" },
new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Unique Room" },
new TextLore.Games.Roguelike.Models.RoomDefinition(2, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 1" },
new TextLore.Games.Roguelike.Models.RoomDefinition(3, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 2" },
new TextLore.Games.Roguelike.Models.RoomDefinition(4, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 3" },
new TextLore.Games.Roguelike.Models.RoomDefinition(5, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 4" },
new TextLore.Games.Roguelike.Models.RoomDefinition(6, TextLore.Games.Roguelike.Models.RoomTag.Unique, "rogelike") { Name = "Normal Room 5" },
new TextLore.Games.Roguelike.Models.RoomDefinition(1, TextLore.Games.Roguelike.Models.RoomTag.End, "rogelike") { Name = "End Room" }
);
_ = await databaseContext.SaveChangesAsync();
Binary file not shown.