This repository was archived by the owner on Jun 27, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbegin.py
More file actions
258 lines (212 loc) · 8.04 KB
/
begin.py
File metadata and controls
258 lines (212 loc) · 8.04 KB
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
class Board:
"""A data type representing a Connect-4 board
with an arbitrary number of rows and columns.
"""
def __init__(self, width, height):
"""Construct objects of type Board, with the given width and height."""
self.width = width
self.height = height
self.data = [[' ']*width for row in range(height)]
# We hoeven niets terug te geven vanuit een constructor!
def __repr__(self):
"""This method returns a string representation
for an object of type Board.
"""
s = '' # de string om terug te geven
for row in range(0, self.height):
s += '|'
for col in range(0, self.width):
s += self.data[row][col] + '|'
s += '\n'
s += (2*self.width + 1) * '-' # onderkant van het bord
# hier moeten de nummers nog onder gezet worden
s += '\n'
for i in range(self.width):
s += ' ' + str(i % 10)
return s # het bord is compleet, geef het terug
def add_move(self, col, ox):
"""Adds a stone for player ox to column col"""
i = 0
while i < self.height and self.data[i][col] == ' ':
i += 1
self.data[i-1][col] = ox
def clear(self):
"""Clears the board"""
self.data = [[' ']*self.width for _ in range(self.height)]
def set_board(self, move_string):
"""Accepts a string of columns and places
alternating checkers in those columns,
starting with 'X'.
For example, call b.set_board('012345')
to see 'X's and 'O's alternate on the
bottom row, or b.set_board('000000') to
see them alternate in the left column.
move_string must be a string of one-digit integers.
"""
next_checker = 'X' # we starten door een 'X' te spelen
for col_char in move_string:
col = int(col_char)
if 0 <= col <= self.width:
self.add_move(col, next_checker)
if next_checker == 'X':
next_checker = 'O'
else:
next_checker = 'X'
def allows_move(self, col):
"""Checks whether column col can be played"""
return 0 <= col < self.width and self.data[0][col] == ' '
def is_full(self):
"""Checks whether the board is full"""
return all(not self.allows_move(col) for col in range(self.width))
def del_move(self, col):
"""Removes a stone from column col"""
i = 0
while i < self.height and self.data[i][col] == ' ':
i += 1
if i < self.height:
self.data[i][col] = ' '
def wins_for(self, ox):
"""Checks whether player ox wins the game"""
for y in range(self.height):
for x in range(self.width):
if in_a_row_n_east(ox, y, x, self.data, 4) or in_a_row_n_south(ox, y, x, self.data, 4) or \
in_a_row_n_southeast(ox, y, x, self.data, 4) or in_a_row_n_northeast(ox, y, x, self.data, 4):
return True
return False
def host_game(self):
"""Plays a game of Connect Four"""
ox = 'O'
while True:
# druk het bord af
print(self)
# controleer of het spel afgelopen is
if self.wins_for(ox):
print(ox, 'heeft gewonnen!')
break
if self.is_full():
print('Gelijkspel!')
break
# verander de huidige speler
if ox == 'O':
ox = 'X'
else:
ox = 'O'
# laat de speler een kolom kiezen
col = -1
while not self.allows_move(col):
col = int(input('Kolom voor '+ox+': '))
# voer de zet uit
self.add_move(col, ox)
def play_game(self, px, po, show_scores=False):
"""
Plays a game of Connect Four between players px and po.
If show_scores is True, the player's board evaluations are printed each turn.
"""
ox = 'O'
while True:
# druk het bord af
print(self)
# controleer of het spel afgelopen is
if self.wins_for(ox):
print(f'{ox} heeft gewonnen!')
break
if self.is_full():
print('Gelijkspel!')
break
# verander de huidige speler
if ox == 'O':
ox = 'X'
player = px
else:
ox = 'O'
player = po
if player == 'human':
# laat de menselijke speler een kolom kiezen
col = -1
while not self.allows_move(col):
col = int(input('Kolom voor ' + ox + ': '))
else:
# de computerspeler berekent een zet
if show_scores:
scores = player.scores_for(self)
print('Scores voor ', ox, ':', [int(sc) for sc in scores])
col = player.tiebreak_move(scores)
else:
col = player.next_move(self)
# voer de zet uit
self.add_move(col, ox)
def in_a_row_n_east(ch, r_start, c_start, a, n):
"""Checks whether ch has n in a row starting at r_start, c_start going east"""
if r_start < 0 or r_start >= len(a) or c_start < 0 or c_start >= len(a[0]) - n+1:
return False
for i in range(0, n):
if a[r_start][c_start+i] != ch:
return False
return True
def in_a_row_n_south(ch, r_start, c_start, a, n):
"""Checks whether ch has n in a row starting at r_start, c_start going south"""
if r_start < 0 or r_start >= len(a) - n+1 or c_start < 0 or c_start >= len(a[0]):
return False
for i in range(0, n):
if a[r_start+i][c_start] != ch:
return False
return True
def in_a_row_n_southeast(ch, r_start, c_start, a, n):
"""Checks whether ch has n in a row starting at r_start, c_start going southeast"""
if r_start < 0 or r_start >= len(a) - n+1 or c_start < 0 or c_start >= len(a[0]) - n+1:
return False
for i in range(0, n):
if a[r_start+i][c_start+i] != ch:
return False
return True
def in_a_row_n_northeast(ch, r_start, c_start, a, n):
"""Checks whether ch has n in a row starting at r_start, c_start going northeast"""
if r_start < n-1 or r_start >= len(a) or c_start < 0 or c_start >= len(a[0]) - n+1:
return False
for i in range(0, n):
if a[r_start-i][c_start+i] != ch:
return False
return True
class Player:
"""An AI player for Connect Four."""
def __init__(self, ox, tbt, ply):
"""Construct a player for a given checker, tie-breaking type,
and ply."""
self.ox = ox
self.tbt = tbt
self.ply = ply
def __repr__(self):
"""Create a string represenation of the player."""
s = "Player: ox = " + self.ox + ", "
s += "tbt = " + self.tbt + ", "
s += "ply = " + str(self.ply)
return s
def opp_ch(self):
'''Deze functie geeft de vijandige speler terug'''
return 'X' if self.ox == 'O' else 'O'
def score_board(self, b):
'''Deze functie geeft een score terug van hoe goed de speler er voor staat
100 is een win
50 is gelijk voor beide speler
0 is een verlies'''
if b.wins_for(self.ox):
return 100.0
if not b.wins_for(self.opp_ch()) and not b.wins_for(self.ox):
return 50.0
return 0.0
# asserts voor opp_ch()
p = Player('O', 'LEFT', 1)
p2 = Player('X', 'RIGHT', 1)
assert p.opp_ch() == 'X'
assert p2.opp_ch() == 'O'
# asserts voor score_board(self, scores)
bord = Board(7, 6)
bord.set_board('01210131')
p = Player('O', 'LEFT', 1)
p2 = Player('X', 'RIGHT', 1)
assert p.score_board(bord) == 100.0
assert p2.score_board(bord) == 0.0
bord.clear()
bord.set_board('0120131')
assert p.score_board(bord) == 50.0
assert p2.score_board(bord) == 50.0