พื้นหลังในอนาคต
ในปี 2560 คุณและคู่ต่อสู้ของคุณจะเผชิญหน้ากันในการต่อสู้ด้วยปืนแห่งอนาคต อยู่ที่คุณมีประสบการณ์มากพอที่จะเอาชนะฝ่ายตรงข้ามของคุณหรือไม่ ตอนนี้เป็นเวลาที่จะขัดเกลาทักษะปืนของคุณในภาษาการเขียนโปรแกรมที่คุณชื่นชอบและต่อสู้กับราคาทั้งหมด!
ผลการแข่งขัน
การแข่งขันครั้งนี้สิ้นสุดลงในช่วงเช้าของ UTC กุมภาพันธ์ 2 ครั้ง 2017 ขอขอบคุณผู้เข้าแข่งขันของเราเรามีการแข่งขันมากมายที่น่าตื่นเต้น!
MontePlayer เป็นผู้ชนะคนสุดท้ายหลังจากการต่อสู้อย่างใกล้ชิดกับ CBetaPlayer และ StudiousPlayer นักสู้ guen duelers ทั้งสามคนได้ถ่ายรูปที่ระลึก:
MontePlayer - by TheNumberOne
+------------+
CBetaPlayer | | - by George V. Williams
+------------+ # 1 | StudiousPlayer - by H Walters
| +----------------+
| # 2 # 3 |
+------------------------------------------+
The Futurustic Gun Duel @ PPCG.SE 2017
ขอแสดงความยินดีกับผู้ชนะ! กระดานแต้มนำแบบละเอียดมีให้เห็นในตอนท้ายของโพสต์นี้
คำแนะนำทั่วไป
- เยี่ยมชมพื้นที่เก็บข้อมูลอย่างเป็นทางการสำหรับซอร์สโค้ดที่ใช้ในทัวร์นาเมนต์นี้
- รายการ C ++: โปรดรับ
Player
ชั้นเรียน - องค์กรไม่แสวงหา c ++ รายการ: เลือกหนึ่งในอินเตอร์เฟซในส่วนอินเตอร์เฟซสำหรับการส่ง ++-C บุหรี่
- ขณะนี้ไม่อนุญาตให้ใช้ภาษา C ++: Python 3, Java
การดวล
- ผู้เล่นแต่ละคนเริ่มด้วยปืนที่ไม่บรรจุกระสุนซึ่งสามารถบรรจุกระสุนได้ไม่ จำกัด
- แต่ละเทิร์นผู้เล่นจะเลือกจากหนึ่งในการกระทำต่อไปนี้:
0
- บรรจุกระสุน 1 นัดเข้าไปในปืน1
- ยิงกระสุนใส่ฝ่ายตรงข้าม; ราคากระสุน 1 นัด2
- ยิงลำแสงพลาสม่าที่ฝ่ายตรงข้าม; ราคากระสุน 2 นัด-
- ป้องกันกระสุนที่เข้ามาโดยใช้โล่โลหะ=
- ป้องกันลำแสงพลาสม่าที่เข้ามาโดยใช้ตัวกระจายความร้อน
- หากผู้เล่นทั้งสองอยู่รอดหลังจากที่ 100 วันที่กลับกันพวกเขาทั้งไอเสียไปสู่ความตายซึ่งผลในการวาด
ผู้เล่นแพ้ปืนดวลหากพวกเขา
- ไม่ไม่ใช้โล่โลหะเพื่อป้องกันกระสุนเข้า
- ไม่ไม่ใช้ความร้อนดันเพื่อปกป้องพลาสม่าที่เข้ามา
- ยิงปืนโดยไม่โหลดกระสุนเพียงพอซึ่งปืนของพวกเขาจะระเบิดเองและฆ่าเจ้าของ
คำเตือน
ตามคู่มือสำหรับเจ้าของปืนแห่งอนาคต :
- โล่โลหะไม่สามารถป้องกันจากลำแสงพลาสมาที่เข้ามา ในทำนองเดียวกันตัวป้องกันความร้อนไม่สามารถป้องกันจากกระสุนที่เข้ามา
- ลำแสงพลาสม่ามีพลังเหนือกระสุน (เพราะในอดีตต้องการกระสุนที่โหลดมากกว่า) ดังนั้นหากผู้เล่นยิงลำแสงพลาสม่าที่ฝ่ายตรงข้ามที่ยิงกระสุนในตาเดียวกันผู้แข่งขันจะถูกฆ่า
- หากผู้เล่นทั้งสองยิงกระสุนใส่กันในเทิร์นเดียวกันกระสุนจะถูกยกเลิกและผู้เล่นทั้งสองจะมีชีวิตรอด ในทำนองเดียวกันหากผู้เล่นทั้งสองยิงลำแสงพลาสม่าไปด้วยกันในตาเดียวผู้เล่นทั้งสองจะมีชีวิตรอด
เป็นที่น่าสังเกตว่า:
- คุณจะไม่ทราบว่าการกระทำของฝ่ายตรงข้ามในทางกลับกันจนกว่ามันจะจบลง
- การเบี่ยงเบนลำแสงพลาสมาและกระสุนป้องกันจะไม่เป็นอันตรายต่อคู่ต่อสู้ของคุณ
ดังนั้นจึงมีการรวมการกระทำที่ถูกต้องรวม 25 รายการในแต่ละเทิร์น:
+-------------+---------------------------------------------+
| Outcome | P L A Y E R B |
| Table +--------+-----------------+------------------+
| for Players | Load | Bullet Plasma | Metal Thermal |
+---+---------+--------+--------+--------+--------+---------+
| P | Load | | B wins | B wins | | |
| L +---------+--------+--------+--------+--------+---------+
| A | Bullet | A wins | | B wins | | A wins |
| Y | +--------+--------+--------+--------+---------+
| E | Plasma | A wins | A wins | | A wins | |
| R +---------+--------+--------+--------+--------+---------+
| | Metal | | | B wins | | |
| | +--------+--------+--------+--------+---------+
| A | Thermal | | B wins | | | |
+---+---------+--------+--------+---------------------------+
Note: Blank cells indicate that both players survive to the next turn.
ตัวอย่างการต่อสู้
นี่คือการต่อสู้ที่ฉันเคยมีกับเพื่อน ย้อนกลับไปตอนนั้นเราไม่ค่อยรู้เรื่องการเขียนโปรแกรมมากนักดังนั้นเราจึงใช้ท่าทางมือและส่งสัญญาณด้วยความเร็วสองรอบต่อวินาที จากซ้ายไปขวาการกระทำของเรากลับ:
Me: 001-000-1201101001----2
Friend: 00-10-=1-==--0100-1---1
ตามกฎข้างต้นฉันแพ้ คุณเห็นเหตุผลไหม นั่นเป็นเพราะฉันยิงลำแสงพลาสมาสุดท้ายเมื่อฉันมีกระสุนเพียง 1 นัดเท่านั้นทำให้ปืนของฉันระเบิด
ผู้เล่น C ++
คุณในฐานะโปรแกรมเมอร์แห่งอนาคตผู้มีอารยธรรมจะไม่จัดการกับปืนโดยตรง แต่คุณต้องเขียนรหัสPlayer
ที่ต่อสู้กับคนอื่นแทน โดยการสืบทอดคลาสc ++ แบบสาธารณะในโครงการ GitHub คุณสามารถเริ่มเขียนคำอธิบายแผนภูมิในเมืองของคุณได้
Player.hpp can be found in Tournament\Player.hpp
An example of a derived class can be found in Tournament\CustomPlayer.hpp
สิ่งที่คุณต้องหรือสามารถทำ
- คุณต้องสืบทอด
Player
คลาสผ่านการสืบทอดสาธารณะและประกาศคลาสของคุณเป็นครั้งสุดท้าย - คุณต้องลบล้าง
Player::fight
ซึ่งจะคืนค่าที่ถูกต้องPlayer::Action
ทุกครั้งที่มีการเรียกใช้ - อีกทางเลือกหนึ่งแทนที่
Player::perceive
และPlayer::declared
คอยจับตาดูการกระทำของคู่ต่อสู้และติดตามชัยชนะของคุณ - คุณสามารถใช้สมาชิกคงที่ส่วนตัวและวิธีการในชั้นเรียนของคุณเพื่อทำการคำนวณที่ซับซ้อนมากขึ้น
- เลือกใช้ไลบรารีมาตรฐาน C ++ อื่น ๆ
สิ่งที่คุณต้องไม่ทำ
- คุณต้องไม่ใช้วิธีการโดยตรงใด ๆ ในการจดจำคู่ต่อสู้ของคุณนอกเหนือจากตัวระบุของคู่ต่อสู้ที่กำหนดซึ่งจะสับในตอนเริ่มต้นของแต่ละทัวร์นาเมนต์ คุณได้รับอนุญาตเท่านั้นที่จะเดาได้ว่าผู้เล่นคนใดที่ผ่านการเล่นเกมในทัวร์นาเมนต์
- คุณจะต้องไม่แทนที่วิธีการใด ๆ ใน
Player
ชั้นเรียนที่ไม่ได้ประกาศเสมือน - คุณต้องไม่ประกาศหรือเริ่มต้นสิ่งใดในขอบเขตส่วนกลาง
- ตั้งแต่การเดบิวต์ของ (ตอนนี้ถูกตัดสิทธิ์)
BlackHatPlayer
ผู้เล่นจะไม่ได้รับอนุญาตให้มองหรือแก้ไขสถานะของฝ่ายตรงข้ามของคุณ
ตัวอย่างการต่อสู้
กระบวนการของการดวลปืนดำเนินการโดยใช้GunDuel
คลาส สำหรับการต่อสู้ตัวอย่างเช่นดูSource.cpp
ในส่วนของการเริ่มต้นการต่อสู้
เราแสดงGunClubPlayer
, HumanPlayer
และGunDuel
ชั้นซึ่งสามารถพบได้ในTournament\
ไดเรกทอรีของพื้นที่เก็บข้อมูล
ในการต่อสู้แต่ละครั้งGunClubPlayer
จะโหลดกระสุน ยิงมัน ล้างและทำซ้ำ ในทุกเทิร์นHumanPlayer
จะแจ้งให้คุณสำหรับการกระทำที่จะเล่นกับฝ่ายตรงข้ามของคุณ ควบคุมด้วยแป้นพิมพ์ของคุณมีตัวละคร0
, 1
, 2
, และ-
=
บน Windows คุณสามารถใช้HumanPlayer
เพื่อดีบักการส่งของคุณ
เริ่มต้นการต่อสู้
นี่คือวิธีที่คุณสามารถดีบักเครื่องเล่นของคุณผ่านทางคอนโซล
// Source.cpp
// An example duel between a HumanPlayer and GunClubPlayer.
#include "HumanPlayer.hpp"
#include "GunClubPlayer.hpp"
#include "GunDuel.hpp"
int main()
{
// Total number of turns per duel.
size_t duelLength = 100;
// Player identifier 1: HumanPlayer.
HumanPlayer human(2);
// Player identifier 2: GunClubPlayer.
GunClubPlayer gunClub(1);
// Prepares a duel.
GunDuel duel(human, gunClub, duelLength);
// Start a duel.
duel.fight();
}
เกมตัวอย่าง
จำนวนน้อยที่สุดของผลัดที่คุณจำเป็นต้องพ่ายแพ้GunClubPlayer
เป็น 3. นี่คือรีเพลย์จากการเล่นกับ0-1
GunClubPlayer
จำนวนใน paranthesis คือจำนวนกระสุนที่บรรจุกระสุนสำหรับผู้เล่นแต่ละคนเมื่อการเลี้ยวสิ้นสุดลง
:: Turn 0
You [0/12/-=] >> [0] load ammo (1 ammo)
Opponent selects [0] load ammo (1 ammo)
:: Turn 1
You [0/12/-=] >> [-] defend using metal shield (1 ammo)
Opponent selects [1] fire a bullet (0 ammo)
:: Turn 2
You [0/12/-=] >> [1] fire a bullet (0 ammo)
Opponent selects [0] load ammo (1 ammo)
:: You won after 3 turns!
:: Replay
YOU 0-1
FOE 010
Press any key to continue . . .
วิธีที่เร็วที่สุดที่จะเอาชนะได้โดยGunClubPlayer
ไม่ทำการเคลื่อนไหวที่ไม่ถูกต้องคือลำดับ0=
เนื่องจากกระสุนยิงผ่านตัวกระจายความร้อน การเล่นซ้ำคือ
:: Turn 0
You [0/12/-=] >> [0] load ammo (1 ammo)
Opponent selects [0] load ammo (1 ammo)
:: Turn 1
You [0/12/-=] >> [=] defend using thermal deflector (1 ammo)
Opponent selects [1] fire a bullet (0 ammo)
:: You lost after 2 turns!
:: Replay
YOU 0=
FOE 01
Press any key to continue . . .
การแข่งขัน
การแข่งขันเป็นไปตามรูปแบบ "สถานะผู้เล่นคนสุดท้าย" ในทัวร์นาเมนต์การส่งที่ถูกต้องทั้งหมด (รวมถึงGunClubPlayer
) จะอยู่ในกลุ่ม การส่งแต่ละครั้งจะถูกกำหนดตัวระบุแบบสุ่ม แต่ไม่ซ้ำกันที่จะยังคงเหมือนเดิมในระหว่างการแข่งขันทั้งหมด ในแต่ละรอบ:
- การส่งแต่ละครั้งเริ่มต้นด้วย 0 คะแนนและจะเล่น 100 ดวลกับการส่งอื่น ๆ
- การต่อสู้เพื่อชัยชนะแต่ละครั้งจะมอบ 1 แต้ม การวาดและการสูญเสียให้ 0 คะแนน
- ในตอนท้ายของรอบการส่งที่มีคะแนนขั้นต่ำออกจากการแข่งขัน ในกรณีที่เสมอกันผู้เล่นที่มีคะแนนน้อยที่สุดจะได้รับตั้งแต่เริ่มต้นการแข่งขัน
- หากมีผู้เล่นมากกว่าหนึ่งคนรอบต่อไปจะเริ่มขึ้น
- คะแนนจะไม่นำไปสู่รอบต่อไป
ส่ง
คุณจะส่งผู้เล่นหนึ่งคนต่อคำตอบ คุณสามารถส่งหลายไฟล์สำหรับผู้เล่นตราบใดที่พวกเขาไม่ได้ยุ่งเกี่ยวกับการส่งอื่น ๆ หากต้องการให้สิ่งต่าง ๆ ราบรื่นโปรด:
- ชื่อไฟล์ส่วนหัวหลักของคุณเป็น
<Custom>Player.hpp
, - ชื่อไฟล์อื่น ๆ ของคุณเป็น
<Custom>Player*.*
เช่นMyLittlePlayer.txt
ถ้าชื่อชั้นของคุณMyLittlePlayer
หรือถ้าชื่อชั้นของคุณEmoPlayerHates.cpp
EmoPlayer
- หากชื่อของคุณมี
Shooter
หรือคำที่คล้ายกันที่เหมาะสมกับบริบทของทัวร์นาเมนต์นี้คุณไม่จำเป็นต้องเพิ่มPlayer
ในตอนท้าย ถ้าคุณรู้สึกอย่างแรงกล้าว่าชื่อส่งของคุณทำงานได้ดีขึ้นโดยไม่ต้องต่อท้ายคุณยังไม่จำเป็นต้องเพิ่มPlayer
Player
- ตรวจสอบให้แน่ใจว่าโค้ดของคุณสามารถรวบรวมและเชื่อมโยงกับ Windows ได้
คุณสามารถแสดงความคิดเห็นเพื่อขอคำชี้แจงหรือจุดช่องโหว่ หวังว่าคุณจะสนุกไปกับการดวลปืนแห่งอนาคตและขอให้คุณมีความสุขในปีใหม่!
การอธิบาย
- คุณได้รับอนุญาตให้มีพฤติกรรมแบบสุ่ม
- การกระทำที่ไม่ถูกต้อง (อนุญาตเมื่อกระสุนถูกโหลดไม่เพียงพอ)
- หากผู้เล่นทำการป้อนที่ไม่ถูกต้องปืนของพวกเขาจะระเบิดทันที
- คุณได้รับอนุญาตให้ศึกษาคำตอบ
- คุณได้รับอนุญาตอย่างชัดเจนให้บันทึกพฤติกรรมของคู่ต่อสู้ในแต่ละทัวร์นาเมนต์
- ในแต่ละรอบคุณจะเล่น 100 ดวลต่อคู่ต่อสู้แต่ละคู่ อย่างไรก็ตามคำสั่งของการดวล 100 ครั้งนั้นถูกสุ่ม - คุณไม่ได้รับประกันว่าจะต่อสู้กับคู่ต่อสู้ 100 คู่ต่อเนื่องกัน
แหล่งข้อมูลเพิ่มเติม
@flawr แปลแหล่ง C ++ ที่ให้มาลงใน Javaเป็นการอ้างอิงหากคุณต้องการส่งรายการ C ++
อินเตอร์เฟสสำหรับการส่งที่ไม่ใช่ C ++
ปัจจุบันได้รับการยอมรับ: Python 3, Java
โปรดปฏิบัติตามหนึ่งในข้อกำหนดด้านล่าง:
สเปคอินเตอร์เฟซ 1: รหัสทางออก
การส่งของคุณจะทำงานหนึ่งครั้งต่อเทิร์น
Expected Command Line Argument Format:
<opponent-id> <turn> <status> <ammo> <ammo-opponent> <history> <history-opponent>
Expected Return Code: The ASCII value of a valid action character.
'0' = 48, '1' = 49, '2' = 50, '-' = 45, '=' = 61
<opponent-id> is an integer in [0, N), where N is size of tournament.
<turn> is 0-based.
If duel is in progress, <status> is 3.
If duel is draw / won / lost, <status> is 0 / 1 / 2.
<history> and <history-opponent> are strings of actions, e.g. 002 0-=
If turn is 0, <history> and <history-opponent> are not provided.
You can ignore arguments you don't particularly need.
คุณสามารถทดสอบการส่งของคุณในPythonPlayer\
และJavaPlayer\
ไดเรกทอรี
ข้อมูลจำเพาะอินเตอร์เฟส 2: stdin / stdout
(ให้เครดิตกับ H Walters)
การส่งของคุณจะทำงานหนึ่งครั้งต่อทัวร์นาเมนต์
มีข้อกำหนดที่แน่นอนสำหรับรายการทั้งหมดเกี่ยวกับวิธีการทำ I / O เนื่องจากทั้ง stdin และ stdout เชื่อมต่อกับไดรเวอร์ทัวร์นาเมนต์ การละเมิดสิ่งนี้อาจนำไปสู่การหยุดชะงัก รายการทั้งหมดต้องเป็นไปตามอัลกอริทึมที่แน่นอนนี้(ในรหัสหลอก):
LOOP FOREVER
READ LINE INTO L
IF (LEFT(L,1) == 'I')
INITIALIZE ROUND
// i.e., set your/opponent ammo to 0, if tracking them
// Note: The entire line at this point is a unique id per opponent;
// optionally track this as well.
CONTINUE LOOP
ELSE IF (LEFT(L,1) == 'F')
WRITELN F // where F is your move
ELSE IF (LEFT(L,1) == 'P')
PROCESS MID(L,2,1) // optionally perceive your opponent's action.
END IF
CONTINUE LOOP
QUIT
นี่เรนไฮน์เป็นหนึ่ง0
, 1
, 2
, -
หรือสำหรับ=
load / bullet / plasma / metal / thermal
กระบวนการหมายถึงการตอบสนองทางเลือกกับสิ่งที่คู่ต่อสู้ทำ (รวมถึงการติดตามกระสุนของฝ่ายตรงข้ามหากคุณทำเช่นนี้) โปรดทราบว่าการกระทำของฝ่ายตรงข้ามก็เป็นหนึ่งใน '0', '1', '2', '-' หรือ '=' และอยู่ในตัวละครที่สอง
สกอร์บอร์ดสุดท้าย
08:02 AM Tuesday, February 2, 2017 Coordinated Universal Time (UTC)
| Player | Language | Points | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|:------------------ |:---------- | ------:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:|
| MontePlayer | C++ | 11413 | 1415 | 1326 | 1247 | 1106 | 1049 | 942 | 845 | 754 | 685 | 555 | 482 | 381 | 287 | 163 | 115 | 61 |
| CBetaPlayer | C++ | 7014 | 855 | 755 | 706 | 683 | 611 | 593 | 513 | 470 | 414 | 371 | 309 | 251 | 192 | 143 | 109 | 39 |
| StudiousPlayer | C++ | 10014 | 1324 | 1233 | 1125 | 1015 | 907 | 843 | 763 | 635 | 555 | 478 | 403 | 300 | 201 | 156 | 76 |
| FatedPlayer | C++ | 6222 | 745 | 683 | 621 | 655 | 605 | 508 | 494 | 456 | 395 | 317 | 241 | 197 | 167 | 138 |
| HanSoloPlayer | C++ | 5524 | 748 | 668 | 584 | 523 | 490 | 477 | 455 | 403 | 335 | 293 | 209 | 186 | 153 |
| SurvivorPlayer | C++ | 5384 | 769 | 790 | 667 | 574 | 465 | 402 | 354 | 338 | 294 | 290 | 256 | 185 |
| SpecificPlayer | C++ | 5316 | 845 | 752 | 669 | 559 | 488 | 427 | 387 | 386 | 340 | 263 | 200 |
| DeceptivePlayer | C++ | 4187 | 559 | 445 | 464 | 474 | 462 | 442 | 438 | 369 | 301 | 233 |
| NotSoPatientPlayer | C++ | 5105 | 931 | 832 | 742 | 626 | 515 | 469 | 352 | 357 | 281 |
| BarricadePlayer | C++ | 4171 | 661 | 677 | 614 | 567 | 527 | 415 | 378 | 332 |
| BotRobotPlayer | C++ | 3381 | 607 | 510 | 523 | 499 | 496 | 425 | 321 |
| SadisticShooter | C++ | 3826 | 905 | 780 | 686 | 590 | 475 | 390 |
| TurtlePlayer | C++ | 3047 | 754 | 722 | 608 | 539 | 424 |
| CamtoPlayer | C++ | 2308 | 725 | 641 | 537 | 405 |
| OpportunistPlayer | C++ | 1173 | 426 | 420 | 327 |
| GunClubPlayer | C++ | 888 | 500 | 388 |
| PlasmaPlayer | C++ | 399 | 399 |
การแข่งขันจะมีอายุจนถึง1 กุมภาพันธ์ 2017เว้นแต่จะระบุไว้เป็นอย่างอื่น
Player
การใช้งานที่เรียกใช้กระบวนการอื่นเพื่อคำนวณการเลี้ยวในปัจจุบัน ซึ่งจะช่วยให้ผู้คนมีส่วนร่วมในภาษาใด ๆ ที่คุณยินดีที่จะทำงานบนเครื่อง
Player::fight
'/' คุณสามารถได้รับมรดกPlayer::perceive
" ... ในทั้งสองกรณีคำคือแทนที่ไม่ได้รับมรดก
GunDuel.hpp
ทั้งในvalidA
และvalidB
ใช้actionA