Korku Filmi Arama Partisi


21

Arsa : Jimmy kayıp; Onu bulmalıyız. Ayrılmalıyız.

Arsa büküm : Jimmy zaten öldü.

Fakat oyuncu kadromuz bunu bilmiyor, bu yüzden yine de tüm alanı aramaları gerekiyor. "N", ". açık alan için veya bir engel için "#". Bu harita .

0 <= p <= 26 costar , 0 <= q <= 26 ekstra ve 1 yıldız var . Herkes başlangıçta S işaretli hücrede.

Kurallar

Her insan aşağıda gösterilen bir görüş yarıçapına sahiptir:

 ...
.....
..@..
.....
 ...

Yıldız, "A" ile başlayan büyük harflerle kostarları "@", ekstralar ise "a" ile başlayan küçük harflerle gösterilir. Başlangıçta, başlangıç ​​noktasını çevreleyen görüş yarıçapı arandı olarak işaretlendi. Bu haritanın tüm açık alanını oluşturuyorsa oyun sona erer. Her sıra, aşağıdaki sırayla :

  1. Her insan eşzamanlı olarak bir kralı hareket ettirir (ya ayakta durur ya da komşu 8 hücreden birine taşınır).
  2. Görme yarıçapındaki her bir insanın etrafındaki hücrelerin tümü aranan sayılır.
  3. Bir costar başka birini göremezse, ölür. Eğer bir ekstra, bir costar, yıldız veya en az 2 ekstra göremiyorsa, ölür. Bunlar eşzamanlı olarak gerçekleşir - yani, tek seferde ölümlerin zincirleme reaksiyonu olamaz; Yukarıdaki koşullar kontrol edilir ve ölecek olan herkes bir kerede ölür.
  4. Haritadaki tüm açık alanlar arandıysa, arama sona erer.

notlar

Birden fazla insan herhangi bir noktada aynı meydanda olabilir ve bu insanlar birbirlerini görebilir.

Engeller görme, sadece hareketi engellemez; insanlar birbirlerini görebilirler.

Haritadaki açık alanların kral hareketleriyle bağlanacağı garanti edilir.

İlk "S" aynı zamanda bir engelden ziyade açık alan olarak kabul edilir.

Açık alana inen herhangi bir kral hareketi geçerlidir. Örneğin, aşağıdaki hamle yasaldır:

....      ....
.@#. ---> ..#.
.#..      .#@.
....      ....

Giriş

Giriş biçiminde olacaktır

N M p q
[N cols x M rows grid with characters ".", "#", and "S"]

Örnek girişler:

6 5 0 0
......
......
..S...
......
......

ve

9 9 1 1
S.......#
.......##
......##.
..#####..
...##....
...##....
...#.....
....#..#.
.........

p ve q, sırasıyla kostarların ve ekstraların sayısıdır.

Çıktı

Çıktı, her bir dönüş için, gösterilen yönlere göre yapılan hareketler olmalıdır.

789
456
123

Hareketlerin sırası önemli değil çünkü hepsi aynı anda hareket ediyor. Bir kişi için bir hareketi listelememek iyidir ve onu 5 yönünde hareket ettirmeye eşdeğerdir. Hareketler aşağıdaki biçimde listelenmelidir:

@9 A2 a2 B7.

"" hamlelerinin sona erdiğini gösterir.

Harita arandıktan sonra, son çıktı satırı boşluklarla ayrılmış üç tamsayı olmalıdır: tahtada arama işlemini bitirmek için götürdüğünüz sıra sayısı, yaşayan koztar sayısı ve canlı ekstra sayısı. İlk örnek giriş için

6 5 0 0
......
......
..S...
......
......

aşağıdakiler geçerli çıktı:

@4.
@6.
@6.
@6.
4 0 0

Son bir not: yıldız ölemez ve haritadaki açık alanın bağlanacağı garanti edilir, bu nedenle arama her zaman başarılı olur.

puanlama

Puanınız, bir dizi kıyaslama testinden geçen toplam tur sayısıdır ; Cevabınızla birlikte kendi test davasınızı gönderebilirsiniz. Kıyas ölçüt setinde yaşayan Kostarların sayısının toplamı kravat kırıcı olarak kullanılacak ve hala bir bağ olması durumunda, yaşayan ekstraların sayısının toplamı kullanılacaktır.

