Compare commits
1 Commits
b6c04bdc54
...
main
Author | SHA1 | Date |
---|---|---|
Suguivy | c63786d516 |
|
@ -3,6 +3,7 @@
|
|||
width: fit-content;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
@ -10,4 +11,16 @@
|
|||
h1 {
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.refresh-button {
|
||||
--color: #ffee33;
|
||||
background-color: transparent;
|
||||
font-size: 40px;
|
||||
color: var(--color);
|
||||
border: none;
|
||||
margin: 5px;
|
||||
aspect-ratio: 1;
|
||||
height: 70px;
|
||||
transition: 0.15s;
|
||||
}
|
|
@ -3,17 +3,83 @@ import { VALUE } from "../Button/Button";
|
|||
import { Board } from "../Board/Board";
|
||||
import { useState } from "react";
|
||||
|
||||
export const MESSAGE = {
|
||||
IN_GAME: 0,
|
||||
WIN: 1,
|
||||
DRAW: 2,
|
||||
};
|
||||
|
||||
function App() {
|
||||
const [nextValue, setNextValue] = useState(VALUE.X);
|
||||
function alternateNextValue() {
|
||||
setNextValue(nextValue === VALUE.X ? VALUE.O : VALUE.X);
|
||||
const [winner, setWinner] = useState(null);
|
||||
const [values, setValues] = useState(Array(9).fill(VALUE.EMPTY));
|
||||
const inGameMessage = ["Turn of ", nextValue];
|
||||
const drawMessage = "It's a draw";
|
||||
const winMessage = ["The winner is ", winner];
|
||||
const message = winner
|
||||
? winner === "Draw"
|
||||
? drawMessage
|
||||
: winMessage
|
||||
: inGameMessage;
|
||||
|
||||
function handleClick(i) {
|
||||
if (!winner) {
|
||||
if (values[i] === VALUE.EMPTY) {
|
||||
let newValues = values.slice();
|
||||
newValues[i] = nextValue;
|
||||
setValues(newValues);
|
||||
let winner = calculateWinner(newValues);
|
||||
if (winner) {
|
||||
setWinner(winner);
|
||||
} else if (newValues.filter((v) => v === VALUE.EMPTY).length === 0) {
|
||||
setWinner("Draw");
|
||||
}
|
||||
alternateNextValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function newGame() {
|
||||
setNextValue(VALUE.X);
|
||||
setWinner(null);
|
||||
setValues(Array(9).fill(VALUE.EMPTY));
|
||||
}
|
||||
|
||||
function alternateNextValue() {
|
||||
setNextValue(nextValue === VALUE.X ? VALUE.O : VALUE.X);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="center">
|
||||
<h1>Turn of {nextValue}</h1>
|
||||
<Board nextValue={nextValue} onBoardClick={alternateNextValue} />
|
||||
<h1>{message}</h1>
|
||||
<Board nextValue={nextValue} handleClick={handleClick} values={values} />
|
||||
<button className="refresh-button" onClick={newGame}>
|
||||
<i className="icon-refresh"></i>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function calculateWinner(values) {
|
||||
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],
|
||||
];
|
||||
|
||||
let line = lines.find(
|
||||
([a, b, c]) =>
|
||||
values[a] === values[b] &&
|
||||
values[b] === values[c] &&
|
||||
values[a] !== VALUE.EMPTY
|
||||
);
|
||||
let winner = line ? values[line[0]] : null;
|
||||
return winner;
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -1,27 +1,7 @@
|
|||
import { useState } from "react";
|
||||
import { Button, VALUE } from "../Button/Button";
|
||||
|
||||
export function Board({ onBoardClick, nextValue }) {
|
||||
const [values, setValues] = useState([
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
VALUE.EMPTY,
|
||||
]);
|
||||
|
||||
function handleClick(i) {
|
||||
if (values[i] === VALUE.EMPTY) {
|
||||
let newValues = values.slice();
|
||||
newValues[i] = nextValue;
|
||||
setValues(newValues);
|
||||
onBoardClick();
|
||||
}
|
||||
}
|
||||
export function Board({ handleClick, values }) {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
|
@ -41,4 +21,4 @@ export function Board({ onBoardClick, nextValue }) {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
.board-button {
|
||||
--color: #edfffd;
|
||||
background-color: transparent;
|
||||
border: 7px solid #00ffdd;
|
||||
border: 7px solid var(--color);
|
||||
font-size: 40px;
|
||||
color: #00ffdd;
|
||||
color: var(--color);
|
||||
border-radius: 25px;
|
||||
margin: 5px;
|
||||
aspect-ratio: 1;
|
||||
|
@ -11,5 +12,14 @@
|
|||
}
|
||||
|
||||
.board-button:hover {
|
||||
box-shadow: #00ffdd 0px 4px 20px;
|
||||
}
|
||||
box-shadow: var(--color) 0px 4px 20px;
|
||||
}
|
||||
|
||||
.board-button.button-x {
|
||||
--color: #ff66ff;
|
||||
}
|
||||
|
||||
.board-button.button-o {
|
||||
--color: #00ffdd;
|
||||
}
|
||||
/* #00ffdd */
|
|
@ -7,9 +7,18 @@ export const VALUE = {
|
|||
};
|
||||
|
||||
export function Button({ value, onButtonClick }) {
|
||||
let colorClass = "";
|
||||
switch (value) {
|
||||
case VALUE.X:
|
||||
colorClass = "button-x";
|
||||
break;
|
||||
case VALUE.O:
|
||||
colorClass = "button-o";
|
||||
break;
|
||||
}
|
||||
return (
|
||||
<button className="board-button" onClick={onButtonClick}>
|
||||
<button className={"board-button " + colorClass} onClick={onButtonClick}>
|
||||
{value}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue