Entwickler-Ecke
Open Source Projekte - Einsiedlerspiel
Fiete - Do 08.05.08 18:24
Titel: Einsiedlerspiel
Einsiedlerspiel ist ein altes Brettspiel für einen Spieler.
Gegeben ist ein Spielbrett in Kreuzform mit 33 Mulden, in denen 32 Steine liegen. Die Mulde in der Mitte ist leer. Man muss nacheinander die Steine entfernen, indem man sie in waagerechter oder senkrechter Richtung überspringt. Am Ende muss ein Stein in der Mitte übrigbleiben (Standardspiel).
Ein Sprung besteht darin, einen Spielstein aus einer Mulde zu nehmen, einen daneben liegenden zu überspringen und den springenden Stein in die dahinterliegende Mulde zu platzieren.
Das Spiel heißt auch Solitaire, Steckhalma, Solohalma, Springer, Jumper, Nonnenspiel oder Solitär.
Ich habe 13 Brett-Varianten implementiert:
die englische Variante(33 Felder) und die französische(37 Felder) sowie einige neue.
Im Ordner Stellungen sind Aufgaben, die selbst gelöst werden können, unter Einstellungen mit der Variante Mensch.
Die Versionen Delphi und Assembler sind zum Berechen von Stellungen.
Ein Zielfeld wird mit der rechten Maustaste gesetzt.
Viel Spaß beim Tüfteln
Fiete
Edit1:
Die neue Version ist da!
Die Menue-Führung ist geändert worden, neu ist das Menue Schablonen. Hierüber können neue Brettformen kreiert werden. Die neue Schablone kann gespeichert werden, gleichzeitig wird dann im Ordner Stellungen ein Unterordner mit dem Namen der Schablone erstellt, jetzt kann gespielt werden.
Wenn die Schablone nicht gespeichert wird muß der Menu-Punkt <Fertig> angeklickt werden, um spielen zu können.
Edit2:
Im Menue <Demo> können Ergebnisse geladen und gespeichert werden.
alzaimar - Do 08.05.08 19:38
Du kannst die Suche drastisch verkürzen, wenn Du dir die Stellungen merkst, die zum Mißerfolg führen und dann die jeweilige um 90/180/270° gedreht Stellung vergleichst. Ist die Stellung in der Liste, kannst Du gleich abbrechen.
Fiete - Mo 12.05.08 10:52
Moin alzaimar,
danke für den Beitrag.
So einfach ist es nicht, die Suchroutine arbeit mit definierten Suchrichtungen, ähnlich einer Suche im Labyrinth.
Die Bretter und Stellungen sind nicht notwendigerweise symmetrisch, s. Beispiele.
Gruß
Fiete
eine neue Version kommt demnächst(verschiedene Brettformen)
Hidden - Mo 12.05.08 12:47
Hi,
Verwendest du einen BruteForce-Algorithmus? Wenn ja, eventuell Hashtabellen.
mfG,
alzaimar - Mo 12.05.08 19:40
Hi Fiete, Das Spielbrett ist doch rotations- und spiegelsymetrisch.
Eine komprimierte Speicherung (Bitvektor) sollte schon recht einfach zu realisieren sein. Beim Eintritt in die rekursive Suchfunktion erstellst Du zunächst die vier Bitvektoren der Stellung (gedreht um 0,90,180,270 Grad) und schaust nach, ob Du schon mal da warst. 33 Mulden = 33 bit = int64, da kannst du mein Integer-Dictionary nehmen. Zur Not einfach umfriesieren (Cardinal-Key => Int64-Key). Da das Teil eh mit einer kleineren Hashtabelle arbeitet, passt das schon.
Fiete - Di 13.05.08 11:38
Moin alzaimar,
ich werde mir mal Gedanken machen.
Gruß
Fiete
meine Prozedur
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| PROCEDURE TSoli.MACHZUG(ZUGNR:BYTE); VAR RICHTUNG,POSITION,X1,X2:BYTE; BEGIN INC(AUFRUF);POSITION:=ANFANGSPOSITION-1; REPEAT INC(POSITION);RICHTUNG:=0; IF FELD[POSITION]=BESETZT THEN REPEAT INC(RICHTUNG);X1:=POSITION+ZUWACHS[RICHTUNG];X2:=X1+ZUWACHS[RICHTUNG]; IF (FELD[X1]=BESETZT) AND (FELD[X2]=FREI) THEN BEGIN FELD[POSITION]:=FREI;FELD[X1]:=FREI;FELD[X2]:=BESETZT; PROTOKOLL[ZUGNR].ZUG:=POSITION;PROTOKOLL[ZUGNR].RI:=RICHTUNG; IF ZUGNR<MA THEN BEGIN MACHZUG(ZUGNR+1); IF NOT ERFOLG THEN BEGIN FELD[POSITION]:=BESETZT;FELD[X1]:=BESETZT;FELD[X2]:=FREI END END ELSE IF WEITER AND (FELD[ZIEL]<>BESETZT) THEN BEGIN FELD[POSITION]:=BESETZT;FELD[X1]:=BESETZT;FELD[X2]:=FREI END ELSE ERFOLG:=TRUE END UNTIL ERFOLG OR (RICHTUNG=4) UNTIL ERFOLG OR (POSITION=ENDPOSITION) END; |
Hidden - Di 13.05.08 12:56
Hmm kann sein, dass das nur mir so geht aber ich fand das unlesbar :wink: falls es noch wem so geht, habe ich das mal formatiert gepostet.
Fiete hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| procedure TSoli.MachZug(ZugNr: Byte); var Richtung, Position, X1, X2: Byte; begin Inc(Aufruf); Position := Pred(AnfangsPosition); repeat Inc(Position); Richtung := 0; if Feld[Position] = Besetzt then begin repeat Inc(Richtung); X1 := Position + Zuwachs[Richtung]; X2 := X1 + Zuwachs[Richtung]; if (Feld[X1] = Besetzt) and (Feld[X2] = Frei) then begin Feld[Position] := Frei; Feld[X1] := Frei; Feld[X2] := Besetzt; Protokoll[ZugNr].Zug := Position; Protokoll[ZugNr].Ri := Richtung; if ZugNr < Ma then begin MachZug(Succ(ZugNr)); if not Erfolg then begin Feld[Position] := Besetzt; Feld[X1] := Besetzt; Feld[X2] := Frei; end; end else begin if Weiter and (Feld[Ziel] <> Besetzt) then begin Feld[Position] := Besetzt; Feld[X1] := Besetzt; Feld[X2] := Frei; end; end else Erfolg := true end; until Erfolg or (Richtung = 4); end; until Erfolg or (Position = EndPosition); end; | |
Fiete - Mi 13.05.20 17:23
Moin,
das Menue <Demo> wurde erweitert: <Starten>, <Speichern> und <Laden> sind jetzt möglich.
Gruß Fiete
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!