SPIEL

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kbr: Ich gehe da jetzt auch von einer Version ohne Klassen aus, das ändert ja nichts daran wie man vorgeht, sondern nur mit welchen Mitteln man das ausdrücken kann. Wie Hyperion schon sagte wissen wir fast nichts über den einzelnen Spieler. Wahrscheinlich kann man seinen Zustand mit einem einzigen skalaren Wert beschreiben, und seine ”Identität” aus der Position in einer Liste ableiten (Spieler 1, Spieler 2, …). Falls ein skalarer Wert nicht reicht, legt man die Daten für einen Spieler in einer Liste ab. Eigentlich besser ein Tupel, aber das wurde bisher ja nicht erwähnt.

Was auch nicht erwähnt wurde sind Funktionen, aber die setze ich jetzt mal voraus, denn ohne wird das eine Übung in „wie man es nicht macht, und auch gar nicht erst lernen sollte“. 🙂

@__deets__: Also man kann das schon mit Funktionen ordentlich und ohne globale Variablen machen würde ich sagen. Das wird dann halt ein wirklich eher funktionaler Ansatz.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

@__blackjack__: hmja, das wird sehr dialektisch. Klar kann ich allen Zustand auch immer reingeben. Und den zB auch auf Ebene der main-Funktion deklarieren, statt wirklich Modul-global. Aber das es nun ein empfehlenswertes und signifikant besserer Ansatz waere bei diesem Problem finde ich nicht. Es ist Zustand + ein Sack Funktionen die darauf arbeite, und den zB auch modifizieren. Das ist nun wirklich marginal besser als globale Variablen und konzeptionell wenn man OO haette auch nicht der Ansatz, den man waehlen wuerde. Voll funktional geht natuerlich auch, aber dann wird es schon etwas sehr abgefahren, und ohne tail-Rekursion auch immer ein bisschen gelogen.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@__blackjack__: Sicher, wenn ein Spieler über ein Tupel modelliert wird, geht es auch ohne Spielfeldliste. Für diese Lösung hilft es aber, wenn bereits in Objekten und Eigenschaften gedacht wird – und ich bezweifle, dass der Kurs so weit ist. Aber das ist geraten, denn in der Tat wissen wir einfach zu wenig über den Kenntnisstand, der für die Aufgabe vorausgesetzt wird.
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kbr: Ich hab's nicht bis zum Ende durchgedacht, aber braucht man für einen Spieler zwingend mehr als eine Zahl die den aktuellen Zustand widerspiegelt?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@__blackjack__: Mmmh, wenn ich so drüber nachdenke ... das müsste eigentlich genügen ... 8)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wenn es zu viele Spieler werden (war die Zahl vorgegeben?) wird eine Liste natürlich mau... ansonsten reicht doch das:

Code: Alles auswählen

players = [0, 3, 5, 7, 12]
Die Spieler sind dabei nur implizit durch den Index in der Liste bestimmt - nicht schön, aber genügt imho.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Apropos nicht schön – eine Lösung in einer Programmiersprache in der es keine Funktionen¹, und keine benutzerdefinierten Datentypen, und schon gar keine Objekte gibt – GW-BASIC:

Code: Alles auswählen

