경찰과 도둑


11

모든 사람은 항상 Conway의 게임 게임을 구현하기를 원합니다. 그건 지루해! 대신 경찰과 강도를하자!

경찰과 강도라는 두 팀이 있습니다. 각 팀에는 50 명의 건강을 가진 5 명의 멤버가 있습니다. 프로그램이 계속 반복됩니다. 반복 할 때마다 다음이 발생합니다.

  • 각 팀마다 첫 번째 문자 ( C경찰, R강도), 공백, 공백으로 구분 된 회원 HP 목록 및 줄 바꿈을 인쇄하십시오. 이것이 팀의 상태입니다. 둘 다 완료되면 다른 줄 바꿈을 인쇄하십시오. 예를 들어 다음은 첫 번째 라운드처럼 보일 수 있습니다.

    C 50 50 50 50 50
    R 50 50 50 50 50
    
  • 1에서 10 사이의 난수를 선택하십시오 (1과 10 모두 포함). 우리는 번호를 호출합니다 N. 경우 N짝수의 강도는이 라운드를 잃게; 홀수이면 경찰이 패배합니다.

  • HP가 0보다 큰 패배 팀의 무작위 멤버를 선택하고 HP를 공제하십시오 N. 회원의 HP는 상태가 0보다 낮은 상태로 나타나지 않아야합니다.

  • 루프를 다시 시작하십시오.

한 팀의 모든 구성원이 자신의 HP를 모두 잃으면 게임이 종료됩니다. 그런 다음 경찰이 이기면 다음이 인쇄됩니다.

C+
R-

강도가 이길 경우 :

R+
C-

이것은 코드 골프이므로 가장 짧은 문자 수가 이깁니다.

다음은 Python 2의 샘플 구현입니다.

import random

cops = [50]*5
robbers = [50]*5

while any(cops) and any(robbers):
    # print the status
    print 'C', ' '.join(map(str, cops))
    print 'R', ' '.join(map(str, robbers))
    print
    # pick N
    N = random.randint(1, 10)
    # pick the losing team (robbers if N is even, else cops)
    losers = robbers if N % 2 == 0 else cops
    # pick a member whose HP is greater than 0
    losing_member = random.choice([i for i in range(len(losers)) if losers[i]])
    losers[losing_member] -= N
    # make sure the HP doesn't visibly drop below 0
    if losers[losing_member] < 0: losers[losing_member] = 0

if any(cops):
    # robbers lost
    print 'C+'
    print 'R-'
elif any(robbers):
    # cops lost
    print 'C-'
    print 'R+'

사소한 아이러니 :이 사이트의 3176 개 이상의 질문 중 11 개 이하로 태그되었습니다 game-of-life.
Sanchises

3
@sanchises Extended irony : 및 14 태그가 지정되었습니다 cops-and-robbers!
Runer112

@sanchises 저는 일반적으로 프로그래밍을 주로 언급하고있었습니다 (예 : "도와주세요! Conway 's Game of Life!"를 구현하려고합니다!) ...하지만 여전히 아이러니합니다.
kirbyfan64sos

@ kirbyfan64sos 내가 아는 (그곳에서 그 일을했지만) 사람들 이 GoL을 구현하고 더 많은 것을 원한 후에 가는 사이트의 종류입니다 ... 어쨌든, 아마도 나는 이것을 <> 내가 할 수 있는지 봅시다.
Sanchises

CnR 태그를 다시 제거했습니다. 이 태그 주위에서이 태그는 매우 특정한 의미를 가지며 특정 작업에서 서로 경쟁하는 두 명의 당사자 (실제로 연결되지 않은)가있는 문제를 설명합니다 (해당 태그의 다른 문제를 살펴보십시오).
Martin Ender

답변:


3

CJam, 86 바이트

나는 파티에 조금 늦었지만 CJam의 선물을 가져 왔습니다! ... 이봐, 어디 가니?

50aA*{"CR"1$+2/zSf*Nf+oNoAmr{_AmrE&+:P2$=:H!}gPH@)-Ue>t_2/z::+0#:L)!}g;'CL'+'-?N'R2$6^

온라인으로 사용해보십시오.

설명

질문이 간단한 프로세스를 모방하도록 요구할 때 이것은 비교적 간단한 대답입니다. 아마도 내가 한 흥미로운 선택은 두 팀의 건강을 같은 목록에 포함시키는 것이 었습니다. 두 개의 별도 목록으로 변환하는 데 3 바이트가 소요되며, 상태 표시 및 팀이 유실되었는지 확인하는 데 필요합니다. 그러나 이것은 초기화에 저장된 2 바이트와 훨씬 간단한 손상 처리 논리로 구성됩니다.

50aA*           "Initialize the health list to 10 copies of 50. Even indices
                 hold the health of cops and odd indices hold the health of
                 robbers.";
{               "Do:";
  "CR"1$+2/z      "Split the health list into the two teams for output, adding
                   the corresponding team letter to the start of each.
                       [a b c d e f g h i j]
                    -> [['C a c e g i] ['R b d f h j]]";
  Sf*Nf+          "Insert a space between each element in each team health list
                   and append a newline to the end of each team health list.";
  oNo             "Print the health status for each team and an extra newline.";
  Amr             "Generate the damage amount minus one. If the damage amount is
                   even (robbers lose), then this is odd and aligns with robbers
                   being at odd indices in the health list, and vice versa.";
  {               "Do:";
    _AmrE&+:P       "Add a random even number from [0, 10) to the damage amount
                     minus one. This value modulo the size of the health list
                     (10) selects a person on the losing team to be damaged.";
    2$=:H!
  }g              "... While the selected person's health is zero.";
  PH@)-Ue>t       "Set the damaged person's new health to the maximum of their
                   current health minus the damage amount and zero.";
  _2/z::+0#:L     "Split the health list into the two teams, sum each team's
                   health, and search for a team's health equal to zero.";
  )!
}g              "... While no team's health was found equal to zero.";
;               "Discard the health list.";
'C              "Produce a 'C'.";
L'+'-?          "Produce a '+' if team 1 (robbers) lost, or '-' otherwise.";
N               "Produce a newline.";
'R              "Produce an 'R'.";
2$6^            "Produce the opposite of the sign produced before.";
                "Implicitly print these final results.";

3

제 201 화

S=sum
Z=sample
C=R=rep(50,5)
while(S(R)*S(C)){cat("C",C,"\nR",R,"\n\n")
N=Z(10,1)
F=function(x,i=Z(rep(which(x>0),2),1)){x[i]=max(0,x[i]-N);x}
if(N%%2)R=F(R)else C=F(C)}
cat(c("R+\nC-\n","C+\nR-\n")[1+!S(R)])

또한 왜에 rep(which(x>0),2)반대 which(x>0)하는가?
MickyT

1) 나는 마지막 문자가 아닌 EOL 문자를 세고 있습니다. 2) sum(R*C)sum(R)*sum(C)같은 것이 아니다. 예를 들어 C = c (0,0,0,10,10)이고 R = c (10, 10, 10, 0, 0) 인 경우 종료하지 않을 것입니다. 이 경우을 할당하여 저장합니다 S=sum. 3) 문제는 sample첫 번째 인수는 하나의 숫자, 예를 들어, 경우 것입니다 sample(5, 1), 다음이하고 같은 것 sample(1:5, 1)대신 항상 반환하는 : 5, 그것에서 어떤 수를 반환합니다 15. 그래서 sample(rep(x, 2), 1)항상 사이의 숫자를 따기위한 나의 트릭 인 x경우에도 경우 length(x)이다가 1.
flodel

미안 내 나쁜 ... 분명히 커피가 충분하지 않습니다. rep () 트릭에 대한 설명을 주셔서 감사합니다. 나는 이유를 찾아야한다고 생각했다
MickyT

2

APL (다이아 로그) (101)

∇K
S←2 5⍴50
→6/⍨~∧/J←∨/S>0
⎕←3↑'CR',0⌈S
S[L;M[?⍴M←(0<S[L←1+~2⊤N;])/⍳5]]-←N←?10
→2
⎕←'CR',⍪'+-'⌽⍨J⍳0
∇

