Erstellen eines Tic-Tac-Toe-Spiels mit TypeScript, React und Mocha

Wir präsentieren Ihnen eine Übersetzung eines Artikels von Josh Kuttler, der auf blog.bitsrc.io veröffentlicht wurde. Erfahren Sie, wie Sie mit React und TypeScript eine Tic-Tac-Toe-Anwendung erstellen.



Ein einfaches Tic-Tac-Toe-Spiel, das modular erstellt und auf die Bit-Website hochgeladen wurde . Sie können die Komponenten meines Spiels ändern und es online auf Bit PlayGround mit NPM, Yarn oder Bit testen. Gehen Sie dazu zu meiner Komponentensammlung .

Wenn Sie Tic-Tac-Toe-Spiele modular erstellen, ist es schwierig, einen Grund zu finden, warum UI-Komponenten jemals wieder verwendet werden können. Daher habe ich mich hauptsächlich auf Spieledienstprogramme konzentriert.

Für die Programmierung habe ich TypeScript gewählt - ich habe den Code mit TypeScript auf der Bit-Website kompiliert. Dann benutzte er das Mokka-Framework zum Testen.

Um Komponenten aus meinem Projekt zu installieren, konfigurieren Sie zuerst bit.dev als Domänenregistrierung (Kopieren und Einfügen auf Ihrem Gerät). Dies sollte nur einmal gemacht werden! Wenn Sie die Bit-Website weiterhin verwenden, müssen Sie sie nicht neu konfigurieren.

npm config set '@bit:registry' https://node.bit.dev 

Installieren Sie dann die Komponente mit den Paketmanagern Yarn oder NPM:

 npm i @bit/joshk.tic-tac-toe-game.game yarn add @bit/joshk.tic-tac-toe-game.game 

Spielkomponente


Die Spielkomponente ist die Hauptkomponente meiner Anwendung - sie wurde mit einer Board-Komponente und zwei Prime React- Komponenten erstellt.

Ich habe die Komponenten Button und Input-Text für den Setup-Bildschirm verwendet - Sie können ihren Code hier testen und sehen.



Installieren Sie PrimeReact-Komponenten in Ihrem Projekt:

 yarn add @bit/primefaces.primereact.inputtext yarn add @bit/primefaces.primereact.button 

Nachdem Sie die Parameter eingestellt haben, können Sie auf "Play" klicken und ... spielen!

Platinenkomponente


Die Board- Komponente erstellt mithilfe von Requisiten eine dynamische Tabelle, legt die Warteschlange für die Spieler fest und ermittelt den Gewinner. Sie können den Code hier testen und sehen.



Quadratische Komponente


Die quadratische Komponente ist eine normale Zelle, die einen Wert mit einer optionalen Farbe empfängt und ein Ereignis an die Board-Komponente sendet, wenn sich der Wert ändert. Sie können den Code hier testen und sehen.



Leere Zellenfunktion


Die Funktion "Leere Zellen" ist eine Hilfsfunktion für die Funktion "Winner-calc", mit der überprüft wird, ob sich leere Zellen in der Spieltabelle befinden.

Mit Bit können Sie Komponentendokumente und Testergebnisse anzeigen:



Funktionscode
 /** * @description * check if 2d array have an empty cell * @param {{Array.<string[]>}} matrix 2d array * @param {number} rowsNum number of rows * @param {number} colsNum number of columns * @returns {boolean} return true if empty cell was found, and false if not. * @example * import haveEmptyCell from '@bit/joshk.tic-tac-toe-game.utils.have-empty-cell'; * * const matrix = [ * ['X', 'O', 'X'], * ['O', 'X', 'O'], * ['O', 'X', 'O'] * ]; * const result = haveEmptyCell(matrix, 3, 3); * * export default result * @example * import haveEmptyCell from '@bit/joshk.tic-tac-toe-game.utils.have-empty-cell'; * * const matrix = [ * ['X', 'O', 'X'], * ['O', '', 'O'], * ['O', 'X', 'O'] * ]; * const result = haveEmptyCell(matrix, 3, 3); * * export default result * @example * import haveEmptyCell from '@bit/joshk.tic-tac-toe-game.utils.have-empty-cell'; * * const matrix = [ * ['X', 'O', 'X'], * ['O', , 'O'], * ['O', 'X', 'O'] * ]; * const result = haveEmptyCell(matrix, 3, 3); * * export default result * @example * import haveEmptyCell from '@bit/joshk.tic-tac-toe-game.utils.have-empty-cell'; * * const matrix = [ * ['X', 'O', 'X'], * ['O', null, 'O'], * ['O', 'X', 'O'] * ]; * const result = haveEmptyCell(matrix, 3, 3); * * export default result */ function haveEmptyCell(matrix: Array<Array<string>>, rowsNum: number, colsNum: number): boolean { let empty: boolean = false; for (let x = 0; x < rowsNum; x++) { for (let y = 0; y < colsNum; y++) { const element: any = matrix[x][y]; if (!element) { empty = true; break; } } if (empty) break; } return empty; } export default haveEmptyCell 


