66from copy import copy , deepcopy
77import itertools
88import math
9+ import operator
910
1011import numpy as np
1112
@@ -104,6 +105,9 @@ def winner(self):
104105 return None
105106
106107 def evaluation (self ):
108+ """Returns 0 if we have a draw.
109+ If we have a winner returns the winner (1 | -1)
110+ else if there are still available moves returns 100"""
107111 if self .winner in (- 1 , 1 ):
108112 return self .winner
109113 if self .move_still_possible ():
@@ -116,7 +120,6 @@ def move_still_possible(self):
116120 if there is no game then the sum of the absolute values
117121 of all elements should be ndarray.size
118122 """
119- #print self.gameState.sum()
120123 return np .absolute (self .gameState ).sum () < self .gameState .size
121124
122125 def get_available_moves (self ):
@@ -144,11 +147,8 @@ def do_move(self, move, player):
144147 def is_win (self , p ):
145148 """Determine if the player has a 4 in a row in:
146149 - columns, rows, diagonals
147- http://docs.scipy.org/doc/numpy/reference/generated/numpy.diag.html
148150 """
149151 assert p != 0
150- # fist for rows:
151- #rows_array = np.array_split(self.gameState, 6, axis=0)
152152 rows = [self .gameState [i ,:].tolist () for i in xrange (0 , 6 )]
153153 columns = [self .gameState [:,i ].tolist () for i in xrange (0 , 7 )]
154154 diags = self .get_diagonals ()
@@ -157,19 +157,36 @@ def is_win(self, p):
157157 return False
158158
159159 def find_score4 (self , l , p ):
160+ """Returns True if the l contains 4 in a row"""
161+ comp_operator = operator .ge if p == 1 else operator .le
160162 for r in l :
161163 for k , v in itertools .groupby (r ):
162- if sum (v ) == p * 4 :
164+ if comp_operator ( sum (v ), p * 4 ) :
163165 return True
164166 return False
165167
166168 def get_diagonals (self ):
167- """"""
169+ """
170+ Returns a list of all* the diagonals of the array.
171+ * Actually we do not return the ones with len()<4 since
172+ there we cannot have a score4 there.
173+
174+ Idea modified from here:
175+ http://stackoverflow.com/questions/6313308/get-all-the-diagonals-in-a-matrix-list-of-lists-in-python
176+
177+ we want lower-left-to-upper-right and upper-left-to-lower right
178+ diagonals.
179+ "::-1" returns the rows in reverse. ":" returns the columns as is,
180+ effectively vertically mirroring the original array so the wanted
181+ diagonals are# lower-right-to-uppper-left.
182+ ::-1 -> returns rows reversed.
183+
184+ """
168185 # upper diagonals k > 0
169186 diags = [self .gameState [::- 1 ,:].diagonal (i )
170187 for i in range (- 6 , 7 )]
171188 diags .extend (self .gameState .diagonal (i ) for i in range (6 ,- 6 ,- 1 ))
172- return list ( d .tolist () for d in diags )
189+ return filter ( lambda e : len ( e ) > 3 , [ d .tolist () for d in diags ] )
173190
174191
175192
0 commit comments