2
2
import time
3
3
from typing import Tuple
4
4
5
- from expression import (
6
- ExpressionItems ,
7
- Expression ,
8
- ExpressionItem ,
9
- Direction ,
10
- )
5
+ from expression import Expression
6
+ from expression_map import ExpressionMap , ExpressionItem , Direction
11
7
from expression_resolver import ExpressionResolver
12
8
13
9
14
10
class CrossMath :
15
- def __init__ (self ):
16
- self ._items = ExpressionItems ()
11
+ def __init__ (self , exp_map : ExpressionMap ):
12
+ self ._map = exp_map
17
13
self ._expression_resolver = ExpressionResolver ()
18
14
19
- def _find_potential_positions (self , items_map : list [ list ] ) -> list [Tuple [int , int ]]:
20
- for y in range (len ( items_map )):
21
- for x in range (len ( items_map [ y ] )):
22
- value = items_map [ y ][ x ]
15
+ def _find_potential_positions (self ) -> list [Tuple [int , int ]]:
16
+ for y in range (self . _map . height ( )):
17
+ for x in range (self . _map . width ( )):
18
+ value = self . _map . get ( x , y )
23
19
if isinstance (value , int ):
24
20
yield x , y
25
21
22
+ def _check_expression_frame (
23
+ self , x : int , y : int , direction : Direction , length : int
24
+ ) -> bool :
25
+ if direction .is_horizontal ():
26
+ if x > 0 and self ._map .get (x - 1 , y ) is not None :
27
+ return False
28
+ if (
29
+ x + length + 1 < self ._map .width ()
30
+ and self ._map .get (x + length + 1 , y ) is not None
31
+ ):
32
+ return False
33
+ elif direction .is_vertical ():
34
+ if y > 0 and self ._map .get (x , y - 1 ) is not None :
35
+ return False
36
+ if (
37
+ y + length + 1 < self ._map .height ()
38
+ and self ._map .get (x , y + length + 1 ) is not None
39
+ ):
40
+ return False
41
+ else :
42
+ raise ValueError (f"Not supported direction: { direction } " )
43
+ return True
44
+
45
+ def _check_x_y_overflow (self , x : int , y : int , length : int ) -> bool :
46
+ if x < 0 :
47
+ return False
48
+ elif x + length >= self ._map .width ():
49
+ return False
50
+ elif y < 0 :
51
+ return False
52
+ elif y + length >= self ._map .height ():
53
+ return False
54
+ return True
55
+
26
56
def _find_potential_values (
27
57
self , potential_positions : list [Tuple [int , int ]]
28
58
) -> list [Tuple [Direction , int , int , list ]]:
59
+ max_expression_length = max (Expression .SUPPORTED_LENGTHS )
29
60
for next_position in potential_positions :
30
61
x , y = next_position
31
- slice_offset = - 1
32
- slice_length = ExpressionItem .LENGTH - slice_offset
33
- values_offset = - slice_offset
34
- for direction in [Direction .HORIZONTAL , Direction .VERTICAL ]:
35
- x_offset = 0 if direction == Direction .VERTICAL else slice_offset
36
- y_offset = 0 if direction == Direction .HORIZONTAL else slice_offset
37
- values = self ._items .get_values (
38
- x + x_offset , y + y_offset , direction , slice_length
39
- )
40
- if values [0 ] is None and values [2 ] is None :
41
- yield (
42
- direction ,
43
- x ,
44
- y ,
45
- values [values_offset :],
62
+ for direction in Direction .all ():
63
+ for expression_offset in range (0 , - max_expression_length - 1 , - 2 ):
64
+ values_x_offset = (
65
+ 0 if direction .is_vertical () else expression_offset
66
+ )
67
+ values_y_offset = (
68
+ 0 if direction .is_horizontal () else expression_offset
46
69
)
70
+ for expression_length in Expression .SUPPORTED_LENGTHS :
71
+ values_x = x + values_x_offset
72
+ values_y = y + values_y_offset
73
+ if not self ._check_x_y_overflow (
74
+ values_x , values_y , expression_length
75
+ ):
76
+ continue
77
+
78
+ if not self ._check_expression_frame (
79
+ values_x , values_y , direction , expression_length
80
+ ):
81
+ continue
82
+
83
+ values = self ._map .get_values (
84
+ values_x , values_y , direction , expression_length
85
+ )
86
+ if all ([value is not None for value in values ]):
87
+ # already filled
88
+ continue
89
+
90
+ yield (
91
+ direction ,
92
+ values_x ,
93
+ values_y ,
94
+ values ,
95
+ )
47
96
48
97
def _init_generate (self ):
49
98
expression = self ._expression_resolver .resolve (Expression ())
50
99
if expression is None :
51
100
raise Exception ("No expression found" )
52
101
direction = random .choice ([Direction .HORIZONTAL , Direction .VERTICAL ])
53
- self ._items .append (ExpressionItem (0 , 0 , direction , expression ))
102
+ item = ExpressionItem (
103
+ 3 ,
104
+ 3 ,
105
+ direction ,
106
+ expression ,
107
+ )
108
+ self ._map .put (item )
54
109
55
110
def generate (self ):
56
111
start_time = time .time ()
57
112
self ._init_generate ()
58
- for i in range (20 ):
59
- items_map = self ._items .get_map ()
60
- potential_positions = self ._find_potential_positions (items_map )
113
+ for i in range (40 ):
114
+ potential_positions = self ._find_potential_positions ()
61
115
potential_values = list (self ._find_potential_values (potential_positions ))
62
116
random .shuffle (potential_values )
63
117
is_expression_appended = False
@@ -66,7 +120,7 @@ def generate(self):
66
120
# print("desc:", desc, "x:", _x, "y:", _y)
67
121
try :
68
122
expression = self ._expression_resolver .resolve (
69
- Expression .instance_from_values (values )
123
+ Expression .from_values (values )
70
124
)
71
125
except ValueError :
72
126
# TODO store dead positions
@@ -75,7 +129,7 @@ def generate(self):
75
129
# TODO store dead positions
76
130
continue
77
131
expression_item = ExpressionItem (_x , _y , direction , expression )
78
- self ._items . append (expression_item )
132
+ self ._map . put (expression_item )
79
133
is_expression_appended = True
80
134
break
81
135
if not is_expression_appended :
@@ -84,4 +138,4 @@ def generate(self):
84
138
print ("time: " , time .time () - start_time )
85
139
86
140
def print (self ):
87
- self ._items .print ()
141
+ self ._map .print ()
0 commit comments