코드 봇 3 : 병렬 프로그래밍 안티 패턴


13

다시 오신 것을 환영합니다! 3 번째 CodeBots 도전 과제를 발표하게되어 기쁩니다. 이것은 제작에 오랜 시간이 걸렸습니다. 이 과제는 짧은 버전, 긴 버전 및 추가 세부 정보의 3 가지 섹션으로 나뉩니다.

짧은 버전

각 참가자는 24 명령 프로그램을 작성합니다. 이 봇은 전 세계로 이동하여 코드를 다른 봇에 복사하는 한편 다른 봇도 동일한 작업을 수행하지 못하게합니다. 가능한 명령 중 하나는 no-op Flag입니다. 봇이 Flag다른 봇보다 더 많은 것을 가지고 있다면 Flag포인트를 얻습니다. 당신은 가장 많은 포인트를 가지고 승리.

위의 모든 것은 지난 두 가지 과제에 해당했습니다. 이번에는 봇이 여러 줄의 코드를 동시에 실행할 수 있습니다.

긴 버전

API

모든 봇에는 정확히 24 줄이 있으며 각 줄의 형식은 다음과 같습니다.

$label command parameters //comments

레이블과 설명은 선택 사항이며 각 명령에는 다른 매개 변수 수가 있습니다. 대소 문자를 구분하지 않습니다.

매개 변수

