รหัสบอท 3: Antipatterns การเขียนโปรแกรมแบบขนาน


13

ยินดีต้อนรับกลับ! ฉันตื่นเต้นที่จะนำเสนอความท้าทาย CodeBots ที่ 3 อันนี้มีมานานแล้วในการทำ ความท้าทายนี้จะแบ่งออกเป็น 3 ส่วน ได้แก่ รุ่นสั้นรุ่นยาวและรายละเอียดเพิ่มเติม

เวอร์ชั่นสั้น

ผู้แข่งขันแต่ละคนจะเขียนโปรแกรม 24 คำสั่ง บอทเหล่านี้จะย้ายไปทั่วโลกและคัดลอกรหัสไปยังบอตอื่น ๆ ในขณะที่พยายามป้องกันไม่ให้บ็อตอื่นทำเช่นเดียวกัน Flagหนึ่งในคำสั่งที่เป็นไปได้คือไม่มี-op หากบอทมีFlagมากกว่าบอทอื่นFlagคุณก็จะได้คะแนน คุณชนะโดยมีคะแนนมากที่สุด

ทั้งหมดที่กล่าวมาเป็นจริงสำหรับความท้าทายสองประการที่ผ่านมา คราวนี้บอทจะสามารถเรียกใช้โค้ดหลายบรรทัดในเวลาเดียวกันได้

รุ่นยาว

API

บอททุกคนจะมี 24 บรรทัดโดยที่แต่ละบรรทัดอยู่ในรูปแบบต่อไปนี้:

$label command parameters //comments

เลเบลและข้อคิดเห็นเป็นทางเลือกและแต่ละคำสั่งมีพารามิเตอร์ที่แตกต่างกัน ทุกอย่างไม่คำนึงถึงขนาดตัวพิมพ์

พารามิเตอร์

พารามิเตอร์ถูกพิมพ์และสามารถอยู่ในรูปแบบต่อไปนี้:

  1. ค่าตั้งแต่ 0 ถึง 23
  2. ตัวแปร: A, B, C,D
  3. ค่าที่ใช้การเพิ่ม: A+3หรือ2+C
  4. บรรทัดของรหัสที่กำหนดโดยใช้#เครื่องหมาย ( #4จะแสดงถึงบรรทัดที่ 5 ในขณะที่#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ต้องเป็นหมายเลขบรรทัด หากVเป็นตัวแปรหรือค่าWจะต้องเป็นตัวแปร

ธง

ไม่ทำอะไรเลย

เริ่ม V

Vเริ่มหัวข้อใหม่ที่แนบมากับตัวแปร Vทันทีและในทางกลับกันในอนาคตด้ายจะรันคำสั่งในบรรทัด

หากVเชื่อมต่อกับเธรดแล้วคำสั่งนี้จะไม่ใช้งาน หากVเป็นตัวแปรของฝ่ายตรงข้ามฝ่ายตรงข้ามจะเริ่มด้ายที่แนบมากับตัวแปรนั้น

หยุด V

หยุดเธรดที่แนบกับตัวแปรVเมื่อสิ้นสุดเทิร์นนี้

ล็อค V

ป้องกันไม่ให้เส้นหรือตัวแปรVจากการถูกนำมาใช้ในทางใดทางหนึ่งLockนอกจากด้ายที่เรียกว่า โทรตามมาโดยปลดล็อคหัวข้อเดียวกันLock Vล็อคไม่สามารถเรียกใช้กับตัวแปรหรือเส้นของคู่ต่อสู้

ถ้า Cond VW

Condนี้จะทดสอบ ถ้าเงื่อนไขเป็นจริงแล้วมันจะย้ายตัวชี้ด้ายจำนวนบรรทัดมิฉะนั้นจะหมายเลขบรรทัดV Wบรรทัดนั้นจะถูกดำเนินการทันที

