Tìm kết quả của một trò chơi chiến tranh


15

Tìm kết quả của một trò chơi chiến tranh

Khi tôi còn học tiểu học, có một trò chơi "Rock-Paper-Kéo" mà chúng tôi đã chơi trong các hội đồng, khi chờ giáo viên của chúng tôi, vào giờ ra chơi, v.v. Chúng tôi gọi đó là "Chiến tranh". Sau khi tìm kiếm, tuy nhiên, hóa ra đây là một biến thể đơn giản hơn nhiều của "Trò chơi bắn súng" (theo WikiHow) . Tôi sẽ gọi nó là "Chiến tranh" vì các quy tắc hơi khác nhau:

2 người ngồi đối diện nhau. Mục tiêu của trò chơi là "giết" người chơi khác. Mỗi lượt, bạn có thể chơi một trong 3 động tác:

  • Tải lại : Bạn có một khẩu súng giữ một phát duy nhất. Nó phải được tải lại trước khi nó có thể bị bắn mỗi lần. Tải lại khi bạn đã có đạn là hợp pháp, nhưng không làm gì cả. Một tải lại được tượng trưng bằng cách chạm vào thái dương của bạn bằng cả hai tay. Mỗi người chơi bắt đầu với 0 đạn.

  • Bảo vệ : Di chuyển an toàn duy nhất. Nếu bạn bị bắn trong khi bảo vệ, bạn sẽ không chết. Bảo vệ được tượng trưng bằng cách khoanh tay trước ngực.

  • Ngọn lửa : Bắn súng của bạn. Để bắn thành công, bạn phải tải lại kể từ lần bắn cuối cùng. Nếu đối thủ của bạn đang tải lại, bạn thắng. Nếu họ cũng bắn, và cả hai bạn đều có đạn, đó là một trận hòa. Nếu họ bảo vệ, bạn đã lãng phí đạn. Mặc dù bắn mà không có đạn là một động thái hợp pháp, nó không làm gì và khiến bạn dễ bị tổn thương như tải lại. Bắn được tượng trưng bằng cách chỉ vào người chơi khác.

Nó được chơi tương tự như RPS, trong đó mỗi người chơi đồng thời ném xuống sự lựa chọn của họ (chúng tôi gõ hai chân vào giữa hai lượt để giữ nhịp với nhau, nhưng điều đó không quan trọng đối với thử thách).

Các thách thức:

Nhiệm vụ của bạn là tìm ra kết quả của một trò chơi Chiến tranh. Nó có thể là một chức năng hoặc chương trình đầy đủ.

Đầu vào

  • Tùy chọn mỗi người chơi chọn mỗi lượt sẽ được thể hiện bằng một ký tự / chuỗi:

    • r : tải lại

    • g : bảo vệ

    • f : lửa

  • Đầu vào sẽ là một danh sách các cặp, một chuỗi được phân tách / không giới hạn hoặc bất cứ thứ gì khác dọc theo các dòng này.

Một ví dụ đầu vào trong Python có thể là [("r", "g"), ("f", "r")], nghĩa là ở lượt đầu tiên, người chơi thứ nhất đã tải lại và người chơi thứ hai được bảo vệ. Ở lượt thứ hai, người chơi thứ nhất bắn, trong khi người chơi thứ hai tải lại. Người chơi thắng một trò chơi này. Các đầu vào tương tự tùy chọn có thể được biểu diễn như "r g f r", "rgfr", "rg fr" "rg-fr"...

Bạn có thể giả sử như sau:

  • Đầu vào sẽ khớp với định dạng bạn đã chọn và nó sẽ chỉ chứa các ký tự hợp lệ.

  • Ai đó sẽ chết trong vòng 100 lượt.

Tuy nhiên, bạn không thể cho rằng lượt chơi kết thúc khi ai đó chết.

Đầu ra

Một giá trị cho biết ai thắng (hoặc, ai thắng trước *). Bạn có thể chọn đầu ra cho mỗi kịch bản, nhưng phải tính đến các trường hợp sau:

  • Người chơi 1 thắng

  • Người chơi thắng 2

  • Họ giết nhau (vẽ)

Mỗi kết quả phải có một giá trị quận và phải luôn giống nhau cho từng kịch bản.

