manasimu 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/ford_fulkerson.so +0 -0
- data/lib/manasimu/card.rb +67 -38
- data/lib/manasimu/data.rb +5 -1
- 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: 3fcf4ab765b75c28a6f58a74bfda7d269c7e5cfc5e70428134ae1180d10808c8
|
4
|
+
data.tar.gz: 24cf80041b275bfb6319281a4690de274c53bbf84d7b346ed09db349554da192
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36302a7575cf1f9816745c859da77b2f5cf1e10b2aa8bc5491819560740a5dbde3b121379ce6d89b906637cddab44f34853d49f9128d03f67ba547370dfb0d1c
|
7
|
+
data.tar.gz: 514f55d99c0bf4a6969a1ed7b00a10e043e8c84afa7341151892d425dd2ac722547093e01feb3eacae91ebe23dc4b97521afe75d1c16e0dca9430b7f5ff9b610
|
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)
|
72
|
+
end
|
73
|
+
|
74
|
+
def edges(lands, capas)
|
75
|
+
@card_type.edges(lands, capas)
|
66
76
|
end
|
67
77
|
|
68
|
-
def
|
69
|
-
@
|
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
|
@@ -148,18 +161,42 @@ class CardType
|
|
148
161
|
end
|
149
162
|
end
|
150
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
|
+
|
151
188
|
def price
|
152
189
|
converted_mana_cost
|
153
190
|
end
|
154
191
|
|
155
|
-
def playable?(lands)
|
156
|
-
return [false, []] if lands.empty?
|
157
|
-
return [false, []] if converted_mana_cost > lands.length
|
158
|
-
mf, used = max_flow(lands)
|
159
|
-
[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]
|
160
197
|
end
|
161
198
|
|
162
|
-
def max_flow(lands)
|
199
|
+
def max_flow(lands, capas)
|
163
200
|
obj = FordFulkersonSingleton.instance.obj
|
164
201
|
# Graph has x+y+2 nodes
|
165
202
|
# source : 0
|
@@ -174,17 +211,29 @@ class CardType
|
|
174
211
|
#
|
175
212
|
|
176
213
|
# create edge
|
177
|
-
x, y, e = edges(lands)
|
214
|
+
x, y, e = edges(lands, capas)
|
178
215
|
g = Graph.new(x + y + 2)
|
179
216
|
e.each do |s, d|
|
180
217
|
g.add_edge(s, d, 1)
|
181
218
|
end
|
182
219
|
|
183
220
|
ret = obj.max_flow(g, 0, x + y + 1)
|
184
|
-
|
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]
|
185
234
|
end
|
186
235
|
|
187
|
-
def edges(lands)
|
236
|
+
def edges(lands, capas)
|
188
237
|
result = []
|
189
238
|
x = lands.length
|
190
239
|
i_src = 0
|
@@ -193,29 +242,9 @@ class CardType
|
|
193
242
|
result << [i_src, i + 1]
|
194
243
|
end
|
195
244
|
|
196
|
-
# create symbol
|
197
|
-
symbols = []
|
198
|
-
mana_cost[1..-2].split('}{').each_with_index do |mana, j|
|
199
|
-
spell_colors = mana.split('/')
|
200
|
-
if spell_colors.length == 1
|
201
|
-
spell_color = spell_colors[0]
|
202
|
-
if spell_color.to_i.to_s == spell_color
|
203
|
-
# numeric symbol
|
204
|
-
spell_color.to_i.times do |k|
|
205
|
-
symbols << "1"
|
206
|
-
end
|
207
|
-
else
|
208
|
-
# color symbol
|
209
|
-
symbols << spell_color
|
210
|
-
end
|
211
|
-
else
|
212
|
-
# multi symbol
|
213
|
-
throw Exception.new('unprogramed exception')
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
245
|
# lands and mana_cost connect to each symbols
|
218
246
|
lands.each_with_index do |land, i|
|
247
|
+
next if capas[i].to_i == 0
|
219
248
|
land_colors = land.color_identity
|
220
249
|
symbols.each_with_index do |symbol, j|
|
221
250
|
if symbol == "1" or land_colors.include? symbol
|
data/lib/manasimu/data.rb
CHANGED
@@ -70,7 +70,11 @@ class Deck
|
|
70
70
|
card_type = @@card_types.find(deck_item[:set], deck_item[:setnum])
|
71
71
|
clone = CardType.create(card_type, deck_item[:name])
|
72
72
|
card_types << clone
|
73
|
-
|
73
|
+
if clone.name =~ /.*Pathway$/ and clone.mana_source?
|
74
|
+
card = PathwayCard.new(clone)
|
75
|
+
else
|
76
|
+
card = Card.new(clone)
|
77
|
+
end
|
74
78
|
deck_item[:amount].to_i.times do
|
75
79
|
card_clone = card.dup
|
76
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.8
|
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
|