mirror of
https://github.com/Wessel/nhl-setgame.git
synced 2026-06-08 14:18:05 +02:00
feat: Clean up set checking, add load spinner
This commit is contained in:
@@ -56,7 +56,7 @@ public class Game {
|
|||||||
public bool GameIsFinished() {
|
public bool GameIsFinished() {
|
||||||
if (Deck == null || Hand == null) return false;
|
if (Deck == null || Hand == null) return false;
|
||||||
|
|
||||||
var finished = Deck.Length == 0 && Hand.Length < 12;
|
var finished = Deck.Length < 1 && Hand.Length < 12;
|
||||||
|
|
||||||
// Check if no sets can be made with the remaining cards
|
// Check if no sets can be made with the remaining cards
|
||||||
if (!finished && GetIndicesOfSet().Count == 0) {
|
if (!finished && GetIndicesOfSet().Count == 0) {
|
||||||
@@ -71,42 +71,43 @@ public class Game {
|
|||||||
return finished;
|
return finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: refactor`
|
public bool SetResult(ushort[] indices) {
|
||||||
public SetCheckResult? IsSet(ushort[] indices, bool remove = true) {
|
if (Hand == null || indices.Length != 3 || indices.Any(index => Hand[index] == 0)) {
|
||||||
if (remove) {
|
return false;
|
||||||
if (GameIsFinished()) {
|
|
||||||
FinishedAt = DateTime.UtcNow;
|
|
||||||
|
|
||||||
return new SetCheckResult { IsFinished = true, NewState = this };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indices.Length != 3 || Hand == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indices.Any(index => Hand[index] == 0)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var cards = indices
|
var cards = indices
|
||||||
.Select(index => Card.ToCard(Hand[index]))
|
.Select(index => Card.ToCard(Hand[index]))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (!(
|
return (
|
||||||
AllSameOrDifferent(cards[0].Shape, cards[1].Shape, cards[2].Shape) &&
|
AllSameOrDifferent(cards[0].Shape, cards[1].Shape, cards[2].Shape) &&
|
||||||
AllSameOrDifferent(cards[0].Color, cards[1].Color, cards[2].Color) &&
|
AllSameOrDifferent(cards[0].Color, cards[1].Color, cards[2].Color) &&
|
||||||
AllSameOrDifferent(cards[0].Shade, cards[1].Shade, cards[2].Shade) &&
|
AllSameOrDifferent(cards[0].Shade, cards[1].Shade, cards[2].Shade) &&
|
||||||
AllSameOrDifferent(cards[0].Count, cards[1].Count, cards[2].Count)
|
AllSameOrDifferent(cards[0].Count, cards[1].Count, cards[2].Count)
|
||||||
)) {
|
);
|
||||||
// todo(wessel): Split up for checking algorithm to game data
|
}
|
||||||
|
|
||||||
|
public SetCheckResult? IsSet(ushort[] indices) {
|
||||||
|
// Also check if finished before anything else, to prevent the board getting stuck
|
||||||
|
if (GameIsFinished()) {
|
||||||
|
FinishedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
return new SetCheckResult { IsFinished = true, NewState = this };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indices.Length != 3 || Hand == null || indices.Any(index => Hand[index] == 0)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetResult(indices)) {
|
||||||
Fails += 1;
|
Fails += 1;
|
||||||
return new SetCheckResult { IsSet = false, NewState = this };
|
return new SetCheckResult { IsSet = false, NewState = this };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order by Descending to make sure the correct card is removed
|
// Order by Descending to make sure the correct card is removed
|
||||||
// (From the top may cause the indices to be off by one)
|
// (From the top may cause the indices to be off by one)
|
||||||
if (remove) {
|
|
||||||
foreach (var index in indices.OrderByDescending(i => i)) {
|
foreach (var index in indices.OrderByDescending(i => i)) {
|
||||||
var foundList = Found.ToList();
|
var foundList = Found.ToList();
|
||||||
foundList.Add(Hand[index]);
|
foundList.Add(Hand[index]);
|
||||||
@@ -127,19 +128,17 @@ public class Game {
|
|||||||
while (GetIndicesOfSet().Count < 1 && Deck?.Length > 0) {
|
while (GetIndicesOfSet().Count < 1 && Deck?.Length > 0) {
|
||||||
DealHand(Hand.Length + 1);
|
DealHand(Hand.Length + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if finished after removing the set
|
||||||
|
if (GameIsFinished()) {
|
||||||
|
FinishedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
return new SetCheckResult { IsFinished = true, NewState = this };
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SetCheckResult { IsSet = true, NewState = this };
|
return new SetCheckResult { IsSet = true, NewState = this };
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool AllSameOrDifferent<T>(T a, T b, T c) where T : Enum {
|
|
||||||
int ai = Convert.ToInt32(a);
|
|
||||||
int bi = Convert.ToInt32(b);
|
|
||||||
int ci = Convert.ToInt32(c);
|
|
||||||
|
|
||||||
return (ai == bi && bi == ci) || (ai != bi && bi != ci && ai != ci);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<int[]> GetIndicesOfSet() {
|
public List<int[]> GetIndicesOfSet() {
|
||||||
if (Hand == null) return new List<int[]>();
|
if (Hand == null) return new List<int[]>();
|
||||||
List<int[]> res = new List<int[]>();
|
List<int[]> res = new List<int[]>();
|
||||||
@@ -147,9 +146,9 @@ public class Game {
|
|||||||
for (int i = 0; i < Hand.Length; i++) {
|
for (int i = 0; i < Hand.Length; i++) {
|
||||||
for (int j = i + 1; j < Hand.Length; j++) {
|
for (int j = i + 1; j < Hand.Length; j++) {
|
||||||
for (int k = j + 1; k < Hand.Length; k++) {
|
for (int k = j + 1; k < Hand.Length; k++) {
|
||||||
var result = IsSet([(ushort)i, (ushort)j, (ushort)k], false);
|
var result = SetResult([(ushort)i, (ushort)j, (ushort)k]);
|
||||||
|
|
||||||
if (result?.IsSet == true) {
|
if (result == true) {
|
||||||
Console.WriteLine($"Found set at {i}, {j}, {k}");
|
Console.WriteLine($"Found set at {i}, {j}, {k}");
|
||||||
res.Add([i, j, k]);
|
res.Add([i, j, k]);
|
||||||
}
|
}
|
||||||
@@ -159,4 +158,12 @@ public class Game {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool AllSameOrDifferent<T>(T a, T b, T c) where T : Enum {
|
||||||
|
int ai = Convert.ToInt32(a);
|
||||||
|
int bi = Convert.ToInt32(b);
|
||||||
|
int ci = Convert.ToInt32(c);
|
||||||
|
|
||||||
|
return (ai == bi && bi == ci) || (ai != bi && bi != ci && ai != ci);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<div class="text-gray-200 flex flex-col md:flex-row w-[90%] mx-auto">
|
<div class="text-gray-200 flex flex-col md:flex-row w-[90%] mx-auto">
|
||||||
|
@if (games) {
|
||||||
<table class="game-table mx-auto w-[90%] mt-15 mb-5 text-xs">
|
<table class="game-table mx-auto w-[90%] mt-15 mb-5 text-xs">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -21,4 +22,10 @@
|
|||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
} @else {
|
||||||
|
<div class="mt-15 flex flex-col items-center w-[90%] mx-auto">
|
||||||
|
<div class="w-16 h-16 border-t-4 border-blue-500 border-solid rounded-full animate-spin"></div>
|
||||||
|
<p class="mt-4">Loading games...</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -10,15 +10,11 @@ import { CommonModule } from '@angular/common';
|
|||||||
styleUrl: './game-list.component.scss'
|
styleUrl: './game-list.component.scss'
|
||||||
})
|
})
|
||||||
export class GameListComponent {
|
export class GameListComponent {
|
||||||
games: { id: number, startedAt: Date, finishedAt: Date | null, fails: number, hand: any[], deck: any[] }[] = [];
|
games: { id: number, startedAt: Date, finishedAt: Date | null, fails: number, hand: any[], deck: any[] }[] | undefined;
|
||||||
constructor(public userService: UserDataService, private router: Router) { this.getGames() }
|
constructor(public userService: UserDataService, private router: Router) { this.getGames() }
|
||||||
|
|
||||||
async getGames() {
|
async getGames() {
|
||||||
this.games = await this.userService.getGames();
|
this.games = await this.userService.getGames();
|
||||||
console.log('gamesfromservice ' + this.userService.getGames())
|
|
||||||
|
|
||||||
console.log('games' + this.games);
|
|
||||||
// return this.userService.getGames();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enterGame(game: number) {
|
enterGame(game: number) {
|
||||||
|
|||||||
@@ -39,6 +39,12 @@
|
|||||||
(click)="selectCard(card)"
|
(click)="selectCard(card)"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@empty() {
|
||||||
|
<div class="flex flex-col items-center justify-center h-full col-span-full row-span-full">
|
||||||
|
<div class="w-16 h-16 border-t-4 border-blue-500 border-solid rounded-full animate-spin"></div>
|
||||||
|
<p class="mt-4">Loading cards...</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stats w-full md:w-2/5">
|
<div class="stats w-full md:w-2/5">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import axios from 'axios';
|
import axios, { AxiosError } from 'axios';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
|||||||
Reference in New Issue
Block a user