pull/1/head
ludovic.castglia 8 months ago
parent 77455796c4
commit 9e0b8ad710

@ -4,7 +4,7 @@ import { HttpClientModule } from '@angular/common/http';
import { BookFormComponent } from './components/book-form/book-form.component';
import { BookListComponent } from './components/book-list/book-list.component';
import { BookMenuComponent } from './components/book-menu/book-menu.component';
import { BookMenuComponent } from './components/book-menu/book-menu.component';
import { UserService } from './services/user-service';
@ -13,6 +13,8 @@ import { User } from './models/user.model';
import { BookService } from './services/book-service';
import { Book } from './models/book.model';
import { SudokuService } from "./services/sudoku-service"
@Component({
selector: 'app-root',
standalone: true,
@ -20,13 +22,14 @@ import { Book } from './models/book.model';
templateUrl: './app.component.html',
providers: [
BookService,
UserService
UserService,
SudokuService,
]
})
export class AppComponent {
title = 'angular-tp2-correct';
constructor(protected bookService: BookService, protected userService: UserService){ }
constructor(protected bookService: BookService, protected userService: UserService, protected sudokuService: SudokuService){ }
addBook($event: Book): void {
this.bookService.addBook($event);

@ -6,6 +6,7 @@ import { BookHomeComponent } from './components/book-home/book-home.component';
import { LoginComponent } from './components/login/login.component';
import { UserListComponent } from './components/user-list/user-list.component';
import { UserDetailComponent } from './components/user-detail/user-detail.component';
import { SudokuComponent } from './components/sudoku/sudoku.component';
export const routes: Routes = [
{ path: '', component: LoginComponent },
@ -14,5 +15,6 @@ export const routes: Routes = [
{ path: 'book/:id', component: BookDetailComponent },
{ path: 'users', component: UserListComponent },
{ path: 'user/:id', component: UserDetailComponent },
{ path: 'sudoku/:difficulty', component: SudokuComponent },
{ path: '**', redirectTo: '', pathMatch: 'full' }
];

@ -0,0 +1,76 @@
:host {
--cellSize: 50px;
--color1: #f00;
--color2: #0f0;
--color3: #00f;
--color4: #ff0;
--color5: #f0f;
--color6: #0ff;
--color7: #f77;
--color8: #7f7;
--color9: #77f;
}
.grille {
position: absolute;
left: 50%;
transform: translate(-50%);
}
.cell::-webkit-outer-spin-button,
.cell::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
.cell[type=number] {
-moz-appearance: textfield;
}
.cell {
height: var(--cellSize);
width: var(--cellSize);
text-align: center;
outline: none;
}
.grille {
display: flex;
}
.column:nth-child(-n+9) div:nth-child(-n+9) {
border: solid 1px var(--color1);
}
.column:nth-child(-n+9) div:nth-child(-n+6) {
border: solid 1px var(--color2);
}
.column:nth-child(-n+9) div:nth-child(-n+3) {
border: solid 1px var(--color3);
}
.column:nth-child(-n+6) div:nth-child(-n+9) {
border: solid 1px var(--color4);
}
.column:nth-child(-n+6) div:nth-child(-n+6) {
border: solid 1px var(--color5);
}
.column:nth-child(-n+6) div:nth-child(-n+3) {
border: solid 1px var(--color6);
}
.column:nth-child(-n+3) div:nth-child(-n+9) {
border: solid 1px var(--color7);
}
.column:nth-child(-n+3) div:nth-child(-n+6) {
border: solid 1px var(--color8);
}
.column:nth-child(-n+3) div:nth-child(-n+3) {
border: solid 1px var(--color9);
}

@ -0,0 +1,19 @@
<p>sudoku works!</p>
<div class="grille">
<div *ngFor="let row of grille" class="column">
<div *ngFor="let cell of row" class="row">
<input *ngIf="cell != 0" type="number" value="{{cell}}" class="cell" max="9" min="0">
<input *ngIf="cell == 0" type="number" value="" class="cell" max="9" min="0">
</div>
</div>
</div>
<button (click)="publish()">
valider la grille
</button>
<button (click)="corriger()">
corriger la grille
</button>

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SudokuComponent } from './sudoku.component';
describe('SudokuComponent', () => {
let component: SudokuComponent;
let fixture: ComponentFixture<SudokuComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [SudokuComponent]
})
.compileComponents();
fixture = TestBed.createComponent(SudokuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,46 @@
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { NgFor,NgIf } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
import { SudokuService } from '../../services/sudoku-service';
@Component({
selector: 'app-sudoku',
standalone: true,
imports: [RouterModule, NgFor, NgIf],
templateUrl: './sudoku.component.html',
styleUrl: './sudoku.component.css'
})
export class SudokuComponent {
grille: number[][] = [];
nbIndice: number = 0;
constructor(protected sudokuService: SudokuService, private activatedRoute: ActivatedRoute) {
}
ngOnInit() {
const difficulty = this.activatedRoute.snapshot.params["difficulty"];
switch (difficulty) {
case 'easy':
this.grille = this.sudokuService.getEasy();
break;
case 'medium':
this.grille = this.sudokuService.getMedium();
break;
case 'hard':
this.grille = this.sudokuService.getHard();
break;
default:
this.grille = this.sudokuService.getEasy();
break;
}
console.log(this.grille);
}
public publish() {
}
public corriger() {
}
}

@ -1,7 +1,25 @@
<h2>User list</h2>
<ul>
<li *ngFor="let user of users">
<a routerLink="/user/{{ user.id }}">{{ user.login }}</a>
</li>
</ul>
<thead>
<tr>
<th scope="col">Pseudo</th>
<th scope="col" (click)="changeWatchedvar('nbPts')">Nombre de points</th>
<th scope="col" (click)="changeWatchedvar('streak')">Streak</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users">
<td >{{user.login}}</td>
<td>{{user.points}}</td>
<td>{{user.streak}}</td>
</tr>
</tbody>
<br>
<button (click)="loadPage(-1)">
<
</button>
<button (click)="loadPage(1)">
>
</button>

@ -14,11 +14,41 @@ import { UserService } from '../../services/user-service';
})
export class UserListComponent {
users: User[] = [];
nbPage: number = 0;
sortBy: string = "nbPts";
sortSens: number = 1;
constructor(protected userService: UserService) {
}
ngOnInit() {
this.nbPage = 1;
this.users = this.userService.getAll();
this.loadPage(0);
console.log(this.users);
}
public changeWatchedvar(newVar:string) {
if (this.sortBy == newVar) this.sortSens -= 2*this.sortSens;
this.sortBy = newVar;
this.nbPage = 1;
this.loadPage(0);
}
public loadPage(nb: number) {
if (this.nbPage + nb > this.userService.getNbPage() || this.nbPage + nb <= 0) {return;}
this.nbPage += nb;
switch(this.sortBy) {
case 'nbPts':
this.users = this.userService.getUserNbPts(this.nbPage,this.sortSens);
break
case 'streak':
this.users = this.userService.getUserNbStreak(this.nbPage,this.sortSens);
break;
default:
this.users = this.userService.getUserNbStreak(this.nbPage,this.sortSens);
break;
}
}
}

@ -32,7 +32,7 @@ export class BookService {
}
private addBookToLocal(book: Book): void{
console.log('addBookToLocal', book);
//console.log('addBookToLocal', book);
if(book.id === 0){
book.id = Math.max(...this.books.map(b => b.id)) + 1;
}

@ -0,0 +1,75 @@
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from "@angular/core";
@Injectable()
export class SudokuService {
private correction: number[][];
private easy: number[][];
private medium: number[][];
private hard: number[][];
private readonly userApiUrl = 'https://sudoku-game-and-api.netlify.app/api/sudoku';
public constructor(private http: HttpClient){
this.correction = [];
this.easy = [];
this.medium = [];
this.hard = [];
this.http.get<string>(this.userApiUrl).subscribe(apiResponse => {
let jsonResponse = JSON.parse(apiResponse);
this.correction = jsonResponse["data"];
this.easy = jsonResponse["easy"];
this.medium = jsonResponse["medium"];
this.hard = jsonResponse["hard"];
});
this.correction = [[3,8,7,1,2,6,5,4,9],[2,1,6,9,4,5,8,7,3],[5,9,4,3,8,7,6,2,1],[4,2,8,5,9,1,7,3,6],[7,5,1,2,6,3,9,8,4],[6,3,9,8,7,4,1,5,2],[1,7,5,6,3,2,4,9,8],[9,4,3,7,1,8,2,6,5],[8,6,2,4,5,9,3,1,7]];
this.easy = [[3,8,0,1,2,0,5,0,9],[2,1,6,9,0,0,8,0,0],[5,9,4,3,8,0,0,0,1],[4,2,8,5,0,0,7,3,6],[7,5,1,2,6,3,9,0,4],[0,3,0,0,0,0,1,5,2],[1,7,5,6,3,0,4,9,0],[9,4,3,0,1,8,0,0,5],[8,6,0,4,5,0,3,1,7]];
this.medium = [[3,0,0,0,0,0,0,4,0],[0,1,6,0,4,5,0,0,3],[0,9,0,3,8,0,0,2,0],[4,2,0,5,0,0,0,3,6],[7,5,0,2,6,0,0,8,4],[0,0,0,0,0,0,0,5,0],[1,0,5,6,3,0,0,9,8],[0,0,0,7,1,8,0,6,5],[0,0,2,4,0,0,0,0,0]];
this.hard = [[0,0,0,1,0,0,0,0,0],[0,1,6,9,0,0,8,0,0],[0,0,0,0,8,0,6,0,0],[0,0,0,5,0,0,0,0,0],[0,0,0,0,6,3,0,0,0],[0,0,0,0,0,0,0,0,0],[0,7,5,0,0,0,0,0,0],[9,0,3,0,0,0,0,0,5],[8,0,0,0,5,0,3,1,0]];
}
public getCorrection(): number[][]{
return this.correction;
}
public getEasy(): number[][]{
return this.easy;
}
public getMedium(): number[][]{
return this.medium;
}
public getHard(): number[][]{
return this.hard;
}
public validationGrille(userGrille: number[][]): number[][] {
let validation: number[][] = [];
for (let x:number = 0; x<userGrille.length; x++) {
validation.push([]);
for (let y:number = 0; y<userGrille[x].length; y++) {
if (userGrille[x][y] == 0) {
validation[x].push(0);
}
if (userGrille[x][y] == this.correction[x][y]) {
validation[x].push(1);
} else {
validation[x].push(-1);
}
}
}
return validation;
}
public isCorrect(userGrille: number[][]): boolean {
for (let x:number = 0; x<userGrille.length; x++) {
for (let y:number = 0; y<userGrille[x].length; y++) {
if (userGrille[x][y] == 0 || userGrille[x][y] != this.correction[x][y]) return true;
}
}
return true;
}
}

@ -6,6 +6,7 @@ import { User } from "../models/user.model";
export class UserService {
private users: User[];
private readonly userApiUrl = 'https://664ba07f35bbda10987d9f99.mockapi.io/api/users';
private pageSize: number = 5;
public constructor(private http: HttpClient){
this.users = [];
@ -29,8 +30,51 @@ export class UserService {
});
}
public getNbPage(): number {
return Math.ceil(this.users.length / this.pageSize)
}
public getUserNbPts(nbPage:number, sortSens:number): User[] {
if (nbPage>this.getNbPage() || nbPage<=0) return[];
let page = this.HardCopy(this.users);
page = page.sort((a,b) => {
if (a.points == null || b.points == null) return 0;
if (a.points>b.points) return 1*sortSens;
if (b.points>a.points) return -1*sortSens;
return 0;
});
page = this.getSubset(page,(nbPage-1)*this.pageSize,nbPage*this.pageSize);
return page;
}
public getUserNbStreak(nbPage:number, sortSens:number): User[] {
if (nbPage>this.getNbPage() || nbPage<=0) return[];
let page = this.HardCopy(this.users);
page = page.sort((a,b) => {
if (a.streak == null || b.streak == null) return 0
if (a.streak>b.streak) return 1*sortSens;
if (b.streak>a.streak) return -1*sortSens;
return 0;
});
page = this.getSubset(page,(nbPage-1)*this.pageSize,nbPage*this.pageSize);
return page;
}
private addUserToLocal(user: User): void{
console.log('addBookToLocal', user);
this.users.push(user);
}
private HardCopy(users: User[]):User[] {
return JSON.parse(JSON.stringify(users));
}
private getSubset(user: User[],deb:number,fin:number):User[] {
let a: User[] = [];
for (let i=0; i<user.length; i++) {
if (deb<=i && fin>i) {
a.push(user[i]);
}
}
return a;
}
}
Loading…
Cancel
Save