manasimu 0.0.6 → 0.0.9
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/ext/ford_fulkerson.so +0 -0
- data/lib/manasimu/card.rb +78 -39
- data/lib/manasimu/data.rb +7 -2
- data/lib/manasimu/game.rb +1 -0
- data/lib/manasimu/planner.rb +68 -62
- data/lib/manasimu.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7daccf511ec20b2a789c10abd6907f9e6de2ad8ab205006c40d43d159a340730
|
|
4
|
+
data.tar.gz: a378ba600c389a14c9f631660aa7000c669f2215966843979d9681be4ce38a46
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2ccab49af9746d58f143401856905f42c79a55e449fbdf3d78a00f39ba022adb622b49b2f0d34a6720df33694653f01b912f2638b1b33db6913a627719afd904
|
|
7
|
+
data.tar.gz: 5423c8b49381c1546c3395a46ef41096f1a00946cd4baa29063f504d0392580412812cd29ec7da700a4abb98b1d7c43cb2f2a5b311fbd92d7a2bd0e9f1814141
|
data/ext/ford_fulkerson.so
CHANGED
|
Binary file
|
data/lib/manasimu/card.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
class Card
|
|
2
|
-
attr_accessor :id, :card_type
|
|
2
|
+
attr_accessor :id, :card_type, :side
|
|
3
3
|
|
|
4
4
|
def initialize(card_type)
|
|
5
5
|
@card_type = card_type
|
|
@@ -13,10 +13,12 @@ class Card
|
|
|
13
13
|
@card_type.drawed(turn)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def played(turn)
|
|
16
|
+
def played(turn, side = "a")
|
|
17
17
|
@played = turn
|
|
18
|
+
@side = side
|
|
18
19
|
@card_type.played(turn)
|
|
19
20
|
end
|
|
21
|
+
|
|
20
22
|
def played?
|
|
21
23
|
@played.nil?
|
|
22
24
|
end
|
|
@@ -29,8 +31,8 @@ class Card
|
|
|
29
31
|
@card_type.mana_source?
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
def playable?(lands)
|
|
33
|
-
@card_type.playable?(lands)
|
|
34
|
+
def playable?(lands, capas)
|
|
35
|
+
@card_type.playable?(lands, capas)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def types
|
|
@@ -61,12 +63,23 @@ class Card
|
|
|
61
63
|
@card_type.price
|
|
62
64
|
end
|
|
63
65
|
|
|
64
|
-
def
|
|
65
|
-
@
|
|
66
|
+
def reset
|
|
67
|
+
@side = nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def max_flow(lands, capas)
|
|
71
|
+
@card_type.max_flow(lands, capas)
|
|
66
72
|
end
|
|
67
73
|
|
|
68
|
-
def edges(lands)
|
|
69
|
-
@card_type.edges(lands)
|
|
74
|
+
def edges(lands, capas)
|
|
75
|
+
@card_type.edges(lands, capas)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def mana_produced?
|
|
79
|
+
@side
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def first_produce_symbol=(symbol)
|
|
70
83
|
end
|
|
71
84
|
|
|
72
85
|
def to_s
|
|
@@ -75,7 +88,16 @@ class Card
|
|
|
75
88
|
end
|
|
76
89
|
|
|
77
90
|
class CardType
|
|
78
|
-
attr_accessor :contents
|
|
91
|
+
attr_accessor :contents, :played, :drawed, :name
|
|
92
|
+
|
|
93
|
+
def self.create(card_type, name)
|
|
94
|
+
ret = card_type.dup
|
|
95
|
+
ret.contents = card_type.contents
|
|
96
|
+
ret.played = nil
|
|
97
|
+
ret.drawed = nil
|
|
98
|
+
ret.name = name
|
|
99
|
+
ret
|
|
100
|
+
end
|
|
79
101
|
|
|
80
102
|
def initialize(contents)
|
|
81
103
|
return if not contents
|
|
@@ -139,18 +161,42 @@ class CardType
|
|
|
139
161
|
end
|
|
140
162
|
end
|
|
141
163
|
|
|
164
|
+
def symbols
|
|
165
|
+
return @symbols if @symbols
|
|
166
|
+
@symbols = []
|
|
167
|
+
mana_cost[1..-2].split('}{').each_with_index do |mana, j|
|
|
168
|
+
spell_colors = mana.split('/')
|
|
169
|
+
if spell_colors.length == 1
|
|
170
|
+
spell_color = spell_colors[0]
|
|
171
|
+
if spell_color.to_i.to_s == spell_color
|
|
172
|
+
# numeric symbol
|
|
173
|
+
spell_color.to_i.times do |k|
|
|
174
|
+
@symbols << "1"
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
# color symbol
|
|
178
|
+
@symbols << spell_color
|
|
179
|
+
end
|
|
180
|
+
else
|
|
181
|
+
# multi symbol
|
|
182
|
+
throw Exception.new('unprogramed exception')
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
@symbols
|
|
186
|
+
end
|
|
187
|
+
|
|
142
188
|
def price
|
|
143
189
|
converted_mana_cost
|
|
144
190
|
end
|
|
145
191
|
|
|
146
|
-
def playable?(lands)
|
|
147
|
-
return [false, []] if lands.empty?
|
|
148
|
-
return [false, []] if converted_mana_cost > lands.length
|
|
149
|
-
mf, used = max_flow(lands)
|
|
150
|
-
[mf == converted_mana_cost, used.to_a[1..lands.length]]
|
|
192
|
+
def playable?(lands, capas)
|
|
193
|
+
return [false, [], []] if lands.empty?
|
|
194
|
+
return [false, [], []] if converted_mana_cost > lands.length
|
|
195
|
+
mf, used, land_symbols = max_flow(lands, capas)
|
|
196
|
+
[mf == converted_mana_cost, used.to_a[1..lands.length], land_symbols]
|
|
151
197
|
end
|
|
152
198
|
|
|
153
|
-
def max_flow(lands)
|
|
199
|
+
def max_flow(lands, capas)
|
|
154
200
|
obj = FordFulkersonSingleton.instance.obj
|
|
155
201
|
# Graph has x+y+2 nodes
|
|
156
202
|
# source : 0
|
|
@@ -165,17 +211,29 @@ class CardType
|
|
|
165
211
|
#
|
|
166
212
|
|
|
167
213
|
# create edge
|
|
168
|
-
x, y, e = edges(lands)
|
|
214
|
+
x, y, e = edges(lands, capas)
|
|
169
215
|
g = Graph.new(x + y + 2)
|
|
170
216
|
e.each do |s, d|
|
|
171
217
|
g.add_edge(s, d, 1)
|
|
172
218
|
end
|
|
173
219
|
|
|
174
220
|
ret = obj.max_flow(g, 0, x + y + 1)
|
|
175
|
-
|
|
221
|
+
|
|
222
|
+
land_symbols = Array.new(lands.length)
|
|
223
|
+
for edges in g.G do
|
|
224
|
+
for edge in edges do
|
|
225
|
+
if edge.cap == 0 and edge.from.between?(1, x) and edge.to.between?(x+1, x+y)
|
|
226
|
+
land_index = edge.from - 1
|
|
227
|
+
spell_index = edge.to - x - 1
|
|
228
|
+
land_symbols[land_index] = symbols[spell_index]
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
[ret, obj.used, land_symbols]
|
|
176
234
|
end
|
|
177
235
|
|
|
178
|
-
def edges(lands)
|
|
236
|
+
def edges(lands, capas)
|
|
179
237
|
result = []
|
|
180
238
|
x = lands.length
|
|
181
239
|
i_src = 0
|
|
@@ -184,29 +242,9 @@ class CardType
|
|
|
184
242
|
result << [i_src, i + 1]
|
|
185
243
|
end
|
|
186
244
|
|
|
187
|
-
# create symbol
|
|
188
|
-
symbols = []
|
|
189
|
-
mana_cost[1..-2].split('}{').each_with_index do |mana, j|
|
|
190
|
-
spell_colors = mana.split('/')
|
|
191
|
-
if spell_colors.length == 1
|
|
192
|
-
spell_color = spell_colors[0]
|
|
193
|
-
if spell_color.to_i.to_s == spell_color
|
|
194
|
-
# numeric symbol
|
|
195
|
-
spell_color.to_i.times do |k|
|
|
196
|
-
symbols << "1"
|
|
197
|
-
end
|
|
198
|
-
else
|
|
199
|
-
# color symbol
|
|
200
|
-
symbols << spell_color
|
|
201
|
-
end
|
|
202
|
-
else
|
|
203
|
-
# multi symbol
|
|
204
|
-
throw Exception.new('unprogramed exception')
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
|
|
208
245
|
# lands and mana_cost connect to each symbols
|
|
209
246
|
lands.each_with_index do |land, i|
|
|
247
|
+
next if capas[i].to_i == 0
|
|
210
248
|
land_colors = land.color_identity
|
|
211
249
|
symbols.each_with_index do |symbol, j|
|
|
212
250
|
if symbol == "1" or land_colors.include? symbol
|
|
@@ -290,6 +328,7 @@ class Content
|
|
|
290
328
|
def to_s
|
|
291
329
|
"[#{@name}] [#{@types}] [#{@color_identity}] [#{@mana_cost}]"
|
|
292
330
|
end
|
|
331
|
+
|
|
293
332
|
end
|
|
294
333
|
|
|
295
334
|
class FordFulkersonSingleton
|
data/lib/manasimu/data.rb
CHANGED
|
@@ -68,8 +68,13 @@ class Deck
|
|
|
68
68
|
card_types = []
|
|
69
69
|
deck_items.each do |deck_item|
|
|
70
70
|
card_type = @@card_types.find(deck_item[:set], deck_item[:setnum])
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
clone = CardType.create(card_type, deck_item[:name])
|
|
72
|
+
card_types << clone
|
|
73
|
+
if clone.name =~ /.*Pathway$/ and clone.mana_source?
|
|
74
|
+
card = PathwayCard.new(clone)
|
|
75
|
+
else
|
|
76
|
+
card = Card.new(clone)
|
|
77
|
+
end
|
|
73
78
|
deck_item[:amount].to_i.times do
|
|
74
79
|
card_clone = card.dup
|
|
75
80
|
card_clone.id = card_id
|
data/lib/manasimu/game.rb
CHANGED
data/lib/manasimu/planner.rb
CHANGED
|
@@ -6,6 +6,8 @@ class Planner
|
|
|
6
6
|
max_price = 0
|
|
7
7
|
max_spells = nil
|
|
8
8
|
max_land = nil
|
|
9
|
+
max_symbols = nil
|
|
10
|
+
max_lands = nil
|
|
9
11
|
|
|
10
12
|
if not lands_in_hand.empty?
|
|
11
13
|
lands_in_hand.each do |play_land|
|
|
@@ -18,23 +20,33 @@ class Planner
|
|
|
18
20
|
current_fields << play_land
|
|
19
21
|
|
|
20
22
|
# search_opt_spells
|
|
21
|
-
price, spells =
|
|
23
|
+
price, spells, symbols, lands =
|
|
22
24
|
search_opt_spells(current_hands, current_fields)
|
|
23
25
|
if price >= max_price and not spells.empty?
|
|
24
26
|
max_price = price
|
|
25
27
|
max_spells = spells
|
|
26
28
|
max_land = play_land
|
|
29
|
+
max_symbols = symbols
|
|
30
|
+
max_lands = lands
|
|
27
31
|
end
|
|
28
32
|
end
|
|
29
33
|
else
|
|
30
34
|
# search_opt_spells
|
|
31
|
-
max_price, max_spells = search_opt_spells(hands, fields)
|
|
35
|
+
max_price, max_spells, max_symbols, max_lands = search_opt_spells(hands, fields)
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
if not max_spells and not lands_in_hand.empty?
|
|
35
39
|
max_land = lands_in_hand[0]
|
|
36
40
|
end
|
|
37
41
|
|
|
42
|
+
if max_lands
|
|
43
|
+
max_lands.each_with_index do |land, i|
|
|
44
|
+
if not land.mana_produced?
|
|
45
|
+
land.first_produce_symbol = max_symbols[i]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
38
50
|
[max_land, max_spells].select {|a| a}.flatten
|
|
39
51
|
end
|
|
40
52
|
|
|
@@ -60,94 +72,88 @@ class Planner
|
|
|
60
72
|
bit_lands = 0
|
|
61
73
|
bit_spells = 0
|
|
62
74
|
# search playable spell comibantion
|
|
63
|
-
cost, bit_spells, bit_lands =
|
|
64
|
-
dfs(1, spells, lands, bit_spells, bit_lands, price)
|
|
65
|
-
[price, bit_select(spells, bit_spells)]
|
|
75
|
+
cost, bit_spells, bit_lands, land_symbols =
|
|
76
|
+
dfs(1, spells, lands, bit_spells, bit_lands, price, [])
|
|
77
|
+
[price, bit_select(spells, bit_spells), land_symbols, lands]
|
|
66
78
|
end
|
|
67
79
|
|
|
68
|
-
def dfs(n, spells, lands, bit_spells, bit_lands, price)
|
|
80
|
+
def dfs(n, spells, lands, bit_spells, bit_lands, price, total_land_symbols)
|
|
69
81
|
index = n - 1
|
|
70
82
|
|
|
71
83
|
# exit
|
|
72
|
-
return [price, bit_spells, bit_lands] if n > spells.length
|
|
84
|
+
return [price, bit_spells, bit_lands, total_land_symbols] if n > spells.length
|
|
73
85
|
|
|
74
86
|
spell = spells[index]
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
87
|
+
used_lands = bit_lands.to_s(2).chars
|
|
88
|
+
capas = lands.length.times.to_a.map do |i|
|
|
89
|
+
used_lands[i] == "1" ? "0" : "1"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# shrink
|
|
93
|
+
# lands_available = []
|
|
94
|
+
# lands.length.times do |i|
|
|
95
|
+
# next if used_lands[i] == "1"
|
|
96
|
+
# lands_available << lands[i]
|
|
97
|
+
# end
|
|
98
|
+
# capas = ("1" * lands_available.length).chars
|
|
79
99
|
|
|
80
100
|
# cast case
|
|
81
|
-
is_playable,
|
|
82
|
-
|
|
101
|
+
is_playable, casted_lands, land_symbols =
|
|
102
|
+
spell.playable?(lands, capas)
|
|
103
|
+
|
|
104
|
+
# expand
|
|
105
|
+
# used_lands_ = []
|
|
106
|
+
# land_symbols_ = []
|
|
107
|
+
# j = 0
|
|
108
|
+
# lands.length.times do |i|
|
|
109
|
+
# if used_lands[i] == "1" or not casted_lands
|
|
110
|
+
# used_lands_ << "1"
|
|
111
|
+
# land_symbols_ << total_land_symbols[i]
|
|
112
|
+
# else
|
|
113
|
+
# used_lands_ << casted_lands[j]
|
|
114
|
+
# land_symbols_ << land_symbols[j]
|
|
115
|
+
# j += 1
|
|
116
|
+
# end
|
|
117
|
+
# end if lands
|
|
118
|
+
|
|
119
|
+
a_price, a_bit_spells, a_bit_lands, a_land_symbols =
|
|
83
120
|
if is_playable
|
|
121
|
+
|
|
84
122
|
bit_spells = bit_spells | 1 << ( n - 1 )
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
123
|
+
bit_lands_ = casted_lands
|
|
124
|
+
.reverse
|
|
125
|
+
.map {|i| i.to_s}
|
|
126
|
+
.join('')
|
|
127
|
+
.to_i(2)
|
|
128
|
+
|
|
129
|
+
land_symbols_ = lands.length.times.to_a.map do |i|
|
|
130
|
+
land_symbols[i] ? land_symbols[i] : total_land_symbols[i]
|
|
131
|
+
end
|
|
132
|
+
|
|
94
133
|
# dfs
|
|
95
|
-
dfs(n + 1 , spells, lands, bit_spells,
|
|
134
|
+
dfs(n + 1 , spells, lands, bit_spells, bit_lands_,
|
|
135
|
+
price + spell.price, land_symbols_)
|
|
96
136
|
else
|
|
97
|
-
[nil, nil, nil]
|
|
137
|
+
[nil, nil, nil, nil]
|
|
98
138
|
end
|
|
99
139
|
|
|
100
140
|
# not cast case
|
|
101
|
-
b_price, b_bit_spells, b_bit_lands =
|
|
102
|
-
dfs(n + 1 , spells, lands, bit_spells, bit_lands, price)
|
|
141
|
+
b_price, b_bit_spells, b_bit_lands, b_land_symbols =
|
|
142
|
+
dfs(n + 1 , spells, lands, bit_spells, bit_lands, price, total_land_symbols)
|
|
103
143
|
|
|
104
144
|
if (a_price and a_price >= b_price)
|
|
105
|
-
[a_price, a_bit_spells, a_bit_lands]
|
|
145
|
+
[a_price, a_bit_spells, a_bit_lands, a_land_symbols]
|
|
106
146
|
else
|
|
107
|
-
[b_price, b_bit_spells, b_bit_lands]
|
|
147
|
+
[b_price, b_bit_spells, b_bit_lands, b_land_symbols]
|
|
108
148
|
end
|
|
109
149
|
end
|
|
110
150
|
|
|
111
|
-
def reverse_bit(bit, length)
|
|
112
|
-
s = bit.to_s(2)
|
|
113
|
-
length.times.to_a.map do |i|
|
|
114
|
-
if s[i] and s[i] == "1"
|
|
115
|
-
"0"
|
|
116
|
-
else
|
|
117
|
-
"1"
|
|
118
|
-
end
|
|
119
|
-
end.join.to_i(2)
|
|
120
|
-
end
|
|
121
|
-
|
|
122
151
|
def bit_select(cards, bit)
|
|
123
152
|
cards.length.times
|
|
124
153
|
.map { |i| cards[i] if (bit & (1 << i) > 0) }
|
|
125
154
|
.select { |o| o }
|
|
126
155
|
end
|
|
127
156
|
|
|
128
|
-
def update_bit(used_lands, bit_lands)
|
|
129
|
-
used_lands.each_with_index do |flg, i|
|
|
130
|
-
bit_lands = bit_lands | ( 1 << i ) if flg == 1
|
|
131
|
-
end
|
|
132
|
-
bit_lands
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def fill_used_lands(used_lands, bit_lands, lands)
|
|
136
|
-
result = []
|
|
137
|
-
j = 0
|
|
138
|
-
lands.length.times do |i|
|
|
139
|
-
if (bit_lands & 1 << i) == 1
|
|
140
|
-
# used before dfs
|
|
141
|
-
result << 1
|
|
142
|
-
else
|
|
143
|
-
# used after dfs
|
|
144
|
-
result << used_lands[j]
|
|
145
|
-
j += 1
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
result
|
|
149
|
-
end
|
|
150
|
-
|
|
151
157
|
def lands(list)
|
|
152
158
|
list.select do |card|
|
|
153
159
|
card.types.include? "Land"
|
data/lib/manasimu.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: manasimu
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- so1itaryrove
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-05-
|
|
11
|
+
date: 2022-05-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: mtg arrena mana curve simulator
|
|
14
14
|
email: so1itaryrove@gmail.com
|