Skip to content

Commit bc581e7

Browse files
committed
fixed bug that win was not recognized when we had 5 or more in a row
1 parent ad9ebd7 commit bc581e7

File tree

4 files changed

+35
-8
lines changed

4 files changed

+35
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,4 @@ About the negamax algorithm here: http://www.hamedahmadi.com/gametree/#negamax
5353
Giorgos Komninos
5454
Alexandr Sapunji
5555
Stephen Gunashekar
56+
Shubham Agarwal

tictac/lib/gamestate.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from copy import copy, deepcopy
77
import itertools
88
import math
9+
import operator
910

1011
import 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

tictac/lib/player.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ def opponent(self):
2929
class RandomPlayer(BasePlayer):
3030

3131
def get_move(self, gs):
32+
"""
33+
:gs : gameState object """
3234
return gs.get_random_move()
3335

3436

tictac/test/test_gamestate.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,18 @@ def test_winner():
8787
assert gs.is_win(1) == False
8888
assert gs.is_win(-1) == True
8989
assert gs.winner == -1
90+
gs = Connect4GameState(gs=np.zeros((6, 7), dtype=int),)
91+
for i in xrange(0, 5):
92+
gs.do_move(i, 1)
93+
print gs
94+
assert gs.is_win(1) == True
95+
96+
9097

9198
def test_diagonals():
9299
gs = Connect4GameState(gs=np.zeros((6, 7), dtype=int),)
93100
gs.do_move(0, 1)
94101
gs.do_move(5, 1)
95102
gs.do_move(6, 1)
96-
assert len(gs.get_diagonals()) == 25
103+
assert len(gs.get_diagonals()) == 12
97104

0 commit comments

Comments
 (0)