매개 변수는 입력되며 다음 형식 일 수 있습니다.

  1. 0에서 23 사이의 값입니다.
  2. 변수 : A, B, C,D
  3. 더하기를 사용하는 값 ​​: A+3또는2+C
  4. 부호를 사용하여 지정된 코드 줄 #( #45 번째 줄 #C+2을 나타내는 반면으로 계산 된 줄을 나타냄 C+2)
  5. $label코드 줄을 지정 하는 대신 사용할 수 있습니다 .
  6. 에 의해 지정된 상대의 변수 또는 코드 라인 *. 상대는 당신이 직면하고있는 광장의 봇입니다. ( *B상대방의 B가치를 *#9나타내며 상대의 10 번째 줄 을 나타냅니다). 해당 사각형에 아무도 없으면 명령이 실행되지 않습니다.

명령

V 이동

봇을 움직 North+(V*90 degrees clockwise)입니다. 움직임은 방향을 바꾸지 않습니다.

V 회전

봇을 V*90 degrees시계 방향으로 돌립니다.

폭스 바겐 복사

에 어떤 사본 VW. V줄 번호 인 경우 줄 번호 W여야합니다. V변수 또는 값인 경우 변수 W여야합니다.

깃발

아무것도하지 않습니다.

스타 TV

변수에 연결된 새 스레드를 시작합니다 V. 즉시, 그리고 매번 턴마다 스레드는 명령을 온라인에서 실행합니다 V.

V이미 스레드에 연결되어 있으면 이 명령은 작동하지 않습니다. 경우 V상대의 변수, 다음 상대는 그 변수에 부착 된 스레드를 시작합니다.

V를 중지

V이 턴이 끝날 때 변수 에 연결된 스레드를 중지합니다 .

V 잠금

광고 또는 가변 방지 V에 사용되는 임의의 방법 이라는 것을 제외 실 Lock. Lock동일한 스레드 에 의한 후속 호출이 잠금 해제 V됩니다. 상대의 변수 또는 행에서는 잠금을 호출 할 수 없습니다.

Cond VW 인 경우

테스트 Cond합니다. 조건이 true이면 스레드 포인터를 줄 번호로 V, 그렇지 않으면 줄 번호로 이동합니다 W. 그러면 해당 라인이 즉시 실행됩니다.

조건문이 될 수있다 X=Y, X<Y, !X, 또는 ?X:

  1. X=Y 두 줄이 같은 유형이고 같은 봇에서 왔는지 테스트하거나 두 값이 같은 양인지 확인합니다.
  2. X<Y의 값 X이보다 작은 지 여부를 테스트합니다 Y.
  3. !X변수 또는 행 X이 잠겨 있는지 테스트합니다 (잠긴 경우 true를 리턴 함)
  4. ?X 주어진 변수에 스레드가 연결되어 있는지 테스트

추가 세부 사항

멀티 스레드 상호 작용

동일한 유형의 작업이 동시에 실행됩니다. 조치는 다음 순서로 실행됩니다.

  1. 자물쇠. 여러 스레드가 변수 잠금을 시도하면 모두 실패합니다. 스레드가 변수를 잠금 해제하는 동안 다른 변수가 잠금을 시도하면 변수는 잠금 해제 상태로 유지됩니다.

  2. 스타트. 여러 스레드가 변수에서 스레드를 시작하려고하면 단일 시작으로 계산됩니다.

  3. 부. 두 스레드가 모두 같은 변수에 복사되면 변수는 임의의 값으로 끝납니다. 둘 다 같은 줄에 복사하면 둘 다 작동하지 않습니다. 스레드가 다른 스레드가 복사하는 동일한 변수에 복사하면 후자의 스레드가 임의의 값을 복사합니다. 두 스레드가 모두 동일한 변수에서 복사하는 경우 모두 정상적으로 작동합니다.

  4. 만약. 모든 조건은 동시에 테스트 된 후 스레드 변수가 업데이트됩니다. 를 실행하면 If우선 순위가 높은 작업이 추가 될 수 있습니다. 우선 순위가 높은 작업은을 지나서 이동하기 전에 실행되고 If우선 순위가 낮은 작업은 If.

  5. 움직임. 동일한 봇에서 여러 번 이동하면 봇이 모든 이동의 합을 이동합니다. 여러 봇이 같은 지점에있게되면 시작 지점으로 돌아갑니다.

  6. 회전. 같은 봇을 여러 차례 켜면 합산됩니다.

  7. 중지. 같은 변수에 여러 정지 명령이 단일 정지로 계산됩니다.

기타 세부 사항

초기 스레드가 D변수에 연결되기 시작 합니다.

If( If문장 자체가 지적)로 되풀이 하면 봇이 아무것도하지 않습니다.

잠금 후 스레드가 중지되면 해당 잠금이 잠금 해제됩니다

잠긴 변수 또는 행을 사용하는 작업은 아무 것도 수행하지 않습니다.

봇이 24 줄보다 짧은 경우 나머지 줄은 Flag

시작 스레드에도 연결된 변수에 대한 쓰기를 수행하면 스레드가 다음 차례를 시작할 때 실제로 스레드가 새 값에서 실행을 시작하게됩니다.

봇은 다음과 같은 패턴으로 환상 세계에 배치됩니다.

B...B...B...
..B...B...B.
B...B...B...

언어 참조로 주석이 달린 몇 가지 샘플 을 추가 했습니다 .

컨트롤러는 여기에 있습니다 . 나는 오랜 시간 동안 노력했지만 여전히 버그가 있습니다. 사양과 컨트롤러가 모순되면 사양이 정확합니다.

스코어 보드

1. 771  LockedScannerBot
2. 297  CopyAndSelfFlag
3. 289  DoubleTapBot
4. 197  ThreadCutterBot
5. 191  TripleThread
6. 180  ThickShelled
7. 155  Attacker
8. 99   RandomMover
9. 90   BananaBot
10. 56  LockedStationaryDoubleTap

와우, 적어도 DoubleTap은 샘플보다 훨씬 나아 보입니다!
Katenkyo

다른 스레드에서 잠긴 변수를 읽으려고하면 어떻게됩니까? LOCK A를하고 다른 스레드에 MOVE A가 있다고 가정 해보십시오 .A는 0 또는 임의의 값으로 평가되거나 이동이 실패합니까 ...?
Sparr

스레드가 다른 스레드에 의해 잠긴 라인에 도달 할 때 발생하는 상황을 결정합니다. 멍청한가요? 건너 뛰나요?
Sparr

"Copy $ label A"가 작동해야합니까? 유효하지 않은 "Copy # 11 A"로 해석되어 원하는대로 "Copy 11 A"대신 인터프리터와 충돌합니다.
Sparr

가능한 버그 ... 다른 스레드에 의해 잠겨있을 때조차도 내 플래그 행을 읽고 복사 할 수있는 것 같습니다.
Sparr

답변:


3

잠긴 스캐너 봇

적을 가능한 빨리 스캔하고 선을 깃발로 바꿉니다.

    Lock D
    Copy $a A
    Start A
    Copy $b B
    Start B

$d  Lock $d0
    Lock $d1    
$d0 Copy $flag *#C+1
$d1 If 1=1 $d0 $d0

$a  Lock A
    Lock $a0
    Lock $a1
    Lock $a2
$a0 Copy $flag *#C
$a1 Copy C+2 C
$a2 If !*#C $a1 $a0

$b  Lock B
    Lock $b0
    Lock $b1
    Lock $b2
$b0 Move C
$b1 Turn 1
$b2 If 1=1 $b0 $b0

$flag Flag

A 스레드의 조건에 대해 궁금합니다. ! * # C는 대상의 라인 #C (C)가 잠겨 있는지 확인합니다. 어떻게 도움이 되나요?
Sparr

@Sparr 스레드가 잠긴 경우 적 코드의 줄을 플래그로 바꾸는 데 시간을 낭비하지 않습니다.
TheNumberOne

감사. 원래 If 문의 속도에 관한 사양을 잘못 읽었습니다.
Sparr

3

DoubleTapBot

이 봇에는 3 개의 스레드가 있습니다. 하나는 이동 (A)이고 다른 하나는 신고 (B 및 D)입니다. B 플래그 1/2 회전, D 플래그 1/3 회전. 그래서 어떤 차례에, 그는 상대에게 두 번 깃발을 붙일 것입니다 :).

