|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 31.03.2023, 18:24 Titel: Variabelen mit selbst definiertem Datentyp |
|
|
Hallo Leute,
ich kämpfe seit einiger Zeit mit folgendem Problem.
Ein Spielfeld bestehe aus X Zellen, ähnlich einem Schachbrett.
Diese Zellen enthalten verschiedene Informationen wie z.B. die Zeile, die Spalte und die Figur, die gerade darauf steht.
Die Variabele "Zelle" würde ich also wie folgt mit einem selbst definieren
Datentyp versehen:
TYPE ZellTyp
Z as integer 'für die Zeile
S as integer 'für die Spalte
F as integer 'für die Figur
End TYPE
Dim shared Zelle (1 to 64) as ZellTyp
Jede dieser 64 Zellen müßte danach also folgende Struktur aufweisen:
Zelle.Z , Zelle.S , Zelle.F
Der Punkt ist also zwecks Unterscheidung der jeweiligen Einzeleinträge einer Zelle zwingend erforderlich.
Wenn ich eine Zelle jetzt aber mit Werten versehen möchte, bekomme ich immer folgende Fehlermeldung:
"Identifikator darf keinen Punkt enthalten."
Ein Punkt ist also einerseits zwingend erforderlich, andererseits ist seine Verwendung aber "verboten". Wie kann das sein? Wo ist der Fehler?
Kann irgend jemand diesen Widerspruch auflösen?
Vielen Dank für eure Bemühungen.
Mit netten Grüßen |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2514 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 31.03.2023, 20:31 Titel: |
|
|
Du bekommst damit nur ein einfaches eindimensionales Array, wo Du Elemente halt mit
Code: | Zelle(3).Z
Zelle(5).F |
usw. ansprechen musst.
Für Dein Problem macht vermutlich ein mehrdimensionales Feld mehr Sinn, z.B.
Code: | CONST Leer=0
CONST Bauer=1
CONST Turm=2
CONST Springer=3
CONST Laeufer=4
CONST Dame=5
CONST Koenig=6
DIM schachfeld(1 TO 8, 1 TO 8)
schachfeld(1, 1)=Turm
schachfeld(1, 2)=Springer
IF schachfeld(5, 3)=Dame Then
...
END IF |
FreeBasic ist hier natürlich gegenüber QB einiges besser:
https://www.freebasic.net/wiki/KeyPgEnum
d.h. statt einem Haufen Konstanten (ähnlich alten C-Programmen) besser für die Figuren ein Enumeration-Typ anlegen.
Code: | Enum Schachfigur
Leer
Bauer
Turm
Springer
Laeufer
Dame
Koenig
End Enum
Dim Schachfeld(1 To 8, 1 To 8) As Schachfigur
Schachfeld(1, 1)=Turm |
_________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 08.04.2023, 03:01 Titel: |
|
|
Hallo dreael,
vielen Dank für deine Hilfe. Ich habe allerdings noch einige Nachfragen und würde mich sehr freuen, wenn du sie mir beantworten könntest.
Du verwendest den Befehl "const = "
Kann ich trotzdem auch das Schlüsselwort "shared" verwenden
oder würden sie einander widersprechen/ausschließen ?
Wie eine Variabele mit einem selbst definierten Datentyp?
Beispiel:
Ich möchte eine Variabele namens "Zelle" mit eigenem Datentyp definieren.
Aus dieser Variabelen namens "Zelle" müssen verschiedene Eigenschaften abrufbar sein:
Aus Zelle.Nr die Nummer der Zelle, um die es gerade geht (1 - 81)
Aus Zelle.Z die Zeile, in der diese Zelle steht (1 - 9)
Aus Zelle.S die Spalte, in der diese Zelle steht (1 - 9)
Aus Zelle.W der gegebene/oder ermittelte pos. Wert dieser Zelle (1-9)
Aus Zelle.A alle Werte , die wegen Zelle .W nicht mehr möglich, also ausgeschlossen sind.
Hier sind also offenbar 9 zusätzliche "Untereinträge" nötig, um zu unterscheiden, welche Einträge der 9 möglichen überhaupt noch möglich sind und welche nicht mehr. Also 9 Einträge zwischen (-1 bis -9 ).
Wie bekomme ich die Variabele "Zelle" unter diesen Bedingungen
mit Type Zelltyp
.
.
.
End Type
DIM SHARED Zelle as Zelltyp sauber definiert?
Oder geht das in QB eventuell auch einfacher?
Mit netten Grüßen |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4637 Wohnort: ~/
|
Verfasst am: 08.04.2023, 08:33 Titel: |
|
|
CONST und SHARED gleichzeitig funktioniert nicht, weil Konstanten sowieso immer global sind. Also entweder CONST Leer=0 oder DIM SHARED Leer=0. Du kannst aber Leer als Konstante defninieren und schachfeld als globale Variable, falls das die Frage war (unter Beachtung der Nachteile, die globale Variablen mit sich bringen können).
Beim zweiten Teil der Frage weiß ich nicht so recht, worauf du hinaus willst. Wenn du ein zweidimensionales Array definierst, steht z. B. Zelle(5, 3) immer in Zeile 5 und immer in Spalte 3 (oder umgekehrt, je nachdem wie du es definieren willst). Wozu muss der Eintrag da noch seine Zeile und Spalte speichern? Aber selbstverständlich ist es möglich:
Code: | TYPE ZellTyp
Z as integer 'für die Zeile
S as integer 'für die Spalte
F as integer 'für die Figur
End TYPE
DIM SHARED Zelle(1 to 8, 1 to 8) as ZellTyp
Zelle(1, 1).Z=1
IF Zelle(5, 3).S <> 3 THEN PRINT "Fehler - Zelle(5,3) steht in der falschen Spalte!" |
_________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1230 Wohnort: Ruhrpott
|
Verfasst am: 09.04.2023, 04:11 Titel: |
|
|
Hallo Revilo!
Das hier
Revilo hat Folgendes geschrieben: | Aus Zelle.A alle Werte , die wegen Zelle .W nicht mehr möglich, also ausgeschlossen sind. |
verstehe ich nicht. Was ist "Zelle.A"? Vielleicht könntest du etwas genauer erläutern, was du vorhast. Handelt es sich um Schach oder ein anderes, eventuell selbst entwickeltes Spiel?
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 09.04.2023, 16:09 Titel: |
|
|
Hallo grindstone,
mein Beispiel mit dem Schach war wohl etwas ungünstig gewählt. Sorry.
Es sollte lediglich die Aufteilung des Spielfeldes in verschiede Zellen
demonstrieren.
Meine Zielstellung ist es, meinem Rechner "beizubringen" , SUDOKUS
selbst zu lösen.
Nach dem Motto: Ich gebe ein Sudoku ein, klicke auf "Autolösen" und fertig.
Ein Sudoku besteht bekanntlich aus 9 x 9 Zellen, von denen einige bereits mit einem gegebenen Wert/Inhalt versehen sind.
Wenn z.B. in Zelle(8,3) also 8. Zeile, 3. Spalte eine 4 steht,
dann darf in der Zeile 8 keine weitere 4 auftauchen. Die 4 muß also für alle anderen Zellen der 8. Zeile ausgeschlossen werden. Dies hoffte ich über die Variable "Zelle.A" hinzubekommen. (A steht für Ausschluß)
Wenn ferner in Zelle(8, 5) eine 7 als ermittelt oder gegeben feststeht,
muß auch die 7 für alle übrigen Zellen der Zeile 8 ausgeschlossen sein. Analog gilt das natürlich auch für die entsprechenden Spalten.
Jede Zelle muß also 9 "Untereinträge für den Wert" ermöglichen.
(einen tatsächlichen und 8 weitere für die 8 sich im "Spielverlauf" als unmöglich herausstellenden)
Wenn alle Zellen 1 tatsächlichen Wert und 8 unmögliche haben, ist das Sudoku gelöst.
Wahrscheinlich tue ich mich mit der ganzen Indizierung schwerer, als eigentlich nötig. Aber besser weiß ich es halt nicht.
Wie also kriege ich das möglichst elegant "gestrickt"?
Gruß Revilo und frohe Ostern |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4637 Wohnort: ~/
|
Verfasst am: 09.04.2023, 16:27 Titel: |
|
|
Für einen Sudoku-Löser kannst du auch mit Backtracking arbeiten; da braucht sich das Programm nicht zu merken, was möglich ist, weil es einfach alle Möglichkeiten durchprobiert und zurückspringt, sobald eine unlösbare Situation auftaucht.
Aber zur Frage mit den "Untereinträgen": Da es sich um neun Einträge handelt, die jeweils nur einen von zwei Werten annehmen kann ("möglich" oder "nicht möglich", bzw. 0 oder 1), ließe sich das effektiv über ein Bitfeld lösen. Ob Bitfelder in QBasic bereits existieren, weiß ich spontan nicht (ich glaube nicht), aber der erste Code auf der Referenzseite lässt sich auf jeden Fall umsetzen.
Statt mit 1, 2, 4, 8 ... lässt sich natürlich auch mit 2^0, 2^1, 2^2, 2^3, ... arbeiten; das wäre dann leichter zu merken. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 09.04.2023, 17:22 Titel: |
|
|
Hallo nemored,
vielen Dank für deinen Hinweis auf die rekursive Programmierung.
Meine Anfrage zeigt doch aber, daß ich immer noch erst mal mit den Grundlagen "kämpfe". Schließlich muß man ja erst mal gehen lernen, um dann mal laufen zu können, um sich dann mal an einen Marathon zu wagen.
Danke dir für den Optimismus hinsichtlich meiner Fortschritte,
aber so weit bin ich noch lange nicht.
Gruß Revilo |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 09.04.2023, 17:56 Titel: |
|
|
Hallo nemored,
du hattest mir geschrieben, daß "const" und "shared" nicht gleichzeitig funktionieren. Zum tieferen Verständnis hätte ich da mal eine Nachfrage.
Angenommen ich definiere die Kreiszahl (Pi) mit const Pi = 3,14...
Die Berechnung der Fläche eines Kreises soll in einem Unterprogramm
"Fläche" erfolgen.
Ist Pi in diesem Unterprogramm dann anwendbar oder nicht?
Schließlich brauche ich sie ja zwingend dafür.
Oder müßte ich in diesem Fall Pi wie folgt definieren:
Dim shared Pi as .... (integer, single usw. ), je nach gewünschter Genauigkeit?
Gruß Revilo |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2514 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 09.04.2023, 20:00 Titel: |
|
|
Revilo hat Folgendes geschrieben: | Meine Zielstellung ist es, meinem Rechner "beizubringen" , SUDOKUS
selbst zu lösen.
Nach dem Motto: Ich gebe ein Sudoku ein, klicke auf "Autolösen" und fertig. |
Von mir früher (schon 17 Jahre her) einmal selber entwickelt:
https://beilagen.dreael.ch/QB/SUDOKU.ZIP
Selbst dem Rätsel generieren hatte ich mich einmal früher angenommen:
https://beilagen.dreael.ch/QB/SUDOKUGN.BAS
Ist noch original QBasic-Code, sollte aber nicht allzu schwierig sein für eine Portierung ins FreeBasic.
Zum Programmaufbau: Wie unschwer erkennbar, wurde auch hier das Feld durch ein einfaches zweidimensionales Integer-Array gelöst, wo der Wert 0 für leeres Feld (Lücke) steht, 1-9 die entsprechende Zahl.
Das eigentliche Lösen erfolgt hier ebenfalls mit Rekursion, wobei hier noch eine Optimierung erfolgt, in dem Felder mit wenig Kandidaten zuerst versuchsweise belegt werden. Auch kann das Programm feststellen, falls ein Rätsel gar nicht lösbar ist oder nicht eindeutig (=mehrere Lösungen möglich). _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 09.04.2023, 21:54 Titel: |
|
|
Hallo dreael,
vielen Dank für deine Bemühungen und dafür daß du mir mir deinem Link praktisch den gesamten Syntax übermittelt hast.
Deine Links haben mir fachlich sehr weitergeholfen.
Offenbar ist der Dim -Befehl auch innerhalb eines später aufgerufenem
Sub möglich. Das wußte ich bisher nicht.
Ich dachte immer, DIM wäre nur ganz zu Beginn eines Programms möglich.
Ok. ich konnte etwas lernen, vielen Dank dafür.
Deinen gesamten Syntax muß ich erst mal "verdauen".
Das wird mir bestimmt nicht leicht fallen, da ich von rekursiver Programmierung (noch) absolut keine Ahnung habe.
Aber es zeigt mir zumindest, in welche Richtung ich mich bewegen muß.
Vielen, vielen Dank dafür. Der Rest ist eben eine Fleißfrage meinerseits.
Gruß Revilo |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1230 Wohnort: Ruhrpott
|
Verfasst am: 10.04.2023, 06:57 Titel: |
|
|
Revilo hat Folgendes geschrieben: | Offenbar ist der Dim -Befehl auch innerhalb eines später aufgerufenem Sub möglich. | Das ist richtig, allerdings gilt die so dimensionierte Variable dann nur innerhalb der Sub (= lokale Variable). Sobald du die Sub verlässt, ist die Variable undefiniert. Wenn du eine Variable mit gleichem Namen sowohl im Hauptprogramm als auch in der Sub dimensionierst, handelt es sich um zwei unterschiedliche Variablen, die auch unterschiedliche Werte annehmen können.
Und um die Verwirrung komplett zu machen, gilt eine im Hauptprogramm mit SHARED dimensionierte Variable auch in Prozeduren (also SUBs und FUNKTIONs), es sei denn, du dimensionierst sie innerhalb der Prozedur noch einmal, dann gilt innerhalb der Prozedur diese lokale Variable.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 05.05.2023, 03:22 Titel: |
|
|
Hallo nemored,
vielen Dank für deine Hilfe, die ich jetzt endlich verstanden habe.
Mein Fehler war, daß ich versucht habe die Variabele "Zelle.Nr" mit einem Wert Nr zu versehen.
Wenn es wie in meinem Fall 81 Zellen geben soll, kann das natürlich nicht funktionieren, wenn ich übersehe, dem Rechner zu sagen, in welcher dieser 81 möglichen Zellen er den Eintrag überhaupt vornehmen soll. Klar, daß er berechtigterweise "meckert".
Nr soll als Zähler von 1 bis 81 laufen.
Statt "Zelle.Nr = Nr" hätte ich korrekterweise nur "Zelle(Nr).Nr= Nr"
schreiben müssen. Ein wirklich simpler Fehler meinerseits.
In diesem Zusammenhang möchte ich mich bei allen hilfsbereiten Mitgliedern für diese "Eselei" in aller Form entschuldigen.
Es tut mir aufrichtig Leid, euch allen unnötige Arbeit bereitet zu haben.
Ganz ganz großes Sorry.
Revilo |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4637 Wohnort: ~/
|
Verfasst am: 05.05.2023, 18:57 Titel: |
|
|
Revilo hat Folgendes geschrieben: | Es tut mir aufrichtig Leid, euch allen unnötige Arbeit bereitet zu haben.
Ganz ganz großes Sorry. |
Unsinn - dass man nicht gleich alles sofort versteht, gehört doch zum Lernprozess dazu. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1230 Wohnort: Ruhrpott
|
Verfasst am: 06.05.2023, 10:01 Titel: |
|
|
Genau! Du glaubst gar nicht, welche "Eseleien" ich mir schon geleistet habe - und gelegentlich immer noch leiste (und alle anderen hier mit Sicherheit auch ).
Das kannst du dir für die Zukunft merken: Hartnäckige Fehler haben ihre Ursache meistens in genau solchen Kleinigkeiten, ganz einfach deshalb, weil man ihnen bei der Fehlersuche (zu) wenig Beachtung schenkt.
Außerdem: Wenn alles perfekt wäre, wäre das Leben doch langweilig!
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 06.05.2023, 15:31 Titel: |
|
|
Vielen Dank für eure aufmunternden Worte.
Ihr habt ja völlig recht. Laufen lernen hießt erst mal hinfallen, um zu erfahren, wie man es nicht machen sollte.
Wenn das oft genug geschieht, bleibt letztlich nur noch eine Möglichkeit übrig, es richtig zu machen. Von da an kann man es dann aber auch für immer. Schwimmen lernt man ohne Wasserschlucken ja schließlich auch nicht.
Passt zwar nicht so ganz zu diesem Thema, aber ich komme mit dem Händling hier noch nicht so richtig zurecht.
Am Ende dieser Seite kann man entweder ein "neues Thema" ansprechen oder eine "Antwort senden".
Gleiches geht aber auch am Anfang der Seite. Warum gibt es diese Option doppelt? Gibt es zwischen beiden einen Unterschied?
Gruß Revilo |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 06.05.2023, 15:47 Titel: |
|
|
In Ergänzung meiner Anfrage zum Händling,
unter jedem Teilnehmer stehen mind. zwei Schaltflächen "Profil" und "pn".
Bei manchen aber zusätzlich auch "E-Mail", "www" oder "ICQ" .
Was hat es damit auf sich? Wann muß was angewendet werden?
Was bedeutet "BBCode in diesem Beitrag deaktivieren"?
Gruß Revilo |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4637 Wohnort: ~/
|
Verfasst am: 06.05.2023, 16:16 Titel: |
|
|
Revilo hat Folgendes geschrieben: | Am Ende dieser Seite kann man entweder ein "neues Thema" ansprechen oder eine "Antwort senden".
Gleiches geht aber auch am Anfang der Seite. Warum gibt es diese Option doppelt? Gibt es zwischen beiden einen Unterschied? |
Kein Unterschied - es ist sicherlich deshalb doppelt (Design-Entscheidung der phpBB-Entwickler bzw. der Entwickler des Skins), damit man bei langen Threads nicht scrollen muss.
Revilo hat Folgendes geschrieben: | In Ergänzung meiner Anfrage zum Händling,
unter jedem Teilnehmer stehen mind. zwei Schaltflächen "Profil" und "pn".
Bei manchen aber zusätzlich auch "E-Mail", "www" oder "ICQ" .
Was hat es damit auf sich? Wann muß was angewendet werden? |
In deinem eigenen Profil kannst du, wenn du willst, deine E-Mail-Adresse, Webseitenadresse, ICQ-Nummer, AIM-Name, MSN-Messenger-Adresse und/oder Yahoo-Messenger-Adresse angeben. Wenn du das tust, erscheinen bei dir diese Buttons. Oder anders gesagt: Wenn es bei jemandem nicht erscheint, hat derjenige dazu keine Angaben gemacht (wie z. B. ich)
Revilo hat Folgendes geschrieben: | Was bedeutet "BBCode in diesem Beitrag deaktivieren"?
Gruß Revilo |
BBCode sind die Formatierungsangaben in eckigen Klammern wie z. B. [b] für Fettdruck oder [code] für Quelltexte. Wenn du BBcode deaktivierst, werden diese Angaben nicht interpretiert, sondern so, wie sie stehen, stehengelassen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 78
|
Verfasst am: 06.05.2023, 16:47 Titel: |
|
|
Hallo nemored,
vielen Dank für die schnelle Antwort.
Wo ich dich gerade an der "Strippe" habe.
Ich hatte dir (wohl als pn) eine Anfrage zugesandt, bei der es darum geht, daß der "Turm" einer Zelle neun oder gar zehn mögliche Einträge benötigt.
Ist diese Mail überhaupt bei dir angekommen, oder habe ich mal wieder etwas falsch gemacht?
Gruß Revilo |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4637 Wohnort: ~/
|
Verfasst am: 06.05.2023, 23:18 Titel: |
|
|
Nein, ist nichts bei mir angekommen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|