حرکت روی گرید بدون بیرون زدن از مرزها
خلاصهٔ کاملتر
وبلاگ kirupa تو ادامهٔ سری ساختمان دادهها و الگوریتمها سراغ یه مسئلهٔ خیلی پایهای رفته: چطور یه شخصیت رو خونهبهخونه روی گرید (همون شبکهٔ سلولی که هر خونهش یه آدرس x و y داره) حرکت بدیم و نذاریم از لبهها بیرون بزنه. مثال مقاله یه دنیای ۱۰ در ۱۰ هست با یه فضایی به اسم Zorb که از خونهٔ (۴, ۴) شروع میکنه و با کلیدهای جهتدار، WASD یا سوایپ جابهجا میشه.
ایدهٔ اصلی یه الگوی سهمرحلهایه: propose، validate و commit. اول جهت درخواستی به یه جفت offset ترجمه میشه؛ یه آبجکت DIRECTIONS که مثلاً right رو به [1, 0] و up رو به [0, -1] نگاشت میکنه. بعد این offset به موقعیت فعلی اضافه میشه و یه خونهٔ کاندید به دست میاد. نویسنده تأکید میکنه که کاندید هنوز موقعیت واقعی نیست، مثل یه برگهٔ یادداشته که اگه ایراد داشت مچالهش میکنی و Zorb سر جاش میمونه.
شرط معتبر بودن دو تا بازهست: x از صفر تا کمتر از تعداد ستونها، و y از صفر تا کمتر از تعداد سطرها. یعنی سمت چپ بازه خودِ صفر رو شامل میشه ولی سمت راست خودِ اندازهٔ گرید رو نه. به گفتهٔ نویسنده همین تفاوت ریز، مسئول کوهی از خطاهای off-by-one تو کدهاست. کل قانون مرز هم تو یه تابع کوچیک جمع شده:
function inBounds(x, y) {
return x >= 0 && x < cols &&
y >= 0 && y < rows;
}تابع tryMove سه مرحله رو کنار هم میذاره: offset جهت رو برمیداره، مختصات بعدی رو حساب میکنه، و فقط وقتی inBounds تأییدش کرد موقعیت واقعی player رو عوض میکنه و دوباره رندر میگیره. اگه کاندید بیرون گرید باشه، تابع زودتر با return false تموم میشه. یعنی مقدار نامعتبر حتی برای یه لحظه هم وارد state نمیشه:
function tryMove(direction) {
const [xOffset, yOffset] = DIRECTIONS[direction];
const nextX = player.x + xOffset;
const nextY = player.y + yOffset;
if (!inBounds(nextX, nextY)) return false;
player.x = nextX;
player.y = nextY;
render();
}فایدهٔ این جداسازی اینه که ورودی هرچی باشه، کیبورد یا دکمه یا سوایپ، همه به همون یه تابع میرسن؛ پس قانون مرز فقط تو یه نقطه نوشته شده و برای عوض کردنش لازم نیست سه جا رو دست بزنی. نویسنده آخر مقاله میگه تو قسمت بعدی همین خط لولهٔ propose و validate و commit رو نگه میداره و بهش مانع اضافه میکنه؛ یعنی خونههایی که از نظر مختصات معتبرن ولی نباید بشه واردشون شد.
نکات کلیدی:
- الگوی حرکت سه مرحله داره: propose (ساخت کاندید)، validate (چک مرز)، commit (ثبت موقعیت)
- هر جهت یه offset دوتایی داره؛ مثلاً right برابر [1, 0] و up برابر [0, -1]
- شرط معتبر بودن: صفر تا کمتر از تعداد ستونها برای x و کمتر از تعداد سطرها برای y
- تو گرید ۱۰ در ۱۰، خونهٔ (۰, ۰) بالا-چپ و (۹, ۹) پایین-راسته؛ (۱۰, ۴) وجود نداره
- موقعیت نامعتبر هیچوقت وارد state نمیشه، فقط به عنوان کاندید رد میشه
- قسمت بعدی سری، همین الگو رو با اضافه کردن مانع روی خونهها ادامه میده




