React로 Tic-React-Toe 게임을 만들어 봅시다!
36465 단어 reactjavascripttutorialtodayilearned
예, 코딩을 배우는 것은 정말 멋진 일이지만, 스스로 해보는 것은 꽤 두려운 일입니다. 그래서 비디오, 코스, 긴 튜토리얼(문서 제외)을 버리고 스스로 React를 코딩하기 위한 첫 번째 단계를 밟았습니다. 즉, 나만의 tic-tac-toe 게임을 만드는 것입니다.
Tic-Tac-Toe 게임은 이미 너무 과장되어 있지만 새로운 프로그래밍 언어를 배울 때 기본 사항 등을 가르쳐 주는 모든 것을 시도하는 것이 좋습니다. 연습은 완벽을 만들고, 완벽하지 않더라도 확실히 더 나아집니다.
이제 내 지식을 미래의 React Master와 공유하겠습니다! 😊
프로젝트에 대한 모든 설명은 주석을 통해 코드 자체에 있지만 막히거나 내 CSS 파일을 보려면 이미지 또는 사용자 지정 글꼴을 사용하고 내 GitHub Repository에서 확인하십시오.
만들기 전에 테스트하고 싶습니까? Heroku에서 테스트해 보십시오.
사전 설정 - 패키지 설치
이 프로젝트를 내가 한 것처럼(또는 원하는 대로) 완료하려면 선호하는 명령줄에서 다음을 수행해야 합니다.
npx create-react-app tic-tac-react
npm i react-bootstrap bootstrap --save
cd tic-tac-react
1단계 - 초기 설정
다음 구성 요소 파일을 포함하도록 App.JS 파일을 설정합니다. 즉,
components
, ./src
, Board.js
, Game.js
파일에 대해 Square.js
폴더에 Header.js
폴더를 만들 수 있습니다.//App.js
import React from 'react';
import Game from './components/Game';
import Header from './components/Header';
import 'bootstrap/dist/css/bootstrap.min.css';
//Exports the App function to be used in index.js
function App() {
return (
<div className="App">
<Header />
<Game />
</div>
);
}
//Exports App Component to be used in index.js`
export default App;
2단계 - 사각형 만들기
나중에 만들 보드에서 값을 선택할 수 있으려면 먼저 "x"또는 "o"값을 포함할 사각형을 렌더링해야 합니다.
Square.js
파일에서 다음을 수행합니다.//Square.js
import React from 'react';
//The Square component function a single <button>
function Square(props) {
return (
//onClick handler that will re-render the Square value whenever the <button> is clicked.
<button className="square" onClick={props.onClick}>
{/* this will call the value passed by the renderSquare component into the square, x or o*/}
{props.value}
</button>
);
}
//Exports Square Component to be used in app.js
export default Square;
3단계 - 보드 만들기
이제 보드는 게임에 대한 기본 인터페이스가 될 것이며 다음 단계에서 작동하도록 만들 것입니다. 이제 게임 보드에 생성된 사각형 버튼을 렌더링해야 합니다.
Board.js
파일에서 다음을 수행합니다.//Board.js
import React from 'react';
import Square from './Square';
import {Container, Row} from 'react-bootstrap';
//Board renders 9 squares to compose the tic-tac-toe board
class Board extends React.Component {
//Pass the props to render the square number value to the board
renderSquare(i) {
/* this will pass a value (x, o, or null) to the Square */
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}
//Board rendering with square value init
render() {
//this will set the render the board
return (
<Container>
<Row>
<div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
</Row>
</Container>
);
};
}
//Exports Board Component to be used in app.js
export default Board;
4단계 - 최종 게임 만들기
이제 보드와 사각형을 만들었으므로 실제 게임에 기능을 추가해야 합니다.
Game.js
파일에서 다음을 수행합니다.//Game.js
import React from 'react';
import Board from './Board';
import {Button, Container, Row, Col} from 'react-bootstrap';
//The Game component renders a board which adds functionality to the game
class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
//sets the Board's initial state to contain an array of 9 nulls on 9 squares
history: [{
squares: Array(9).fill(null),
}],
//Indicates which step we’re currently viewing.
stepNumber: 0,
//xIsNext (a boolean) will be flipped to determine which player goes next and the game’s state will be saved
xIsNext: true,
}
}
//sets the state of the clicked square to an X value
handleClick(i) {
//ensures we don’t get stuck showing the same move after a new one has been made.
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
//returns early by ignoring a click if someone has won the game or if a Square is already filled:
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
//will either set the state of the clicked block to be x, or negate it to o
this.setState ({
history: history.concat([{
squares: squares
}]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext
});
}
//update that stepNumber to its current step and that the number of the step is even
jumpTo(step) {
this.setState({
stepNumber: step,
xIsNext: (step % 2) === 0,
})
}
render() {
// uses the most recent history entry to determine and display the game’s status
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
//For each move in the tic-tac-toe game’s history, we create a list item <li> which contains a button <button>.
const moves = history.map((step, move) => {
//display the current move and history upon click
const desc = move ?
'Return To Move #' + move :
'Reset Game Board ';
return (
//we assign a key to the move list to make each move unique so it cannot be re-ordered, deleted or inserted
<li key={move}>
<Button className="btn-prim" size="lg" onClick={() => this.jumpTo(move)}>{desc}</Button>
</li>
);
});
let status;
if (winner) {
status = 'Congrats! The winner is: ' + winner;
} else {
status = 'Player Turn: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<Container>
<Row className="col-12">
<div className="game-space"></div>
</Row>
<Row className="col-12">
<div className="game">
<Col className="col-12 col-md-6 col-lg-6">
<div className="game-board">
<Board
squares={current.squares}
onClick={i => this.handleClick(i)}
/>
</div>
</Col>
<Col className="col-12 col-md-6 col-lg-6">
<div className="game-info">
<div className="game-status">{status}</div>
<ol className="game-moves">{moves}</ol>
</div>
</Col>
</div>
</Row>
</Container>
);
}
}
//This will calculate the winner of the game after all possible moves are used
function calculateWinner(squares) {
//possible winning moves for array of 9 squares
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
//Given an array of 9 squares, this function will check for a winner and return 'X', 'O', or null as appropriate.
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
};
//Exports Game Component to be used in app.js
export default Game;
5단계 - 최종 수정
이제 완전히 선택 사항인 헤더 파일을 추가할 수 있지만 기능적 구성 요소에서 레이아웃 파일을 분리하는 것을 선호합니다.
이것을/components 폴더에 넣는 대신
/layout
라는 새 폴더를 만들고 거기에 Header.js
를 저장할 수도 있습니다.//Header.js
import React from 'react';
import {Container, Row} from 'react-bootstrap';
//The Header component which will be main ui of game
function Header() {
return (
<Container>
<Row>
<div className="Header">
<h4 className="pre-title">WELCOME TO</h4>
<h1 className="game-title">Tic Tac React!</h1>
</div>
</Row>
<Row> </Row>
</Container>
);
}
//Exports Header Component to be used in app.js
export default Header;
6단계 - CSS 및 배포!
수고하셨습니다. 튜토리얼을 완료했습니다. 이제 다음 명령으로 게임을 테스트할 수 있습니다.
npm start
응용 프로그램에 일부 CSS 또는 스타일을 추가하는 것을 잊지 마십시오. 그렇지 않으면 확실한 uggo입니다. 위에 나열된 내 GitHub 저장소에서 내 CSS 파일에 대해 내가 수행한 작업을 볼 수 있습니다.
최종 프로젝트는 다음과 같아야 합니다.
내가 말했듯이, 나는 React 전문가는 아니지만 오늘 뭔가 새롭고/다른 것을 보여줄 수 있기를 바랍니다! 저에게 알려주시거나 새로운 것을 가르쳐주세요. 댓글로 여러분의 의견을 듣고 싶습니다.😊
Reference
이 문제에 관하여(React로 Tic-React-Toe 게임을 만들어 봅시다!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/christinec_dev/let-s-make-tic-react-toe-2lka텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)