Loading...
zdravkostov avatar zdravkostov 4 Точки

Java Advanced, 8. The Heigan Dance

Дава ми 20/100 в Джъдж. Направих си няколко теста и не съм сигурен къде ми е грешката. Логически слаби места са ми:

-ArrayOutOfBoundsException handling - на много места съм сложил много if-ове и може там да имам някъде пропуск

-какво се случва точно ако и двамата умрат по едно и също време? Това не се казва в задачата и там е доста вероятно да имам грешка

 

Условие:

https://softuni.bg/trainings/resources/officedocument/59902/exercise-java-advanced-may-2021/3345

 

Моето Решение:

package JavaAdvanced;

import java.util.Scanner;

public class TheHeiganDance {
    public static void addSpell(int row, int col, boolean[][] arr) {

        if (row - 1 >= 0 && col - 1 >= 0) {
            arr[row - 1][col - 1] = true;
        }
        if (row - 1 >= 0) {
            arr[row - 1][col] = true;
        }
        if (row - 1 >= 0 && col + 1 < 15) {
            arr[row - 1][col + 1] = true;
        }

        if (col - 1 >= 0) {
            arr[row][col - 1] = true;
        }

        arr[row][col] = true;

        if (col + 1 < 15) {
            arr[row][col + 1] = true;
        }

        if (row + 1 < 15 && col - 1 >= 0) {
            arr[row + 1][col - 1] = true;
        }
        if (row + 1 < 15) {
            arr[row + 1][col] = true;
        }
        if (row + 1 < 15 && col + 1 < 15) {
            arr[row + 1][col + 1] = true;
        }
    }

    public static void removeAllSpells(boolean[][] arr) {
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                arr[i][j] = false;
            }
        }
    }

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);

        boolean[][] spellMap = new boolean[15][15];

        double damageDoneToHeigan = Double.parseDouble(scan.nextLine());
        double heiganHitPoints = 3000000;
        int playerHitPoints = 18500;

        String[] data;
        String spell = "";
        int spellRow;
        int spellCol;
        int playerRow = 7;
        int playerCol = 7;

        boolean inevitableDamage;
        boolean poisoned = false;

        while (heiganHitPoints > 0 && playerHitPoints > 0) {
            heiganHitPoints = heiganHitPoints - damageDoneToHeigan;
            if (heiganHitPoints <= 0) {
                break;
            }
            if (poisoned == true) {
                playerHitPoints = playerHitPoints - 3500;
                poisoned = false;
            }

            data = scan.nextLine().split(" ");
            spell = data[0];
            spellRow = Integer.parseInt(data[1]);
            spellCol = Integer.parseInt(data[2]);

            inevitableDamage = false;
            addSpell(spellRow, spellCol, spellMap);

            boolean upWallCheck = false;
            boolean rightWallCheck = false;
            boolean downWallCheck = false;
            boolean leftWallCheck = false;

            if (playerRow + 1 == 15) {
                upWallCheck = true;
            }
            if (playerCol + 1 == 15) {
                rightWallCheck = true;
            }
            if (playerRow - 1 == -1) {
                downWallCheck = true;
            }
            if (playerCol - 1 == -1) {
                leftWallCheck = true;
            }

            boolean moved = false;

            if (spellMap[playerRow][playerCol] == true) {
                if (upWallCheck == false) {
                    if (spellMap[playerRow + 1][playerCol] == false) {
                        playerRow = playerRow + 1;
                        moved = true;
                    }
                }
                if (moved == false) {
                    if (rightWallCheck == false) {
                        if (spellMap[playerRow][playerCol + 1] == false) {
                            playerCol = playerCol + 1;
                            moved = true;
                        }
                    }
                }
                if (moved == false) {
                    if (downWallCheck == false) {
                        if (spellMap[playerRow - 1][playerCol] == false) {
                            playerRow = playerRow - 1;
                            moved = true;
                        }
                    }
                }
                if (moved == false) {
                    if (leftWallCheck == false) {
                        if (spellMap[playerRow][playerCol - 1] == false) {
                            playerCol = playerCol - 1;
                            moved = true;
                        }
                    }
                }
                if (moved == false) {
                    inevitableDamage = true;
                }
            }

            if (inevitableDamage == true) {
                switch (spell) {
                    case "Cloud":
                        playerHitPoints = playerHitPoints - 3500;
                        poisoned = true;
                        break;
                    case "Eruption":
                        playerHitPoints = playerHitPoints - 6000;
                        break;
                }
            }

            removeAllSpells(spellMap);
        }

        if (heiganHitPoints <= 0 && playerHitPoints > 0) {
            System.out.println("Heigan: Defeated!");
            System.out.println("Player: " + playerHitPoints);
        }
        if (heiganHitPoints > 0 && playerHitPoints <= 0) {
            System.out.printf("Heigan: %.2f%n", heiganHitPoints);
            System.out.print("Player: Killed by ");
            if (spell.equals("Cloud")) {
                System.out.println("Plague Cloud");
            } else {
                System.out.println("Eruption");
            }
        }
        if (heiganHitPoints <= 0 && playerHitPoints <= 0) {
            System.out.println("Heigan: Defeated!");
            System.out.print("Player: Killed by ");
            if (spell.equals("Cloud")) {
                System.out.println("Plague Cloud");
            } else {
                System.out.println("Eruption");
            }
        }
        System.out.println("Final position: " + playerRow + ", " + playerCol);
    }
}
Тагове:
0
Java Advanced
ypetroffrs avatar ypetroffrs 2 Точки

Здравей!

Видях, че нулевите тестове преминават успешно. Затова си мисля, че проблемите идват от движението из матрицата при магията и движението на героя.

В while цикъла има break, след като Heigan получи damage. Трябва да го изместиш малко по-долу, след проверката дали предходната атака е Plague Cloud. Така могат да умрат и двамата. Разпишеш ли output-a в съответните проверки ще ти излезе, че Heigan е умрял и че Player-a също е умрял.

В addSpell можеш да използваш for цикъл вместо if проверки (от row - 1 до row + 1 включително, за col е същото) Може би най-важното е да съобразиш, че Heigan може да посочи клетка извън матрицата, но на база свойството магията да обхваща една по-малка матрица 3х3, да засегне поне една клетка от матрицата 15х15. Представи си, че ударът е в клетка 16, 16 - тогава ще засегне само клетка (както е записано и в условието -  A damaging spell will always affect at least one cell) 15, 15, а при теб ще се опита да постави true на несъществуващи клетки, което води до Runtime error. Трябва да провериш параметрите на всяка клетка, преди да ѝ поставиш стойност.

Същото се отнася и до придвижването на героя, когато се опитва да избяга от магията. Проверка дали съседната клета за бягство е в рамките на матрицата и дали е засегната от магията на Heigan.

Накрая искам да кажа, че в проверките не е нужно да пишеш, напр. boolean b == true, ако напишеш името на променливата, проверката ще влезе, само ако е вярна. Ако напишеш името с удивителен отпред, ще влезе, само ако е грешна. Има и други възможности за оптимизация, които можеш да погледнеш в Intellij като натиснеш малкия жълт триъгълник или от менюто долу в ляво избереш problems.

Успех!

ПС: Ако ти трябва код за справка MartinBG е предложил много добро решение:

import java.util.Scanner;
 
public class Pr08TheHeiganDance {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
 
        double hsPoints = 3000000.0;
        int playerPoints = 18500;
 
        int startPlRow = 7;
        int startPlCol = 7;
 
        String lastSpell = "";
        boolean activeCloud = false;
 
        double damage = Double.parseDouble(scanner.nextLine());
 
        while (playerPoints > 0 && hsPoints > 0) {
            hsPoints -= damage;
            
            if (activeCloud) {
                playerPoints -= 3500;
                activeCloud = false;
                
                if (playerPoints < 0) {
                    break;
                }
            }
            
            if (hsPoints < 0) {
                break;
            }
            
            String[] tokens = scanner.nextLine().split("\\s+");
 
            String spell = tokens[0];
            int row = Integer.parseInt(tokens[1]);
            int col = Integer.parseInt(tokens[2]);
 
            boolean[][] hsChamber = new boolean[15][15];
            for (int i = row - 1; i <= row + 1; i++) {
                if (i >= 0 && i < hsChamber.length) {
                    for (int j = col - 1; j <= col + 1; j++) {
                        if (j >= 0 && j < hsChamber[row].length) {
                            hsChamber[i][j] = true;
                        }
                    }
                }
            }
 
            if (hsChamber[startPlRow][startPlCol]) {
                if (isRowValid(hsChamber, startPlRow - 1) && !hsChamber[startPlRow - 1][startPlCol]) {
                    startPlRow--; // move up
                } else if (isColValid(hsChamber, startPlCol + 1) && !hsChamber[startPlRow][startPlCol + 1]) {
                    startPlCol++; // move right
                } else if (isRowValid(hsChamber, startPlRow + 1) && !hsChamber[startPlRow + 1][startPlCol]) {
                    startPlRow++; // move down
                } else if (isColValid(hsChamber, startPlCol - 1) && !hsChamber[startPlRow][startPlCol - 1]) {
                    startPlCol--; // move left
                }
 
                if (hsChamber[startPlRow][startPlCol]) {
                    switch (spell) {
                    case "Cloud":
                        playerPoints -= 3500;
                        activeCloud = true;
                        lastSpell = "Plague Cloud";
                        break;
                    case "Eruption":
                        playerPoints -= 6000;
                        lastSpell = spell;
                        break;
                    default:
                        throw new IllegalArgumentException("Invalid spell: " + spell);
                    }
                }
            }
        }
 
        if (hsPoints > 0) {
            System.out.printf("Heigan: %.2f%n", hsPoints);
        } else {
            System.out.println("Heigan: Defeated!");
        }
        if (playerPoints > 0) {
            System.out.printf("Player: %d%n", playerPoints);
        } else {
            System.out.println("Player: Killed by " + lastSpell);
        }
 
        System.out.println("Final position: " + startPlRow + ", " + startPlCol);
    }
 
    private static boolean isRowValid(boolean[][] hsChamber, int startPlRow) {
        return startPlRow >= 0 && startPlRow < hsChamber[startPlRow].length;
    }
 
    private static boolean isColValid(boolean[][] hsChamber, int startPlCol) {
        return startPlCol >= 0 && startPlCol < hsChamber.length;
    }
}

 

0
26/12/2021 00:55:36
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.