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 #1 (Nowshin Owishi) #17

Open
wants to merge 6 commits into
base: module-1
Choose a base branch
from
Open
Changes from 2 commits
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
98 changes: 75 additions & 23 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ const getRandomCell = () => ({
y: Math.floor(Math.random() * Config.width),
});

const Snake = () => {
//custom hook
//controller
const UseSnake = () => {
const getDefaultSnake = () => [
{ x: 8, y: 12 },
{ x: 7, y: 12 },
Expand All @@ -75,67 +77,110 @@ const Snake = () => {
const [snake, setSnake] = useState(getDefaultSnake());
const [direction, setDirection] = useState(Direction.Right);

const [food, setFood] = useState({ x: 4, y: 10 });
const [score, setScore] = useState(0);
const [foods, setFoods] = useState([{ x: 4, y: 10 }]);
const score = snake.length-3;

const resetGame = () => {
setSnake(getDefaultSnake())
setDirection(Direction.Right)
setFoods([{ x: 4, y: 10 }])
}
// move the snake
useEffect(() => {
const runSingleStep = () => {
setSnake((snake) => {
const head = snake[0];
const newHead = { x: head.x + direction.x, y: head.y + direction.y };
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
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
const newSnake = [newHead, ...snake];

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

return newSnake;
});
};

runSingleStep();
const timer = setInterval(runSingleStep, 500);
const timer = setInterval(runSingleStep, 300);

return () => clearInterval(timer);
}, [direction, food]);
}, [direction]);

// update score whenever head touches a food
useEffect(() => {
const head = snake[0];
if (isFood(head)) {
setScore((score) => {
return score + 1;
});
setFoods(currentFoods =>
currentFoods.filter(food => food.x!==head.x && food.y!==head.y)
);//doesnt work with return
}
}, [snake]);

//food after 3s
useEffect(() => {
const interval = setInterval(()=> {
let newFood = getRandomCell();
while (isSnake(newFood)) {
while (isSnake(newFood) || isFood(newFood)) {
newFood = getRandomCell();
}

setFood(newFood);
}
}, [snake]);
setFoods(currentFoods => [...currentFoods,newFood]);
},3000);

return ( () =>
clearInterval(interval)
)

},[foods])

//food after 10s
//doesnt work
useEffect(() => {
const interval = setInterval(()=> {
setFoods(currentFoods => currentFoods.slice(1))
// currentFoods.shift(); --> doesnt work

},10000);

return ( () =>
clearInterval(interval)
)

},[foods])

const changeDir = (checkDir, newDir) => {
setDirection((direction) => {
if(direction!=checkDir)
return newDir;
return direction;
})

}

useEffect(() => {
const handleNavigation = (event) => {
switch (event.key) {
case "ArrowUp":
setDirection(Direction.Top);
changeDir(Direction.Bottom,Direction.Top);
break;

case "ArrowDown":
setDirection(Direction.Bottom);
changeDir(Direction.Top,Direction.Bottom);
break;

case "ArrowLeft":
setDirection(Direction.Left);
changeDir(Direction.Right,Direction.Left);
break;

case "ArrowRight":
setDirection(Direction.Right);
changeDir(Direction.Left,Direction.Right);
break;
}
};
Expand All @@ -145,12 +190,19 @@ const Snake = () => {
}, []);

// ?. is called optional chaining
// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
const isFood = ({ x, y }) => food?.x === x && food?.y === y;
const isFood = ({ x, y }) =>
foods.find((position)=> position.x === x && position.y === y);

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


return {score,isFood, isSnake}
}

//view
const Snake = () => {
const {score, isFood, isSnake} = UseSnake()
const cells = [];
for (let x = 0; x < Config.width; x++) {
for (let y = 0; y < Config.height; y++) {
Expand Down