This repository has been archived by the owner on Jun 21, 2020. It is now read-only.
forked from Gravitar64/A-beautiful-code-in-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Teil_16_2_Vier_gewinnt.py
153 lines (134 loc) · 3.78 KB
/
Teil_16_2_Vier_gewinnt.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from collections import defaultdict
spielfeld = {} # Key = (spalte, zeile), Value = 'O' oder 'X'
SPALTEN = 7
ZEILEN = 6
ZELLEN = SPALTEN * ZEILEN
RICHTUNGEN = [(-1, -1), (0, -1), (1, -1), (-1, 0),
(1, 0), (-1, 1), (0, 1), (1, 1)]
pos2Index = defaultdict(list)
def quadPositionen(pos, richtung):
positionen = set()
sp, ze = pos
rsp, rze = richtung
neue_sp, neue_ze = sp + rsp*3, ze+rze*3
if neue_sp < 0 or neue_sp >= SPALTEN or neue_ze < 0 or neue_ze >= ZEILEN:
return False
for i in range(4):
positionen.add((sp+rsp*i, ze+rze*i))
return positionen
def quadsErmitteln():
zähler = 0
quads = {}
bekannte_positionen = set()
for i in range(ZELLEN):
for richtung in RICHTUNGEN:
pos = (i % SPALTEN, i // SPALTEN)
positionen = quadPositionen(pos, richtung)
if not positionen or positionen in bekannte_positionen: continue
quads[zähler] = [0,0] # Anzahl der gelben[0], roten[1] Steine im Quad
for position in positionen:
pos2Index[position].append(zähler)
bekannte_positionen.add(frozenset(positionen))
zähler += 1
return quads
def findeTiefsteZeile(spalte):
for zeile in reversed(range(ZEILEN)):
if (spalte, zeile) not in spielfeld:
return zeile
def spalteGültig(spalte):
if (spalte, 0) in spielfeld:
return False
if 0 <= spalte < 7:
return True
def printSpielfeld():
for i in range(ZELLEN):
if i % SPALTEN == 0:
print()
pos = (i % SPALTEN, i // SPALTEN)
if pos in spielfeld:
print(spielfeld[pos], end=' ')
else:
print('.', end=' ')
print()
def steinSetzen(pos, spieler):
win = False
spielfeld[pos] = 'O' if spieler else 'X'
for i in pos2Index[pos]:
quads[i][spieler] +=1
if quads[i][spieler] == 4:
win = True
return win
def steinLöschen(pos, spieler):
del spielfeld[pos]
for i in pos2Index[pos]:
quads[i][spieler] -=1
def bewerten():
score = 0
for pos in spielfeld:
for i in pos2Index[pos]:
gelbe, rote = quads[i]
if gelbe > 0 and rote > 0: continue
score += rote*10
score -= gelbe*10
return score
def zugliste():
züge = []
for spalte in range(SPALTEN):
if not spalteGültig(spalte): continue
zeile = findeTiefsteZeile(spalte)
züge.append((spalte,zeile))
return züge
def human(spieler):
while True:
spalte = int(input('Ihr Zug (Spalte 0-6): '))
if spalteGültig(spalte):
break
zeile = findeTiefsteZeile(spalte)
win = steinSetzen((spalte,zeile), spieler)
return win
def computer(spieler):
bewertete_züge = []
for zug in zugliste():
win = steinSetzen(zug, spieler)
score = minimax(7, -999999, 999999, spieler, win)
steinLöschen(zug, spieler)
bewertete_züge.append((score,zug))
bewertete_züge.sort(reverse=spieler)
score, bester_zug = bewertete_züge[0]
win = steinSetzen(bester_zug, spieler)
print(bewertete_züge)
print(f'Spieler {1 if spieler else 2} setzt {bester_zug} mit der Bewertung {score}')
return win
def minimax(tiefe, alpha, beta, spieler, win):
if win:
return 99999+tiefe if spieler else -99999-tiefe
if tiefe == 0 or len(spielfeld) == ZELLEN:
return bewerten()
spieler = not spieler
value = -999999 if spieler else 999999
for zug in zugliste():
win = steinSetzen(zug, spieler)
score = minimax(tiefe-1, alpha, beta, spieler, win)
steinLöschen(zug, spieler)
if spieler:
value = max(value, score)
alpha = max(value, alpha)
else:
value = min(value, score)
beta = min(value, beta)
if alpha >= beta:
break
return value
quads = quadsErmitteln()
spieler = True
while True:
printSpielfeld()
if spieler:
win = human(spieler)
else:
win = computer(spieler)
if win:
printSpielfeld()
print('GEWONNEN!!!')
break
spieler = not spieler