diff --git a/backend/backend/Migrations/20250311160942_HintsnFound.Designer.cs b/backend/backend/Migrations/20250311160942_HintsnFound.Designer.cs new file mode 100644 index 0000000..a3369bf --- /dev/null +++ b/backend/backend/Migrations/20250311160942_HintsnFound.Designer.cs @@ -0,0 +1,66 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using backend.Models; + +#nullable disable + +namespace backend.Migrations +{ + [DbContext(typeof(GameContext))] + [Migration("20250311160942_HintsnFound")] + partial class HintsnFound + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("backend.Models.Game", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.PrimitiveCollection("Deck") + .HasColumnType("integer[]"); + + b.Property("Fails") + .HasColumnType("integer"); + + b.Property("FinishedAt") + .HasColumnType("timestamp with time zone"); + + b.PrimitiveCollection("Found") + .HasColumnType("integer[]"); + + b.PrimitiveCollection("Hand") + .HasColumnType("integer[]"); + + b.Property("Hints") + .HasColumnType("integer"); + + b.Property("StartedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("CURRENT_TIMESTAMP"); + + b.HasKey("Id"); + + b.ToTable("Games"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/backend/Migrations/20250311160942_HintsnFound.cs b/backend/backend/Migrations/20250311160942_HintsnFound.cs new file mode 100644 index 0000000..190d0c5 --- /dev/null +++ b/backend/backend/Migrations/20250311160942_HintsnFound.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace backend.Migrations +{ + /// + public partial class HintsnFound : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Found", + table: "Games", + type: "integer[]", + nullable: true); + + migrationBuilder.AddColumn( + name: "Hints", + table: "Games", + type: "integer", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Found", + table: "Games"); + + migrationBuilder.DropColumn( + name: "Hints", + table: "Games"); + } + } +} diff --git a/backend/backend/Migrations/GameContextModelSnapshot.cs b/backend/backend/Migrations/GameContextModelSnapshot.cs index a105ccd..907a568 100755 --- a/backend/backend/Migrations/GameContextModelSnapshot.cs +++ b/backend/backend/Migrations/GameContextModelSnapshot.cs @@ -39,9 +39,15 @@ namespace backend.Migrations b.Property("FinishedAt") .HasColumnType("timestamp with time zone"); + b.PrimitiveCollection("Found") + .HasColumnType("integer[]"); + b.PrimitiveCollection("Hand") .HasColumnType("integer[]"); + b.Property("Hints") + .HasColumnType("integer"); + b.Property("StartedAt") .ValueGeneratedOnAdd() .HasColumnType("timestamp with time zone") diff --git a/backend/backend/Models/Game.cs b/backend/backend/Models/Game.cs index bfe0b45..8ca1638 100755 --- a/backend/backend/Models/Game.cs +++ b/backend/backend/Models/Game.cs @@ -11,8 +11,10 @@ public class Game { public DateTime StartedAt { get; set; } public DateTime? FinishedAt { get; set; } public int Fails { get; set; } + public int Hints { get; set; } public ushort[]? Hand { get; set; } public ushort[]? Deck { get; set; } + public ushort[]? Found { get; set; } public void ShuffleDeck() { if (Deck == null) return; @@ -54,7 +56,12 @@ public class Game { public bool GameIsFinished() { if (Deck == null || Hand == null) return false; - var finished = Deck.Length == 0 && Hand.All(card => card == 0); + var finished = Deck.Length == 0 && Hand.Length < 12; + + // Check if no sets can be made with the remaining cards + if (!finished && GetIndicesOfSet().Count == 0) { + finished = true; + } // Empty hand if game is finished for optimal database space usage if (finished) { @@ -64,11 +71,14 @@ public class Game { return finished; } +// todo: refactor` public SetCheckResult? IsSet(ushort[] indices, bool remove = true) { - if (GameIsFinished()) { - FinishedAt = DateTime.Now; + if (remove) { + if (GameIsFinished()) { + FinishedAt = DateTime.UtcNow; - return new SetCheckResult { IsFinished = true, NewState = this }; + return new SetCheckResult { IsFinished = true, NewState = this }; + } } if (indices.Length != 3 || Hand == null) { @@ -98,7 +108,17 @@ public class Game { // (From the top may cause the indices to be off by one) if (remove) { foreach (var index in indices.OrderByDescending(i => i)) { - ReplaceCardInHand(index); + Console.WriteLine(Hand.Length); + if (Hand.Length < 13) + { + ReplaceCardInHand(index); + } + else + { + var handList = Hand.ToList(); + handList.RemoveAt(index); + Hand = handList.ToArray(); + } } while (GetIndicesOfSet().Count < 1 && Deck?.Length > 0) {