Conditionals สามารถX=Y, X<Y, !Xหรือ?X:

  1. X=Y ทดสอบว่าสองบรรทัดเป็นประเภทเดียวกันและจากบอทเดียวกันหรือไม่หรือคุณทดสอบว่าสองค่ามีค่าเท่ากันหรือไม่
  2. X<Yทดสอบว่าค่าXน้อยกว่าYหรือไม่
  3. !Xทดสอบว่าตัวแปรหรือบรรทัดXถูกล็อคหรือไม่ (คืนจริงถ้าล็อค)
  4. ?X ทดสอบว่าตัวแปรที่กำหนดมีเธรดติดอยู่หรือไม่

รายละเอียดเพิ่มเติม

การทำงานแบบมัลติเธรด

การกระทำประเภทเดียวกันจะดำเนินการในเวลาเดียวกัน การดำเนินการจะดำเนินการตามลำดับต่อไปนี้:

  1. ล็อค. หากมีหลายเธรดพยายามล็อกตัวแปรทั้งหมดจะล้มเหลว หากเธรดกำลังปลดล็อกตัวแปรขณะที่อีกอันพยายามล็อกตัวแปรนั้นจะยังคงถูกปลดล็อค

  2. เริ่มต้น หากมีหลายเธรดพยายามเริ่มเธรดกับตัวแปรมันจะนับเป็นการเริ่มต้นครั้งเดียว

  3. สำเนา. หากทั้งสองเธรดคัดลอกทั้งสองไปยังตัวแปรเดียวกันตัวแปรจะจบลงด้วยค่าสุ่ม หากพวกเขาทั้งคู่คัดลอกไปยังบรรทัดเดียวกันจะไม่ทำงาน หากเธรดคัดลอกไปยังตัวแปรเดียวกันอีกเธรดหนึ่งกำลังคัดลอกจากเธรดหลังจะคัดลอกค่าแบบสุ่ม หากทั้งสองเธรดกำลังคัดลอกจากตัวแปรเดียวกันทั้งสองเธรดจะทำงานได้ดี

  4. ถ้า. เงื่อนไขทั้งหมดจะถูกทดสอบพร้อมกันจากนั้นตัวแปรเธรดจะได้รับการอัปเดตหลังจากนั้น การเรียกใช้งานIfสามารถทำให้แอคชันที่มีลำดับความสำคัญสูงกว่าถูกเพิ่มเข้าไป การกระทำที่มีความสำคัญสูงจะถูกดำเนินการก่อนที่จะย้ายที่ผ่านมาในขณะที่การกระทำที่มีความสำคัญที่ต่ำกว่าจะดำเนินการหลังจากที่IfIf

  5. ย้าย. การเคลื่อนไหวหลายครั้งบนบอทเดียวกันจะย้ายบอทรวมของการเคลื่อนไหวทั้งหมด หากบอตหลายตัวจบลงที่จุดเดียวกันพวกมันจะกลับสู่จุดเริ่มต้น

  6. กลับ. การหมุนหลายครั้งบนบอทเดียวกันจะรวมกัน

  7. หยุด. คำสั่งหยุดหลายคำสั่งในตัวแปรเดียวกันจะนับเป็นการหยุดครั้งเดียว

รายละเอียดอื่น ๆ

เธรดเริ่มต้นของคุณเริ่มแนบกับDตัวแปร

Recursing กับIf(มีIfคำสั่งชี้ไปที่ตัวเอง) จะทำให้ ธ ปทของคุณจะทำอะไร

หากเธรดหยุดหลังจากล็อคการล็อคเหล่านั้นจะถูกปลดล็อค

การกระทำที่ใช้ตัวแปรหรือบรรทัดที่ถูกล็อคจะไม่ทำอะไรเลย

หากบอทสั้นกว่า 24 บรรทัดบรรทัดที่เหลือจะถูกเติมด้วย Flag

การดำเนินการเขียนในตัวแปรที่เชื่อมต่อกับเธรดเริ่มต้นจะทำให้เธรดเริ่มการทำงานโดยใช้ค่าใหม่เนื่องจากเธรดเริ่มการหมุนต่อไปนี้

บอทจะถูกวางไว้ในโลก toroidal ในรูปแบบต่อไปนี้:

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 แล้วในเธรดอื่นจะมีการย้าย A. การประเมินเป็น 0 หรือค่าสุ่มหรือการย้ายล้มเหลวหรือ ...
Sparr

