add bot in myrummy

This commit is contained in:
2026-08-23 13:42:39 +02:00
parent 50dcb7fc8a
commit d78f25d530
2 changed files with 96 additions and 9 deletions
+9 -1
View File
@@ -3,10 +3,18 @@ MYRUMMY CLI
Start:
python main.py
Beim Start werden zwei Einstellungen abgefragt:
Beim Start werden Einstellungen abgefragt:
- Wie viele menschliche Spieler (1-4)
- Wie viele Bots (menschliche + Bots insgesamt max. 4):
- Bei 1 menschlichem Spieler ist mindestens 1 Bot Pflicht
- Bei 2-4 Spielern sind Bots optional (0 für keine)
- 13-1-Umlauf: Folgen dürfen über 13 hinweg weiterlaufen (z.B. 12,13,1)
- Erstmeldung 30: Für die erste Meldung werden 30 Punkte gebraucht
Bots spielen automatisch: Sie legen, was sie können (Sätze und Folgen,
beachten die 30-Punkte-Regel) und ziehen sonst eine Karte. Die Handkarten
eines Bots werden nie angezeigt.
Nach jedem beendeten Zug erscheint ein Übergabe-Bildschirm, damit der
nächste Spieler die Karten des Vorgängers nicht sieht.
+87 -8
View File
@@ -9,9 +9,19 @@ def yes_no(q, default=None):
if not a and default is not None: return default
print(' Bitte j oder n eingeben.')
def number(q, lo, hi):
while True:
a=input(q+f' ({lo}-{hi}): ').strip()
try: n=int(a)
except ValueError:
print(f' Bitte eine Zahl von {lo} bis {hi} eingeben.'); continue
if lo<=n<=hi: return n
print(f' Bitte eine Zahl von {lo} bis {hi} eingeben.')
class Player:
def __init__(self,name):
def __init__(self,name,bot=False):
self.name=name
self.bot=bot
self.hand=[]
self.opened=False
@@ -19,9 +29,14 @@ class Game:
def __init__(self):
print('EINSTELLUNGEN')
print(' ~~~~~~~~~~~~')
n=number(' Wie viele menschliche Spieler', 1, 4)
if 4-n>0:
b=number(' Wie viele Bots' + (' (mindestens 1)' if n==1 else ' (0 für keine)'), 1 if n==1 else 0, 4-n)
else:
b=0
self.wrap=yes_no(' 13-1-Umlauf erlauben (z.B. 12,13,1)')
self.min30=yes_no(' Braucht die Erstmeldung 30 Punkte')
self.players=[Player('Spieler 1'),Player('Spieler 2')]
self.players=[Player(f'Spieler {i+1}') for i in range(n)]+[Player(f'Bot {i+1}', bot=True) for i in range(b)]
self.turn=0
self.table=[]
self.deck=deck(); random.shuffle(self.deck)
@@ -110,7 +125,7 @@ class Game:
if not self.deck: raise ValueError('Stapel leer.')
card=self.deck.pop(); self.p.hand.append(card); self.p.hand=sort_hand(self.p.hand)
print(f'\n {self.p.name} zieht {card.text()} und beendet damit den Zug.')
self.turn=1-self.turn; self.drew=False; self.melded=False; self.history=[]
self.turn=(self.turn+1)%len(self.players); self.drew=False; self.melded=False; self.history=[]
self.handover=True
def finish(self):
@@ -131,7 +146,7 @@ class Game:
if not self.p.hand:
print(f'\n{self.p.name} gewinnt!')
return True
self.turn=1-self.turn; self.drew=False; self.melded=False; self.history=[]
self.turn=(self.turn+1)%len(self.players); self.drew=False; self.melded=False; self.history=[]
self.handover=True
return False
@@ -160,13 +175,77 @@ class Game:
input('\nENTER...')
return False
def find_meld(self, hand):
# Satz: gleicher Wert, unterschiedliche Farben, 3-4 Karten
by_val={}
for c in hand:
if not c.joker: by_val.setdefault(c.value, []).append(c)
for val in sorted(by_val):
by_col={}
for c in by_val[val]: by_col.setdefault(c.color, []).append(c)
if len(by_col)>=3:
return [by_col[col][0] for col in sorted(by_col)[:4]]
# Folge: gleiche Farbe, aufeinanderfolgend, 3+ Karten
by_col={}
for c in hand:
if not c.joker: by_col.setdefault(c.color, []).append(c)
for col in by_col:
vals=sorted({c.value for c in by_col[col]})
i=0
while i<len(vals):
j=i
while j+1<len(vals) and vals[j+1]==vals[j]+1: j+=1
if j-i+1>=3:
return [next(c for c in by_col[col] if c.value==v) for v in vals[i:j+1]]
i=j+1
return None
def bot_turn(self):
p=self.p
print(f'\n {p.name} ist am Zug:')
melded=[]
while True:
m=self.find_meld(p.hand)
if not m: break
for c in m: p.hand.remove(c)
melded.append(m)
total=sum(points(c) for m in melded for c in m)
if melded and (p.opened or not self.min30 or total>=30):
for m in melded: self.table.append(m)
if not p.opened: p.opened=True
for m in melded:
print(' legt: '+' '.join(c.plain() for c in m))
if not p.hand:
print(f'\n {p.name} gewinnt!')
return True
else:
for m in melded:
for c in m: p.hand.append(c)
p.hand=sort_hand(p.hand)
if self.deck:
card=self.deck.pop(); p.hand.append(card); p.hand=sort_hand(p.hand)
print(f' kann nicht legen und zieht {card.plain()}.')
else:
print(' Stapel leer - Zug wird beendet.')
self.turn=(self.turn+1)%len(self.players); self.drew=False; self.melded=False; self.history=[]
self.handover=True
input('\n ENTER...')
return False
def run(self):
while True:
self.show()
if self.command(input('\n> ')): return
if self.p.bot:
if self.bot_turn(): return
else:
self.show()
if self.command(input('\n> ')): return
if self.handover:
self.handover=False
self.clear()
print(f'\n Zug beendet. Bitte gib den Computer an {self.p.name} weiter,')
print(' damit der andere Spieler deine Karten nicht sehen kann.')
if self.p.bot:
print(f'\n Zug beendet. {self.p.name} ist jetzt am Zug,')
print(' seine Karten bleiben verborgen.')
else:
print(f'\n Zug beendet. Bitte gib den Computer an {self.p.name} weiter,')
print(' damit der andere Spieler deine Karten nicht sehen kann.')
input(' ENTER drücken, wenn du bereit bist...')