From c2a29de42db37dfdc0213c610be7ca067e61e395 Mon Sep 17 00:00:00 2001 From: Shibi Suriya Date: Fri, 29 Sep 2023 00:39:04 +0530 Subject: [PATCH] Impemented direction guard --- src/App.jsx | 85 +++++++++++++++++++++++++++--------------------- src/constants.js | 13 ++++---- src/utils.js | 17 +++++++++- 3 files changed, 71 insertions(+), 44 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 1df3a05..ceb87ad 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,20 +1,25 @@ import React, { useState, useEffect, useRef } from 'react'; -import { generateKey } from './utils'; +import { generateKey, getOppositeDirection } from './utils'; +import { DIRECTIONS } from './constants'; import Grid from './Grid'; const SPEED = 1 * 100; -const DIRECTION = { - UP: 'up', - DOWN: 'down', - LEFT: 'left', - RIGHT: 'right', -}; - function App() { - const [currentDirection, setCurrentDirection] = useState(DIRECTION.RIGHT); + const currentDirection = useRef(DIRECTIONS.RIGHT); + const [snake, setSnake] = useState({ + // snake is based on the ordered hashmap data structure. + hash: { + '0-0': { x: 0, y: 0 }, + '0-1': { x: 0, y: 1 }, + '0-2': { x: 0, y: 2 }, + '0-3': { x: 0, y: 3 }, + }, + list: ['0-3', '0-2', '0-1', '0-0'], + }); function moveForward() { + console.log(snake.list[0], ' ', Date.now()); setSnake((prevSnake) => { const updatedHash = { ...prevSnake.hash }; const updatedList = [...prevSnake.list]; @@ -27,22 +32,22 @@ function App() { const [headKey] = updatedList; const head = updatedHash[headKey]; - if (currentDirection == DIRECTION.RIGHT) { + if (currentDirection.current == DIRECTIONS.RIGHT) { const newHead = { x: head.x, y: head.y + 1 }; const newHeadKey = generateKey(newHead.x, newHead.y); updatedHash[newHeadKey] = newHead; updatedList.unshift(newHeadKey); - } else if (currentDirection == DIRECTION.UP) { + } else if (currentDirection.current == DIRECTIONS.UP) { const newHead = { x: head.x - 1, y: head.y }; const newHeadKey = generateKey(newHead.x, newHead.y); updatedHash[newHeadKey] = newHead; updatedList.unshift(newHeadKey); - } else if (currentDirection == DIRECTION.DOWN) { + } else if (currentDirection.current == DIRECTIONS.DOWN) { const newHead = { x: head.x + 1, y: head.y }; const newHeadKey = generateKey(newHead.x, newHead.y); updatedHash[newHeadKey] = newHead; updatedList.unshift(newHeadKey); - } else if (currentDirection == DIRECTION.LEFT) { + } else if (currentDirection.current == DIRECTIONS.LEFT) { const newHead = { x: head.x, y: head.y - 1 }; const newHeadKey = generateKey(newHead.x, newHead.y); updatedHash[newHeadKey] = newHead; @@ -53,20 +58,37 @@ function App() { }); } - const up = () => { - setCurrentDirection(DIRECTION.UP); + const moveUp = () => { + if (currentDirection.current == DIRECTIONS.UP) { + // moving up only. + return; + } else if (getOppositeDirection(currentDirection.current) !== DIRECTIONS.UP) { + currentDirection.current = DIRECTIONS.UP; + } }; - const down = () => { - setCurrentDirection(DIRECTION.DOWN); + const moveDown = () => { + if (currentDirection.current == DIRECTIONS.DOWN) { + return; + } else if (getOppositeDirection(currentDirection.current) !== DIRECTIONS.DOWN) { + currentDirection.current = DIRECTIONS.DOWN; + } }; - const right = () => { - setCurrentDirection(DIRECTION.RIGHT); + const moveRight = () => { + if (currentDirection.current == DIRECTIONS.RIGHT) { + return; + } else if (getOppositeDirection(currentDirection.current) !== DIRECTIONS.RIGHT) { + currentDirection.current = DIRECTIONS.RIGHT; + } }; - const left = () => { - setCurrentDirection(DIRECTION.LEFT); + const moveLeft = () => { + if (currentDirection.current == DIRECTIONS.LEFT) { + return; + } else if (getOppositeDirection(currentDirection.current) !== DIRECTIONS.LEFT) { + currentDirection.current = DIRECTIONS.LEFT; + } }; useEffect(() => { @@ -75,31 +97,20 @@ function App() { document.addEventListener('keydown', (event) => { const key = event.key.toLowerCase(); if (['w', 'arrowup'].includes(key)) { - up(); + moveUp(); } else if (['s', 'arrowdown'].includes(key)) { - down(); + moveDown(); } else if (['a', 'arrowleft'].includes(key)) { - left(); + moveLeft(); } else if (['d', 'arrowright'].includes(key)) { - right(); + moveRight(); } }); return () => { clearInterval(timer); }; - }, [currentDirection, snake]); - - // snake is based on the ordered hashmap data structure. - const [snake, setSnake] = useState({ - hash: { - '0-0': { x: 0, y: 0 }, - '0-1': { x: 0, y: 1 }, - '0-2': { x: 0, y: 2 }, - '0-3': { x: 0, y: 3 }, - }, - list: ['0-3', '0-2', '0-1', '0-0'], - }); + }, [snake]); return (
diff --git a/src/constants.js b/src/constants.js index ba9d3a5..45e7915 100644 --- a/src/constants.js +++ b/src/constants.js @@ -6,10 +6,11 @@ const CELL_DIMENSION = 30; const NUMBER_OF_ROWS = GRID_HEIGHT / CELL_DIMENSION; const NUMBER_OF_COLUMNS = GRID_WIDTH / CELL_DIMENSION; -export { - GRID_HEIGHT, - GRID_WIDTH, - CELL_DIMENSION, - NUMBER_OF_COLUMNS, - NUMBER_OF_ROWS, +const DIRECTIONS = { + UP: 'up', + DOWN: 'down', + LEFT: 'left', + RIGHT: 'right', }; + +export { GRID_HEIGHT, GRID_WIDTH, CELL_DIMENSION, NUMBER_OF_COLUMNS, NUMBER_OF_ROWS, DIRECTIONS }; diff --git a/src/utils.js b/src/utils.js index 18bb6dc..41ea5d5 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,4 +1,4 @@ -import { NUMBER_OF_COLUMNS, NUMBER_OF_ROWS } from './constants'; +import { NUMBER_OF_COLUMNS, NUMBER_OF_ROWS, DIRECTIONS } from './constants'; export const generateKey = (i, j, columns, rows) => { // TODO: tighten this code. @@ -7,3 +7,18 @@ export const generateKey = (i, j, columns, rows) => { // } return `${i}-${j}`; }; + +export const getOppositeDirection = (direction) => { + switch (direction) { + case DIRECTIONS.DOWN: + return DIRECTIONS.UP; + case DIRECTIONS.UP: + return DIRECTIONS.DOWN; + case DIRECTIONS.LEFT: + return DIRECTIONS.RIGHT; + case DIRECTIONS.RIGHT: + return DIRECTIONS.LEFT; + default: + throw new Error(`Invalid direction, ${direction}.`); + } +};