Ví dụ: bạn có thể xuất 1khi người chơi 1 thắng, 2khi người chơi 2 thắng và 0trong trường hợp bốc thăm. Sau đó, bạn phải luôn xuất 1khi người chơi 1 thắng, 2khi người chơi 2 thắng và 0trong trường hợp bốc thăm.

Nó có thể được trả lại, hoặc in ra thiết bị xuất chuẩn. Trailing khoảng trắng là tốt.

Thật rõ ràng, kịch bản duy nhất dẫn đến một trận hòa là nếu cả hai người chơi đều nổ súng và cả hai đều có đạn.

*Vì trong thử thách này, lượt chơi có thể tiếp tục sau khi ai đó chết, cuối cùng có thể nhiều hơn 1 người chơi có thể giành chiến thắng. Bạn cần tìm ai thắng trước theo đầu vào.

Các trường hợp thử nghiệm (giả sử 1khi P1 thắng, 2khi P2 thắng và 0rút thăm):

"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

Đây là mã golf, vì vậy số byte nhỏ nhất sẽ thắng!

Lưu ý, như các trường hợp thử nghiệm cho thấy, bạn phải xử lý các động thái "ngu ngốc". Nó hoàn toàn hợp lệ khi người chơi cố gắng bắn khi họ không có đạn hoặc tải lại 2 lượt liên tiếp (và chỉ tích lũy một đạn duy nhất).


Tôi có thiếu thứ gì không hoặc có thể xác định đầu ra từ vòng trước không?
xnor

@Cập nhật câu hỏi. Và không, vì bạn cần biết người chơi có đạn hay không. Mặc dù vậy, tôi nhận ra rằng bạn có thể cho rằng người chơi nào có đạn dựa trên thực tế rằng đó là lượt cuối cùng. Tôi thực sự đã thay đổi các quy tắc vào phút cuối cho phép giả sử đầu vào sẽ kết thúc khi ai đó chết. Tôi đang hối hận vì điều đó.
Carcigenicate


3
Điều này rất giống với Điểm một trò chơi Tải, Bảo vệ và Bắn . Sự khác biệt duy nhất là thử thách khác có súng với nhiều hơn một phát bắn và việc bắn một khẩu súng trống được coi là gian lận và làm mất trò chơi.
Dennis

Chúng ta có thể lấy hai đầu vào riêng biệt cho hai người chơi thay vì vòng, ví dụ {"rff","rgf"}không?
betseg

Câu trả lời:


2

Võng mạc , 36 byte

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

Định dạng đầu vào phải là các cặp tách dòng, ví dụ:

rr
fr

Đầu ra là !_người chơi 1 thắng, _!nếu người chơi 2 thắng và !!nếu có hòa.

Hãy thử trực tuyến! (Một bộ thử nghiệm sử dụng phân tách không gian để thuận tiện.)

Tôi phải hoàn toàn bỏ qua thử thách này. Tôi chắc chắn rằng tôi đã thử điều này ở Retina trước đó. :)

Giải trình

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

Chúng tôi bắt đầu bằng cách đánh dấu các ảnh "hợp lệ" bằng cách chuyển ảnh đầu tiên fsau mỗi ảnh rthành !. Chúng tôi thực hiện điều này bằng cách kết hợp từng ftừ đó có thể tìm thấy một rngười chơi trên cùng một người chơi mà không vượt qua người khác f. Việc giới hạn tìm kiếm rtrên s trên cùng một người chơi rất dễ dàng bằng cách luôn đi ba ký tự cùng một lúc.

A`g

Bây giờ chúng tôi loại bỏ tất cả các lượt trong đó ai đó tự bảo vệ mình, vì lượt kết thúc không thể là một trong số đó.

G1`!

Bây giờ chúng tôi chỉ giữ lượt đầu tiên có chứa một !. Nếu một phát bắn hợp lệ xảy ra (và chúng tôi biết rằng không có ai bảo vệ), trò chơi kết thúc.

\w
_

Cuối cùng, chúng ta cần hợp nhất chuỗi để đưa ra kết quả đầu ra nhất quán và chúng ta chỉ cần thực hiện điều này bằng cách biến các !ký tự không (hoặc rhoặc f) thành _.


5

Con trăn, 139 byte

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]