เหมือนกันกับสิ่งที่เกิดขึ้นเมื่อเธรดมาถึงบรรทัดที่ถูกล็อกโดยเธรดอื่น มันเป็น noop หรือไม่? มันถูกข้ามไปหรือไม่
Sparr

"คัดลอก $ ป้าย A" ควรใช้งานได้หรือไม่ มันแปลว่า "คัดลอก # 11 A" ซึ่งไม่ถูกต้องและขัดข้องล่ามแทน "คัดลอก 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

ฉันอยากรู้เกี่ยวกับเงื่อนไขในเธรดของคุณ ! * # C ตรวจสอบว่าบรรทัด #C (C ของคุณ) เป้าหมายของคุณถูกล็อคใช่ไหม? มันมีประโยชน์อย่างไร
Sparr

@Sparr เธรดไม่ต้องเสียเวลาแทนที่บรรทัดของรหัสศัตรูด้วยการตั้งค่าสถานะถ้ามันถูกล็อค
TheNumberOne

ขอบคุณ ฉันอ่านสเป็กผิดครั้งแรกเกี่ยวกับความเร็วของคำสั่ง If
Sparr

3

DoubleTapBot

บอทนี้มี 3 เธรด: หนึ่งรายการสำหรับการย้าย (A), สองรายการสำหรับการตั้งค่าสถานะ (B และ D) B ธง 1/2 หัน, D ธง 1/3 เปิด ดังนั้นในบางครั้งเขาจะตั้งค่าสถานะของคู่ต่อสู้เป็นสองเท่า :)

ฉันคิดว่า C จะกลับมาเป็น 0 ถ้าเกิน 23

มันจะค่อนข้างปลอดภัยหากมีการเลี้ยวเพื่อเตรียมพร้อมตัวเอง (8 ตาแหน่ง) เนื่องจากเขาจะต้องทำงานอย่างน้อย 2 เธรด (A & B) ตามปกติ

ฉันไม่สามารถลองได้ในขณะนี้ดังนั้นฉันจะทำการทดสอบเมื่อฉันจะกลับบ้าน :)

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 

หมายเลขล็อคไม่ใช่คำสั่งที่ถูกต้อง ฉันใส่เครื่องหมาย # ไว้หน้าตัวเลขแต่ละตัว นอกจากนี้คำสั่งคือ "หมุน" ไม่ใช่ "หมุน"
นาธานเมอร์ริลล์

@NathanMerrill วิธีการที่เป็นพิมพ์ผิดลืม # ขอบคุณที่ชี้ให้เห็น และสำหรับเทิร์นให้แก้ไขโพสต์ของคุณดังนั้นคุณเขียน Turn V หมุน bot V * 90 องศาตามเข็มนาฬิกา :)
Katenkyo

โอ้ฉันทำ เทิร์นถูกต้องจริงจากนั้นฉันจะกลับไปและอัปเดตรหัส
Nathan Merrill

คุณกำลังล็อค 11,12,13 เมื่อคุณตั้งใจจะล็อค 10,11,12?
Sparr

ว้าวขอบคุณที่ชี้ให้เห็น!
Katenkyo

2

เครื่องเขียนแตะสองครั้งที่ล็อคอยู่กับที่

ได้รับแรงบันดาลใจจาก DoubleTapBot ของ @ Katenkyo คนนี้ยอมแพ้สองสามธงและมีความหวังว่าจะได้รับผลตอบแทนกลับคืนมาเพื่อล็อคกระทู้ของตัวเองอย่างสมบูรณ์ อย่างไรก็ตามมันยังคงเป็นที่ยอมรับได้ที่จะมีการเขียนธงศัตรูไว้ในส่วนของโค้ดที่ไม่วนลูป

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

ผู้เสนอญัตติแบบสุ่ม

เคลื่อนที่ไปในทิศทาง psuedorandom

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

บอทกล้วย

พยายามโยนกล้วยในวงล้อศัตรูก่อนที่ศัตรูจะทำอะไรได้ มีแนวโน้มที่จะถูก squished

$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 aha ขอบคุณ ฉันคิดถึงสิ่งนั้น
Sparr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.