add bot in myrummy
This commit is contained in:
+9
-1
@@ -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
@@ -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...')
|
||||||
|
|||||||
Reference in New Issue
Block a user