diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 5533c3b..9580d21 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,7 +6,7 @@ import FogImages from './components/FogImages'; import HitElems from './components/HitElems'; import Labeling from './components/Labeling'; import Ships from './components/Ships'; -import { hitReducer, initlialTarget, initlialTargetPreview } from './helpers'; +import { hitReducer, initlialTarget, initlialTargetPreview, isHit } from './helpers'; import { HitType, TargetPreviewType, TargetType } from './interfaces'; import './styles/App.scss'; @@ -16,26 +16,6 @@ function App() { const [target, setTarget] = useState(initlialTarget); const [targetPreview, setTargetPreview] = useState(initlialTargetPreview); const [hits, DispatchHits] = useReducer(hitReducer, [] as HitType[]); - const [x, setX] = useState(0); - const [y, setY] = useState(0); - - useEffect(() => { - if (hits.length === count*count) - return; - if (x === count) { - setX(0); - setY(y => y+1); - return; - } - const autoTimer = setTimeout(() => { - DispatchHits({type: 'fireMissle', payload: {hit: (x+y)%2 !== 0, x: x+2, y: y+2}}); - setX(x => x+1); - }, 100); - - return () => { - clearTimeout(autoTimer); - } - }, [x, y, hits.length]); // handle visibility and position change of targetPreview useEffect(() => { @@ -47,11 +27,11 @@ function App() { if (show) { // hide preview to change position when hidden setTargetPreview(e => ({...e, appearOK: false, eventReady: false, show: false})); - } else if (shouldShow && appearOK) { + } else if (shouldShow && appearOK && !isHit(hits, newX, newY).length) { // BUT only appear again if it's supposed to (in case the mouse left over the edge) and () setTargetPreview(e => ({...e, appearOK: false, eventReady: false, show: true, x: newX, y: newY})); } - }, [targetPreview]) + }, [targetPreview, hits]) // enable targetPreview event again after 200 mil. sec. useEffect(() => { @@ -87,7 +67,7 @@ function App() {
{/* Bordes */} - + {/* Collumn lettes and row numbers */} @@ -99,10 +79,10 @@ function App() { {/* Fog images */} {/* */} -
+
-
+
diff --git a/frontend/src/components/BorderTiles.tsx b/frontend/src/components/BorderTiles.tsx index b30f999..b5e5ceb 100644 --- a/frontend/src/components/BorderTiles.tsx +++ b/frontend/src/components/BorderTiles.tsx @@ -1,8 +1,8 @@ -import { CSSProperties } from 'react'; -import { borderCN, cornerCN, fieldIndex } from '../helpers'; -import { TargetPreviewType, TargetType } from '../interfaces'; +import { CSSProperties, Dispatch, SetStateAction } from 'react'; +import { borderCN, cornerCN, fieldIndex, isHit } from '../helpers'; +import { HitDispatchType, HitType, TargetPreviewType, TargetType } from '../interfaces'; -function BorderTiles({count, targets: {setTarget, setTargetPreview}}: {count: number, targets: {setTarget: React.Dispatch>, setTargetPreview: React.Dispatch>}}) { +function BorderTiles({count, actions: {setTarget, setTargetPreview, hits, DispatchHits}}: {count: number, actions: {setTarget: Dispatch>, setTargetPreview: Dispatch>, hits: HitType[], DispatchHits: Dispatch}}) { let tilesProperties: { key: number, isGameTile: boolean, @@ -23,7 +23,7 @@ function BorderTiles({count, targets: {setTarget, setTargetPreview}}: {count: nu if (isGameTile) classNames.push('game-tile'); const classNameString = classNames.join(' ') - tilesProperties.push({key, classNameString, isGameTile, x, y}) + tilesProperties.push({key, classNameString, isGameTile, x: x+1, y: y+1}) } } return <> @@ -31,10 +31,19 @@ function BorderTiles({count, targets: {setTarget, setTargetPreview}}: {count: nu return
{ - if (isGameTile) - setTarget({ show: true, x, y }); + if (!isGameTile && !isHit(hits, x, y).length) + return; + setTarget(t => { + if (t.x === x && t.y === y) { + DispatchHits({type: 'fireMissle', payload: {hit: (x+y)%2 !== 0, x, y}}); + return { show: false, x, y }; + } else { + return { show: true, x, y }; + } + }); + }} onMouseEnter={() => setTargetPreview(e => ({...e, newX: x, newY: y, shouldShow: isGameTile}))} >
diff --git a/frontend/src/helpers.ts b/frontend/src/helpers.ts index da0fcf4..8a14f25 100644 --- a/frontend/src/helpers.ts +++ b/frontend/src/helpers.ts @@ -1,5 +1,28 @@ import { HitType, HitDispatchType } from "./interfaces"; +export const borderCN = (count: number, x: number, y: number) => { + if (x === 0) + return 'left'; + if (y === 0) + return 'top'; + if (x === count+1) + return 'right'; + if (y === count+1) + return 'bottom'; + return ''; +}; +export const cornerCN = (count: number, x: number, y: number) => { + if (x === 0 && y === 0) + return 'left-top-corner'; + if (x === count+1 && y === 0) + return 'right-top-corner'; + if (x === 0 && y === count+1) + return 'left-bottom-corner'; + if (x === count+1 && y === count+1) + return 'right-bottom-corner'; + return ''; +}; +export const fieldIndex = (count: number, x: number, y: number) => y*(count+2)+x; export const hitReducer = (formObject: HitType[], action: HitDispatchType) => { switch (action.type) { @@ -12,29 +35,6 @@ export const hitReducer = (formObject: HitType[], action: HitDispatchType) => { return formObject; } } -export const fieldIndex = (count: number, x: number, y: number) => y*(count+2)+x; -export const cornerCN = (count: number, x: number, y: number) => { - if (x === 0 && y === 0) - return 'left-top-corner'; - if (x === count+1 && y === 0) - return 'right-top-corner'; - if (x === 0 && y === count+1) - return 'left-bottom-corner'; - if (x === count+1 && y === count+1) - return 'right-bottom-corner'; - return ''; -}; -export const borderCN = (count: number, x: number, y: number) => { - if (x === 0) - return 'left'; - if (y === 0) - return 'top'; - if (x === count+1) - return 'right'; - if (y === count+1) - return 'bottom'; - return ''; -}; export const initlialTarget = { show: false, x: 0, @@ -49,4 +49,5 @@ export const initlialTargetPreview = { show: false, x: 0, y: 0 -}; \ No newline at end of file +}; +export const isHit = (hits: HitType[], x: number, y: number) => hits.filter(h => h.x === x && h.y === y); diff --git a/frontend/src/interfaces.ts b/frontend/src/interfaces.ts index 61f9cb2..e1c957a 100644 --- a/frontend/src/interfaces.ts +++ b/frontend/src/interfaces.ts @@ -25,5 +25,6 @@ export interface HitType { }; interface fireMissle { type: 'fireMissle', payload: { x: number, y: number, hit: boolean } }; +interface removeMissle { type: 'removeMissle', payload: { x: number, y: number, hit: boolean } }; -export type HitDispatchType = fireMissle; +export type HitDispatchType = fireMissle | removeMissle;