C가 23을 초과하면 0으로 돌아 간다고 가정합니다.

그는 적어도 2 개의 스레드 (A & B)가 정상적으로 계속 작동하기 때문에 스스로 준비 할 차례가 있다면 (8 턴) 꽤 안전합니다.

나는 지금 그것을 시도 할 수 없으므로 내가 돌아올 때 테스트를 할 것이다. :)

Lock D          //Thread D locks itself
Copy 6 A        //Thread A will start line 6
Start A     
Copy 13 B       //Thread B will start line 13
Start B        
Copy 20 D       //Moving Thread D to an other part of the program
Lock A          //Thread A locks itself and the line it will be using
Lock #10
Lock #11
Lock #12
Move C          //Move in a pseudo random direction
Turn 1      //always turn to the right
If 1=1 #10 #10  //return to Move C
Lock B          //Thread B locks itself and the line it will be using
Lock #13
Lock #14
Copy #18 *#C    //Copy a flag to the Cth line of the opponent
If 1=1 #16 #16  //jump back to the copy
Flag   
Flag   
Copy C+1 C      //Increment C
Copy #19 *#C+1  //Copy a flag to the Cth+1 line of the opponent
If 1=1 #20 #20  //jump back to the increment
Flag 

잠금 번호는 유효한 명령이 아닙니다. 각 숫자 앞에 # 기호를 넣습니다. 또한, 명령은 "회전"이 아닌 "회전"
Nathan Merrill

@NathanMerrill 오타 인 방법을 지적 해 주셔서 감사합니다. 그리고 회전을 위해 글을 수정하십시오 .V 회전 봇을 시계 방향으로 90도 회전시킵니다. :)
Katenkyo

아, 했어요 차례가 실제로 정확하다면, 돌아가서 코드를 업데이트하겠습니다
Nathan Merrill

10,11,12를 잠그려고 할 때 11,12,13을 잠그고 있습니까?
Sparr

와우, 지적 해줘서 고마워!
Katenkyo

2

고정식 더블 탭 잠금

@Katenkyo의 DoubleTapBot에서 영감을 얻은이 플래그는 자체 스레드를 완전히 잠그기 위해 몇 개의 플래그와 움직임에 대한 희망을 포기하므로 ​​다시 프로그래밍 할 수 없습니다. 그러나, 비 루핑 코드 영역에 적 플래그를 기록하는 것은 여전히 ​​가능하다.

Lock $flag              // lock the only flag line, super important!
Lock D                  // lock thread D
Copy 10 A
Start A                 // start thread A at $Astart
Copy 17 B
Start B                 // start thread B at $Bstart
Lock $D1                // lock thread D lines
Lock $D2                // thread D should be safe on turn 8
$D1 Turn C              // Spin in place, once every 2 turns
$D2 If 0=0 $D1 $D1      // thread D loop
$Astart Lock A          // thread A starts here, locks itself
Lock $A1                // lock thread A lines
Lock $A2
Lock $A3                // thread A should be safe on turn 7
$A1 Copy $flag *#C      // ATTACK! once every 3 turns
$A2 Copy C+1 C          // increment C, used for attacks and turning
$A3 If 0=0 $A1 $A1      // thread A loop
$Bstart Lock B          // thread B starts here, locks itself
Lock $B1                // lock thread B lines
Lock $B2                // thread B should be safe on turn 8
$B1 Copy $flag *#C+12   // ATTACK! once every 2 turns
$B2 If 0=0 $B1 $B1      // thread B loop
$flag Flag

하하, 깃발을 잠그는 것은 꽤 좋은 생각입니다. 어쨌든, 내 봇이 누군가에게 영감을 준 것이 기쁘다!
Katenkyo

@Katenkyo 그것이 작동하면 좋은 생각이지만 작동해야한다고 생각하지 않습니다. 작성된 규칙은 D가 플래그 라인을 잠그면 A / B가 그로부터 복사 할 수 없음을 나타냅니다. 그러나 그것은 사실이 아닙니다. 질문에 대한 의견의 버그보고.
Sparr

1

랜덤 발동기

의사 난수 방향으로 이동

