diff --git a/src/App.js b/src/App.js
index 6cdf5dc..5d2af09 100644
--- a/src/App.js
+++ b/src/App.js
@@ -6,19 +6,33 @@ import { useEffect } from "react";
import ShowMessage from './ShowMessage.js';
import { levels } from './Levels';
+// Ada errors di console:
+// react-dom.development.js:86 Warning: Encountered two children with the same key, `[object Object]`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
+// at div
+
+// pas kelar muncul ini, keknya dia akses array index yang terlalu kanan?
+// perlu bikin corner case buat handle ini
+// App.js:11 Uncaught TypeError: Cannot read properties of undefined (reading 'initialBody')
+
export default function App() {
const [currentLevel, setCurrentLevel] = useState(0);
+ // mungkin player movement handling sama setup handling bisa dipisah, player movement handling mungkin bisa di context? https://reactjs.org/docs/hooks-reference.html#usecontext
+ // board handling di context terpisah mubgkin juga bisa
const initialBody = levels[currentLevel].initialBody;
const walls = levels[currentLevel].walls;
const goal = levels[currentLevel].goal;
- const length = levels[currentLevel].length;
+ const length = levels[currentLevel].length; // naming can be improved. ini length apa? probably something like gridDimension?
const superJump = levels[currentLevel].superJump;
const switchClockwise = levels[currentLevel].switchClockwise;
+
+ // why do you decide buat pake reducer?
const [player, dispatch] = useReducer(
PlayerManager,
{position: {...initialBody.position}, stepRemaining: {...initialBody.stepRemaining}, stepRange: initialBody.stepRange}
);
-
+
+ // function2 gini keknya enak dipisah jadi utils function aja kali biar gampang liatnya
+ // wait itu di MoveDirection file ada function2 yang mirip gini....
function isPossible({nextPlace, can}){
if(walls.find(wall => wall.koorX === nextPlace.koorX && wall.koorY === nextPlace.koorY))can = false;
return nextPlace.koorX > 0 && nextPlace.koorX <= length && nextPlace.koorY > 0 && nextPlace.koorY <= length && can;
@@ -27,6 +41,7 @@ export default function App() {
return nextPlace.koorX === goal.koorX && nextPlace.koorY === goal.koorY & can;
}
function isSuperJump({nextPlace}){
+ // sama aja kek return superJump.find(twoTimes => twoTimes.koorX === nextPlace.koorX && twoTimes.koorY === nextPlace.koorY)
if(superJump.find(twoTimes => twoTimes.koorX === nextPlace.koorX && twoTimes.koorY === nextPlace.koorY)){
return true;
}
@@ -36,7 +51,11 @@ export default function App() {
return switchClockwise.find(clockwise => clockwise.koorX === nextPlace.koorX && clockwise.koorY === nextPlace.koorY);
}
function moveDirection(e){
+ // Instead of if(condition) { ... very long logic .... } prefer if(!condition) return;
+ // Soalnya kalo orang baca, dia perlu inget kalo "ini di dalam if" sampe baca logicnya selesai
if(e.key === 'a' || e.key === 'd' || e.key === 'w' || e.key === 's'){
+ // keknya instead pake string 'left' 'right' gitu2 lebih bagus pake enum (at least constant kek diluar ada `const LEFT_DIRECTION = 1` dll)
+ // soalnya kalo pake simple string kalo typo gg debugnya susah
let direction = 'null';
if(e.key === 'a')direction = 'left';
if(e.key === 'd')direction = 'right';
@@ -102,6 +121,8 @@ export default function App() {
return (
+ {/* ah cara pakenya ga gini kalo bikin functional components */}
+ {/* function Component({a, b}){} gitu pakenya */}
{createGrid({player, length, walls, goal, superJump, switchClockwise})}
{ShowMessage({player})}
diff --git a/src/Levels.js b/src/Levels.js
index 28daa8c..076adad 100644
--- a/src/Levels.js
+++ b/src/Levels.js
@@ -1,5 +1,6 @@
export const levels = [
{
+ // I guess initialPlayerConfig is a better naming?
initialBody: {
position: {koorX: 1, koorY: 5},
stepRange: 1,
diff --git a/src/MoveDirection.js b/src/MoveDirection.js
index 2ac90c4..cd7f505 100644
--- a/src/MoveDirection.js
+++ b/src/MoveDirection.js
@@ -1,3 +1,6 @@
+// filename should be utils?
+// PascalCase cuma dipake kalo dia mainnya Component, dan ditulis dalam Noun
+// kalo utils atau helper functions pakenya camelCase
function isPossible({nextPlace, can, walls, length}){
if(walls.find(wall => wall.koorX === nextPlace.koorX && wall.koorY === nextPlace.koorY))can = false;
return nextPlace.koorX > 0 && nextPlace.koorX <= length && nextPlace.koorY > 0 && nextPlace.koorY <= length && can;
diff --git a/src/PlayerManager.js b/src/PlayerManager.js
index 8824e2b..d6a9ffb 100644
--- a/src/PlayerManager.js
+++ b/src/PlayerManager.js
@@ -1,3 +1,4 @@
+// reducePlayer? PlayerManager itu Noun sedangkan dia melakukan logic here, should use verb as function name here
export default function PlayerManager(player, action){
switch (action.type){
case 'movePlayer': {
diff --git a/src/ShowMessage.js b/src/ShowMessage.js
index f75b966..a60b0bb 100644
--- a/src/ShowMessage.js
+++ b/src/ShowMessage.js
@@ -1,3 +1,4 @@
+// Message (Noun) should be more accurate
export default function ShowMessage({player}){
let upStep = `(press w) up: ${player.stepRemaining.upStep}`;
let downStep = `(press s) down: ${player.stepRemaining.downStep}`;
@@ -6,6 +7,9 @@ export default function ShowMessage({player}){
return(
{upStep}
+ {/* 1) component kosong biasa ditulisnya */}
+ {/* 2) gimana kalo ditulis penuh disini instead pake variable diatas ya? instead of {rightStep} prefer kayak (press d) right: ${player.stepRemaining.rightStep}*/}
+ {/* Agak ga konsisten sebagian jadi variabel sebagian jadi html */}
{rightStep}
diff --git a/src/createGrid.js b/src/createGrid.js
index 30b5865..50a1d4b 100644
--- a/src/createGrid.js
+++ b/src/createGrid.js
@@ -12,6 +12,12 @@ const Container = styled.div`
height: 50vw;
`
+// keknya lebih bagus dibikin terpisah, kek
+// const PlayerBox = styled(Box)`
+// background: green;
+// `;
+// and so on
+// terus bisa bikin component lain / utils function yang ngurus if conditionnya
const Box = styled.div`
border-color: black;
border-style: solid;
@@ -34,14 +40,17 @@ const Box = styled.div`
`}
`;
+// btw mungkin bisa consider pake prettier (https://prettier.io/) buat autoformatter jadi consistent, ini ada yang belakangnya pake ; ada yang engga
const Baris = styled.div`
display: flex;
flex-grow: 1;
`
+// Ini namanya functional component, dia itu Component bukan action, jadi namingnya mestinya Noun, kek Grid gitu
export default function CreateGrid({player, length, walls, goal, superJump, switchClockwise}){
const [boxes, setBoxes] = useState([]);
useEffect(() => {
+ // ini berarti tiap player movement dia dibikin semua baru? kayaknya agak kurang efisien deh, mungkin pake ide separated component di atas (yang aku tulis di Box) jadi dia self rerendernya kalo diperlukan aja
let nextId = 0;
const newBoxes = [];
for(let i = 1 ; i <= length ; i++){
@@ -72,6 +81,7 @@ export default function CreateGrid({player, length, walls, goal, superJump, swit
return(
{
+ // kalo one liner prefer langsung a.map(elem =>
{elem}
) gitu instead pake return lagi
boxes.map((row, i)=> {
return(