Compare commits
10 Commits
9983f7b212
...
f72097b265
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f72097b265 | ||
![]() |
82e06917cf | ||
![]() |
78a5e73371 | ||
![]() |
6cecebec12 | ||
![]() |
915dbd4ed8 | ||
![]() |
b333149754 | ||
![]() |
056cbd0ef7 | ||
![]() |
628c2b932e | ||
![]() |
d2bb025723 | ||
![]() |
3d71f5dee6 |
@ -1,6 +1,8 @@
|
|||||||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
||||||
import Home from './screens/Home.js';
|
import Home from './screens/Home.js';
|
||||||
import NewGame from './screens/NewGame.js';
|
import NewGame from './screens/NewGame.js';
|
||||||
|
import Connect from './screens/Connect.js';
|
||||||
|
import Game from './screens/Game.js';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@ -9,6 +11,8 @@ function App() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path='/' element={<Home />} />
|
<Route path='/' element={<Home />} />
|
||||||
<Route path='/new_game' element={<NewGame />} />
|
<Route path='/new_game' element={<NewGame />} />
|
||||||
|
<Route path='/connect' element={<Connect />} />
|
||||||
|
<Route path='/game' element={<Game />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Component } from "react";
|
import { Component } from "react";
|
||||||
|
import request from "../scripts/requests";
|
||||||
import '../styles/styles.css'
|
import '../styles/styles.css'
|
||||||
|
|
||||||
class Cell extends Component {
|
class Cell extends Component {
|
||||||
@ -8,9 +9,25 @@ class Cell extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
h: props.h,
|
h: props.h,
|
||||||
v: props.v,
|
v: props.v,
|
||||||
color: "white",
|
shotState: props.shotState,
|
||||||
|
changeable: props.changeable
|
||||||
}
|
}
|
||||||
this.symb = " ";
|
if (this.state.shotState === "x") {
|
||||||
|
this.state.color = "red";
|
||||||
|
} else if (this.state.shotState === ".") {
|
||||||
|
this.state.color = "grey";
|
||||||
|
} else if (this.state.shotState === "+") {
|
||||||
|
this.state.color = "yellow";
|
||||||
|
} else {
|
||||||
|
this.state.color = "white";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(props) {
|
||||||
|
this.setState({
|
||||||
|
shotState: props.shotState,
|
||||||
|
changeable: props.changeable
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
changeColor() {
|
changeColor() {
|
||||||
@ -27,11 +44,30 @@ class Cell extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shoot() {
|
shoot() {
|
||||||
|
this.props.parent.setState({
|
||||||
|
changeable: false,
|
||||||
|
text: "Подожди"
|
||||||
|
})
|
||||||
|
request("shoot", {
|
||||||
|
game_id: localStorage.getItem("gameId"),
|
||||||
|
token: localStorage.getItem("token"),
|
||||||
|
h: this.props.h,
|
||||||
|
v: this.props.v
|
||||||
|
}, (response) => {
|
||||||
|
if (response.shot) {
|
||||||
|
this.setState({
|
||||||
|
shotState: "+",
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
shotState: "."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
click() {
|
click() {
|
||||||
if (!this.props.changeable) return;
|
if (!this.state.changeable) return;
|
||||||
if (this.props.parent.props.ready)
|
if (this.props.parent.props.ready)
|
||||||
this.shoot();
|
this.shoot();
|
||||||
else
|
else
|
||||||
@ -39,11 +75,20 @@ class Cell extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.parent.cells.includes(this))
|
let color = "white";
|
||||||
this.props.parent.cells.push(this);
|
if (this.state.shotState === "x") {
|
||||||
this.props.parent.cells.sort((a, b) => a.key < b.key);
|
color = "red";
|
||||||
|
} else if (this.state.shotState === "o") {
|
||||||
|
color = "darkcyan";
|
||||||
|
} else if (this.state.shotState === ".") {
|
||||||
|
color = "gray";
|
||||||
|
} else if (this.state.shotState === "+") {
|
||||||
|
color = "yellow";
|
||||||
|
} else if (this.symb === "o") {
|
||||||
|
color = "green";
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<button style={{backgroundColor: this.state.color}} onClick={() => this.click()} className="cell"></button>
|
<button style={{backgroundColor: color}} onClick={() => this.click()} className="cell"></button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,15 +112,29 @@ class Field extends Component {
|
|||||||
this.line = first + symb + last;
|
this.line = first + symb + last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
cells: this.props.cells,
|
||||||
|
changeable: props.changeable
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(props) {
|
||||||
|
this.setState({
|
||||||
|
changeable: props.changeable
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
this.cells = [];
|
|
||||||
let cells = [];
|
let cells = [];
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
let line = []
|
let line = []
|
||||||
for (let j = 0; j < 10; j++) {
|
for (let j = 0; j < 10; j++) {
|
||||||
const cell = <Cell parent={this} changeable={this.props.changeable} key={(i * 10 + j)} pos={i * 10 + j} h={i} v={j} />;
|
let shotState = null;
|
||||||
|
if (this.props.cells !== undefined && this.props.cells !== null) {
|
||||||
|
shotState = this.props.cells[i][j]
|
||||||
|
}
|
||||||
|
const cell = <Cell shotState={shotState} parent={this} changeable={this.state.changeable} key={(i * 10 + j)} pos={i * 10 + j} h={i} v={j} ready={this.props.ready} />;
|
||||||
line.push(<td key={(i * 10 + j) * 100}>{cell}</td>);
|
line.push(<td key={(i * 10 + j) * 100}>{cell}</td>);
|
||||||
}
|
}
|
||||||
cells.push(<tr key={(i * 100000)}>{line}</tr>);
|
cells.push(<tr key={(i * 100000)}>{line}</tr>);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { Component } from "react";
|
import { Component } from "react";
|
||||||
import request from "../scripts/requests";
|
|
||||||
|
|
||||||
class Ready extends Component {
|
class Ready extends Component {
|
||||||
|
|
||||||
@ -10,19 +9,6 @@ class Ready extends Component {
|
|||||||
disabled: true,
|
disabled: true,
|
||||||
parent: props.parent
|
parent: props.parent
|
||||||
}
|
}
|
||||||
this.state.parent.ready = this;
|
|
||||||
this.click = this.click.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
click() {
|
|
||||||
request("place_ships", {
|
|
||||||
game_id: this.state.parent.getGameId(),
|
|
||||||
token: localStorage.getItem('token'),
|
|
||||||
field: this.state.parent.field.getLine()
|
|
||||||
}, () => this.setState({
|
|
||||||
text: "Ждем ответа соперника",
|
|
||||||
disabled: true
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
@ -41,7 +27,7 @@ class Ready extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <button onClick={this.click} className='main' disabled={this.state.disabled}><p>{this.state.text}</p></button>
|
return <button onClick={this.props.onClick} className='main' disabled={this.props.disabled}><p>{this.props.text}</p></button>
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,37 @@
|
|||||||
import {Component} from 'react';
|
import {Component} from 'react';
|
||||||
|
import request from '../scripts/requests';
|
||||||
|
|
||||||
class Connect extends Component {
|
class Connect extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.queryParams = new URLSearchParams(window.location.search);
|
||||||
|
const game_id = this.queryParams.get('gameId');
|
||||||
|
localStorage.setItem('gameId', game_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
getToken() {
|
||||||
|
return this.queryParams.get('token');
|
||||||
|
}
|
||||||
|
|
||||||
|
getGameId() {
|
||||||
|
return localStorage.getItem('gameId');
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
document.title = "Подключиться к игре";
|
||||||
|
request("attend_game", {
|
||||||
|
game_id: this.getGameId(),
|
||||||
|
attend_token: this.getToken()
|
||||||
|
}, (response) => {
|
||||||
|
localStorage.setItem("token", response.token);
|
||||||
|
window.location.href = "/new_game?gameId=" + this.getGameId()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div></div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Connect;
|
68
src/screens/Game.js
Normal file
68
src/screens/Game.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { Component } from "react";
|
||||||
|
import Field from '../components/Field.js';
|
||||||
|
import request from "../scripts/requests.js";
|
||||||
|
|
||||||
|
class Game extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
myField: null,
|
||||||
|
opponentField: null,
|
||||||
|
myTurn: false,
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doUpdate = () => {
|
||||||
|
|
||||||
|
const process = (response) => {
|
||||||
|
this.setState({
|
||||||
|
myField: response.my_field,
|
||||||
|
opponentField: response.opponent_field,
|
||||||
|
myTurn: response.my_turn,
|
||||||
|
text: response.my_turn ? "Твой ход" : "Ход соперника"
|
||||||
|
})
|
||||||
|
if (response.game_finished) {
|
||||||
|
this.setState({
|
||||||
|
text: "Игра окончена"
|
||||||
|
})
|
||||||
|
this.timer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request("get_fields", {
|
||||||
|
game_id: localStorage.getItem("gameId"),
|
||||||
|
token: localStorage.getItem("token")
|
||||||
|
}, process)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
document.title = "Battleship";
|
||||||
|
this.timer = setInterval(() => this.doUpdate(), 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<center><p className='logo'>Let's play!</p></center>
|
||||||
|
<div className='row'>
|
||||||
|
<div className='col-1'>
|
||||||
|
<p>Player1</p>
|
||||||
|
<Field cells={this.state.myField} parent={this} changeable={false} ready={false} />
|
||||||
|
</div>
|
||||||
|
<div className='col-5'>
|
||||||
|
<p>
|
||||||
|
{this.state.text}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='col-1'>
|
||||||
|
<p>Player2</p>
|
||||||
|
<Field cells={this.state.opponentField} parent={this} changeable={this.state.myTurn} ready={true} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Game;
|
@ -7,11 +7,16 @@ class Home extends Component {
|
|||||||
goNewGame() {
|
goNewGame() {
|
||||||
function go(response) {
|
function go(response) {
|
||||||
localStorage.setItem('token', response.my_token);
|
localStorage.setItem('token', response.my_token);
|
||||||
|
localStorage.setItem('gameId', response.game_id);
|
||||||
window.location.href='/new_game?gameId=' + response.game_id.toString() + "&playerToken=" + response.player_token;
|
window.location.href='/new_game?gameId=' + response.game_id.toString() + "&playerToken=" + response.player_token;
|
||||||
}
|
}
|
||||||
request("new_game", {}, go);
|
request("new_game", {}, go);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
document.title = "Sprint Battleship";
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className='center'>
|
<div className='center'>
|
||||||
@ -19,8 +24,6 @@ class Home extends Component {
|
|||||||
<center><p className='logo'><b>Sprint Battleship</b></p></center>
|
<center><p className='logo'><b>Sprint Battleship</b></p></center>
|
||||||
</div>
|
</div>
|
||||||
<button className='main' onClick={() => this.goNewGame()}><p>Новая игра</p></button>
|
<button className='main' onClick={() => this.goNewGame()}><p>Новая игра</p></button>
|
||||||
<div className='space'></div>
|
|
||||||
<button className='main' onClick={() => window.location.href="/connect"}><p>Присоединиться</p></button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,19 @@ import Field from '../components/Field.js';
|
|||||||
import Ready from '../components/Ready.js';
|
import Ready from '../components/Ready.js';
|
||||||
import request, {host} from '../scripts/requests.js';
|
import request, {host} from '../scripts/requests.js';
|
||||||
|
|
||||||
|
class AttendLink extends Component {
|
||||||
|
render() {
|
||||||
|
if (this.props.token !== null)
|
||||||
|
return (
|
||||||
|
<center>
|
||||||
|
<p>Ссылка для подключения</p>
|
||||||
|
<input className='borders' readOnly value={host + "connect?token=" + this.props.token + "&gameId=" + localStorage.getItem('gameId')} />
|
||||||
|
</center>
|
||||||
|
)
|
||||||
|
else return <div></div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class NewGame extends Component {
|
class NewGame extends Component {
|
||||||
|
|
||||||
getToken() {
|
getToken() {
|
||||||
@ -12,62 +25,87 @@ class NewGame extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getGameId() {
|
getGameId() {
|
||||||
return this.queryParams.get('gameId');
|
return localStorage.getItem('gameId');
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
document.title = "Новая игра";
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
ok: false
|
ok: false,
|
||||||
|
readyText: "Заполни поле чтобы начать",
|
||||||
|
readyDisabled: true
|
||||||
}
|
}
|
||||||
this.queryParams = new URLSearchParams(window.location.search);
|
this.queryParams = new URLSearchParams(window.location.search);
|
||||||
|
this.setState = this.setState.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
const line = this.field.getLine();
|
const line = this.field.getLine();
|
||||||
request("check_field_correct", {field: line}, (response) => {
|
request("check_field_correct", {field: line}, (response) => {
|
||||||
this.setState({ok: response.correct});
|
|
||||||
if (response.correct) {
|
if (response.correct) {
|
||||||
this.ready.setState({
|
this.setState({
|
||||||
text: "Я готов",
|
readyText: "Я готов",
|
||||||
disabled: false
|
readyDisabled: false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.ready.setState({
|
this.setState({
|
||||||
text: "Расставь корабли чтобы активировать",
|
readyText: "Заполни поле чтобы начать",
|
||||||
disabled: true
|
readyDisabled: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.ready.setState({ok: this.state.ok});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doUpdate(obj) {
|
||||||
|
const game_id = localStorage.getItem('gameId');
|
||||||
|
request("check_opponent", {
|
||||||
|
game_id: game_id,
|
||||||
|
token: localStorage.getItem("token")
|
||||||
|
}, function(response) {
|
||||||
|
obj.setState({
|
||||||
|
readyText: response.attend ? "Соперник ставит корабли" : "Ждем ответа соперника",
|
||||||
|
readyDisabled: true
|
||||||
|
})
|
||||||
|
if (response.ready) {
|
||||||
|
window.location.href = '/game?gameId=' + game_id;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
clickReady() {
|
||||||
|
request("place_ships", {
|
||||||
|
game_id: this.getGameId(),
|
||||||
|
token: localStorage.getItem('token'),
|
||||||
|
field: this.field.getLine()
|
||||||
|
}, (response) => {
|
||||||
|
this.setState({
|
||||||
|
readyText: "Ждем ответа соперника",
|
||||||
|
readyDisabled: true
|
||||||
|
})
|
||||||
|
});
|
||||||
|
this.timer = setInterval(() => this.doUpdate(this), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<center><p className='logo'>Расставь корабли</p></center>
|
<center><p className='logo'>Расставь корабли</p></center>
|
||||||
{/* <div className='row'>
|
|
||||||
<div className='col-1'>
|
|
||||||
<p>Player1</p>
|
|
||||||
<Field parent={this} changeable={true} />
|
|
||||||
</div>
|
|
||||||
<div className='col-5'></div>
|
|
||||||
<div className='col-1'>
|
|
||||||
<p>Player2</p>
|
|
||||||
<Field parent={this} changeable={false} />
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
<div className='row'>
|
<div className='row'>
|
||||||
<div className='col-1'>
|
<div className='col-1'>
|
||||||
<p>Player1</p>
|
<p>Player1</p>
|
||||||
<Field ready={false} parent={this} changeable={true} />
|
<Field ready={false} parent={this} changeable={true} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<center>
|
<AttendLink token={this.getToken()} gameId={this.getGameId()} />
|
||||||
<p>Ссылка для подключения</p>
|
<Ready onClick={() => this.clickReady()} text={this.state.readyText} disabled={this.state.readyDisabled} />
|
||||||
<input className='borders' value={host + "connect?token=" + this.getToken()} />
|
|
||||||
</center>
|
|
||||||
<Ready ok={this.state.ok} parent={this} />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export const host = "http://battleship.develop.sprinthub.ru/"
|
export const host = "https://battleship.sprinthub.ru/"
|
||||||
|
|
||||||
|
|
||||||
function request(method, body, callback) {
|
function request(method, body, callback) {
|
||||||
|
Loading…
Reference in New Issue
Block a user