설명:

  • S←2 5⍴50: 처음 S에는 각 값이 50 인 5x2 행렬로 설정 합니다. 행렬의 맨 위 행은 경찰을 나타내고 두 번째 행은 강도를 나타냅니다.
  • J←∨/S>0: 행렬의 각 행에 J대해 HP가 0보다 큰지 여부를 저장 합니다.
  • →6/⍨~∧/J: 두 팀 모두 살아있는 멤버가없는 경우 6 행으로 이동하십시오.
  • ⎕←3↑'CR',0⌈S: 행렬의 각 값에 대해 최대 값과 0을 출력하고 첫 번째 행에 'C'를 추가하고 두 번째 행에 'R'을 추가하고 세 번째 (빈) 행을 추가하십시오.
  • N←?10: [1,10] 간격의 난수를 구하여에 저장합니다 N.
  • L←1+~2⊤N: 숫자가 홀수 인지 짝수인지 L(패배 팀)으로 1설정하십시오 2.
  • M←(0<S[L... ;])/⍳5: 해당 팀의 살아있는 구성원의 색인을 가져 와서M
  • M[?⍴M... ]:에서 임의의 값을 선택하십시오M
  • S[L;M... ]-←N: N선택된 팀원의 가치에서 빼기
  • →2: 2 번 줄로 이동 (살아있는 사람을위한 시험)
  • ⎕←'CR',⍪'+-'⌽⍨J⍳0: 최종 상태를 출력하여 +승 팀 -앞과 패 팀 앞

샘플 출력


1

루비, 184

c,r=[p,p].map{('50 '*5).split}
puts([?C,*c]*' ',[?R,*r]*' ')while (u,v=[r,c].map{|a|a.shuffle.find{|x|x>?0}}).all?&&[u,v][rand(1..10)%2].sub!(/.+/){eval"#$&-1"}
puts u ?'R+
C-':'C+
R-'

1

수학, 246241 바이트

아마도 더 골프를 칠 수있을 것입니다 ...

a=ConstantArray[50,{2,5}];b=Or@@(#<1&)/@#&;c=Print;d=StringJoin@Riffle[IntegerString/@#," "]&;e=RandomInteger;Label@f;Which[b@a[[1]],c@"R+\nC-",b@a[[2]],c@"C+\nR-",True,c["C "<>d@a[[1]]<>"\nR "<>d@a[[2]]];a[[Mod[g=e@9+1,2]+1,e@4+1]]-=g;Goto@f]

1

PHP-416 바이트

나는 골프를 처음 접했지만이 도전은 시도하기에 충분히 쉬울 것이다. 그래서 여기에 내가 생각해 낸 것이 있습니다.

<?$c=[50,50,50,50,50];$r=[50,50,50,50,50];while((array_sum($c)!=0)&&(array_sum($r)!=0)){$a="C ".join(" ",$c)."\n";$b="R ".join(" ",$r)."\n";echo$a,$b;$n=rand(1,10);$m=rand(0,4);if($n %2==0){while($r[$m]==0){$m=rand(0,4);}$r[$m]=$r[$m]-$n;if($r[$m]<0){$r[$m]=0;}}else{while($c[$m]==0){$m=rand(0,4);}$c[$m]=$c[$m]-$n;if($c[$m]<0){$c[$m]=0;}}if(array_sum($r)==0){echo"C+\nR-\n";}if(array_sum($c)==0){echo"R+\nC-\n";}}?>

설명과 함께 :

<? 
$c=[50,50,50,50,50];$r=[50,50,50,50,50];                       populate Arrays
while((array_sum($c) != 0) && (array_sum($r) != 0)){           loop until on array sums up to 0
    $a="C ".join(" ",$c)."\n";                                 set cops health to a
    $b="R ".join(" ",$r)."\n";                                 set robbers health to b
    echo$a,$b;                                                 print cop and robber health
    $n=rand(1,10);                                             chose random n
    $m=rand(0,4);                                              chose random member
    if($n % 2 == 0){                                           check if n is even
        while($r[$m] == 0){ $m=rand(0,4); }                    loop until value m of array r is not 0
        $r[$m]=$r[$m]-$n;                                      lower health of member m
        if($r[$m] < 0){ $r[$m]=0; }                            if health goes below 0 set it to 0
    }else{
        while($c[$m] == 0){ $m=rand(0,4); }                    same as above
        $c[$m]=$c[$m] - $n;
        if($c[$m] < 0){$c[$m]=0;}
    }
    if(array_sum($r) == 0){ echo"C+\nR-\n"; }                  check if r array sums up to 0 and print that cops won
    if(array_sum($c) == 0){ echo"R+\nC-\n"; }                  check if c array sums up to 0 and print that robbers won
}
?>

필자는 PHP 사용자가 아니지만 != 00과 같은 검사를 제거 하고 not 연산자 ( !array_sum($r))로 바꾸면 몇 가지 문자를자를 수 있습니다 .
kirbyfan64sos

작동하지 않는 @ kirbyfan64sos
Timo

오. 대부분의 언어에서 가능합니다.
kirbyfan64sos

1

C, 390 384 371 바이트

내 첫 번째 골프, 가능한 개선이 있다면, 저에게 말 해주세요 :)

