# Nim-Spiel programmieren so richtig?



## Loddakwin (6. Nov 2015)

Hey Leute,

ich bins schon wieder ich weiß ich erstelle momentan einige Themen aber es ist für mich richtig schwierig herauszufinden ob ich auf dem richtigen weg bin oder nicht. Wir bekommen auch dementsprechend viele Aufgaben auf der Uni und ich wüsste nicht wie ich die sonst alle fertigstellen könnte gäbe es dieses forum nicht. Ich wollte mal nachfragen ob ich auf dem richtigen weg bin was das Programm betrifft.


```
public class Bsp04 {

    static int sp;
    static int co;
    static int n = PRNG.randomInt(100 - 10 + 1) + 10;

    public static void main(String[] args) {

        while (n > 0) {
            System.out.println("asdasdasdasdsd");
            moveHuman(co);
            moveComputerBasic(sp);
        }

    }

    // prompts the user to input a valid number to remove from n balls and
    // returns it
    static int moveHuman(int co) {
        sp = co;

        System.out.print("Verbleibende Kugeln: " + n);
        System.out.print("     Wie viele Kugeln entfernen (1 bis " + pruef(n) + ")? ");
        int eingabe = SavitchIn.readInt();
        System.out.println("                 Du -" + eingabe);

        n = n - eingabe;
        sp = n;

        if (n == 0) {
            System.out.print("Gewinner: Computer!");
        }

        return sp;

    }

    // chooses a number to remove from n balls according to basic strategy and
    // returns it
    static int moveComputerBasic(int sp) {
        co = sp;
        int zufall = 0;

        System.out.println("Verbleibende Kugeln: " + n);

        if (n == 0) {
            System.out.print("Gratuliere dir zum Gewinn!");
        } else if(n == 1) {
            zufall = 1;
        } else {
            int halb = n / 2;
            zufall = PRNG.randomInt(halb - 1 + 1) + 1;

        }

        n = n - zufall;
        System.out.println("           Computer -" + zufall);
        co = n;

        return co;
    }

    // chooses a number to remove from n balls according to smart strategy and
    // returns it
    static int moveComputerSmart(int n) {
        return n;
    }

    static int pruef(int n) {
        if (n == 1) {
            n = 1;
        } else {
            n = n / 2;
        }
        return n;
    }
}
```

lg


----------



## Loddakwin (7. Nov 2015)

Kann mir keiner einen Tipp geben? Bitte


----------



## Tobse (7. Nov 2015)

Also erstmal: mach dir keinen Kopf darum, wieviele Themen du erstellst. Gut programmieren zu lernen ist nicht einfach und wir helfen gerne.

Was die konkrete Frage angeht: Die Aufgabenstellung lässt gegenüber deiner Lösung nicht viel Raum für Verbesserungsmöglichkeiten. Wenn dein Progamm tut, was es soll, ist es so in Ordnung, würde ich sagen.


----------



## Loddakwin (7. Nov 2015)

Naja das ist ja das Problem ich bekomme immer eine fehlermeldung bei der Abgabe zurück.



> Wrong result(s) detected. Please check the return values of your methods and compare them to the expected return values below!
> Exception in thread "test" java.lang.Exception:
> Part 1
> >> Input <<
> ...



Ich weiß aber nicht wie ich es abändern muss damit ich das nicht mehr bekomme 

lg


----------



## Tobse (7. Nov 2015)

Steht ja direkt drin: Beim aufruf von moveHuman(1) versucht dein Code, 97 Kugeln zu entfernen. Da ist was faul


----------



## Loddakwin (7. Nov 2015)

ich hab das ganze jetzt umgeschrieben jetzt hab ich wieder das problem das ich die methoden in der schleife nicht random aufrufen kann -.-

```
//
public class Bsp04 {

    static int sp;
    static int co;
    static int eingabe;
    static int zufall;
    static int n = PRNG.randomInt(100 - 10 + 1) + 10;

    public static void main(String[] args) {

        int ent = PRNG.randomInt(2);

        while (n > 0) {
            System.out.print("Verbleibende Kugeln: " + n);
            moveHuman(n);
            System.out.println("                 Du -" + eingabe);
            n = n - eingabe;
            if (n == 0) {
                System.out.print("Gewinner: Computer!");
                break;
            }
            System.out.println("Verbleibende Kugeln: " + n);
            moveComputerBasic(n);
            System.out.println("           Computer -" + zufall);
            n = n - zufall;
            if (n == 0) {
                System.out.print("Gratuliere dir zum Gewinn!");
            }
        }

    }

    // prompts the user to input a valid number to remove from n balls and
    // returns it
    static int moveHuman(int n) {

        System.out.print("    Wie viele Kugeln entfernen ( 1 bis " + pruef(n) + ")? ");
        eingabe = SavitchIn.readInt();

        return eingabe;
    }

    // chooses a number to remove from n balls according to basic strategy and
    // returns it
    static int moveComputerBasic(int n) {

        int halb = n / 2;
        zufall = (int) (Math.random() * halb + 1);

        return zufall;
    }

    // chooses a number to remove from n balls according to smart strategy and
    // returns it
    static int moveComputerSmart(int n) {
        return n;
    }

    static int pruef(int n) {
        if (n == 1) {
            n = 1;
        } else {
            n = n / 2;
        }
        return n;
    }

}
```


