Création d'un jeu Tic-Tac-Toe avec TypeScript, React et Mocha

Nous vous présentons une traduction d'un article de Josh Kuttler publié sur blog.bitsrc.io. Apprenez à créer une application Tic-Tac-Toe à l'aide de React et TypeScript.



Un jeu de tic-tac-toe simple créé sur une base modulaire et téléchargé sur le site Web de Bit . Vous pouvez modifier les composants de mon jeu et le tester en ligne sur Bit PlayGround en utilisant NPM, Yarn ou Bit. Pour ce faire, accédez à ma collection de composants .

Lorsque vous créez des jeux Tic-Tac-Toe de manière modulaire, il est difficile de trouver une raison pour laquelle les composants de l'interface utilisateur peuvent être réutilisés. Par conséquent, je me suis concentré principalement sur les utilitaires de jeu.

Pour la programmation, j'ai choisi TypeScript - j'ai compilé le code en utilisant TypeScript sur le site Web de Bit . Il a ensuite utilisé le framework Mocha pour les tests.

Pour installer des composants de mon projet, configurez d'abord bit.dev comme registre de domaine (copiez et collez sur votre appareil). Cela ne devrait être fait qu'une seule fois! Si vous continuez à utiliser le site Web Bit, vous n'aurez pas besoin de le reconfigurer.

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

Installez ensuite le composant à l'aide des gestionnaires de packages Yarn ou NPM:

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

Composant de jeu


Le composant de jeu est le composant principal de mon application - il a été créé en utilisant un composant Board et deux composants Prime React .

J'ai utilisé les composants Button et Input-text pour l'écran de configuration - vous pouvez tester et voir leur code ici .



Installez les composants PrimeReact dans votre projet:

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

Après avoir réglé les paramètres, vous pouvez cliquer sur "Play" et ... jouer!

Composant de la carte


Le composant Board crée une table dynamique à l'aide des accessoires, définit la file d'attente pour les joueurs et détermine le gagnant. Vous pouvez tester et voir le code ici .



Composant carré


Le composant Square est une cellule normale qui reçoit une valeur avec une couleur facultative et envoie un événement au composant Board lorsque la valeur change. Vous pouvez tester et voir le code ici .



Fonction cellule vide


La fonction Cellule vide est une fonction d'aide pour la fonction Winner-calc, qui vérifie s'il y a des cellules vides dans la table de jeu.

Bit vous permet de voir les documents des composants et les résultats des tests:



Code de fonction
 /** * @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 


Fonction de calcul du gagnant


Le calcul du gagnant est une fonction qui calcule le gagnant sur les plans horizontal, vertical et diagonal.

Bit vous permet de voir les documents des composants et les résultats des tests:



Code de fonction
 /** * @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 


Le projet est disponible dans ma collection sur Bit et dans mon référentiel GitHub .

N'hésitez pas à commenter cet article et à vous abonner à mon Twitter .

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


All Articles