골프 버전 :

#include <time.h>
#include <stdio.h>
int p[10],j,r,c,w,N,x;int s(){r=c=0;for(j=5;j--;){c+=p[5+j];r+=p[j];}return !!r-!!c;}void t(){for(j=10;j--;)printf("%s %d",j-4?j-9?"":"\n\nC":"\nR",p[j]*=p[j]>0);}main(){srand(time(0));for(j=10;j--;)p[j]=50;t();while(!(w=s())){N=rand()%10+1;while(!p[x=N%2*5+rand()%5]);p[x]-=N;t();}N=(x=w<1?'C':'R')-w*15;printf("\n\n%c+\n%c-",x,N);}

다소 골치 아픈 버전 :

#include <time.h>
#include <stdio.h>
int p[10],j,r,c,w,N,x;

int s(){
    r=c=0;
    for(j=5;j--;){
        c+=p[5+j];
        r+=p[j];
    }
    return !!r-!!c;
}

void t(){
    for(j=10;j--;)printf("%s %d",j-4?j-9?"":"\n\nC":"\nR",p[j]*=p[j]>0);
}

main(){
    srand(time(0));
    for(j=10;j--;)p[j]=50;
    t();
    while(!(w=s())){
        N=rand()%10+1;
        while(!p[x=N%2*5+rand()%5]);
        p[x]-=N;
        t();
    }
    //w=-1 if cops won, w=1 if robbers won
    N=(x=w<1?'C':'R')-w*15;
    printf("\n\n%c+\n%c-",x,N);
}

편집 : 나는 그것을 조금 단축하고 작은 버그를 수정하는 방법을 찾았다


작은 개선 : 루프 (예 for(j=0;j<10;j++):)를 더 짧은 버전 ( for(j=10;--j;))으로 바꿀 수 있습니다 .
kirbyfan64sos

당신은 이것과 몇 가지 사소한 것들을 "고정"했습니다. 감사합니다.
Metaforce

0

배치-396 바이트

건강이 0보다 큰 팀의 무작위 구성원을 실제로 선택하지 않기 때문에 이것이 기술적으로 계산되는지는 알 수 없습니다 . 임의의 멤버를 선택하기 만하면 건강 빼기가 0보다 작은 숫자를 생성하면 숫자는 0이됩니다.

@echo off&setLocal enableDelayedExpansion&for %%a in (C R)do for %%b in (1 2 3 4 5)do set %%a%%b=50
:a
set/aN=%RANDOM%*10/32768+1
set/ac=%N%/2*2
if %c%==%N% (set T=C&set L=R)else set T=R&set L=C
set/aG=%RANDOM%*5/32768+1
set/a%T%%G%-=%N%
for %%a in (C R)do set %%a=0&for %%b in (1 2 3 4 5)do (if !%%a%%b! LEQ 0 set %%a%%b=0
set/a%%a+=!%%a%%b!)
if %C% NEQ 0 if %R% NEQ 0 goto :a
echo !T!+&echo !L!-

