Buchempfehlung
Visual Basic 6 Kochbuch
Visual Basic 6 Kochbuch
Viele praktische Tipps zum Programmieren mit Visual Basic 6, die sich oft auch auf FB übertragen lassen. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

Nim-Spiel mit Alpha-Beta-Suche

Uploader:Redakteurnemored
Datum/Zeit:14.09.2011 22:38:30

' Ein einfaches Nim-Spiel, bei dem der Computer die Alpha-Beta-Suche einsetzt
' Jeder Spieler wählt abwechselnd eine Reihe und entfernt aus ihr
' eine beliebige Anzahl an Streichhölzern (mindestens eines)
' Wer das letzte Streichholz nehmen muss, verliert.
'
' Damit die Computerzüge nicht zu stereotyp sind, wählt der Computer dann,
' wenn er sowieso auf der Verliererstraße ist, einen zufälligen Zug aus.

#DEFINE Mensch 1
#DEFINE Computer -1

TYPE zugtyp
  AS INTEGER reihe, anz, wert
END TYPE

DIM SHARED AS INTEGER reihenzahl = 5, rechentiefe = 16, reihe(1 TO reihenzahl), gesamtzahl
FOR r AS INTEGER = 1 TO reihenzahl
  reihe(r) = r
  gesamtzahl += r
NEXT
DIM AS INTEGER spieler = 1, r, anz
DIM zug AS zugtyp, taste AS STRING
RANDOMIZE

FUNCTION alphabeta(resttiefe AS INTEGER, alph AS INTEGER, bet AS INTEGER) AS zugtyp
  DIM AS INTEGER besteReihe, besteAnz, zugWert
  ' generiere mögliche Zuege
  FOR r AS INTEGER = 1 TO reihenzahl
    FOR anz AS INTEGER = reihe(r) TO 1 STEP -1
      gesamtzahl -= anz
      IF gesamtzahl = 0 THEN  'letzten Stein genommen
        zugwert = -1
      ELSE
        IF restTiefe <= 1 THEN
          zugWert = 0
        ELSE
          reihe(r) -= anz
          zugWert = -alphabeta(restTiefe-1, -bet, -alph).wert
          reihe(r) += anz
        END IF
      END IF
      gesamtzahl += anz
      IF zugWert > alph THEN
        alph = zugWert
        besteReihe = r
        besteAnz = anz
      END IF
      IF alph >= bet THEN RETURN TYPE(besteReihe, besteAnz, 1)
    NEXT
  NEXT
  IF alph >= 0 THEN RETURN TYPE(besteReihe, besteAnz, alph)
  ' keinen Gewinnzug gefunden; damit ist es egal, wie gezogen wird
  DO
    besteReihe = INT(RND*reihenzahl) + 1
    IF reihe(besteReihe) = 0 THEN CONTINUE DO
    besteAnz = INT(RND*reihe(besteReihe)) + 1
    RETURN TYPE(besteReihe, besteAnz, alph)
  LOOP
END FUNCTION

DO
  ' neues Spiel
  PRINT "Wer beginnt? (1) Spieler  (2) Computer  (0) Ende"
  DO
    taste = INPUT(1)
  LOOP UNTIL taste = "1" OR taste = "2" OR taste ="0"
  IF taste = "0" THEN EXIT DO
  IF taste = "1" THEN spieler = Mensch ELSE spieler = Computer
  ' Spielstart
  DO
    'Spielfeld zeichnen
    CLS
    FOR r AS INTEGER = 1 TO reihenzahl
      PRINT r & ") " & SPACE(reihenzahl - r);
      FOR anz AS INTEGER = 1 TO reihe(r)
        PRINT "| ";
      NEXT
      PRINT : PRINT
    NEXT
    IF gesamtzahl = 0 THEN
      PRINT "Das Spiel ist aus. Du hast ";
      IF spieler = Mensch THEN PRINT "gewonnen!" ELSE PRINT "verloren!"
      EXIT DO, DO
    END IF
    IF spieler = Mensch THEN
      PRINT "Gib eine Reihe an (1-" & reihenzahl & "), in der sich noch Striche befinden."
      PRINT "'0' beendet das Spiel."
      DO
        taste = INPUT(1)
        IF taste = "0" THEN EXIT DO, DO, DO
        r = VAL(taste)
      LOOP UNTIL r > 0 AND r <= reihenzahl ANDALSO reihe(r) > 0
      PRINT "Gib an, wie viele Striche du entfernen willst (1-" & reihe(r) & ")."
      DO
        anz = VAL(INPUT(1))
      LOOP UNTIL anz > 0 AND anz <= reihe(r)
      reihe(r) -= anz
      gesamtzahl -= anz
    ELSE
      zug = alphabeta(rechentiefe, -2, 2)
      PRINT "Der Computer wird aus der " & zug.reihe & ". Reihe " & zug.anz & " Strich(e) entfernen."
      PRINT "(Die neue Spielsituation wird erst nach einem Tastendruck angezeigt.)"
      reihe(zug.reihe) -= zug.anz
      gesamtzahl -= zug.anz
      GETKEY
    END IF
    spieler = -spieler
  LOOP
LOOP