hokusai-zero 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/Gemfile.lock +4 -0
- data/README.md +2 -0
- data/ast/src/core/hml.c +9 -9
- data/ast/src/core/text.c +1 -3
- data/ast/test/text.c +3 -3
- data/docs.sh +29 -0
- data/ext/extconf.rb +50 -14
- data/grammar/corpus/1_document.txt +24 -0
- data/grammar/corpus/6_styles.txt +23 -0
- data/grammar/grammar.js +4 -4
- data/grammar/src/grammar.json +19 -19
- data/grammar/src/parser.c +1904 -1956
- data/grammar/test.nml +10 -8
- data/hokusai.gemspec +2 -1
- data/ui/examples/assets/Delius-Regular.ttf +0 -0
- data/ui/examples/assets/DoHyeon.ttf +0 -0
- data/ui/examples/assets/Inter-Regular.ttf +0 -0
- data/ui/examples/assets/ernest.gif +0 -0
- data/ui/examples/assets/icons/audio-x-generic.png +0 -0
- data/ui/examples/assets/icons/image-x-generic.png +0 -0
- data/ui/examples/assets/icons/media-playback-pause.png +0 -0
- data/ui/examples/assets/icons/media-playback-start.png +0 -0
- data/ui/examples/assets/icons/media-playback-stop.png +0 -0
- data/ui/examples/assets/icons/package-x-generic.png +0 -0
- data/ui/examples/assets/icons/text-x-generic.png +0 -0
- data/ui/examples/assets/icons/video-x-generic.png +0 -0
- data/ui/examples/buddy.rb +16 -14
- data/ui/examples/clock.rb +38 -36
- data/ui/examples/counter.rb +100 -98
- data/ui/examples/dynamic.rb +115 -113
- data/ui/examples/foobar.rb +189 -187
- data/ui/examples/forum/file.rb +54 -0
- data/ui/examples/forum/music.rb +76 -0
- data/ui/examples/forum/post.rb +146 -0
- data/ui/examples/forum.rb +198 -0
- data/ui/examples/spreadsheet/csv.rb +261 -0
- data/ui/examples/spreadsheet.rb +138 -0
- data/ui/examples/stock.rb +86 -92
- data/ui/examples/stock_decider/option.rb +1 -1
- data/ui/examples/tic_tac_toe.rb +193 -191
- data/ui/lib/lib_hokusai.rb +0 -1
- data/ui/src/hokusai/ast.rb +42 -43
- data/ui/src/hokusai/backends/raylib/font.rb +1 -2
- data/ui/src/hokusai/backends/raylib.rb +16 -7
- data/ui/src/hokusai/backends/sdl2/font.rb +13 -9
- data/ui/src/hokusai/backends/sdl2.rb +5 -5
- data/ui/src/hokusai/block.rb +7 -0
- data/ui/src/hokusai/blocks/hblock.rb +2 -2
- data/ui/src/hokusai/blocks/image.rb +5 -1
- data/ui/src/hokusai/blocks/input.rb +17 -0
- data/ui/src/hokusai/blocks/label.rb +5 -2
- data/ui/src/hokusai/blocks/text.rb +10 -5
- data/ui/src/hokusai/blocks/titlebar/osx.rb +4 -4
- data/ui/src/hokusai/blocks/variable.rb +33 -0
- data/ui/src/hokusai/blocks/vblock.rb +1 -1
- data/ui/src/hokusai/commands/rect.rb +4 -4
- data/ui/src/hokusai/commands.rb +33 -31
- data/ui/src/hokusai/diff.rb +11 -0
- data/ui/src/hokusai/event.rb +19 -5
- data/ui/src/hokusai/events/mouse.rb +9 -1
- data/ui/src/hokusai/font.rb +60 -0
- data/ui/src/hokusai/meta.rb +10 -16
- data/ui/src/hokusai/node.rb +1 -1
- data/ui/src/hokusai/painter.rb +1 -2
- data/ui/src/hokusai/util/clamping_iterator.rb +5 -6
- data/ui/src/hokusai.rb +36 -4
- metadata +37 -3
data/ui/examples/stock.rb
CHANGED
@@ -5,111 +5,105 @@ require_relative "./stock_decider/option"
|
|
5
5
|
|
6
6
|
# aim for over 24 percent sort by percentage first
|
7
7
|
# 3 week = 1 option premium * 100 shares / 12
|
8
|
-
module
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
8
|
+
module Demos
|
9
|
+
module StockDecider
|
10
|
+
class StackedBar < Hokusai::Block
|
11
|
+
COLORS = {
|
12
|
+
:week_3 => [157, 221, 117],
|
13
|
+
:week_4 => [117, 157, 221],
|
14
|
+
:week_5 => [221, 180, 117]
|
15
|
+
}
|
16
|
+
|
17
|
+
template <<~EOF
|
18
|
+
[template]
|
19
|
+
virtual
|
20
|
+
EOF
|
21
|
+
|
22
|
+
uses(
|
23
|
+
vblock: Hokusai::Blocks::Vblock,
|
24
|
+
label: Hokusai::Blocks::Label
|
25
|
+
)
|
26
|
+
|
27
|
+
computed! :data
|
28
|
+
|
29
|
+
def symbol
|
30
|
+
data[0]
|
31
|
+
end
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
33
|
+
def render(canvas)
|
34
|
+
key, weeks = data
|
35
|
+
theight = canvas.height - 50
|
36
|
+
draw do
|
37
|
+
weeks.reject(&:nil?).sort { |a, b| b <=> a }.each_with_index do |percent, idx|
|
38
|
+
color = COLORS["week_#{idx + 3}".to_sym]
|
39
|
+
height = (theight * percent) / 100
|
40
|
+
y = canvas.y + theight - height
|
41
|
+
|
42
|
+
rect(canvas.x, y , 150, height) do |command|
|
43
|
+
command.color = Hokusai::Color.convert(color)
|
44
|
+
command.outline = Hokusai::Outline.convert("4,4, 0, 0")
|
45
|
+
command.outline_color = Hokusai::Color.convert("0,0,0,110")
|
46
|
+
end
|
47
|
+
|
48
|
+
text("Week #{idx + 3} (#{percent.round(2)})", canvas.x + 2, y + 10) do |command|
|
49
|
+
command.size = 12
|
50
|
+
end
|
47
51
|
end
|
48
52
|
|
49
|
-
text(
|
50
|
-
command.size =
|
53
|
+
text(symbol, canvas.x + 12, theight + 5) do |command|
|
54
|
+
command.size = 25
|
55
|
+
command.color = Hokusai::Color.new(233,233,233,255)
|
51
56
|
end
|
52
57
|
end
|
53
58
|
|
54
|
-
|
55
|
-
|
56
|
-
command.color = Hokusai::Color.new(233,233,233,255)
|
57
|
-
end
|
59
|
+
canvas.x -= 100
|
60
|
+
yield canvas
|
58
61
|
end
|
59
|
-
|
60
|
-
canvas.x -= 100
|
61
|
-
yield canvas
|
62
62
|
end
|
63
|
-
end
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
64
|
+
class App < Hokusai::Block
|
65
|
+
template <<~EOF
|
66
|
+
[template]
|
67
|
+
vblock { background="84,23,77" padding="0,20,0,20"}
|
68
|
+
hblock { padding="0,20,0,20"}
|
69
|
+
[for="data in attractive_options"]
|
70
|
+
stackedbar { :key="key(index)" :data="data" }
|
71
|
+
EOF
|
72
|
+
|
73
|
+
uses(
|
74
|
+
vblock: Hokusai::Blocks::Vblock,
|
75
|
+
hblock: Hokusai::Blocks::Hblock,
|
76
|
+
stackedbar: StackedBar
|
77
|
+
)
|
78
|
+
|
79
|
+
def attractive_options
|
80
|
+
@options.to_a
|
81
|
+
end
|
83
82
|
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
def key(index)
|
84
|
+
"Key_#{index}"
|
85
|
+
end
|
87
86
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
87
|
+
def on_mounted
|
88
|
+
puts ["mounted"]
|
89
|
+
add_ticker("TSLA")
|
90
|
+
add_ticker("OXY")
|
91
|
+
add_ticker("DG")
|
92
|
+
end
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
94
|
+
def add_ticker(sym)
|
95
|
+
ticker_opts = Option.from_ticker(sym)
|
96
|
+
w3 = ticker_opts.select { |a| a.attractive?(3) }.sort_by { |a| a.percent(3) }.last
|
97
|
+
w4 = ticker_opts.select { |a| a.attractive?(4) }.sort_by { |a| a.percent(4) }.last
|
98
|
+
w5 = ticker_opts.select { |a| a.attractive?(5) }.sort_by { |a| a.percent(5) }.last
|
99
|
+
@options[sym] = [w3&.percent(3), w4&.percent(4), w5&.percent(5)]
|
100
|
+
puts @options[sym]
|
101
|
+
end
|
103
102
|
|
104
|
-
|
105
|
-
|
106
|
-
|
103
|
+
def initialize(**args)
|
104
|
+
@options = {}
|
105
|
+
super
|
106
|
+
end
|
107
107
|
end
|
108
108
|
end
|
109
109
|
end
|
110
|
-
# #
|
111
|
-
# Hokusai::Backends::SDLBackend.run(StockDecider::App) do |config|
|
112
|
-
# config.width = 500
|
113
|
-
# config.height = 500
|
114
|
-
# config.title = "Loop application"
|
115
|
-
# end
|
data/ui/examples/tic_tac_toe.rb
CHANGED
@@ -2,238 +2,240 @@ require_relative "../src/hokusai"
|
|
2
2
|
require_relative "../src/hokusai/backends/raylib"
|
3
3
|
require_relative "../src/hokusai/backends/sdl2"
|
4
4
|
|
5
|
-
module
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
EOF
|
20
|
-
|
21
|
-
template <<-EOF
|
22
|
-
[template]
|
23
|
-
vblock {
|
24
|
-
@click="emit_position"
|
25
|
-
@hover="set_hover"
|
26
|
-
@mouseout="set_mouseout"
|
27
|
-
:background="compute_background"
|
28
|
-
...squareStyle
|
5
|
+
module Demos
|
6
|
+
module TicTacToe
|
7
|
+
module Player
|
8
|
+
X = 0
|
9
|
+
O = 1
|
10
|
+
None = 2
|
11
|
+
end
|
12
|
+
|
13
|
+
class Square < Hokusai::Block
|
14
|
+
style <<-EOF
|
15
|
+
[style]
|
16
|
+
squareStyle {
|
17
|
+
outline: 3.0;
|
18
|
+
outline_color: rgb(233,233,233);
|
29
19
|
}
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
20
|
+
EOF
|
21
|
+
|
22
|
+
template <<-EOF
|
23
|
+
[template]
|
24
|
+
vblock {
|
25
|
+
@click="emit_position"
|
26
|
+
@hover="set_hover"
|
27
|
+
@mouseout="set_mouseout"
|
28
|
+
:background="compute_background"
|
29
|
+
...squareStyle
|
30
|
+
}
|
31
|
+
label { height="13" :content="read_position" }
|
32
|
+
[if="has_player"]
|
33
|
+
image { :source="square_image" }
|
34
|
+
EOF
|
35
|
+
|
36
|
+
computed! :player
|
37
|
+
computed! :position
|
38
|
+
|
39
|
+
uses(
|
40
|
+
vblock: Hokusai::Blocks::Vblock,
|
41
|
+
image: Hokusai::Blocks::Image,
|
42
|
+
label: Hokusai::Blocks::Label
|
43
|
+
)
|
44
|
+
|
45
|
+
def compute_background
|
46
|
+
case player
|
47
|
+
when Player::X
|
48
|
+
[52,168,77]
|
49
|
+
when Player::O
|
50
|
+
[219,176,57]
|
51
|
+
when Player::None
|
52
|
+
@hover ? [55, 110, 155] : [47,98,140]
|
53
|
+
end
|
52
54
|
end
|
53
|
-
end
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
56
|
+
def set_hover(event)
|
57
|
+
@hover = true
|
58
|
+
end
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
def set_mouseout(event)
|
61
|
+
@hover = false
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
def read_position
|
65
|
+
position.inspect
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
def emit_position(click)
|
69
|
+
emit("position", position)
|
70
|
+
end
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
72
|
+
def has_player
|
73
|
+
player != Player::None
|
74
|
+
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
def square_image
|
77
|
+
case player
|
78
|
+
when Player::X
|
79
|
+
return "#{__dir__}/assets/science-troll.png"
|
80
|
+
when Player::O
|
81
|
+
return "#{__dir__}/assets/football-troll.png"
|
82
|
+
end
|
81
83
|
end
|
82
84
|
end
|
83
|
-
end
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
86
|
+
class Row < Hokusai::Block
|
87
|
+
template <<-EOF
|
88
|
+
[template]
|
89
|
+
hblock
|
90
|
+
[for="player in row"]
|
91
|
+
square { cursor="pointer" @position="emit_position" :player="player" :key="key(index)" :position="position(index)" }
|
92
|
+
EOF
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
uses(
|
95
|
+
square: Square,
|
96
|
+
hblock: Hokusai::Blocks::Hblock
|
97
|
+
)
|
97
98
|
|
98
|
-
|
99
|
-
|
99
|
+
computed! :row
|
100
|
+
computed! :row_index
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
def emit_position(pos)
|
103
|
+
emit("position", pos)
|
104
|
+
end
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
106
|
+
def key(index)
|
107
|
+
"player_#{row_index}_#{index}"
|
108
|
+
end
|
108
109
|
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
def position(index)
|
111
|
+
[row_index, index]
|
112
|
+
end
|
112
113
|
|
113
|
-
|
114
|
+
end
|
114
115
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
116
|
+
class App < Hokusai::Block
|
117
|
+
template <<-EOF
|
118
|
+
[template]
|
119
|
+
vblock
|
120
|
+
[if="has_winner"]
|
121
|
+
vblock { background="10,10,10,222" }
|
122
|
+
img { :source="winner_image"}
|
123
|
+
vblock
|
124
|
+
label { :content="winner_text" color="255,255,255", size="30"}
|
125
|
+
label { @click="restart" color="222,199,199" size="20" content="restart"}
|
126
|
+
[else]
|
122
127
|
vblock
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
super
|
146
|
-
|
147
|
-
restart
|
148
|
-
end
|
128
|
+
[for="row in board"]
|
129
|
+
row { @position="update_game" :row="row" :key="key(index)" :row_index="index" }
|
130
|
+
EOF
|
131
|
+
|
132
|
+
uses(
|
133
|
+
row: Row,
|
134
|
+
vblock: Hokusai::Blocks::Vblock,
|
135
|
+
hblock: Hokusai::Blocks::Hblock,
|
136
|
+
label: Hokusai::Blocks::Label,
|
137
|
+
empty: Hokusai::Blocks::Empty,
|
138
|
+
img: Hokusai::Blocks::Image
|
139
|
+
)
|
140
|
+
|
141
|
+
attr_accessor :current_player, :board, :count
|
142
|
+
|
143
|
+
def initialize(**args)
|
144
|
+
@current_player = Player::X
|
145
|
+
@count = 0
|
146
|
+
super
|
147
|
+
|
148
|
+
restart
|
149
|
+
end
|
149
150
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
151
|
+
def restart(*args)
|
152
|
+
@board = [
|
153
|
+
[Player::None, Player::None, Player::None],
|
154
|
+
[Player::None, Player::None, Player::None],
|
155
|
+
[Player::None, Player::None, Player::None]
|
156
|
+
]
|
157
|
+
self.count = 0
|
158
|
+
end
|
158
159
|
|
159
|
-
|
160
|
-
|
161
|
-
|
160
|
+
def key(index)
|
161
|
+
"row_#{index}"
|
162
|
+
end
|
162
163
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
164
|
+
def winner_image
|
165
|
+
case winner
|
166
|
+
when Player::X
|
167
|
+
return "#{__dir__}/assets/science-troll.png"
|
168
|
+
when Player::O
|
169
|
+
return "#{__dir__}/assets/football-troll.png"
|
170
|
+
else
|
171
|
+
return "#{__dir__}/assets/baby_sean.png"
|
172
|
+
end
|
171
173
|
end
|
172
|
-
end
|
173
174
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
175
|
+
def winner_text
|
176
|
+
case winner
|
177
|
+
when Player::X
|
178
|
+
"Player X won!"
|
179
|
+
when Player::O
|
180
|
+
"Player O won!"
|
181
|
+
else
|
182
|
+
"No winner"
|
183
|
+
end
|
182
184
|
end
|
183
|
-
end
|
184
185
|
|
185
|
-
|
186
|
-
|
187
|
-
|
186
|
+
def has_winner
|
187
|
+
count >= 9 || !check_win.nil?
|
188
|
+
end
|
188
189
|
|
189
|
-
|
190
|
-
|
191
|
-
|
190
|
+
def winner
|
191
|
+
check_win
|
192
|
+
end
|
192
193
|
|
193
|
-
|
194
|
-
|
194
|
+
def update_game(position)
|
195
|
+
row, col = position
|
195
196
|
|
196
|
-
|
197
|
+
self.count += 1
|
197
198
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
199
|
+
case current_player
|
200
|
+
when Player::X
|
201
|
+
board[row][col] = Player::X unless board[row][col] != Player::None
|
202
|
+
self.current_player = Player::O
|
203
|
+
when Player::O
|
204
|
+
board[row][col] = Player::O unless board[row][col] != Player::None
|
205
|
+
self.current_player = Player::X
|
206
|
+
end
|
205
207
|
end
|
206
|
-
end
|
207
208
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
209
|
+
def check_win
|
210
|
+
[Player::X, Player::O].each do |player|
|
211
|
+
(0...3).step do |i|
|
212
|
+
if board[i][0] == player && board[i][1] == player && board[i][2] == player
|
213
|
+
return player
|
214
|
+
end
|
214
215
|
|
215
|
-
|
216
|
-
|
217
|
-
|
216
|
+
if board[0][i] == player && board[1][i] == player && board[2][i] == player
|
217
|
+
return player
|
218
|
+
end
|
218
219
|
|
219
|
-
|
220
|
-
|
220
|
+
diagonal_left = board[0][0] == player && board[1][1] == player && board[2][2] == player
|
221
|
+
diagonal_right = board[2][0] == player && board[1][1] == player && board[0][2] == player
|
221
222
|
|
222
|
-
|
223
|
-
|
223
|
+
if diagonal_left || diagonal_right
|
224
|
+
return player
|
225
|
+
end
|
224
226
|
end
|
225
227
|
end
|
226
|
-
end
|
227
228
|
|
228
|
-
|
229
|
-
|
229
|
+
nil
|
230
|
+
end
|
230
231
|
|
231
|
-
|
232
|
-
|
232
|
+
def render(canvas)
|
233
|
+
if Hokusai.can_render(canvas)
|
233
234
|
|
234
|
-
|
235
|
+
emit("width", canvas.width)
|
235
236
|
|
236
|
-
|
237
|
+
yield canvas
|
238
|
+
end
|
237
239
|
end
|
238
240
|
end
|
239
241
|
end
|
data/ui/lib/lib_hokusai.rb
CHANGED