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: Start:
python main.py 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) - 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 - 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 Nach jedem beendeten Zug erscheint ein Übergabe-Bildschirm, damit der
nächste Spieler die Karten des Vorgängers nicht sieht. nächste Spieler die Karten des Vorgängers nicht sieht.
+83 -4
View File
@@ -9,9 +9,19 @@ def yes_no(q, default=None):
if not a and default is not None: return default if not a and default is not None: return default
print(' Bitte j oder n eingeben.') 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: class Player:
def __init__(self,name): def __init__(self,name,bot=False):
self.name=name self.name=name
self.bot=bot
self.hand=[] self.hand=[]
self.opened=False self.opened=False
@@ -19,9 +29,14 @@ class Game:
def __init__(self): def __init__(self):
print('EINSTELLUNGEN') print('EINSTELLUNGEN')
print(' ~~~~~~~~~~~~') 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.wrap=yes_no(' 13-1-Umlauf erlauben (z.B. 12,13,1)')
self.min30=yes_no(' Braucht die Erstmeldung 30 Punkte') 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.turn=0
self.table=[] self.table=[]
self.deck=deck(); random.shuffle(self.deck) self.deck=deck(); random.shuffle(self.deck)
@@ -110,7 +125,7 @@ class Game:
if not self.deck: raise ValueError('Stapel leer.') 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) 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.') 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 self.handover=True
def finish(self): def finish(self):
@@ -131,7 +146,7 @@ class Game:
if not self.p.hand: if not self.p.hand:
print(f'\n{self.p.name} gewinnt!') print(f'\n{self.p.name} gewinnt!')
return True 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 self.handover=True
return False return False
@@ -160,13 +175,77 @@ class Game:
input('\nENTER...') input('\nENTER...')
return False 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): def run(self):
while True: while True:
if self.p.bot:
if self.bot_turn(): return
else:
self.show() self.show()
if self.command(input('\n> ')): return if self.command(input('\n> ')): return
if self.handover: if self.handover:
self.handover=False self.handover=False
self.clear() self.clear()
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(f'\n Zug beendet. Bitte gib den Computer an {self.p.name} weiter,')
print(' damit der andere Spieler deine Karten nicht sehen kann.') print(' damit der andere Spieler deine Karten nicht sehen kann.')
input(' ENTER drücken, wenn du bereit bist...') input(' ENTER drücken, wenn du bereit bist...')