mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
106 lines
2.8 KiB
JavaScript
106 lines
2.8 KiB
JavaScript
// This example is an implementation of the Tic-Tac-Toe game, from
|
|
// https://react.dev/learn/tutorial-tic-tac-toe. This is an easy application to start learning owl
|
|
// with some interesting user interactions.
|
|
//
|
|
// In this implementation, we use the owl reactivity mechanism.
|
|
import { Component, useState, mount } from "@odoo/owl";
|
|
|
|
|
|
class Square extends Component {
|
|
static template = "Square";
|
|
}
|
|
|
|
class Board extends Component {
|
|
static template = "Board"
|
|
static components = { Square };
|
|
|
|
handleClick(i) {
|
|
if (this.calculateWinner(this.props.squares) || this.props.squares[i]) {
|
|
return;
|
|
}
|
|
const nextSquares = this.props.squares.slice();
|
|
if (this.props.xIsNext) {
|
|
nextSquares[i] = 'X';
|
|
} else {
|
|
nextSquares[i] = 'O';
|
|
}
|
|
this.props.onPlay(nextSquares);
|
|
}
|
|
|
|
get status(){
|
|
const winner = this.calculateWinner(this.props.squares);
|
|
if (winner) {
|
|
return 'Winner: ' + winner;
|
|
} else {
|
|
if (Object.values(this.props.squares).filter((v) => v === null).length > 0)
|
|
return 'Next player: ' + (this.props.xIsNext ? 'X' : 'O');
|
|
else
|
|
return 'Draw';
|
|
}
|
|
}
|
|
|
|
calculateWinner(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],
|
|
];
|
|
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;
|
|
}
|
|
}
|
|
|
|
class Game extends Component {
|
|
static template = "Game"
|
|
static components = { Board };
|
|
|
|
setup() {
|
|
this.state = useState({
|
|
currentMove: 0,
|
|
history: [Array(9).fill(null)],
|
|
});
|
|
}
|
|
|
|
get currentSquares() {
|
|
return this.state.history[this.state.currentMove];
|
|
}
|
|
|
|
get xIsNext() {
|
|
return this.state.currentMove % 2 === 0;
|
|
}
|
|
|
|
jumpTo(nextMove) {
|
|
this.state.currentMove = nextMove;
|
|
}
|
|
|
|
handlePlay(nextSquares) {
|
|
const nextHistory = [...this.state.history.slice(0, this.state.currentMove + 1), nextSquares];
|
|
this.state.history = nextHistory;
|
|
this.state.currentMove = this.state.history.length - 1;
|
|
}
|
|
|
|
get moves() {
|
|
return this.state.history.map((_squares, move) => {
|
|
if (move > 0) {
|
|
return {id: move, description: 'Go to move #' + move};
|
|
} else {
|
|
return {id: move, description: 'Go to game start'};
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
// Application setup
|
|
mount(Game, document.body, { templates: TEMPLATES, dev: true});
|