איקס עיגול|בדיקה האם יש מנצח|js
-
@צבי-ש זו שאלה יפה.
אני חושב שאין מנוס מהזנה של כל הכללים, כלומר שיש שלושה סוגי נצחונות, 3 בשורות, 3 בעמודות ושני אלכסונים.
אבל בא תראה את הקוד שלך:if (allData[1].value === allData[0].value && allData[2].value === allData[0].value){
פה אתה בודק את שורה 1, אתה קודם משווה את אלמנט 1 עם 0, ואח"כ את 2 עם 0.
זה בגלל שיש לך בראש שהשוואה עושים רק 1:1, אולם אתה יכול לקצר ולכתוב ככה:if (allData[1].value === allData[1].value == allData[2].value) {
בשלב שני כשאתה מסתכל על כזו השוואה, אתה יכול לומר שיש פה קטע של התנהגות של בדיקת רצף של שלוש. כשיש לך בקוד קטע של פעולה עם מטרה אחת מוגדרת, זה הזמן להעביר את זה לפונקציה:
function compareLine(array){ return array[0].value == array[1].value == array[2].value; }
בקוד הקורא, ניצלנו משורה ארוכה, אבל עדיין שאלתך עומדת לגבי if שמונה פעמים.
באמת אלגנטי יותר לולאה בכזה מקרה. אתה מכין מערך של 8 רצפים, ובודק את כולם בלולאה. כשיש התאמה אתה מכריז ניצחון:function checkRuls(array){ const listWin = [ [0,1,2], [3,4,5], [6,7,8], //rows [0,3,6], [1,4,7], [2,5,8], //cols [0,4,8], [2,4,6] //alachsonim ]; for(arr of listWin) if(compareLine(arr)) { console.log(`winner ${arr[0].value} by ${arr}"); return true; } }
listWin הוא מערך שכל איבר בו הוא גם מערך (מערך של מערכים). כל אלמנט בו הוא רצף של שלוש שזהים, מביאה ניצחון.
ככה הקוד קריא.
אבל הוא עדיין קשוח. אם תרצה להוסיף טור ושורה, תצטרך לשנות את הקוד הרבה.
אם אתה רוצה שהמחשב יבין את הפרנציפ, אתה צריך ללמד אותו שיש שלוש כללים. ולפי הכללים ייקבעו גם הלולאות ליצירת המערך listWin. -
הקוד שלי שגוי, כי ב
compareLine(arr)
אני מעביר מערך שנראה ככה: [0,1,2] שזה סתם מספרים ולא אלמנט שאפשר לבדוק את הvalue שלו.
לכן צריך לתקן את הקוד ככה:function checkRuls(array){ const listWin = [ [0,1,2], [3,4,5], [6,7,8], //rows [0,3,6], [1,4,7], [2,5,8], //cols [0,4,8], [2,4,6] //alachsonim ]; for(arr of listWin) { const elArr = [allData[arr[0]], allData[arr[1]], allData[arr[2]]]; if(compareLine(arr)) { console.log(`winner ${arr[0].value} by ${arr}"); return true; } } }
אפשר לעשות את זה אלגנטית עם map שבעצם ממיר כל איבר במערך לאיבר אחר רצוי:
function checkRuls(array){ const listWin = [ [0,1,2], [3,4,5], [6,7,8], //rows [0,3,6], [1,4,7], [2,5,8], //cols [0,4,8], [2,4,6] //alachsonim ]; for(arr of listWin) if(compareLine(arr.map(x => allData[x]))) { console.log(`winner ${arr[0].value} by ${arr}"); return true; } }
-
-
@dovid
תודה רבה על המענה המפורט,כאן כתבת
@dovid כתב באיקס עיגול|בדיקה האם יש מנצח|js:
if (allData[1].value === allData[1].value == allData[2].value) {
השוואה אחת עם 2 = ואחת עם 3 =
בדקתי באמת ורק ככה זה עובד,
עריכה: זה גם לא עובד, הפתרון הוא כדלקמן, לעשות פשוט שתי השוואות שונות
אבל אשמח אם תוכל להסביר יותר למה זה לא השוואה שווה אלא אחד == ואחד === ?
ולמה אם אני משווה === בין 3 ערכים שווים יוצא false? -
@dovid כתב באיקס עיגול|בדיקה האם יש מנצח|js:
@צדיק-תמים כי השוואה האחרונה היא מול תוצאת ההשוואה שקדמה לה.
ההשוואה הראשונה מחזירה true, וtrue !== 1.אז בעצם איך לעשות את התנאי?
אם אני רוצה להשוואת בין 3 דברים?
אני משווה רק בין שתיים?
או שיש דרך בין 3 גם?
כי אם כשאני משווה בין 3 ככהa === b
יוצא true
ואז אני ממשיך ומשלים לa === b == c
אז אני בעצם משווה בין true לc
ואמור לצאת false , רק בגלל ששמתי == זה סתם ענה לי true,
כלומר אין לי דרך להשוואת בין 3 ערכים מלבד לעשותa === b & b === c
אני צודק?
או שפיספסתי משהו? -
@צבי-ש כתב באיקס עיגול|בדיקה האם יש מנצח|js:
ואמור לצאת false , רק בגלל ששמתי == זה סתם ענה לי true,
זה לא סתם ענה לך, זה ענה לך true בגלל שבJS (כמו בC) אז 1 == true.
ניצלתי את זה לצרכים שלנו.
אם מדובר בהשוואה אחרת שאינה כוללת רק 1 0 כמו פה, כלומר 2 == 2 == 2 זה אכן לא יעבוד, וחייבים לעשות && ולכפול את ההשוואה.נ.ב. שים לב להשתמש ב&& במקום ב& למרות שנראה שגם השני עובד.
& בודד זה Bitwise AND וזה גם יקר יותר בביצועים וגם יכול להביא תוצאות שגויות (למשל 2 & 1 יחזיר 0 במקום 1)
אם הנושא הזה (או נושא אחר ) מעניין אותך פתח נושא ייעודי.