----------



## Tobse (7. Nov 2015)

EDIT:
Sorry, hab mist gepostet.

Wieso ist es ein Problem, dass du die Methoden nicht beliebig aufrufen kannst? SIe haben ja eine ganz klare aufgabe im Programm.


----------



## Loddakwin (7. Nov 2015)

Wie kann ich die methoden in der schleife zufällig aufrufen? Vl ein Tipp?


----------



## Tobse (7. Nov 2015)

Ich weiss nicht, was du mit "zufällig aufrufen" meinst. Du hast doch das Math.random() in moveComputerBasic


----------



## Loddakwin (7. Nov 2015)

In der Angabe steht "Danach ist mittels Zufall festzulegen, wer den ersten Zug macht." ^^

lg


----------



## Tobse (7. Nov 2015)

Achso, sorry, hatte ich nichtmehr im Kopf. Was mir spontan einfällt:


```
/* true = mensch, false = computer */
boolean spielerAmZug = Math.random() > 0.5d;

while (n > 0) {
    if (spielerAmZug) {
        // mensch
    } else {
        // computer
    }
    spielerAmZug = !spielerAmZug;
}
```


----------



## klauskarambulut (7. Nov 2015)

```
public class Bsp04 {

//    static int sp;  // Weg damit weil hat hier nichts zu suchen
//    static int co; //
//    static int eingabe;//
//    static int zufall;
//    static int n = PRNG.randomInt(100 - 10 + 1) + 10;

    public static void main(String[] args) {

//        int ent = PRNG.randomInt(2);
      int n = PRNG.randomInt(91) +10;
// Wer zieht zuerst
       if(0 < PRNG.randomInt(2)) {
        int computerMove = moveComputerBasic(n);
              n = n - computerMove;
              if (n == 0) {
                  System.out.print("Gratuliere dir zum Gewinn!");
                }
          }
       }

        while (n > 0) {
         
           int yourMove = moveHuman(n);
           n = n - yourMove;
            if (n == 0) {
                System.out.print("Gewinner: Computer!");
                break;
            }

            int computerMove = moveComputerBasic(n);
            n = n - computerMove;
            if (n == 0) {
                System.out.print("Gratuliere dir zum Gewinn!");
                break;
            }
        }
    }

    // prompts the user to input a valid number to remove from n balls and
    // returns it
    static int moveHuman(int n) {
        System.out.print("Verbleibende Kugeln: " + n);
        System.out.print("    Wie viele Kugeln entfernen ( 1 bis " + pruef(n) + ")? ");
        int eingabe = SavitchIn.readInt();
        System.out.println("                Du -" + eingabe);
        return eingabe;
    }

    // chooses a number to remove from n balls according to basic strategy and
    // returns it
    static int moveComputerBasic(int n) {
        System.out.println("Verbleibende Kugeln: " + n);
        int pruef = pruef(n);
        int zufall = PRNG.randomInt(pruef) + 1; // mit Sicherheit nicht Math.int, da dies sonst nicht überprüft werden kann.
        System.out.println("          Computer -" + zufall);
        return zufall;
    }

    // chooses a number to remove from n balls according to smart strategy and
    // returns it
    static int moveComputerSmart(int n) {
        return n;
    }

    static int pruef(int n) {
        if (n == 1) {
            n = 1;
        } else {
            n = n / 2;
        }
        return n;
    }

}
```


----------



## Loddakwin (7. Nov 2015)

Wie würde ich es bei 3 methoden machen ? Da bei meiner Aufgabe noch eine 3 hinzu kommt.

lg


----------



## Tobse (7. Nov 2015)

Jetzt aber mal im ernst: das benötigt genau 1 if statement, das kriegst du ja selber hin, oder?


----------



## Loddakwin (8. Nov 2015)

Ok danke Leute ich hab das jetzt umgesetzt und es funktioniert einwandfrei. Jetzt steh ich aber vor dem nächsten Problem und zwar bei der moveComputerSmart methode. Da heißt es in der Angabe 


> Bei Anwendung der _smart_-Strategie versucht der Computer so viele Kugeln zu entfernen, dass die Anzahl der verbleibenden eine Zweierpotenz minus 1 beträgt (also: 1, 3, 7, 15, ...). Ist dies nicht möglich, dann erfolgt eine zufällige Auswahl (wie bei der basic-Strategie).
> 
> Programmieren Sie auch die smart-Strategie mittels der oben genannten Methode und erweitern Sie nun Ihr Programm, sodass zu Beginn eines Spiels die Strategie des Computers zufällig ausgewählt wird. Das Ausgabeformat bleibt unverändert.