10 RANDOMIZE TIMER:INPUT"Anzahl der Spieler";PC:INPUT"Anzahl Spielfelder";FC
20 DIM PP(PC):FOR I=1 TO PC:PP(I)=1:NEXT:PI=1
30 ' Main loop.
40 P$="Spieler"+STR$(PI)+" ":PRINT:PRINT P$;"ist am Zug.":GOSUB 70
50 IF FW THEN PRINT P$;"hat gewonnen!":END
60 PI=(PI MOD PC)+1:GOTO 30
70 ' Play one round with player PI.
80 PP=PP(PI):V=INT(RND*6)+1:NP=PP+V
90 PW$=P$+"hat eine"+STR$(V)+" gewürfelt":PRINT PW$;"."
100 GOSUB 150:IF F THEN PRINT"Zielfeldnummer ist eine Schnapszahl: +5":NP=NP+5
110 IF NP>FC THEN 130
120 PRINT P$;"zieht von";PP;"nach";STR$(NP);".":GOSUB 200:PP(PI)=NP
130 FW=NP=FC:IF FW OR (V<>6) THEN RETURN
140 PRINT PW$;" und ist weiterhin am Zug.":GOTO 70
150 ' Check if target field number is repdigit.
160 IF NP<11 THEN F=0:RETURN
170 T$=STR$(NP):A$=MID$(T$,2,1):X=0:FOR I=2 TO LEN(T$)
180 IF MID$(T$,I,1)=A$ THEN X=X+1
190 NEXT:F=X=LEN(T$)-1:RETURN
200 ' Move players on field NP back by 2 fields.
210 BP=NP-2:IF BP<1 THEN BP=1
220 FOR I=1 TO PC:IF PP(I)<>NP THEN 240
230 PRINT"Spieler";I;"wird auf Position";BP;"zurückgesetzt.":PP(I)=BP
240 NEXT:RETURN
1) Keine Funktionen stimmt nicht so ganz, weil man sich mit DEF FN Funktionen mit definieren kann, die aus einem einzigen Ausdruck bestehen dürfen. Also ähnliche Einschränkungen wie bei Python's ``lambda``-Ausdrücken.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mir fiel gerade auf, dass ein ungünstige Kombination in den Regeln (sofern ich die überhaupt korrekt interpretiere) von dem obigen Programm nicht abgedeckt wird und zu einer Endlosschleife führt. Also nicht einfach blind übernehmen. 😊
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Soo, Zeilennummern entfernt und wo nötig durch Sprungmarken ersetzt, und nun mit QBasic ausführbar. Der Fehler ist behoben und der Test auf Schnappszahl ist jetzt ”mathematischer” gelöst – heisst der Zeichenkettenspeicher wird weniger vollgemüllt.

Code: Alles auswählen

RANDOMIZE TIMER
DIM PlayerCount AS INTEGER, FieldCount AS INTEGER, PlayerIndex AS INTEGER
DIM i AS INTEGER, isRepdigit AS INTEGER, n AS INTEGER, digit AS INTEGER
DIM hasWon AS INTEGER, score AS INTEGER, newPosition AS INTEGER
DIM backPosition AS INTEGER

INPUT "Anzahl der Spieler"; PlayerCount
INPUT "Anzahl Spielfelder"; FieldCount

DIM PlayerPosition(PlayerCount) AS INTEGER

FOR i = 1 TO PlayerCount
  PlayerPosition(i) = 1
NEXT
PlayerIndex = 1
DO
  p$ = "Spieler" + STR$(PlayerIndex) + " "
  PRINT : PRINT p$; "ist am Zug."
  GOSUB PlayTurn
  IF hasWon THEN EXIT DO
  PlayerIndex = (PlayerIndex MOD PlayerCount) + 1
LOOP
PRINT p$; "hat gewonnen!"
END

' Play one turn with player at PlayerIndex.
PlayTurn:
  DO
    PlayerPosition = PlayerPosition(PlayerIndex)
    score = INT(RND * 6) + 1
    newPosition = PlayerPosition + score
    PW$ = p$ + "hat eine" + STR$(score) + " gewürfelt"
    PRINT PW$; "."
    IF newPosition <> FieldCount THEN
      n = newPosition
      GOSUB CheckRepdigit
      IF isRepdigit THEN
        PRINT "Zielfeldnummer ist eine Schnapszahl: +5"
        newPosition = newPosition + 5
      END IF
    END IF
    IF newPosition <= FieldCount THEN
      PRINT p$; "zieht von"; PlayerPosition; "nach"; STR$(newPosition); "."
      GOSUB MoveBack
      PlayerPosition(PlayerIndex) = newPosition
    END IF
    hasWon = newPosition = FieldCount
    IF hasWon OR (score <> 6) THEN EXIT DO
    PRINT PW$; " und ist weiterhin am Zug."
  LOOP
  RETURN

' Check if n is repdigit.
CheckRepdigit:
  digit = n MOD 10
  isRepdigit = n > 9
  DO WHILE n <> 0
    IF (n MOD 10) <> digit THEN
      isRepdigit = 0
      EXIT DO
    END IF
    n = n \ 10
  LOOP
  RETURN

' Move players on field newPosition back by 2 fields.
MoveBack:
  backPosition = newPosition - 2
  IF backPosition < 1 THEN backPosition = 1
  FOR i = 1 TO PlayerCount
    IF PlayerPosition(i) = newPosition THEN
      PRINT "Spieler"; i; "wird auf Position"; backPosition; "zurückgesetzt."
      PlayerPosition(i) = backPosition
    END IF
  NEXT
  RETURN
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten