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) {