Files
tinyproject-monorepo/myrummy/game.py
T
2026-08-23 13:03:06 +02:00

160 lines
6.5 KiB
Python

import copy, random
from cards import *
def yes_no(q, default=None):
while True:
a=input(q+' (j/n): ').strip().lower()
if a in ('j','ja','y','yes'): return True
if a in ('n','nein','no'): return False
if not a and default is not None: return default
print(' Bitte j oder n eingeben.')
class Player:
def __init__(self,name):
self.name=name
self.hand=[]
self.opened=False
class Game:
def __init__(self):
print('EINSTELLUNGEN')
print(' ~~~~~~~~~~~~')
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.turn=0
self.table=[]
self.deck=deck(); random.shuffle(self.deck)
self.history=[]
self.drew=False
self.handover=False
for p in self.players:
p.hand=sort_hand([self.deck.pop() for _ in range(14)])
@property
def p(self): return self.players[self.turn]
def save(self):
self.history.append(copy.deepcopy((self.players,self.table,self.deck,self.drew)))
def undo(self):
if not self.history:
print('Nichts zum Rückgängigmachen.'); return
self.players,self.table,self.deck,self.drew=self.history.pop()
def clear(self): print('\033[2J\033[H',end='')
def show(self):
self.clear()
print('╔════════════════════════════════════════════════════╗')
print('║ MYRUMMY ║')
print('╚════════════════════════════════════════════════════╝')
print(f' Am Zug: {self.p.name} Karten im Stapel: {len(self.deck)}')
print(f' Regeln: 13-1-Umlauf: {"ja" if self.wrap else "nein"} Erstmeldung 30: {"ja" if self.min30 else "nein"}')
print(f' Erstmeldung: {"ja" if self.p.opened else "nein"}')
print('\nTISCH')
if not self.table: print(' (leer)')
for i,g in enumerate(self.table,1):
print(f' {i:>2}: ' + ' '.join(f'{j}:{c.text()}' for j,c in enumerate(g,1)) + f' [{kind(g, self.wrap)}]')
print('\nHAND')
lines=[]; key=None
for i,c in enumerate(self.p.hand,1):
k='J' if c.joker else c.color
if k!=key: lines.append([]); key=k
lines[-1].append(f'{i}:{c.text()}')
for l in lines: print(' '+ ' '.join(l))
print('\nBEFEHLE')
print(' m H G Handkarte H -> Gruppe G')
print(' m H new Handkarte H -> neue Gruppe')
print(' t G C Tischkarte C aus Gruppe G -> Hand')
print(' n leere neue Gruppe')
print(' a G1 G2 Gruppen verbinden')
print(' s G POS Gruppe nach POS teilen')
print(' d ziehen')
print(' u undo')
print(' sort Hand sortieren')
print(' finish Zug prüfen/beenden')
print(' q beenden')
def idx(self,x,maxi):
n=int(x)
if not 1<=n<=maxi: raise ValueError('Nummer außerhalb des gültigen Bereichs.')
return n-1
def move_hand(self,h,g):
hi=self.idx(h,len(self.p.hand)); self.save()
card=self.p.hand.pop(hi)
if g.lower()=='new': self.table.append([card])
else: self.table[self.idx(g,len(self.table))].append(card)
def move_table(self,g,c):
gi=self.idx(g,len(self.table)); ci=self.idx(c,len(self.table[gi])); self.save()
self.p.hand.append(self.table[gi].pop(ci))
if not self.table[gi]: self.table.pop(gi)
self.p.hand=sort_hand(self.p.hand)
def merge(self,a,b):
ai=self.idx(a,len(self.table)); bi=self.idx(b,len(self.table))
if ai==bi: raise ValueError('Gleiche Gruppe.')
self.save(); self.table[ai]+=self.table[bi]; self.table.pop(bi)
def split(self,g,pos):
gi=self.idx(g,len(self.table)); pos=int(pos)
if not 1<=pos<len(self.table[gi]): raise ValueError('Teilposition ungültig.')
self.save(); x=self.table[gi]; self.table[gi]=x[:pos]; self.table.insert(gi+1,x[pos:])
def draw(self):
if self.drew: raise ValueError('Du hast bereits gezogen.')
if not self.deck: raise ValueError('Stapel leer.')
self.save(); self.p.hand.append(self.deck.pop()); self.p.hand=sort_hand(self.p.hand); self.drew=True
def finish(self):
if any(not g or not valid(g, self.wrap) for g in self.table):
print('Zug ungültig: Es gibt eine ungültige Tischgruppe.')
return False
if not self.p.opened:
if self.min30:
total=sum(sum(points(c) for c in g) for g in self.table)
if total<30:
print(f'Erstmeldung braucht mindestens 30 Punkte. Aktuell: {total}')
return False
self.p.opened=True
if not self.p.hand:
print(f'\n{self.p.name} gewinnt!')
return True
self.turn=1-self.turn; self.drew=False; self.history=[]
self.handover=True
return False
def command(self,line):
a=line.split()
if not a:return False
try:
cmd=a[0].lower()
if cmd=='m' and len(a)==3:self.move_hand(a[1],a[2])
elif cmd=='t' and len(a)==3:self.move_table(a[1],a[2])
elif cmd=='n':self.save();self.table.append([])
elif cmd=='a' and len(a)==3:self.merge(a[1],a[2])
elif cmd=='s' and len(a)==3:self.split(a[1],a[2])
elif cmd=='d':self.draw()
elif cmd=='u':self.undo()
elif cmd=='sort':self.p.hand=sort_hand(self.p.hand)
elif cmd=='finish':return self.finish()
elif cmd in ('q','quit','exit'):raise SystemExit
elif cmd=='show':pass
else: raise ValueError('Unbekannter Befehl.')
except (ValueError,IndexError) as e: print('Fehler:',e)
input('\nENTER...')
return False
def run(self):
while True:
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.')
input(' ENTER drücken, wenn du bereit bist...')