Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module #2 (Nowshin Owishi) #29

Open
wants to merge 11 commits into
base: module-2
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 67 additions & 56 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const Cell = ({ x, y, type }) => {
const getRandomCell = () => ({
x: Math.floor(Math.random() * Config.width),
y: Math.floor(Math.random() * Config.width),
start: Math.floor(Math.random()*100),
start: Date.now(),
});

//custom hook
Expand All @@ -81,49 +81,62 @@ const UseSnake = () => {
const [foods, setFoods] = useState([]);
const score = snake.length - 3;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as snake state is different from objects state,it makes sense to have a different function for checking snake.And it also makes the code more readable

  const isSnake = useCallback(
    ({ x, y }) =>
      snake.find((position) => position.x === x && position.y === y),
    [snake]
  );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I give an upvote to this. @owishiboo your function can work with all three types but loses simplicity. poison and food are similiar and we put them to one object state, but snake is different so we can keep it seperate fully.
well there is no right or wrong here, it comes down to your opinion.

// ?. is called optional chaining
const isFood = useCallback(({ x, y }) =>
foods.find((position) => position.x === x && position.y === y),[foods]);

const isSnake = useCallback(({ x, y }) =>
snake.find((position) => position.x === x && position.y === y),[snake]);
// ?. is called optional chaining
const isFood = useCallback(
({ x, y }) =>
foods.find((position) => position.x === x && position.y === y),
[foods]
);

const isSnake = useCallback(
({ x, y }) =>
snake.find((position) => position.x === x && position.y === y),
[snake]
);
//restart the game
const resetGame = useCallback(() => {
setSnake(getDefaultSnake());
setDirection(Direction.Right);
setFoods([]);
},[]);
// move the snake
useEffect(() => {
const runSingleStep = () => {
setSnake((snake) => {
const head = snake[0];
const newHead = {
x: (head.x + direction.x + Config.width) % Config.width,
y: (head.y + direction.y + Config.height) % Config.height,
};

// make a new snake by extending head
const newSnake = [newHead, ...snake];

// remove tail when head doesnt eat food
if (!isFood(newHead)) {
newSnake.pop();
}
if (isSnake(newHead)) {
resetGame();
}

return newSnake;
});
};

runSingleStep();
const timer = setInterval(runSingleStep, 300);
}, []);
//moving the snake
const runSingleStep = useCallback(() => {
setSnake((snake) => {
const head = snake[0];
const newHead = {
x: (head.x + direction.x + Config.width) % Config.width,
y: (head.y + direction.y + Config.height) % Config.height,
};

// make a new snake by extending head
const newSnake = [newHead, ...snake];

// remove tail when head doesnt eat food
if (!isFood(newHead)) {
newSnake.pop();
}
if (isSnake(newHead)) {
resetGame();
}

return () => clearInterval(timer);
}, [direction, isFood, isSnake, resetGame]);
return newSnake;
});
}, [direction.x, direction.y, isFood, isSnake, resetGame]);

//add new food
const addFood = () => {
let newFood = getRandomCell();
while (isSnake(newFood) || isFood(newFood)) {
newFood = getRandomCell();
}
setFoods((currentFoods) => [...currentFoods, newFood]);
};
//remove food
const removeFood = useCallback(()=>{
setFoods((currentFoods)=> {
currentFoods.filter((food) => Date.now() - food.start <10000)
})
},[setFoods])
// update score whenever head touches a food
useEffect(() => {
const head = snake[0];
Expand All @@ -134,25 +147,24 @@ const UseSnake = () => {
}
}, [isFood, snake]);

//food after 3s
useEffect(() => {
const interval = setInterval(() => {
let newFood = getRandomCell();
while (isSnake(newFood) || isFood(newFood)) {
newFood = getRandomCell();
const UseInterval = (func, dir) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this outside of useSnake

const timer = useRef(Date.now());
const createCallback = useCallback(() => {
if (Date.now() - timer.current > dir) {
timer.current = Date.now();
func();
}
setFoods((currentFoods) => [...currentFoods, newFood]);
// setTimeout(() => {
// setFoods((f) =>
// f.filter(
// (e) =>
// e.start!==newFood.start
// )
// );
// },10*1000);
}, 3000);
return () => clearInterval(interval);
}, []);
}, [dir, func]);

useEffect(() => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Corei13 why does removefood() doesn't work? it says 'Cannot read properties of undefined (reading 'find')'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@owishiboo because on line 136-138, you are setting setFoods(undefined). Why? Because you are calling setFoods(currentFoords => { expression }. Correct form would be either
a. setFoods(currentFoords => expression (without {} or
b. setFoods(currentFoords => { return expression }

const interval = setInterval(createCallback, 1000 / 60);
return () => clearInterval(interval);
}, [createCallback]);
};

UseInterval(addFood, 3000);
UseInterval(runSingleStep, 300);
UseInterval(removeFood,5000);

const changeDir = (checkDir, newDir) => {
setDirection((direction) => {
Expand Down Expand Up @@ -186,7 +198,6 @@ const UseSnake = () => {
return () => window.removeEventListener("keydown", handleNavigation);
}, []);


return { score, isFood, isSnake };
};

Expand Down