[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Civ4/integration question and practice for the golfers

Luke Graham

11/3/2006 7:40:00 PM

Not sure if anyone's reading this, but here's where I'm at now.
Permutations are generated and selected for each resource.


# Warning! Running time is sensitive to changes in this number.
NumberOfTilesPerCity = 6

puts "Starting #{Time.now}"

# Generate tiles
NumArray = (1..NumberOfTilesPerCity).to_a
tiles = NumArray.inject([]) { |acc, node| acc + [[rand(4),rand(4), rand(4)]] }

# Calc food required to achieve a pop size
def inc(size)
10 * 2 ** size - 20 # Or similar
end

# Given a total amount of food, calc current size
def currentSize(food)
s = 1
s += 1 while food > inc(s)
s
end

# Generate combinations
Combinations = NumArray.inject([[]]) { |acc, node| # Combinations (ints)
acc.inject([]) { |acc, injectedNodes| acc + [injectedNodes,
injectedNodes + [node]] }
}.map { |c|
c.inject([0,2,1,2]) { |acc, node| # Combinations (tiles)
(0..2).inject([acc[0].succ]) { |i,n| i + [acc[n.succ] + tiles[node-1][n]] }
}
}.uniq.sort.inject([]) { |acc, node| # Tranches
acc + [acc.size <= node[0] ? [node] : acc.pop + [node]]
}.each { |set|
set.delete_if { |test| # Prune
set.inject(false) { |acc, comp|
acc or (!test.equal?(comp) and ((1..3).inject(true) { |i,n| test[n]
<= comp[n] and i } and acc = true))
}
}
}

# Generate permutations
class Array
def permute(i = 0, *a)
return [a] if i == size
self[i].map { |x| permute(i+1, *(a + [x])) }.inject([]) { |m,x| m + x }
end
end
Permutations = Combinations.permute

# Containers to store results
EmptyResult = [0,0,0,0]
bestResult = []
strings = "Pop,Food,Gold,Hammers".split(',')
4.times { |x| bestResult << (EmptyResult.dup << strings[x]) }

# Integrate across t
PermutationResults = Permutations.map { |p|
result = [1,0,0,0]
80.times { |t|
result = [currentSize(result[1])] + (1..3).to_a.inject([]) { |i,n|
i + [result[n] + p[result[0]][n]]
}
result[0] = NumArray.size if result[0] > NumArray.size # Cap size
}
result
}.inject(bestResult) { |acc, node|
ret = acc
(acc.size).times { |x| ret[x] = node + [ret[x][ret.size]] if node[x]
> ret[x][x] }
ret
}

# Write results to disk
File::open("output.txt", "w") { |file|
file << "# Combinations\n"
Combinations.each { |set|
set.each { |comb|
file << " " << comb.join(" ") << "\n"
}
file << "\n"
}

file << "# Permutations\n"
Permutations.each { |pset|
pset.each { |p|
file << " " << p.join(" ") << "\n"
}
file << "\n"
}
file << "# Results\n"
PermutationResults.each { |res|
file << " " << res.join(" ") << "\n"
}
}

puts "Finished #{Time.now}"



On 11/2/06, spooq <spoooq@gmail.com> wrote:
> For reasons not clear even to myself, I'm trying to predict the growth and
> production of a city in CivIV (c.f. CivFanatics <http://www.civfanati...
> ).
>
> Each city has an integer population and a number of tiles (actually 20 but
> reduced here to 10 to speed-up testing). Each population point (P) can work
> one tile in a given turn. Tiles have three attributes excitingly named
> F, G and H. I am attempting to enumerate all interesting combinations
> of worked tiles for any given city size. Output is in gnuplot format.
>
> Here's the code (fore!).
>
> puts "Starting #{Time.now}"
>
> numArray = (1..10).to_a
>
> # Generate tiles
> tiles = numArray.inject([]) { |acc, node| acc + [[rand(4),rand(4), rand(4)]]
> }
>
> # Generate unique combinations for given size
> File::open("output.txt", "w") { |file|
> file << "#P F G H\n"
> numArray.inject([[]]) { |acc, node|
> acc.inject([]) { |acc, injectedNodes| acc + [injectedNodes,
> injectedNodes + [node]] }
> }.collect { |c|
> c.inject([0,0,0,0]) { |acc, node| [acc[0].succ, acc[1] +
> tiles[node-1][0], acc[2] + tiles[node-1][1], acc[3] + tiles[node-1][2]] }
> }.uniq.sort.inject(1) { |acc, node|
> file << "\n" if node[0] == acc
> file << " " << node.join(" ") << "\n"
> node[0] == acc ? acc.succ : acc
> }
> }
>
> puts "Finished #{Time.now}"
>
> My problem is ensuring that only efficient combinations are output. If we
> look at a doctored example...
>
> #P A B C
> 0 0 0 0
>
> 1 0 0 0
> 1 2 0 0 <- This is not interesting,
> 1 2 0 3 <- when this is possible.
> 1 0 1 0 <- However this still is, even though A+B+C is less than
> the line above.
>
> Can anyone suggest a nice golfed algorithm to get rid of the useless
> combinations? Remember that any of the three resources might be deemed most
> important, e.g. 1 1 0 0 is still interesting when 1 0 9 9 exists.
>
> When this bit gets nailed down, the next step is integrating permutations of
> combinations over time and solving for maximum G and/or H, given that
> acquiring enough F will increase P. It's probably best to assume no
> micro-management, i.e. when a city grows, the combination chosen for the new
> size remains in place until the next growth.
>
> Thanks for getting this far, all comments welcome.
>
>