Savaş oyununun sonucunu bulun


15

Savaş oyununun sonucunu bulun

İlkokuldayken, toplantılarda, öğretmenimizi beklerken, teneffüste vb. Oynadığımız bir "Taş-Kağıt-Makas" oyunu vardı. Buna "Savaş" dedik. Ancak bazı aramalardan sonra, bu "Av Tüfeği Oyunu" nun (WikiHow'a göre) çok daha basit bir çeşidi olduğu ortaya çıkıyor . Kurallar biraz farklı olduğu için buna "Savaş" diyeceğim:

2 kişi birbirinin karşısında oturuyor. Oyunun amacı diğer oyuncuyu "öldürmektir". Her turda 3 hamleden birini oynayabilirsiniz:

  • Reload : Tek atış tutan bir silahınız var. Her seferinde ateşlenmeden önce yeniden yüklenmesi gerekir. Cephaneniz olduğunda yeniden yükleme yasaldır, ancak hiçbir şey yapmaz. Tapınaklarınıza iki elinizle dokunarak bir yeniden yükleme sembolize edildi. Her oyuncu 0 cephane ile başlar.

  • Muhafız : Tek güvenli hamle. Eğer korurken vurursanız ölmezsiniz. Koruma kollarınızı göğsünüz üzerinden geçerek sembolize edildi.

  • Ateş : Silahını ateşle. Başarılı bir şekilde ateş etmek için son atıştan bu yana yeniden yüklemiş olmanız gerekir. Rakibiniz yeniden yükleniyorsa kazanırsınız. Onlar da ateş ederse ve ikinizin de cephaneniz varsa, bu bir beraberlik. Eğer koruyorlarsa, cephaneyi boşa harcadın. Cephane olmadan ateş etmek yasal bir hareketken, hiçbir şey yapmaz ve sizi yeniden yükleme gibi savunmasız bırakır. Ateş diğer oyuncuya işaret edilerek sembolize edildi.

RPS'ye benzer şekilde oynandı, çünkü her oyuncu aynı anda seçimlerini atıyor (birbirimizle ritmi korumak için bacaklarımızı sırayla iki kez dokunduk, ancak bu meydan okuma için önemli değil).

Meydan okuma:

Göreviniz bir Savaş oyununun sonucunu bulmak. Bir işlev veya tam program olabilir.

Giriş

  • Her oyuncunun her turu seçtiği seçenek bir karakter / dize ile temsil edilir:

    • r : yeniden yükle

    • g : bekçi

    • f : ateş

  • Girdi, bir çiftler listesi, ayrılmış / sınırlandırılmamış bir dize veya bu satırlar boyunca başka bir şey olacaktır.

Python'a örnek bir giriş olabilir [("r", "g"), ("f", "r")], yani ilk turda ilk oyuncu tekrar yüklenir ve ikinci oyuncu korunur. İkinci turda ilk oyuncu ateşlenirken, ikinci oyuncu yeniden yüklenir. Birinci oyuncu bu oyunu kazanır. Aynı giriş isteğe olarak temsil edilebilir "r g f r", "rgfr", "rg fr" "rg-fr"...

Aşağıdakileri varsayabilirsiniz:

  • Giriş, seçtiğiniz biçimle eşleşecek ve yalnızca geçerli karakterler içerecek.

  • Birisi 100 turda ölecek.

Ancak biri öldüğünde dönüşlerin sona erdiğini varsayamazsınız.

Çıktı

Kimin kazandığını (veya önce kimin kazandığını *) gösteren bir değer . Her senaryo için ne çıktı verileceğini seçebilirsiniz, ancak aşağıdakileri dikkate almalısınız:

  • Oyuncu 1 kazanır

  • Oyuncu 2 kazanır

  • Birbirlerini öldürüyorlar (çiziyorlar)

Her sonucun bir bölge değeri olmalı ve her senaryo için her zaman aynı olmalıdır.

Örnek olarak: 1Oyuncu 1 kazandığında, 2oyuncu 2 kazandığında ve 0berabere kaldığında çıktı alabilirsiniz. Oyuncu 1 kazandığında, oyuncu 2 kazandığında ve berabere kaldığında daima çıkış yapmanız gerekir .120

İade edilebilir veya stdout'a yazdırılabilir. Sondaki boşluk gayet iyi.

Açıktır ki, berabere giden tek senaryo, her iki oyuncunun da ateş ettiği ve her ikisinin de cephanesi olduğu.

*Bu mücadelede, birileri öldükten sonra dönüşler devam edebileceğinden, 1'den fazla oyuncunun sonunda kazanması mümkündür. Girişe göre ilk kimin kazandığını bulmanız gerekiyor.

Test Durumları ( 1P1 kazandığında, 2P2 kazandığında ve 0berabere varsa):

"rg fr" => 1 (P1 shot P2 while they were reloading)

"rg ff" => 1 (They both shot, but only P1 had ammo)

"rr ff" => 0 (Both had ammo and shot each other)

"rr ff rr fg" => 0 (Both had ammo and shot each other. Everything after the first win is ignored)

"rr fg rf" => 2 (P2 shot P1 while they were reloading)

"rf gg rr fg rr fr" => 1
    (P2 tried to shoot but didn't have any ammo, then they both guarded, then they both reloaded, then P2 blocked a shot, then they both reloaded again [but P2 still only has 1 ammo!], then P1 shoots P2 while they're reloading.

"rr gf fr rf gg rg ff" => 1
       ^ Player 1 wins here. The rest to the right has no effect on the output

Bu kod golf, yani en az bayt sayısı kazanır!

Test durumlarının gösterdiği gibi, "aptal" hareketleri ele almanız gerektiğini unutmayın. Bir oyuncunun cephanesi olmadığında ateş etmeye çalışması veya arka arkaya 2 tur yeniden yüklemesi (ve yalnızca tek bir cephane biriktirmesi) için mükemmel bir şekilde geçerlidir.


Bir şey eksik mi yoksa çıktı sadece son turdan mı belirlenebilir?
xnor

@ Soruyu güncelledi. Ve hayır, çünkü bir oyuncunun cephanesi olup olmadığını bilmeniz gerekir. Yine de, hangi oyuncunun cephanenin son sıraya geldiği gerçeğine dayanarak kabul edebileceğinizi fark ediyorum. Aslında birileri öldüğünde girdinin sona ereceğini varsayarak kuralları son dakikada değiştirdim. Şimdi pişmanım.
17'de Carcigenicate


3
Bu bir Load, Defend ve Shoot oyunu puanlamaya çok benzer . Tek fark, diğer mücadelenin birden fazla atışlı silahları olması ve boş bir silahı vurmanın hile olarak kabul edilmesi ve oyunu kaybetmesidir.
Dennis

İki oyuncu için mermi yerine iki ayrı girdi alabilir miyiz, örneğin {"rff","rgf"}?
17'de

Yanıtlar:


2

Retina , 36 bayt

s`(?<=r..([^f]..)*)f
!
A`g
G1`!
\w
_

Giriş biçimi satır besleme ayrı çiftleri olmalıdır, ör.

rr
fr

Çıktı !_oyuncu 1 kazanırsa, _!oyuncu 2 kazanırsa ve !!berabere kalırsa.

Çevrimiçi deneyin! (Kolaylık için alan ayırma kullanan bir test takımı.)

Bu meydan okumayı tamamen gözden kaçırmış olmalıyım. Eminim bunu daha önce Retina denedim aksi takdirde. :)

açıklama

s`(?<=r..([^f]..)*)f
!

Biz ilk çevirerek "geçerli" çekim işaretleyerek başlamak fher sonrasında rINTO !. Bunu , aynı oyuncu üzerinde fbulabilen her birini rdiğerini geçmeden eşleştirerek yapıyoruz f. rHer seferinde üç karakter olacak şekilde aramayı aynı oynatıcıda sınırlamak kolaydır.

A`g

Şimdi birinin kendini koruduğu tüm dönüşleri atıyoruz, çünkü bitiş sırası bunlardan biri olamaz.

G1`!

Şimdi sadece bir !. Geçerli bir atış gerçekleşirse (ve kimsenin koruduğunu bilmezsek) oyun sona erer.

\w
_

Son olarak, tutarlı çıktılar vermek için dizeyi birleştirmemiz gerekiyor ve bunu !karakter olmayanları (ya rda f) dönüştürerek yapıyoruz _.


5

Python, 139 Bayt

c=d=0
for i in input():
 b=(c&(i=='fr'))-(d&(i=='rf'));p,q=i
 if b|(i=='ff')&c&d:print b;break
 c,d=(p=='r',i!='fg')[c],(q=='r',i!='gf')[d]

Stdin üzerine girişi 2 karakterli dizeler (örn. ['Rf', 'rr', 'rg', 'ff'] şeklinde) alır. Oyuncu 1 kazanırsa 1, oyuncu 2 kazanırsa -1 ve beraberlik için 0 çıkar.

Açıklama: Önce kimsenin mermiyi ateşleyip ateşlemediğini kontrol eder, eğer oyun biterse. Sonra oyuncuların silahlarını tekrar doldurup doldurmadıklarını veya cephanelerini boşa harcadıklarını belirledik.

Bu benim ilk codegolf yazım :)


4

JavaScript (ES6), 108 107 93 91 89 85 bayt

Titus yardımı ile 4 bayt kaydedildi

Girişi, her oyuncunun oynadığı hamleleri açıklayan 2 karakterlik dizelerden oluşan bir dizi olarak alır.

b=>b.map(c=>w=w||b&'312'[b=(s='0210231')[m='ffrfgrrggf'.search(c)]|s[m-2]&b,m],w=0)|w

İadeler:

  • 1 eğer oyuncu 1 kazanırsa
  • 2 eğer oyuncu 2 kazanırsa
  • 3 beraberlik için

Nasıl çalışır

bKimin yüklü bir mermi olduğunu açıklayan bir bitmask sürdürüyoruz :

  • bit # 0: Oyuncu 1'de bir madde işareti var
  • bit # 1: Oyuncu 2'nin bir mermisi var

De Bruijn dizisini 'ffrfgrrggf' , olası 9 hareket kombinasyonunu tanımlamak için kullanıyoruz . Taşıma bkombinasyonuna göre güncellemek için OR ve AND bitmasks kullanıyoruz . bKazananı belirlemek için AND ile birlikte 3'üncü bir bit maskesi seti kullanıyoruz w. (Sadece kazanan üç kombinasyon ff, frverf .)

OR ve AND maskelerinin iki pozisyonla değiştirilerek aynı desende saklanabileceğini belirtmek gerekir.

 Index in | Combination | Bullet   | Bullet  | Winner
 sequence |             | AND mask | OR mask | mask
----------+-------------+----------+---------+--------
    0     |     ff      |    0     |    0    |   3
    1     |     fr      |    0     |    2    |   1
    2     |     rf      |    0     |    1    |   2
    3     |     fg      |    2     |    0    |   0
    4     |     gr      |    1     |    2    |   0
    5     |     rr      |    0     |    3    |   0
    6     |     rg      |    2     |    1    |   0
    7     |     gg      |    3     |    0    |   0
    8     |     gf      |    1     |    0    |   0

Test senaryoları


@Carcigenicate Bu, her iki başarısız durum için de düzeltilmelidir. Ancak, beraberlik durumunda geri dönüyorum 0(hiç kimse vurulmadı) veya 3(oyuncular birbirlerini öldürüyor). Buna izin verilip verilmediğinden emin değilim. Değilse, w%3bunun yerine geri dönebilirim .
Arnauld

Senaryo başına 1 çıktı istedim. Birisinin her zaman vurulacağını garanti ederim, bu nedenle bu dava için muhasebe gerekli değildir. Çekilişe yol açan tek dava, her ikisinin de birbirini vurması ve her ikisinin de cephanesi olması.
17'de Carcigenicate

&Maske için 0 olabilir fr,rf,ff. '312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]veya '123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]bir bayt kaydedin; ama çalışıyorlar mı?
Titus

