-
Notifications
You must be signed in to change notification settings - Fork 2
/
board.py
83 lines (66 loc) · 2.83 KB
/
board.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
from copy import deepcopy
class Board:
"""Abstraction of state"""
def __init__(self, board, parent=None, from_which=-1, to_which=-1):
"""Initialize a board(state)
Board and state are equivalent in our comments.
Args:
board [list[list]]: all bottles
parent [Board]: the parent of current state
from_which [int]: index of bottle which pops color blocks
to_which [int]: index of bottle which push color blocks
"""
self.board = board
self.parent = parent
self.from_which = from_which
self.to_which = to_which
def next_boards(self):
"""Successor function: all next states of the current state
Returns: list[Board]
All valid successive states from current state
"""
next_states = []
n_bottles = len(self.board)
for i in range(n_bottles):
if self.board[i].finished:
continue
pseudo_pop_res = self.board[i].pop(pseudo=True)
if pseudo_pop_res is None:
continue
for j in range(n_bottles):
if i == j: continue
if self.board[j].finished:
continue
pseudo_push_res = self.board[j].push(pseudo_pop_res, pseudo=True)
if pseudo_push_res == -1:
continue
# Add your heuristic pruning strategies here
if self.board[i].size == len(pseudo_pop_res) and self.board[j].size == 0:
continue
# generate new boards(states)
copied_board = deepcopy(self.board)
copied_board[j].push(copied_board[i].pop())
next_states.append(Board.board_factory(board=copied_board,
parent=self,
from_which=i,
to_which=j))
return next_states
def state_checking(self):
"""Whether current state is our goal state"""
for bottle in self.board:
if not self._consisitent(bottle.data):
return False
return True
def _consisitent(self, bottle_data):
"""Whether we have done with this bottle"""
return bottle_data[0] == bottle_data[1] and \
bottle_data[1] == bottle_data[2] and \
bottle_data[2] == bottle_data[3]
@property
def string(self):
"""String representation of the current state"""
return "".join([bottle.string for bottle in self.board])
@classmethod
def board_factory(cls, board, parent=None, from_which=-1, to_which=-1):
"""Generate new state"""
return cls(board, parent=parent, from_which=from_which, to_which=to_which)