1
+ from collections import deque
2
+
3
+
4
+ class ConnectFourGame :
5
+
6
+ def __init__ (self , field : list , players : deque ):
7
+ self .field = field
8
+ self .players = players
9
+
10
+ def check_win (self , player ):
11
+ checks = {
12
+ "vertical" : ([1 , 1 , 1 ], 0 ),
13
+ "horizontal" : (0 , [1 , 1 , 1 ]),
14
+ "diagonal" : [
15
+ ([1 , 1 , 1 ], [1 , 1 , 1 ]),
16
+ ([1 , 1 , 1 ], [- 1 , - 1 , - 1 ]),
17
+ ([- 1 , - 1 , - 1 ], [1 , 1 , 1 ]),
18
+ ([- 1 , - 1 , - 1 ], [- 1 , - 1 , - 1 ])
19
+ ]
20
+ }
21
+
22
+ for row in range (6 ):
23
+
24
+ for col in range (7 ):
25
+
26
+ if self .field [row ][col ] == player :
27
+
28
+ winner = True
29
+ m_row = row
30
+
31
+ for num in checks ["vertical" ][0 ]:
32
+ try :
33
+
34
+ m_row += num
35
+
36
+ if self .field [m_row ][col ] != player :
37
+ winner = False
38
+ break
39
+
40
+ except IndexError :
41
+ winner = False
42
+ break
43
+
44
+ if winner :
45
+ return True
46
+
47
+ winner = True
48
+ m_col = col
49
+
50
+ for num in checks ["horizontal" ][1 ]:
51
+ try :
52
+
53
+ m_col += num
54
+
55
+ if self .field [row ][m_col ] != player :
56
+ winner = False
57
+ break
58
+
59
+ except IndexError :
60
+ winner = False
61
+ break
62
+
63
+ if winner :
64
+ return True
65
+
66
+ diag_winner = False
67
+
68
+ for movement in checks ["diagonal" ]:
69
+
70
+ dm_row = row
71
+ dm_col = col
72
+
73
+ for index in range (3 ):
74
+ try :
75
+
76
+ dm_row += movement [0 ][index ]
77
+ dm_col += movement [1 ][index ]
78
+
79
+ if self .field [dm_row ][dm_col ] == player and index == 2 :
80
+ diag_winner = True
81
+
82
+ if self .field [dm_row ][dm_col ] != player :
83
+ break
84
+
85
+ except IndexError :
86
+ break
87
+
88
+ if diag_winner :
89
+ return True
90
+
91
+ return False
92
+
93
+ def append_to_column (self ):
94
+
95
+ player = self .players .popleft ()
96
+ print (f"Player { player } , please choose a column" )
97
+
98
+ while True :
99
+ column = input ()
100
+
101
+ if column .isdigit ():
102
+
103
+ if 0 < int (column ) <= 7 :
104
+
105
+ found_spot = False
106
+ reversed_field = self .field [::- 1 ]
107
+
108
+ for row in range (6 ):
109
+
110
+ if reversed_field [row ][int (column )- 1 ] == 0 :
111
+ found_spot = True
112
+ reversed_field [row ][int (column )- 1 ] = player
113
+ self .field = reversed_field [::- 1 ]
114
+ break
115
+
116
+ if found_spot :
117
+ break
118
+
119
+ print ("The column is full!" )
120
+
121
+ else :
122
+ print ("Column out of range!" )
123
+
124
+ else :
125
+ print ("Column must be digit in the range 1-7" )
126
+
127
+ print (f"Player { player } , please choose a column" )
128
+
129
+ self .players .append (player )
130
+ return [self .check_win (player ), player ]
131
+
132
+
133
+ def start_game ():
134
+ matrix = [[0 ] * 7 for _ in range (6 )]
135
+
136
+ while True :
137
+ how_many_players = input ("How many players will play: " )
138
+
139
+ if how_many_players .isdigit ():
140
+ if 1 < int (how_many_players ) <= 4 :
141
+ break
142
+ print ()
143
+ print ("Minimum players must be 2, maximum players must be 4." )
144
+
145
+ else :
146
+ print ()
147
+ print ("Players must be number" )
148
+
149
+ players = deque ([num + 1 for num in range (int (how_many_players ))])
150
+
151
+ print ("MAP:" )
152
+ [print (row ) for row in matrix ]
153
+ print ()
154
+ print ()
155
+
156
+ play (matrix , players )
157
+
158
+
159
+ def play (matrix , players ):
160
+ game = ConnectFourGame (matrix , players )
161
+
162
+ while True :
163
+ have_winner = game .append_to_column ()
164
+
165
+ [print (row ) for row in matrix ]
166
+
167
+ if have_winner [0 ]:
168
+ print (f"The winner is player { have_winner [1 ]} \n " )
169
+ restart = input ("type \" r\" to restart the game: " ).lower ()
170
+
171
+ if restart == "r" :
172
+ start_game ()
173
+
174
+ else :
175
+ break
176
+
177
+
178
+ start_game ()
0 commit comments