Đưa đầu vào vào stdin dưới dạng danh sách các chuỗi 2 ký tự (ví dụ: ['rf', 'rr', 'rg', 'ff']). Xuất ra 1 nếu người chơi 1 thắng, -1 nếu người chơi 2 thắng và 0 cho một trận hòa.

Giải trình: Đầu tiên kiểm tra xem có ai bắn một viên đạn không, nếu vậy trò chơi kết thúc. Sau đó, chúng tôi xác định xem người chơi có nạp lại súng hay lãng phí đạn không.

Đây là bài viết về codegolf đầu tiên của tôi :)


4

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

Đã lưu 4 byte với sự trợ giúp của Titus

Lấy đầu vào dưới dạng một chuỗi các chuỗi 2 ký tự mô tả các bước di chuyển của mỗi người chơi.

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

Trả về:

  • 1 nếu người chơi 1 thắng
  • 2 nếu người chơi 2 thắng
  • 3 cho một trận hòa

Làm thế nào nó hoạt động

Chúng tôi duy trì một bitmask bmô tả ai có một viên đạn được nạp:

  • bit # 0: người chơi 1 có một viên đạn
  • bit # 1: người chơi 2 có một viên đạn

Chúng tôi sử dụng chuỗi De Bruijn 'ffrfgrrggf' để xác định tất cả 9 kết hợp di chuyển có thể. Chúng tôi sử dụng bit OR và AND để cập nhật btheo kết hợp di chuyển. Chúng tôi sử dụng bộ bitmas thứ 3 được AND'ed bđể xác định người chiến thắng w. (Ba kết hợp chiến thắng duy nhất là ff, frrf.)

Điều đáng chú ý là mặt nạ OR và AND có thể được lưu trữ với cùng một mẫu, được dịch chuyển bởi hai vị trí.

 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

Các trường hợp thử nghiệm


@Carcigenicate Điều này nên được sửa cho cả hai trường hợp thất bại. Tuy nhiên, bây giờ tôi trở lại 0(không ai bị bắn) hoặc 3(người chơi giết nhau) trong trường hợp hòa. Không chắc chắn nếu điều này được cho phép. Nếu không, tôi có thể trở lại w%3thay thế.
Arnauld

Tôi muốn 1 đầu ra cho mỗi kịch bản. Tôi đảm bảo rằng ai đó sẽ luôn bị bắn, vì vậy việc hạch toán cho trường hợp đó là không cần thiết. Trường hợp duy nhất dẫn đến một trận hòa là khi cả hai bắn nhau, và cả hai đều có đạn.
Carcigenicate

Các &mặt nạ có thể là 0 cho fr,rf,ff. '312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]hoặc '123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]lưu một byte; Nhưng họ có làm việc không?
Tít

@Titus Thật thú vị, áp dụng mặt nạ OR trước mặt nạ AND sẽ hoạt động cho tất cả các trường hợp thử nghiệm hiện có. Nhưng điều đó sẽ thất bại cho một cái gì đó như["rr","fg","fr","rf"]
Arnauld

&có quyền ưu tiên cao hơn |, vì vậy việc thay đổi thứ tự không nên thay đổi bất cứ điều gì ở đó (ngoài việc lưu byte). Nhưng bài tập bị thiếu trong mã của tôi. Hãy thử ...'123'[b='2100231'....
Tít

2

Perl 6 , 71 62 byte

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

Giải pháp dựa trên Regex.

Lấy đầu vào dưới dạng một chuỗi trong biểu mẫu "rg fr".
Ba kết quả đầu ra có thể là các giá trị enum More(người chơi 1 thắng), Less(người chơi 2 thắng), Same(hòa) - biến thành những từ đó khi được in hoặc thành 1, -1.0 khi bị cưỡng chế số.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

    Thực hiện hai trận đấu regex trên đầu vào. Sau khi nội suy, hai biểu thức chính là:

    • r[..[r|g]]*.[r|f]f - Trận đấu thành công đầu tiên của người chơi 2.
    • r[..[r|g]]*..f[r|f] - Phù hợp với phát bắn thành công đầu tiên của người chơi 1.

    Trong mỗi trường hợp, nó trả về vị trí kết thúc của trận đấu ( .to) hoặc vô cùng nếu không có kết quả khớp.

  • &[<=>](|   )

    Áp dụng <=>toán tử cho hai vị trí kết thúc khớp. Nó trả về một giá trị từ Orderenum ( More, Lesshoặc Same), tùy thuộc vào việc đối số thứ nhất lớn hơn, nhỏ hơn hay bằng giá trị thứ hai.


Khéo léo. Vì tò mò, làm thế nào để bạn gõ biểu tượng vô cực? Bàn phím đặc biệt, hoặc bạn gõ alt + some number? Và bạn có thực sự sử dụng các ký tự như thế trong mã Perl thông thường, hay đó chỉ là để chơi golf?
Carcigenicate

@Carcigenicate: Sơ đồ bàn phím tùy chỉnh của tôi cho phép tôi nhập nó bằng cách nhấn bốn phím [Menu] i n f(nó được gọi là trình tự soạn thảo ). Tuy nhiên, tất cả các ký hiệu Perl 6 đều có phiên bản ASCII - ví dụ Inflà từ đồng nghĩa - vì vậy không cần thiết phải sử dụng các ký hiệu Unicode trong mã Perl 6. Tôi chỉ thích nó ... :)
smls

