This repository has been archived by the owner on May 6, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
engine.py
149 lines (115 loc) · 4.4 KB
/
engine.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
#TODO think about Classes, Responsibilities, and Collaborations...
#What entities are there? What should they do?
class Piece(object):
color = None
name = None
def __eq__(self, other):
return isinstance(self, other.__class__)
def __ne__(self, other):
return not self.__eq__(other)
class EmptyPiece(Piece):
color = "brown"
name = ""
class Player1Piece(Piece):
color = "white"
name = "White"
class Player2Piece(Piece):
color = "black"
name = "Black"
class Engine:
def __init__(self, turn=Player2Piece()):
"""Put the pieces on the board, set the turn,
scores and the directions to check valid positions.
"""
self.board = dict()
for row in range(8):
for column in range(8):
self.board[(row, column)] = EmptyPiece()
self.board[(3, 3)] = self.board[(4, 4)] = Player2Piece()
self.board[(3, 4)] = self.board[(4, 3)] = Player1Piece()
self.directions = [(1, 0), (0, 1), (-1, 0), (0, -1),
(1, 1), (-1, -1), (1, -1), (-1, 1)]
self.black_score = self.white_score = 2
self.turn = turn
def change_turn(self):
"""Passes the turn to the other player."""
if isinstance(self.turn, Player2Piece):
self.turn = Player1Piece()
else:
self.turn = Player2Piece()
#TODO a method should have one and only one behavior (no flag-driven behavior)
def move(self, position, play):
"""If play is True, moves to that position.
If play is False, just checks if the position is valid.
"""
to_change = list()
any_valid_position = False
for direction in self.directions:
i, j = position
between = 0
while True:
if (direction[0] == 1 and i == 7) or (direction[0] == -1 and i == 0) or \
(direction[1] == 1 and j == 7) or (direction[1] == -1 and j == 0):
break
i += direction[0]
j += direction[1]
if isinstance(self.board[(i, j)], EmptyPiece):
break
if self.turn != self.board[(i, j)]:
between += 1
else:
if between == 0:
break
else:
if not play:
return True
any_valid_position = True
x, y = position
for times in range(between+1):
to_change.append((x, y))
x += direction[0]
y += direction[1]
break
if play and any_valid_position:
for item in to_change:
self.board[item] = self.turn
self.calculate_score()
self.change_turn()
return True
return False
def find_valid_positions(self):
"""Return a list of valid positions."""
valid_positions = list()
for i in range(8):
for j in range(8):
if isinstance(self.board[(i, j)], EmptyPiece) and self.move((i, j), False):
valid_positions.append((i, j))
return valid_positions
def calculate_score(self):
"""Update the player's score."""
self.black_score = self.white_score = 0
for i in range(8):
for j in range(8):
if isinstance(self.board[(i, j)], Player1Piece):
self.white_score += 1
if isinstance(self.board[(i, j)], Player2Piece):
self.black_score += 1
#TODO I think we can work on the betterment of this approach :P
def check_end(self):
"""Return a bool."""
this_turn = self.find_valid_positions()
self.change_turn()
next_turn = self.find_valid_positions()
self.change_turn()
return len(this_turn) == len(next_turn) == 0
def someone_winning(self):
"""Returns a bool."""
return self.black_score != self.white_score
def who_is_winning(self):
"""Returns a string with the winning side. None if no one is winning."""
if self.someone_winning():
if self.black_score > self.white_score:
return "Black"
else:
return "White"
return None