Test Seti ve Kontrol Cihazı

Şu anda, 5 harita https://github.com/Tudwell/HorrorMovieSearchParty/ adresinde çevrimiçi . Cevap gönderen herhangi bir kişi, herhangi bir sebeple reddetme hakkını saklı tuttuğum bir test vakası da gönderebilir (haritanızı bir nedenden dolayı reddedersem, başka bir tane gönderebilirsiniz). Bunlar benim takdirime göre belirlenen teste eklenecek.

Python (2.7.5 test) kontrol olarak github sağlanır controller.py . Buradaki ikinci denetleyici, controller_disp.py , arama sırasında grafiksel çıktı göstermesi dışında aynıdır (Pygame kütüphanesi gerektirir).

Grafiksel denetleyici çıkışı

Kullanım :

python controller.py <map file> <your execution line>

yani:

python controller.py map1.txt python solver.py map1.txt

Denetleyici, formun çıktısına sahiptir (programınızın stdinine )

Turn 1
@:2,3 A:2,3 B:2,3.
##...##
#ooo..#
ooooo..
ooooo..
ooooo..
#ooo...
##.....
###....
----------------------------------------

Bu, sıra numarası (1. sıra sizden hareket etmeden önce), tüm oyuncuların ve. kurulu ve 40 '' ile bir çizgi. Daha sonra formun girişini (programınızın stdoutundan ) bekler

@9 A2 B7.

Bu yukarıda belirtilen çıktı formatıdır. Kontrolör, aranan açık alan için bir 'o' üretir '.' aranmamış açık alan için ve engeller için '#'. Yalnızca insanlar listesinde ve koordinatlarında yaşayan insanları içerir ve oyunun tüm kurallarını izler. Geçersiz bir hareket denendiğinde denetleyici çıkacaktır. Belirli bir dönüşün hamleleri aramayı bitirirse, çıktı yukarıdaki gibi olmaz; bunun yerine biçimindedir

Finished in 4 turns
4 1 0

Burada "4 1 0", 4 toplam dönüş, 1 yaşayan koztar ve 0 yaşayan ekstra anlamına gelir. Denetleyiciyi kullanmanıza gerek yoktur; kullanmak veya kendi girişiniz için değiştirmek için çekinmeyin. Kullanmaya ve sorunla karşılaşmaya karar verirseniz, bana bildirin.

Denetleyiciyi yazmama yardım ettiğin için @githubphagocy'e teşekkür ederim.

Düzenleme: Randomize bir giriş için, belirli bir haritadaki herhangi bir koşuyu o harita için puanınız olarak seçebilirsiniz. Puanlama gereklilikleri nedeniyle, her harita için her zaman en az dönüş, en az ölü costar, sonra en az ölü ekstra seçmelisiniz.


7
İkinci satır spoiler etiketleri arasında olmalı!
Averroes

Yanıtlar:


8

Yakut, Önce Güvenlik + BFS + Rastgele, Puan 58 1458

Rasgele gönderileri nasıl puanlayacağınızdan emin değilim. Tüm cevapların deterministik olması gerekiyorsa, bana haber verin; bir tohum seçerim veya tamamen rastlantısallıktan kurtulurum.

Bu çözümün bazı özellikleri ve eksiklikleri:

  • Hiç kimse ölmez. Başlangıçta, tüm oyuncuları herkesin güvende olacağı şekilde gruplandırıyorum. Bu grupların her birindeki karakterler birlikte hareket eder. Bu, herkesi canlı tutmak için idealdir ancak optimal olarak verimli değildir.
  • Grupların her biri, haritadaki en yakın keşfedilmemiş noktayı genişlik birinci aramasıyla arar ve aramanın ilk bölümünü hareket ettirir. Birden fazla optimal hareket arasında bağ varsa rastgele bir tane seçilir. Bu, tüm grupların daima aynı yöne yönelmemelerini sağlamak içindir.
  • Bu program görüş alanı hakkında bir şey bilmiyor. Aslında keşfedilmemiş her hücreye taşınmaya çalışıyor. Bunu dikkate almak, performansı önemli ölçüde artırabilir, çünkü o zaman her hareketin kalitesini, kaç hücreyi açığa çıkaracağıyla da ölçebilirsiniz.
  • Program, sıralar arasındaki bilgileri takip etmez (oyuncu grupları hariç). Bu büyük test durumlarında oldukça yavaşlatır. map5.txttamamlamak için 1 ila 13 dakika sürer.