À Đó là một điều khiến tôi nhớ về Perl là biểu tượng vô cực. Tôi nghĩ rằng đó là một yêu cầu, có vẻ phức tạp không cần thiết. Có lẽ khi tôi chán Clojure, tôi sẽ thử Perl. Gần đây tôi đã thấy rất nhiều mã Perl.
Carcigenicate

@Carcigenicate: Xin lưu ý rằng Perl 6 về cơ bản là một ngôn ngữ mới không tương thích ngược với Perl và trình thông dịch của nó vẫn còn chậm (và đối với một số tính năng, lỗi). Perl, hiện tại phiên bản v5.24, tiếp tục được duy trì riêng.
smls

Được rồi cảm ơn. Tốt để biết.
Carcigenicate

2

Haskell , 101 91 87 byte

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

Hãy thử trực tuyến! Hàm infix #lấy hai chuỗi biểu thị hành động của mỗi hai người chơi và trả về (0,1)nếu người chơi 1 thắng, (1,0)cho người chơi 2 và(0,0) cho một trận hòa.

Ví dụ sử dụng:

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

Giải trình:

Hàm infix !chuyển một chuỗi các hành động 'r'(tải lại), 'f'(lửa) và 'g'(bảo vệ) thành một chuỗi các hành động có thể quan sát được 0(lửa thực tế), 1(không có hành động) và2 (bảo vệ), trong đó một hành động cháy chỉ được tính là hành động cháy thực tế nếu một viên đạn được nạp, và như không có hành động nào khác. Để đạt được điều này, đối số đầu tiên n0nếu một viên đạn được nạp và 1nếu súng không được nạp. Bằng cách này, mỗi cách 'f'đơn giản có thể được thay thế bằng hiện tại n. ( n=0-> đã tải -> cháy thực tế -> 0, n=1-> không tải -> không có hành động -> 1)

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

Chín khả năng kết quả là sau đó

  • (0,0): Cả hai người chơi bắn và chết, trò chơi kết thúc.
  • (0,1) hoặc là (1,0) : Một người chơi bắn người kia, trò chơi kết thúc.
  • (0,2) hoặc là (2,0) : Một người chơi bắn nhưng những người bảo vệ khác, trò chơi tiếp tục.
  • (1,1), (1,2), (2,1)Hoặc (2,2): Không có chồi người chơi, trò chơi tiếp tục.

Theo thiết kế, tổng các tùy chọn kết thúc trò chơi nhỏ hơn 2 và tổng của mỗi khả năng tiếp tục trò chơi lớn hơn hoặc bằng 2. Kết quả của trò chơi sau đó là lần đầu tiên với tổng nhỏ hơn 2.

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

Mẻ, 249 byte

@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%

Đầu vào ở dạng các cặp ký tự cho mỗi lượt và xuất ra theo mức lỗi (0 = vẽ, 1 = người chơi 1, 2 = người chơi 2). xytheo dõi xem người chơi có đạn hay không, vì vậy khi cả hai bắn, kết quả là 3-x-x-y, trừ khi đó là 3, trong trường hợp chúng ta tiếp tục. Trên dòng 5 tôi lạm dụng trình phân tích cú pháp của Batch -%1 (đó là động thái hiện tại) được thay thế trước khi shiftcâu lệnh thực thi và xóa nó, vì vậy chúng tôi vẫn đi đến nhãn chính xác.