Also wie ich das jetzt geschrieben habe macht es das auch? Oder versteh ich in der Angabe irgendwas falsch?


```
public class Bsp04 {

    public static void main(String[] args) {

        int n = PRNG.randomInt(91) + 10;
        int ent = PRNG.randomInt(2);

        if (0 < PRNG.randomInt(2)) {
            if (ent == 0) {
                int computerBasic = moveComputerBasic(n);
                n = n - computerBasic;
            } else {
                int computerSmart = moveComputerSmart(n);
                n = n - computerSmart;
            }
        }

        while (n > 0) {

            int yourMove = moveHuman(n);
            n = n - yourMove;
            if (n == 0) {
                System.out.print(" Gewinner: Computer!");
                break;
            }

            if (ent == 0) {
                int computerBasic = moveComputerBasic(n);
                n = n - computerBasic;
                if (n == 0) {
                    System.out.print(" Gratuliere dir zum Gewinn!");
                    break;
                }
            } else {
                int computerSmart = moveComputerSmart(n);
                n = n - computerSmart;
                if (n == 0) {
                    System.out.print(" Gratuliere dir zum Gewinn!");
                    break;
                }
            }
        }
    }

    // prompts the user to input a valid number to remove from n balls and
    // returns it
    static int moveHuman(int n) {
        System.out.print("Verbleibende Kugeln: " + n);
        System.out.print("    Wie viele Kugeln entfernen ( 1 bis " + pruef(n) + ")? ");
        int eingabe = SavitchIn.readInt();
        System.out.println("                 Du -" + eingabe);
        return eingabe;
    }

    // chooses a number to remove from n balls according to basic strategy and
    // returns it
    static int moveComputerBasic(int n) {
        System.out.println("Verbleibende Kugeln: " + n);
        int zufall = basic(n);
        return zufall;
    }

    // chooses a number to remove from n balls according to smart strategy and
    // returns it
    static int moveComputerSmart(int n) {
        int zwisch;
        System.out.println("Verbleibende Kugeln: " + n);
        if (n > 63) {
            zwisch = n - 63;
            System.out.println("           Computer -" + zwisch);
            return zwisch;
        } else if (n > 31) {
            zwisch = n - 31;
            System.out.println("           Computer -" + zwisch);
            return zwisch;
        } else if (n > 15) {
            zwisch = n - 15;
            System.out.println("           Computer -" + zwisch);
            return zwisch;
        } else if (n > 7) {
            zwisch = n - 7;
            System.out.println("           Computer -" + zwisch);
            return zwisch;
        } else if (n > 3) {
            zwisch = n - 3;
            System.out.println("           Computer -" + zwisch);
            return zwisch;
        } else if (n > 1) {
            zwisch = n - 1;
            System.out.println("           Computer -" + zwisch);
            return zwisch;
        }

        int zufall = basic(n);
        return zufall;
    }

    static int basic(int n) {
        int pruef = pruef(n);
        int zufall = PRNG.randomInt(pruef) + 1;
        System.out.println("           Computer -" + zufall);
        return zufall;
    }

    static int pruef(int n) {
        if (n == 1) {
            n = 1;
        } else {
            n = n / 2;
        }
        return n;
    }

}
```

Fehlerbeschreibung:


> Wrong result(s) detected. Please check the return values of your methods and compare them to the expected return values below!
> Exception in thread "test" java.lang.Exception:
> Part 2
> >> Input <<
> ...



Die zahlen können ja nie übereinstimmen da es ja zufallszahlen sind??
Naja ich hoffe ihr könnt mir nochmal helfen wäre euch sehr sehr dankbar!

lg


----------



## klauskarambulut (8. Nov 2015)

Spielregeln?

Was sind valide Züge?

Was ist ein valider Zug für n:7?
Kopfrechnen überfordert ja heutzutage schnell, aber es sind alle Zahlen von 1 bis 3.
Warum 3? Weil 7 / 2 = 3 (Ganzzahldivision) ist.

Was versuchst dein Smarter Computer? Er versucht 4 zu ziehen.

Also in deinem if-else-Schleiße jeweils dies entfernen
System.out.println("           Computer -"+ zwisch);
return zwisch;

nach dem if-else-Gedöns ist zwisch gesetzt.

danach prüfen ob zwisch erlaubt ist.

```
if(isValidMove(n, zwisch)) {
  System.out.println("Verbleibende Kugeln: "+ n);
  System.out.println("           Computer -"+ zwisch);
  return zwisch; 
} else {
  int basic = basicMove(n);
  return basic;
}

static boolean isValidMove(int n,int zwisch) {
  return zwisch == 1 || (1 < zwisch && zwisch <= (n/2));
}
```


----------