Bazı sonuçlar

Map     Min turns    Max turns
map1        46           86
map2        49          104
map3       332          417
map4       485          693
map5       546          887

Şimdi kod burada:

start = Time.now

map_file = ARGV.shift
w=h=p=q=0
File::open(map_file, 'r') do |file|
    w,h,p,q = file.gets.split.map(&:to_i)
end

costars = p > 0 ? (1..p).map {|i| (i+64).chr} : []
extras = q > 0 ? (1..q).map {|i| (i+96).chr} : []
groups = []

costars.zip(extras).each do |costar, extra|
    break unless extra
    groups << (costar + extra)
    costars.delete(costar)
    extras.delete(extra)
end

costars.each_slice(2) {|c1, c2| groups << (c1 + (c2 || '@'))} unless costars.empty?
extras.each_slice(3) {|c1, c2, c3| groups << (c1 + (c2 || '') + (c3 || '@'))} unless extras.empty?
groups << '@' unless groups.join['@']

#$stderr.puts groups.inspect


directions = {
    1 => [-1, 1],
    2 => [ 0, 1],
    3 => [ 1, 1],
    4 => [-1, 0],
    5 => [ 0, 0],
    6 => [ 1, 0],
    7 => [-1,-1],
    8 => [ 0,-1],
    9 => [ 1,-1]
}

loop do
    break unless gets # slurp turn number
    coords = {}
    input = gets
    input.chop.chop.split.each{|s| actor, c = s.split(':'); coords[actor] = c.split(',').map(&:to_i)}
    #$stderr.puts input
    #$stderr.puts coords.inspect
    map = []
    h.times { map << gets.chomp }

    gets # slurp separator
    moves = groups.map do |group|
        x, y = coords[group[0]]
        distances = {[x,y] => 0}
        first_moves = {[x,y] => nil}
        nearest_goal = Float::INFINITY
        best_move = []
        active = [[x,y]]
        while !active.empty?
            coord = active.shift
            dist = distances[coord]
            first_move = first_moves[coord]
            next if dist >= nearest_goal
            [1,2,3,4,6,7,8,9].each do |move|
                dx, dy = directions[move]
                x, y = coord
                x += dx
                y += dy
                next if x < 0 || x >= w || y < 0 || y >= h || map[y][x] == '#'
                new_coord = [x,y]
                if !distances[new_coord]
                    distances[new_coord] = dist + 1
                    first_moves[new_coord] = first_move || move
                    active << new_coord if map[y][x] == 'o'
                end

                if dist < distances[new_coord]
                    distances[new_coord] = dist + 1
                    first_moves[new_coord] = first_move || move
                end

                if map[y][x] == '.'
                    if dist + 1 < nearest_goal
                        nearest_goal = dist + 1
                        best_move = [first_moves[new_coord]]
                    elsif dist + 1 == nearest_goal
                        best_move << first_moves[new_coord]
                    end
                end
            end
        end

        #if group['@']
        #    distances.each{|k,v|x,y=k;map[y][x]=(v%36).to_s(36)}
        #    $stderr.puts map
        #end

        dir = best_move.sample
        group.chars.map {|actor| actor + dir.to_s}
    end * ' '
    #$stderr.puts moves
    puts moves
    $stdout.flush
end

#$stderr.puts(Time.now - start)

Orada birkaç yorumlanan hata ayıklama çıktıları vardır. Özellikle if group['@']blok oldukça ilginçtir çünkü BFS verilerinin görselleştirilmesini basar.

Düzenleme: Daha iyi bir hamle bulunmuşsa BFS'yi durdurarak önemli hız artışı (ilk olarak BFS kullanma noktasıydı).


girişinizin her zaman harita dosyasına erişebilmesini beklemek güvenli midir?
Sparr

Evet; Harita dosyası her zaman oradadır ve denetleyiciyi kullanırsanız, her dönüşünde güncellenmiş bir kopyasını alırsınız.
Eric Tressler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.