요구 사항은 인쇄 상태에서 값이 0 미만으로 표시되지 않아야한다는 것입니다. 내가 보여준 예에서 똑같은 일을했습니다.
kirbyfan64sos

0

자바 스크립트 : 410

function x(l){var t=this,o=t.p={n:l||"C",h:[50,50,50,50,50],s:function(){return o.h.reduce(function(a,b){return a+b})},r:function(){console.log(o.n+' '+o.h.join(' '))},d:function(m){while(o.h[z=~~(Math.random()*5)]<1){}o.h[z]=m>o.h[z]?0:o.h[z]-m}};o.r()}q=[new x(),new x('R')];while((c=q[0].p.s()>0)&&q[1].p.s()>0){q[(z=~~(Math.random()*10))%2].p.d(z);q[0].p.r();q[1].p.r()}console.log(c?'C+\r\nR-':'R+\n\rC-')

0

옥타브, 182177158145 바이트

145 :

t=repmat(50,5);while prod(any(t))d=ceil(rand*10);c=2-mod(d,2);r=ceil(rand*5);t(r,c)-=d;t.*=t>0;end;p=2*any(t,1);['C-';'R+';'C+';'R-'](1+p:2+p,:)

캐릭터 촬영이 0보다 큰지 확인을 포기했습니다. 이것은 매 턴마다 상태를 표시해야 할 때만 중요합니다. 여기서 RNG에서 무작위로 하나의 숫자를 건너 뛰고 더 무작위로 만듭니다.

또한 교체

t=max(0,t)

더 짧게

t.*=t>0


[참고-줄 바꿈없이 'C + R-'를 인쇄 중입니다-145 바이트 버전으로 수정되었습니다.]

158 :

t=repmat(50,5);while prod(any(t))d=ceil(rand*10);c=2-mod(d,2);do r=ceil(rand*5);until t(r,c);t(r,c)-=d;t=max(0,t);end;p=4*any(t,1);disp('C-R+C+R-'(1+p:4+p))

디고 프드 :

t=repmat(50,5);               #only first two columns (cops, robbers) relevant
while prod(any(t))
    d=ceil(rand*10);
    c=2-mod(d,2);
    do r=ceil(rand*5);until t(r,c);
    t(r,c)-=d;
    t=max(0,t);
end;
p=4*any(t,1);
disp('C-R+C+R-'(1+p:4+p))

변경 repmat(50,5,2)했습니다 repmat(5)-이제 5x2 대신 5x5 행렬이 있습니다 (추가 3 열은 알고리즘에 영향을 미치지 않습니다). 또한 출력을 압축하는 방법을 찾았습니다.

177 년

t=repmat(50,5,2);while prod(sum(t))d=ceil(rand*10);c=2-mod(d,2);do r=ceil(rand*5);until t(r,c);t(r,c)-=d;t=max(0,t);end;if sum(t)(1)printf "C+\nR-\n";else printf "C-\nR+\n";end

디고 프드 :

t=repmat(50,5,2);
while prod(sum(t))
    d=ceil(rand*10);
    c=2-mod(d,2);                  #cops or robbers affected?
    do r=ceil(rand*5);until t(r,c);
    t(r,c)-=d;
    t=max(0,t);
end
if sum(t)(1)
    printf "C+\nR-\n"
else
    printf "C-\nR+\n"
end

기본적으로 5x2 행렬을 만듭니다. 첫 번째 열은 경찰이고 두 번째 열은 강도입니다.

t =
50     50
50     50
50     50
50     50
50     50
[cops] [robbers]

sum하나의 인수가 적용될 때 의 함수는 열을 기준으로 합계하므로 처음에는 다음과 같습니다.

250    250

그중 하나가 0에 도달 prod(sum(t))하면 루프를 제로로 평가합니다. 그런 다음 열 합계가 0 인 사람을 확인한 사람을 검사 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.