@Titus İlginç bir şekilde, VE maskesinden önce OR maskesini uygulamak, mevcut tüm test senaryolarında işe yarayacaktır. Ama bu gibi bir şey için başarısız olur["rr","fg","fr","rf"]
Arnauld

&önceliğe göre daha yüksek önceliğe sahiptir |, bu nedenle düzeni değiştirmek orada hiçbir şeyi değiştirmemelidir (bayt tasarrufu dışında). Ancak kodumda ödev eksikti. Deneyin ...'123'[b='2100231'....
Titus

2

Perl 6 , 71 62 bayt

{&[<=>](|map {m/r[..[r|g]]*.$^f/.to//∞},/[r|f]f/,/.f[r|f]/)}

Regex tabanlı çözüm.

Girdiyi formdaki bir dize olarak alır "rg fr".
Üç olası çıkış enum değerleri More(oyuncu 1 kazandı), Less(oyuncu 2 kazandı), Same(çekme) - baskılı zaman bu kelimeler dönüşür ya da 1, -1,0 sayılara Zorlama olduğu.

Çevrimiçi deneyin!

Nasıl çalışır

  • map { m/r[..[r|g]]*.$^f/.to // ∞ }, /[r|f]f/, /.f[r|f]/

    Girişte iki normal ifade eşleşmesi gerçekleştirir. İnterpolasyondan sonra iki regex:

    • r[..[r|g]]*.[r|f]f - Oyuncu 2'nin ilk başarılı vuruşuyla eşleşir.
    • r[..[r|g]]*..f[r|f] - Oyuncu 1'in ilk başarılı vuruşuyla eşleşir.

    Her durumda, eşleşmenin ( .to) son konumunu veya eşleşme yoksa sonsuzluğu döndürür .

  • &[<=>](|   )

    Uygular <=>iki maç sonu pozisyonlarına operatörü. İlk argümanın ikincisine göre daha büyük, daha az veya eşit olmasına bağlı olarak , Ordernumaradan ( More, Lessveya Same) bir değer döndürür .


Temiz. Meraktan sonsuzluk sembolünü nasıl yazıyorsunuz? Özel klavye mi yoksa alt + yazıyor some numbermusunuz? Ve aslında ortak Perl kodunda böyle karakterler mi kullanıyorsunuz, yoksa bu sadece golf için mi?
Şubat'ta Carcigenicate

@Karksigenat: Özelleştirilmiş klavye düzenim, dört tuşa [Menu] i n f(bir oluşturma sırası denir ) basarak onu girmeme izin veriyor . Ancak, tüm Perl 6 sembollerinin ASCII sürümleri vardır - örn. InfVe eşanlamlıdır - bu nedenle Perl 6 kodunda Unicode sembollerini kullanmak gerekli değildir . I like it ... :)
smls

Ahh. Bana Perl hakkında atılan şeylerden biri sonsuzluk simgesiydi. Gereksiz derecede karmaşık görünen bir gereklilik olduğunu düşündüm. Belki Clojure'dan sıkıldığımda Perl'i deneyeceğim. Son zamanlarda bir sürü Perl kodu gördüm.
17'de Carcigenicate

@Karksigenat: Perl 6'nın temel olarak Perl ile geriye dönük olarak uyumlu olmayan yeni bir dil olduğunu ve yorumlayıcının hala yavaş olduğunu (ve bazı özellikler için buggy) unutmayın. Halen v5.24 sürümünde olan Perl ayrı olarak korunmaya devam etmektedir.
smls

Tamam teşekkürler. Bunu bildiğim iyi oldu.
17'de Carcigenicate

2

Haskell , 101 91 87 bayt

n!(c:r)|'g'>c=n:1!r|'g'<c=1:0!r|1<3=2:n!r
_!r=[]
a#b=[x|x@(y,z)<-zip(1!a)$1!b,2>y+z]!!0

Çevrimiçi deneyin! Infix işlevi #, iki oyuncunun her birinin eylemlerini temsil eden iki dize alır ve (0,1)1. oyuncu kazanırsa (1,0)2. oyuncu ve (0,0)beraberlik için geri döner .

Örnek kullanım:

Prelude> "rgrfrf" # "fgrgrr"
(0,1)

Açıklama:

Infix işlevi , bir yangın eyleminin yalnızca gerçek yangın eylemi olarak sayıldığı !bir dizi eylem 'r'(yeniden yükleme), 'f'(yangın) ve 'g'(koruma) bir dizi gözlemlenebilir eylem 0(gerçek yangın), 1(eylem yok) ve 2(koruma) dizisine çevirir bir mermi yüklüyse ve aksi halde işlem yapılmazsa . Bu ilk argüman elde etmek olduğunu bir mermi yüklü ise ve silahın dolu değilse. Bu şekilde her biri basitçe akım ile değiştirilebilir . ( -> yüklü -> gerçek yangın -> , -> yüksüz -> işlem yok -> )n01'f'nn=00n=11

n ! (c:r)                -- n is 0 or 1, c is 'f', 'g' or 'r' and r the rest of the string
    |'g'>c = n : (1 ! r) -- c is smaller 'g', so it must be 'f'. append n to the list
                         --  and set load status to 1 (unloaded)
    |'g'<c = 1 : (0 ! r) -- c is larger 'g', so it must be 'r'. append 1 (no action)
                         --  and set load status to 0 (loaded)
    |1<3   = 2 : (n ! r) -- c must be equal to 'g'. append 2 (guard)
                         --  and leave the load status unchanged
_ ! r = []               -- base case for recursion

Sonuçta ortaya çıkan dokuz olasılık

  • (0,0): Her iki oyuncu da ateş eder ve ölür, oyun biter.
  • (0,1)veya (1,0): Bir oyuncu diğerini vurur, oyun biter.
  • (0,2)ya da (2,0): Bir oyuncu vuruyor, ancak diğer gardiyanlar, oyun devam ediyor.
  • (1,1), (1,2), (2,1)Veya (2,2): Hiçbir oyuncu sürgünler, oyun devam eder.

Tasarım gereği, oyun bitirme seçeneklerinin toplamı 2'den küçük ve devam eden her oyunun toplamı 2'den büyük veya eşittir.

a#b=[x|         -- build the list of all x
    x@(y,z) <-  -- where x is an alias for the tuple (y,z) which is drawn from the list
    zip (1!a)   -- of tuples where the first component is from 1!a = eg. [1,2,1,0,1,0] 
        (1!b)   -- and the second from 1!b = eg. [1,2,1,2,1,1]
    , 2 > y+z]  -- and y+z are smaller 2.
    !!0         -- return the first element of this list

1

Toplu, 249 bayt

@echo off
set g=goto gg
set/ax=y=0
:gg
shift&goto %1
:fg
set x=0
%g%
:gf
set y=0
%g%
:rr
set/ax=y=1
%g%
:fr
if %x%==1 exit/b1
:gr
set y=1
%g%
:rf
if %y%==1 exit/b2
:rg
set x=1
%g%
:ff
set/az=3-x-x-y
if %z%==3 %g%
exit/b%z%

Giriş, her dönüş için karakter çiftleri biçimindedir ve hata seviyesine göre çıkış yapar (0 = beraberlik, 1 = oyuncu 1, 2 = oyuncu 2). xve yoyuncunun cephanesi olup olmadığını takip edin, bu yüzden her iki atışta da sonuç 3-x-x-y3 değilse bu sonuç devam eder. Satır 5'te Batch ayrıştırıcısını kötüye kullanıyorum - %1(geçerli hareket), shiftifade çalıştırılmadan ve kaldırılmadan önce değiştirilir , bu yüzden hala doğru etikete gideriz.


1

Clojure, 168 bayt

#(reduce(fn[[l L r R][a A]](if(and l L)(let[M(fn[r a A](if(and(= a \f)r)[nil(= A \g)][(or(= a \r)r)1]))[r L](M r a A)[R l](M R A a)][l L r R])[l L r R]))[1 1 nil nil]%)

Daha az golf (her iki kişi de canlıysa M, cephanelerini ve düşmanlarının yaşam durumunu güncellemek için kullanırız , aksi takdirde mevcut durumu iade ederiz):

(def f (fn[A] (reduce
                (fn [[l1 l2 r1 r2] [a1 a2]]
                  (if (and l1 l2)
                    (let[M (fn [r1 a1 a2]
                             (if (and(= a1 \f)r1)
                               [false (= a2 \g)]        ; we lost the ammo, a2 lives if he was guarding
                               [(or(= a1 \r)r1) true])) ; we might gain or keep ammo, a2 lives no matter what
                         [r1 l2] (M r1 a1 a2)
                         [r2 l1] (M r2 a2 a1)]
                      [l1 l2 r1 r2])
                    [l1 l2 r1 r2]))
                [true true false false] A)))

Örnek kullanım (ilk öğe Oyuncu 1'in oyun sonunda hayatta olup olmadığını söyler, ikinci öğe Oyuncu 2'nin hayatta olup olmadığını söyler, 3. ve 4. kazanan kazananı belirlerken ilgili olmayan cephane durumunu söyler):

(-> (for[[a b s] (partition 3 "rr fg rf fr ")][a b]) f (subvec 0 2))

Güncelleme: Şuna bir bak, bunun loopuzunluğu aynı! reduceAra durumları kolayca inceleyebildiğiniz için sürümün geliştirilmesini daha kolay buluyorum reductions.

#(loop[l 1 L 1 r nil R nil[[a A]& I]%](if(and l L)(let[M(fn[r a A](if(and(= a \f)r)[nil(= A \g)][(or(= a \r)r)1]))[r L](M r a A)[R l](M R A a)](recur l L r R I))[l L]))

Bekliyordum! Çok yoğun, vay.
Carcigenicate

Hehe teşekkürler, tekrarlamak zorunda kaldığım beni hala rahatsız ediyor [l1 l2 r1 r2](değiştirilmiş değerleri letve orijinal değerleri) ve bu fnimzalar.
NikoNyrh

En azından ikincisi için, bu yüzden tercih ederim loop. Bunu daha temiz kodlara götürürüm. 1'den fazla akümülatör ile katlanmaya ihtiyaç duymaz değiştiririm.
Carcigenicate

1

PHP, 107 101 90 bayt

yükleme durumu için $ d bit maskesi ve ateşleme hamleleri için DeBruijn dizisi kullanarak.

for(;!$x=$d&strpos(_frff,$m=$argv[++$i]);)$d=$d&g<$m|h<$m|2*($d/2&f<$m[1]|g<$m[1]);echo$x;

girdiyi 2 karakterlik komut satırı bağımsız değişkenleri olarak alır, ile çalıştır -nr.

1 = Oyuncu 1 kazanır
2 = Oyuncu 2 kazanır
3 = berabere

Yıkmak

for(;!$x=$d&strpos(_frff,       // 1. $x=someone dies, loop while not
    $m=$argv[++$i]          // loop throug moves
);)
    $d=
        $d&g<$m|h<$m            // 2. unload/reload Player 1 = bit 0
    |2*(
        $d/2&f<$m[1]|g<$m[1]    // 3. unload/reload Player 2 = bit 1
    );
echo$x;
  • DeBruijn Dizisi: fr konum = 1 = P1 yangınları; rf= konum 2 = P2 yangınları, ff= konum 3 = her iki yangın
  • g<$m<=> f<$m[0]( f<$mher zaman doğrudur, çünkü ikinci bir karakter vardır).

0

Python, 200 bayt

def war_game(turns):
    turn=0
    player1=True
    player2=True
    ammo1=False
    ammo2=False
    while turn<len(turns):
        if turns[turn][0]=='f' and ammo1==True and turns[turn][1]!='g':
            player2=False
        elif turns[turn][0]=='f' and turns[turn][1]=='g':
            ammo1=False
        elif turns[turn][0]=='r':
            ammo1=True
        if turns[turn][1]=='f' and ammo1==True and turns[turn][0]!='g':
            player1=False
        elif turns[turn][1]=='f' and turns[turn][0]=='g':
            ammo2=False            
        elif turns[turn][1]=='r':
            ammo2=True
        if player2==False or player1==False:
            break
        turn+=1
    if player1==True and player2==False:
        print('Player 1 wins')
        return 1
    elif player1==False and player2==True:
        print('Player 2 wins')
        return 2
    print('Draw')
    return 0

2
Siteye hoş geldiniz. Yarışma bayt sayımında puanlanır, bu yüzden başlığınıza bir bayt sayımı eklemenizi ve değişken adlarının uzunluğunu azaltarak en aza indirmeyi denemenizi öneririm. Bunu yazdığınız dili de eklemelisiniz (bana Python3'e benziyor).
Post Rock Garf Hunter

2
Yukarıda belirtildiği gibi, bu, görevi gerçekleştirmek için mümkün olan en küçük programı yapabilen bir yarışmadır. Tam ad turnsyerine tam adlar kullanıyorsunuz t, bu da programın gerekenden çok daha büyük olduğu anlamına geliyor. Ayrıca lütfen gönderiminize aşağıdaki gibi bir şeyle başlayın #Python 2, 200 bytes(bunun 2 olduğunu ve programın 200 bayt uzunluğunda olduğunu varsayarak) kullandığınız dil açıktır.
Carcigenicate

0

Clojure, 180 173 bayt

(fn[t](loop[z nil x nil[[c v]& r]t](let[k #(and %3(= %\f)(not= %2\g))h #(and(not= %\f)(or %2(= %\r)))q(k v c x)w(k c v z)](cond(and q w)0 q 2 w 1 1(recur(h c z)(h v x)r)))))

Makro kullanmak yerine işlevi tam işlev olarak değiştirerek -7 bayt. Bu, iç fonksiyonları makrolar yapmama izin veriyor, bu da biraz tasarruf sağlıyor.

Bu çok gerçek bir çözüm. Oyunun tam bir versiyonunu yazdığım için biraz zihin kilitliyim ve bu temelde kullandığım algoritmanın büyük ölçüde soyulmuş bir versiyonudur. Muhtemelen yapabileceğim birçok optimizasyon var, ancak bundan oldukça memnunum. Açıklama için önceden golf koduna bakınız.

(defn outcome [turns] ; Take input as ["rr" "ff"]
  (loop [p1-ammo? false ; Keep track of if each player has ammo
         p2-ammo? false
         [[p1-move p2-move] & rest-turns] turns] ; Deconstruct the turns out

    (let [killed? (fn [m m2 a] (and a (= m \f) (not= m2 \g))) ; Function that checks if one player killed the other
          has-ammo? (fn [m a] (and (not= m \f) (or a (= m \r)))) ; Function that decides if a player has ammo in the
                                                                 ;  next turn
          p1-killed? (killed? p2-move p1-move p2-ammo?) ; Check if each player was killed.
          p2-killed? (killed? p1-move p2-move p1-ammo?)]

      (cond ; Check who (if any) died. If no one died, recur to next turn.
        (and p1-killed? p2-killed?) 0
        p1-killed? 2
        p2-killed? 1
        :else (recur (has-ammo? p1-move p1-ammo?)
                     (has-ammo? p2-move p2-ammo?)
                     rest-turns)))))
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.