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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa769c22b5954b3410dec04b773abab6ec9130953b07946ec229528cd38dd7a9
4
- data.tar.gz: 0c96dcee60c36629f885e3dbcb0c236c4a699c6bab064a323f7b56968041733f
3
+ metadata.gz: 3fcf4ab765b75c28a6f58a74bfda7d269c7e5cfc5e70428134ae1180d10808c8
4
+ data.tar.gz: 24cf80041b275bfb6319281a4690de274c53bbf84d7b346ed09db349554da192
5
5
  SHA512:
6
- metadata.gz: 00b241f58208db388327de9e23686f41871a3f446dd99d1100589ddc777debc78c9fd551d0edc9ad220c40060fb7f1620e9986445f461a4df50b4afe32f8f171
7
- data.tar.gz: e620e1ec3ed3f2b2d5c963aa1a4fd8712c4016ca028e7e0efc13efb1abd4af1de0a88d4300145040a433656cc12e9867b5963fecf54a7008208e88c655f8a25e
6
+ metadata.gz: 36302a7575cf1f9816745c859da77b2f5cf1e10b2aa8bc5491819560740a5dbde3b121379ce6d89b906637cddab44f34853d49f9128d03f67ba547370dfb0d1c
7
+ data.tar.gz: 514f55d99c0bf4a6969a1ed7b00a10e043e8c84afa7341151892d425dd2ac722547093e01feb3eacae91ebe23dc4b97521afe75d1c16e0dca9430b7f5ff9b610
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 max_flow(lands)
65
- @card_type.max_flow(lands)
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 edges(lands)
69
- @card_type.edges(lands)
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
- [ret, obj.used]
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
- card = Card.new(clone)
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
@@ -3,6 +3,7 @@ class Game
3
3
 
4
4
  def initialize(deck)
5
5
  @deck = deck.shuffle(random: Random.new)
6
+ @deck.each { |card| card.reset }
6
7
  @hands = []
7
8
  @plays = []
8
9
  @planner = Planner.new
@@ -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
- # ex) lands [a,b,c,d]
76
- # bit_lands is 3 ( = 0011)
77
- # then left_lands to be [c, d]
78
- left_lands = bit_select(lands, reverse_bit(bit_lands, lands.length))
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, used_lands = spell.playable?(left_lands)
82
- a_price, a_bit_spells, a_bit_lands =
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
- # ex) lands [a,b,c,d]
86
- # bit_lands 3 ( = 0011)
87
- # used_lands [d]
88
- # then used_lands to be [0,0,0,d]
89
- used_lands = fill_used_lands(used_lands, bit_lands, lands)
90
- # ex) used_lands [0,0,0,d]
91
- # bit_lands 3 ( = 0011)
92
- # then bit_lands to be 11 ( = 1011)
93
- bit_lands = update_bit(used_lands, bit_lands)
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, bit_lands, price + spell.price)
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
@@ -2,6 +2,7 @@ require 'bundler'
2
2
  Bundler.require
3
3
 
4
4
  require_relative './manasimu/card.rb'
5
+ require_relative './manasimu/card/pathway.rb'
5
6
  require_relative './manasimu/planner.rb'
6
7
  require_relative './manasimu/game.rb'
7
8
  require_relative './manasimu/simulator.rb'
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.7
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-08 00:00:00.000000000 Z
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