1.1-Introductie-Programmeren

Problem Solving (Probleem oplossing)

Competentie: Ik kan een basis probleem vertalen in Java code

Specifieke leerdoelen:

Samenvatting

Grote (programmeer)problemen kunnen worden opgelost door ze op te splitsen in kleinere problemen. Het probleem maak een getallenraadspel is te groot om zo even in één keer te implementeren. Eerst moet je nadenken over de kleinere stapjes die nodig zijn. Dat kun je doen in gewoon Nederlands. Het begint met goed lezen (of een video kijken) over het probleem dat je moet oplossen. Daarna beschrijf je het in je eigen woorden en probeer je op te splitsen in kleiner stapjes. Steeds opnieuw. Net zolang totdat de stapjes klein genoeg zijn zodanig dat je weet hoe je het zou moeten implementeren in Java (dus in enkele regels code).

Uitleg

Problem Solving gaat over, nogal logisch, problemen oplossen. Als een programmeur wil je problemen oplossen met behulp van code. In dit geval Java code. Programmeren gaat over twee dingen:

  1. Je grote probleem opsplitsen in kleinere probleempjes (dat heet decomposition)
  2. Het vertalen van die stapjes in Java code.

Het is goed om deze twee stappen apart te bekijken als je gaat werken aan een programma.

Stap 1: Een probleem opsplitsen in kleine stapjes

De meeste mensen vinden dit het moeilijkste van programmeren. Dat komt omdat het vergt dat je heel specifiek kijkt naar het probleem en je moet in hele kleine stapjes denken. Dit vergt oefening en ik ga je daarmee proberen te helpen in deze paragraaf. Een goede en klein genoege stap is zo klein dat je het in één of enkele regels kunt programmeren in Java (zoals bijvoorbeeld een regel printen, een if-statement maken, enzovoorts).

1. Beschrijf het probleem duidelijk in je eigen woorden

Laten we aannemen dat we een getallenraadspel willen maken, zoals je al eerder gedaan hebt. De eerste is om het heel gedetailleerd te beschrijven in een taal die voor jou makkelijk is (We gebruiken hier Nederlands, maar Engels of wat ons betreft Twents of Fries mag ook ;-)). Ik kwam bijvoorbeeld hierop:

– Ik wil dat de gebruiker een getal intypt tussen de 1 en de 100 en dat het programma daarna zegt of het getal groter of kleiner is dan het te raden getal. Het programma moet draaien totdat de gebruiker het juiste getal heeft geraden. –

2. Identificeer stukjes die je al weet

Na deze eerste stap kan het handig zijn om eens te kijken of je al stukjes herkent die je eerder gedaan hebt, of dingen die heel eenvoudig zijn in Java. Je weet bijvoorbeeld al hoe je een willekeurig getal tussen de 1 en de 100 kunt uitzoeken. En waarschijnlijk weet je ook wel hoe je twee getallen kunt vergelijken in een if. Daarnaast kom je er misschien wel op dat “het programma moet draaien totdat” neerkomt op een while loop. Tot slot ontdek je misschien ook nog dat er gebruikersinvoer gevraargd wordt. Je weet misschien al wel dat dat met SaxionApp.read...() kan.

3. Schrijf de stappen op in het Nederlands (of een andere taal)

Nu je een kleine analyse op het probleem hebt gedaan kun je aan de slag met het schrijven van stapjes. Doe dat niet gelijk in Java, maar wel gelijk in een Java project in IntelliJ. Het handigst is ze als commentaarregels op te nemen. Bijvoorbeeld als volgt: (Ik heb het vanaf hier even in het Engels gedaan).

public class Application implements Runnable {

    public static void main(String[] args) {
        SaxionApp.start(new Application(), 1024, 768);
    }

    public void run() {
        //Pick a random number

        //Ask the user for a number

        //Check if the number is bigger or smaller and print that to the user

        //When the user guesses the correct number, end the game
    }
}

4. Kijk terug op je stappen

Ok. Goed gedaan! Misschien had je gezien dat er een loop in het programma moet, omdat je de gebruiker telkens opnieuw wilt vragen om nummers in te typen. We kunnen een beetje meer detail en nesting toevoegen in onze pseudo code.

Dus laten we dat doen:

public class Application implements Runnable {

    public static void main(String[] args) {
        SaxionApp.start(new Application(), 1024, 768);
    }

    public void run() {
        //Pick a random number between 1 and 100

        //As long as the number is not guessed...
            //Print "Type a number" and ask the user for a number

            //Check if the number is bigger or smaller and print that to the user

            //When the user guesses the correct number, Congratulate the user and end the game

    }
}

Je ziet dat het er al een beetje als een Java programma uitziet. Het idee is dat je dit net zolang doet totdat je een lijst van stappen krijgt waarvan je per stap weet hoe je die zou moeten bouwen in Java. Ik denk dat de bovenstaande stappen daarvoor goed genoeg zijn. Want ik denk dat je elke afzonderlijke stap wel weet. Misschien is het lastigste nog de “As long as…” zin. Daarvoor zou ik een boolean numberGuessed maken en die default op false zetten. Dan wordt de while dus while (!numberGuessed) {.

Stap 2: Vertaal de stappen in Java code

Zodra je klein genoege stappen beschreven hebt kun je onder elke commentaarregel de juiste code typen.

Het is een goed gebruik om je Java programma heel vaak te runnen. Elke keer als je een klein stukje functionaliteit hebt toegevoegd test je het even. Soms ontdek je dat het handiger is om eerst een stukje te maken dat wat verderop in je programma zit. Dat is prima. Hier zou je bijvoorbeeld eerst het vergelijken van getallen kunnen bouwen, daarbij gebruikmakend van twee hardcoded getallen.

Een ander ding dat kan gebeuren is dat je stappen toch wat meer code innemen dan je hoopte. Dan zou je voor sommige van die stappen een methode kunnen maken. Zo maak je een methode voor een klein stukje functionaliteit (Lees de informatie over methodes voor details. Het mooie van methodes is dat je ze altijd los van elkaar kunt testen door ze vanuit de run-methode aan te roepen.

Mocht je nu helemaal vast lopen, probeer dan terug te gaan naar het moment dat je programma nog wel werkt (control-z is je vriend).

Succes! Hieronder staat de implementatie van het getallenraadspel dat we hierboven bedachten. Ik weet dat het een vrij klein probleem is, maar grotere problemen kun je op een vergelijkbare manier aanpakken.

public class Application implements Runnable {

    public static void main(String[] args) {
        SaxionApp.start(new Application(), 1024, 768);
    }

    public void run() {
        //Pick a random number between 1 and 100
        int number = SaxionApp.getRandomValueBetween(1, 101);

        //As long as the number is not guessed...
        boolean numberGuessed = false;
        while (!numberGuessed) {
            //Print "Type a number" and ask the user for a number
            SaxionApp.printLine("Type a number: ");
            int userInput = SaxionApp.readInt();

            //Check if the number is bigger or smaller and print that to the user
            if (userInput < number) {
                SaxionApp.printLine("Too low. Try again!");
            } else if (userInput > number) {
                SaxionApp.printLine("Too high. Try again!");
            } else {
                //When the user guesses the correct number, Congratulate the user and end the game
                //(Please note: When it's not higher, and not lower than it is the correct number
                SaxionApp.printLine("Congratulations");
                numberGuessed = true;
            }

        }
        
    }
}