Copy 5 C
Copy 8 B
Start C
Move A // If you can't catch me, you can't modify me
If 1=1 #3 #3 //Continue to execute the above line
Start B
Copy 4 A
If 1=1 #6 #6 //Continue to execute the above line
Flag
Copy 5 A
If 1=1 #9 #9 //Continue to execute the above line

1

두꺼운 껍질

그가 할 수있는 한 그의 물건을 잠급니다

Copy 5 B //Designating that the B thread will start on line 5
Start B //Starting the B thread
Lock C //Preventing C from being used
Copy A+1 A //The two threads are offset, meaning that the two threads shouldn't access this at the same time
Lock #A
Copy 2 B

1

공격자 봇

플래그를 다양한 위치에 복사

Copy A+1 A // Increment A
Move A //Move in the Ath direction
Turn A //Rotate A times
Copy #8 *#A //Copy my flag over
Copy 23 D //Loop back to the beginning.  (I use 23 here as threads auto-increment)

0

트리플 스레드

이 간단한 봇은 동일한 코드로 세 개의 스레드를 모두 실행합니다. 각 스레드는 1/3 회전, 1/6 이동, 1/6 회전 및 부기 1/3을 수행합니다.

Move 0
Start A
Start B
$loop Copy #A+9 *#C
Move C
Copy #A+9 *#C
Turn C
Copy C+1 C
If 0=0 $loop $loop

0

바나나 봇

적이 무엇이든 할 수 있기 전에 적의 바퀴에 바나나를 던지려고합니다. 찌그러지기 쉽다.

$d     If !*D $d1 $d0
$d0    Copy 24 *D
$d1    If !D $d2 $start
$d2    If !*B $d5 $d3
$d3    Copy 24 *B
$d4    Copy $d D

$start Lock D             //Banana's like to split.
       Copy $a A
       Start A
       Copy $b B
       Start B
       Lock $flag

$d5    Copy $start *C     //It's okay if enemy messes up our start.
       Copy $d d

$a     Lock A
$a1    Move C
       Turn 1
       Copy $a1 A

$b     Lock B
$b0    Copy C+1 C
       If !*#C $b0 $b1    //Banana's are good at slipping.
$b1    Copy $flag *#C
$b2    Copy $b0 B

$flag  Flag

0

실 절단기 봇

   Lock D
   Lock $f
   Copy 16 C
$S If ?*D $1 $2
   Move 1
   Copy $S D
$f Flag
$1 Stop *D
$2 If ?*A $3 $4
$3 Stop *A
$4 If ?*B $5 $6
$5 Stop *B
$6 Copy $f *#C
   Copy C+1 C
   If *#C=#C $E $6
   Copy 2 D
$E Start *D

코드를 채우기 전에 모든 적 스레드를 중지하십시오.


0

복사 및 자체 플래그

이 봇은 세 개의 스레드를 실행합니다. D 실은 적에게 닿을 때까지 움직 인 다음 깃발을 복사하려고 시도한 다음 무작위 방향으로 움직입니다. A 스레드는 봇 코드의 비 필수 줄에 자체 플래그를 복사합니다. B 스레드는 카운터 일뿐입니다. 각 스레드에서 사용하는 변수, 플래그 및 코드 줄은 처음 15 턴에 완전히 잠기 며 봇은 거의 모든 시작 코드를 자체 플래그로 덮어 씁니다. 전용 공격 로봇이 깃발을 쓰는 것 외에는 아무것도하지 않는 15 세 이후에이 로봇을 다른 팀의 배너로 변환 할 수 없다고 생각합니다.

    Lock D              // Lock D thread
    Copy $AS A
    Start A             // Start A thread at $AS
    Start B             // B is just a counter
    Copy $DL D          // Jump to D thread startup code
$DC Start B             // Don't let B thread get stopped
$D0 If !*#B $D1 $D2
$D1 Copy $DF *#B
$D2 If !*#B+6 $D3 $DM
$D3 Copy $DF *#B
$DM Move B              // Move some direction after attacking
$DA Move 0              // Move north ...
    If ?*D $DC $DA      // until we hit a live target
$DF Flag                // Flag to copy
$DL Lock #B+3           // Lock the D thread's lines
    If B<12 $DL $DA     // jump to `Move 0` when D thread is safe
$AS Lock A
$AL Lock #B+20
    If B<4 $AL $AD
    Copy 23 B           // reset B so A doesn't overwrite its own code
$AF Flag
    Flag
$AD Copy $AF #B+1       // Copy a safe flag over every unused line of code
    If B<18 $AD $AF

Move 0앞으로가 아니라 북쪽으로 이동합니다.
MegaTom

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