From 4c985cd734478d9c1851fb6b73bb9962f69b74bd Mon Sep 17 00:00:00 2001 From: Nifle CGE Date: Mon, 22 Sep 2025 16:49:25 +0200 Subject: [PATCH 1/2] =?UTF-8?q?readme=20etu=20+=20format=20+=20test=20pr?= =?UTF-8?q?=C3=A9c=C3=A9dent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README ETUDIANTS.md | 6 + src/12_RefactoringGolf/exo5/README.md | 14 +-- src/12_RefactoringGolf/exo5/kata.ts | 154 +++++++++++++------------- src/12_RefactoringGolf/exo5/test.ts | 6 + 4 files changed, 96 insertions(+), 84 deletions(-) create mode 100644 README ETUDIANTS.md diff --git a/README ETUDIANTS.md b/README ETUDIANTS.md new file mode 100644 index 0000000..16d11b0 --- /dev/null +++ b/README ETUDIANTS.md @@ -0,0 +1,6 @@ +# Nom Prénom + +- Pesant Fantin +- Chlabi Aymen +- Pouget--Péjoan Elfin +- Hoarau Allan diff --git a/src/12_RefactoringGolf/exo5/README.md b/src/12_RefactoringGolf/exo5/README.md index 2168b16..311f775 100644 --- a/src/12_RefactoringGolf/exo5/README.md +++ b/src/12_RefactoringGolf/exo5/README.md @@ -1,17 +1,17 @@ # Exo 5 to Exo 6 - ## Refactorings + - PROBLEME: la loi de Demeter n'est pas respectée ("Tell, Don't Ask" ou "principle of least knowledge") - - https://martinfowler.com/bliki/TellDontAsk.html - - https://savoiragile.com/2012/05/04/connaissez-vous-la-loi-de-demeter/ - - https://tech-fr.netlify.app/articles/fr512716/index.html - - https://www.arolla.fr/blog/2017/02/principes-solid-vie-de-jours/#Loi_de_Demeter + - + - + - + - - -- REVUE DE CODE: repérez les endroits où, pour obtenir une condition dans un IF, on fait appel (ASK) à des propriétés +- REVUE DE CODE: repérez les endroits où, pour obtenir une condition dans un IF, on fait appel (ASK) à des propriétés qui ne sont pas dans l'objet courant Example: + ```javascript if ( this._board.TileAt(row, firstColumn)!.Symbol == diff --git a/src/12_RefactoringGolf/exo5/kata.ts b/src/12_RefactoringGolf/exo5/kata.ts index 22d3cae..56ee416 100644 --- a/src/12_RefactoringGolf/exo5/kata.ts +++ b/src/12_RefactoringGolf/exo5/kata.ts @@ -11,105 +11,105 @@ const playerO = 'O'; const emptyPlay = ' '; export class Game { -private _lastSymbol = emptyPlay; -private _board: Board = new Board(); + private _lastSymbol = emptyPlay; + private _board: Board = new Board(); -public Play(symbol: string, x: number, y: number): void { -this.validateFirstMove(symbol); -this.validatePlayer(symbol); -this.validatePositionIsEmpty(x, y); + public Play(symbol: string, x: number, y: number): void { + this.validateFirstMove(symbol); + this.validatePlayer(symbol); + this.validatePositionIsEmpty(x, y); -this.updateLastPlayer(symbol); -this.updateBoard(symbol, x, y); -} + this.updateLastPlayer(symbol); + this.updateBoard(symbol, x, y); + } -private validateFirstMove(player: string) { -if (this._lastSymbol == emptyPlay) { - if (player == playerO) { - throw new Error('Invalid first player'); + private validateFirstMove(player: string) { + if (this._lastSymbol == emptyPlay) { + if (player == playerO) { + throw new Error('Invalid first player'); + } + } } -} -} -private validatePlayer(player: string) { -if (player == this._lastSymbol) { - throw new Error('Invalid next player'); -} -} + private validatePlayer(player: string) { + if (player == this._lastSymbol) { + throw new Error('Invalid next player'); + } + } -private validatePositionIsEmpty(x: number, y: number) { -if (this._board.TileAt(x, y).Symbol != emptyPlay) { - throw new Error('Invalid position'); -} -} + private validatePositionIsEmpty(x: number, y: number) { + if (this._board.TileAt(x, y).Symbol != emptyPlay) { + throw new Error('Invalid position'); + } + } -private updateLastPlayer(player: string) { -this._lastSymbol = player; -} + private updateLastPlayer(player: string) { + this._lastSymbol = player; + } -private updateBoard(player: string, x: number, y: number) { -this._board.AddTileAt(player, x, y); -} + private updateBoard(player: string, x: number, y: number) { + this._board.AddTileAt(player, x, y); + } -public Winner(): string { -return this._board.findRowFullWithSamePlayer(); -} + public Winner(): string { + return this._board.findRowFullWithSamePlayer(); + } } interface Tile { -X: number; -Y: number; -Symbol: string; + X: number; + Y: number; + Symbol: string; } class Board { -private _plays: Tile[] = []; - -constructor() { -for (let i = firstRow; i <= thirdRow; i++) { - for (let j = firstColumn; j <= thirdColumn; j++) { - const tile: Tile = { X: i, Y: j, Symbol: emptyPlay }; - this._plays.push(tile); + private _plays: Tile[] = []; + + constructor() { + for (let i = firstRow; i <= thirdRow; i++) { + for (let j = firstColumn; j <= thirdColumn; j++) { + const tile: Tile = { X: i, Y: j, Symbol: emptyPlay }; + this._plays.push(tile); + } + } } -} -} -public TileAt(x: number, y: number): Tile { -return this._plays.find((t: Tile) => t.X == x && t.Y == y)!; -} + public TileAt(x: number, y: number): Tile { + return this._plays.find((t: Tile) => t.X == x && t.Y == y)!; + } -public AddTileAt(symbol: string, x: number, y: number): void { -this._plays.find((t: Tile) => t.X == x && t.Y == y)!.Symbol = symbol; -} + public AddTileAt(symbol: string, x: number, y: number): void { + this._plays.find((t: Tile) => t.X == x && t.Y == y)!.Symbol = symbol; + } -public findRowFullWithSamePlayer(): string { -if (this.isRowFull(firstRow) && this.isRowFullWithSameSymbol(firstRow)) { - return this.TileAt(firstRow, firstColumn)!.Symbol; -} + public findRowFullWithSamePlayer(): string { + if (this.isRowFull(firstRow) && this.isRowFullWithSameSymbol(firstRow)) { + return this.TileAt(firstRow, firstColumn)!.Symbol; + } -if (this.isRowFull(secondRow) && this.isRowFullWithSameSymbol(secondRow)) { - return this.TileAt(secondRow, firstColumn)!.Symbol; -} + if (this.isRowFull(secondRow) && this.isRowFullWithSameSymbol(secondRow)) { + return this.TileAt(secondRow, firstColumn)!.Symbol; + } -if (this.isRowFull(thirdRow) && this.isRowFullWithSameSymbol(thirdRow)) { - return this.TileAt(thirdRow, firstColumn)!.Symbol; -} + if (this.isRowFull(thirdRow) && this.isRowFullWithSameSymbol(thirdRow)) { + return this.TileAt(thirdRow, firstColumn)!.Symbol; + } -return emptyPlay; -} + return emptyPlay; + } -private isRowFull(row: number) { -return ( - this.TileAt(row, firstColumn)!.Symbol != emptyPlay && - this.TileAt(row, secondColumn)!.Symbol != emptyPlay && - this.TileAt(row, thirdColumn)!.Symbol != emptyPlay -); -} + private isRowFull(row: number) { + return ( + this.TileAt(row, firstColumn)!.Symbol != emptyPlay && + this.TileAt(row, secondColumn)!.Symbol != emptyPlay && + this.TileAt(row, thirdColumn)!.Symbol != emptyPlay + ); + } -private isRowFullWithSameSymbol(row: number) { -return ( - this.TileAt(row, firstColumn)!.Symbol == this.TileAt(row, secondColumn)!.Symbol && - this.TileAt(row, thirdColumn)!.Symbol == this.TileAt(row, secondColumn)!.Symbol -); -} + private isRowFullWithSameSymbol(row: number) { + return ( + this.TileAt(row, firstColumn)!.Symbol == this.TileAt(row, secondColumn)!.Symbol && + this.TileAt(row, thirdColumn)!.Symbol == this.TileAt(row, secondColumn)!.Symbol + ); + } } \ No newline at end of file diff --git a/src/12_RefactoringGolf/exo5/test.ts b/src/12_RefactoringGolf/exo5/test.ts index 9aa2e2e..a533194 100644 --- a/src/12_RefactoringGolf/exo5/test.ts +++ b/src/12_RefactoringGolf/exo5/test.ts @@ -109,4 +109,10 @@ describe('TicTacToe game', () => { expect(winner).toBe('O'); }); + + it('should declare empty string as winner if nothing is played', () => { + const winner = game.Winner(); + + expect(winner).toBe(' '); + }); }); From 152d4badb89aff794e4f3dd16da8e08a11cfa1d8 Mon Sep 17 00:00:00 2001 From: Nifle CGE Date: Mon, 22 Sep 2025 17:04:21 +0200 Subject: [PATCH 2/2] refactor --- src/12_RefactoringGolf/exo5/kata.ts | 49 ++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/12_RefactoringGolf/exo5/kata.ts b/src/12_RefactoringGolf/exo5/kata.ts index 56ee416..b2beeb1 100644 --- a/src/12_RefactoringGolf/exo5/kata.ts +++ b/src/12_RefactoringGolf/exo5/kata.ts @@ -10,6 +10,32 @@ const thirdColumn = 2; const playerO = 'O'; const emptyPlay = ' '; +interface TileInterface { + X: number; + Y: number; + Symbol: string; +} + +class Tile implements TileInterface { + X: number; + Y: number; + Symbol: string; + + constructor(x: number, y: number, symbol: string) { + this.X = x; + this.Y = y; + this.Symbol = symbol; + } + + isEmpty(): boolean { + return this.Symbol === emptyPlay; + } + + hasSameSymbolAs(other: Tile): boolean { + return this.Symbol === other.Symbol; + } +} + export class Game { private _lastSymbol = emptyPlay; private _board: Board = new Board(); @@ -38,7 +64,7 @@ export class Game { } private validatePositionIsEmpty(x: number, y: number) { - if (this._board.TileAt(x, y).Symbol != emptyPlay) { + if (!this._board.TileAt(x, y).isEmpty()) { throw new Error('Invalid position'); } } @@ -56,20 +82,13 @@ export class Game { } } -interface Tile { - X: number; - Y: number; - Symbol: string; -} - class Board { private _plays: Tile[] = []; constructor() { for (let i = firstRow; i <= thirdRow; i++) { for (let j = firstColumn; j <= thirdColumn; j++) { - const tile: Tile = { X: i, Y: j, Symbol: emptyPlay }; - this._plays.push(tile); + this._plays.push(new Tile(i, j, emptyPlay)); } } } @@ -79,7 +98,7 @@ class Board { } public AddTileAt(symbol: string, x: number, y: number): void { - this._plays.find((t: Tile) => t.X == x && t.Y == y)!.Symbol = symbol; + this.TileAt(x, y).Symbol = symbol; } public findRowFullWithSamePlayer(): string { @@ -100,16 +119,16 @@ class Board { private isRowFull(row: number) { return ( - this.TileAt(row, firstColumn)!.Symbol != emptyPlay && - this.TileAt(row, secondColumn)!.Symbol != emptyPlay && - this.TileAt(row, thirdColumn)!.Symbol != emptyPlay + !this.TileAt(row, firstColumn).isEmpty() && + !this.TileAt(row, secondColumn).isEmpty() && + !this.TileAt(row, thirdColumn).isEmpty() ); } private isRowFullWithSameSymbol(row: number) { return ( - this.TileAt(row, firstColumn)!.Symbol == this.TileAt(row, secondColumn)!.Symbol && - this.TileAt(row, thirdColumn)!.Symbol == this.TileAt(row, secondColumn)!.Symbol + this.TileAt(row, firstColumn).hasSameSymbolAs(this.TileAt(row, secondColumn)) && + this.TileAt(row, thirdColumn).hasSameSymbolAs(this.TileAt(row, secondColumn)) ); } } \ No newline at end of file