Gewinnerberechnungsfunktion


Die Gewinnerberechnung ist eine Funktion, die den Gewinner in horizontalen, vertikalen und diagonalen Ebenen berechnet.

Mit Bit können Sie Komponentendokumente und Testergebnisse anzeigen:



Funktionscode
 /** * @description * check winner horizontal, vertical and diagonal * @param {Array.<string[]>} matrix 2d array with X and O * @param {number} rowsNum number of rows * @param {number} colsNum number of columns * @param {number} numToWin the number of matching to win * @param {number} lastRow the row number of the square player click * @param {number} lastCol the column number of the square player click * @returns {string} return the winner, X or O or '' if no one win. * @example * import winnerCalc from '@bit/joshk.tic-tac-toe-game.utils.winner-calc'; * * const matrix = [ * ['O', 'O', 'X'], * ['O', 'X', ''], * ['X', '', ''] * ]; * const result = winnerCalc(matrix, 3, 3, 3, 0, 2); * * export default result */ import haveEmptyCell from '../HaveEmptyCell' function winnerCalc(matrix: Array<Array<string>>, rowsNum: number, colsNum: number, numToWin: number, lastRow: number, lastCol: number): string { let winner: string = ''; let match: number = 0; const lastValue: string = matrix[lastRow][lastCol]; //check Horizontal for (let c = 0; c < colsNum; c++) { let currentValue = matrix[lastRow][c]; if (currentValue === lastValue) match++; else match = 0; if (match === numToWin) { winner = lastValue; break; } } if (winner !== '') return winner; match = 0; //check Vertical for (let r = 0; r < rowsNum; r++) { let currentValue = matrix[r][lastCol]; if (currentValue === lastValue) match++; else match = 0; if (match === numToWin) { winner = lastValue; break; } } if (winner !== '') return winner; //check diagonal top-left to bottom-right - include middle match = 0; for (let r = 0; r <= rowsNum - numToWin; r++) { let rowPosition = r; for (let column = 0; column < colsNum && rowPosition < rowsNum; column++) { const currentValue = matrix[rowPosition][column]; if (currentValue === lastValue) match++; else match = 0; if (match === numToWin) { winner = lastValue; break; } rowPosition++; } if (winner !== '') break; } if (winner !== '') return winner; //check diagonal top-left to bottom-right - after middle match = 0; for (let c = 1; c <= colsNum - numToWin; c++) { let columnPosition = c; for (let row = 0; row < rowsNum && columnPosition < colsNum; row++) { let currentValue = matrix[row][columnPosition]; if (currentValue === lastValue) match++; else match = 0; if (match === numToWin) { winner = lastValue; break; } columnPosition++; } if (winner !== '') break; } if (winner !== '') return winner; //check diagonal bottom-left to top-right - include middle match = 0; for (let r = rowsNum - 1; r >= rowsNum - numToWin - 1; r--) { let rowPosition = r; for (let column = 0; column < colsNum && rowPosition < rowsNum && rowPosition >= 0; column++) { let currentValue = matrix[rowPosition][column]; if (currentValue === lastValue) match++; else match = 0; if (match === numToWin) { winner = lastValue; break; } rowPosition--; } if (winner !== '') break; } if (winner !== '') return winner; //check diagonal bottom-left to top-right - after middle match = 0; for (let c = 1; c < colsNum; c++) { let columnPosition = c; for (let row = rowsNum - 1; row < rowsNum && row >= 0 && columnPosition < colsNum && columnPosition >= 1; row--) { console.log(`[${row}][${columnPosition}]`); let currentValue = matrix[row][columnPosition]; if (currentValue === lastValue) match++; else match = 0; if (match === numToWin) { winner = lastValue; break; } columnPosition++; } if (winner !== '') break; } if (winner !== '') return winner; if(haveEmptyCell(matrix, rowsNum, colsNum) === false) { winner = '-1'; } return winner; } export default winnerCalc 


Das Projekt ist in meiner Sammlung auf Bit und in meinem GitHub-Repository verfügbar.

Fühlen Sie sich frei, diesen Artikel zu kommentieren und meinen Twitter zu abonnieren.

Source: https://habr.com/ru/post/de456000/


All Articles