1

Clojure, 168 byte

#(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]%)

Ít chơi gôn hơn (nếu cả hai người còn sống chúng tôi sử dụng M để cập nhật đạn và trạng thái sống của kẻ thù, nếu không chúng tôi sẽ trả lại trạng thái hiện tại):

(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)))

Sử dụng ví dụ (yếu tố thứ nhất cho biết Người chơi 1 còn sống ở cuối trò chơi hay không, yếu tố thứ hai cho biết Người chơi 2 còn sống, thứ 3 và thứ 4 cho biết trạng thái đạn không liên quan khi xác định người chiến thắng):

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

Cập nhật: Hãy nhìn vào đó, cái này loopcó độ dài giống hệt nhau! Tôi thấy reducephiên bản dễ phát triển hơn vì bạn có thể dễ dàng kiểm tra các trạng thái trung gian nếu bạn sử dụng 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]))

Tôi đã chờ đợi! Thật dày đặc, wow.
Carcigenicate

Hehe cảm ơn, điều đó vẫn làm tôi khó chịu khi tôi phải lặp lại [l1 l2 r1 r2](giá trị được sửa đổi tại letvà giá trị ban đầu của nó) và những fnchữ ký đó.
NikoNyrh

Ít nhất là cho cái sau, đó là lý do tại sao tôi ủng hộ loop. Tôi thấy nó dẫn đến mã gọn gàng hơn. Ngay khi tôi cần gấp với hơn 1 ắc quy, tôi chuyển sang.
Carcigenicate

1

PHP, 107 101 90 byte

sử dụng mặt nạ bit $ d cho trạng thái tải và chuỗi DeBruijn cho các động tác bắn.

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;

nhận đầu vào dưới dạng đối số dòng lệnh 2 ký tự, chạy với -nr .

1 = Người chơi 1 thắng
2 = Người chơi 2 thắng
3 = hòa

phá vỡ

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;
  • Trình tự DeBruijn fr:: vị trí = 1 = P1 cháy; rf= vị trí 2 = đám cháy P2, ff= vị trí 3 = cả hai đám cháy
  • g<$m<=> f<$m[0]( f<$mluôn luôn đúng, vì có một ký tự thứ hai).

0

Python, 200 byte

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
Chào mừng đến với trang web. Cuộc thi được tính bằng số byte vì vậy tôi khuyên bạn nên bao gồm số byte trong tiêu đề của bạn và cố gắng giảm thiểu nó bằng cách giảm độ dài của tên biến. Bạn cũng nên bao gồm ngôn ngữ bạn đã viết này (giống như Python3 với tôi).
Đăng Rock Garf Hunter

2
Như đã đề cập ở trên, đây là một cuộc thi có thể tạo ra chương trình nhỏ nhất có thể để hoàn thành nhiệm vụ. Bạn đang sử dụng tên đầy đủ như turnsthay vì chỉ t, điều đó có nghĩa là chương trình lớn hơn mức cần thiết. Ngoài ra, vui lòng bắt đầu gửi của bạn với một cái gì đó như #Python 2, 200 bytes(giả sử đây là 2 và chương trình dài 200 byte) để ngôn ngữ bạn đang sử dụng rõ ràng.
Carcigenicate

0

Clojure, 180 173 byte

(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)))))

-7 byte bằng cách thay đổi hàm thành hàm đầy đủ thay vì sử dụng macro. Điều đó cho phép tôi thực hiện các macro chức năng bên trong, giúp tiết kiệm một chút.

Đây là một giải pháp rất chính xác. Tôi khá là khó chịu vì tôi vừa mới viết một phiên bản đầy đủ của trò chơi, và về cơ bản đây là phiên bản rút gọn rất nhiều của thuật toán mà tôi đã sử dụng. Có thể có nhiều tối ưu hóa tôi có thể làm, nhưng tôi khá hài lòng với nó. Xem mã pregolfed để giải thích.

(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)))))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.