หากคุณเคยเล่นSpacewar! คุณรู้ว่ามันเป็นเกมที่สนุก หากคุณยังไม่รู้ให้รู้เลยว่ามันเป็นเกมคอมพิวเตอร์เกมแรกและสำคัญที่สุดเกมหนึ่ง (และเป็น) และมันก็ยังสนุก! โคลนที่ฉันโตขึ้นมาคืออันนี้ซึ่งเห็นได้ชัดและน่าเสียดายที่ Windows เท่านั้น ดังนั้นฉันจึงสร้างมันขึ้นมาใหม่!
The KotH โฮสต์ที่นี่: PPCG - Spacewar! กษัตริย์ของเขา ฉันแนะนำให้คุณเล่นเป็นมนุษย์ต่อต้านบอทอย่างน้อยหนึ่งตัวเพื่อให้เข้าใจถึงวิธีการทำงานของเกม
เกม
- หนึ่งเฟรมคือ 30 มิลลิวินาที (ดังนั้นประมาณ 33 เฟรมต่อวินาที)
- ฟิลด์นี้มีความกว้าง 800 พิกเซลและสูง 600 พิกเซล
- สนามนั้นเป็นวงแหวนซึ่งหมายความว่ายานอวกาศและขีปนาวุธที่เคลื่อนที่ออกนอกสนามปรากฏขึ้นอีกด้านหนึ่ง
- ยานอวกาศมีสองสีคือสีแดงและสีน้ำเงิน
- สีแดงวางตำแหน่งที่ x = 50 และสุ่ม y ระหว่าง 50, (ความสูงของฟิลด์ - 50) พิกเซล
- สีน้ำเงินอยู่ในตำแหน่งที่ x = (ความกว้างของฟิลด์ - 50) และสุ่ม y ระหว่าง 50, (ความสูงของฟิลด์ - 50) พิกเซล
- ทั้งสองหน้า x = (ความกว้างของฟิลด์) / 2
- การควบคุมที่ใช้ได้คือ:
- เลี้ยวซ้าย - 5 องศาต่อกรอบทวนเข็มนาฬิกา
- เลี้ยวขวา - 5 องศาต่อกรอบตามเข็มนาฬิกา
- ขีปนาวุธไฟ - เดินทางด้วยความเร็ว 10 พิกเซลต่อเฟรมนอกเหนือจากความเร็วของเรือในทิศทางที่เรือกำลังชี้
- รถดับเพลิง - เร่งยานอวกาศที่ 0.30 พิกเซลต่อเฟรมในทิศทางที่ยานอวกาศชี้
- Hyperspace jump - เทเลพอร์ตไปยังพิกัดสุ่มในสนามโดยมีโอกาส 25% ในการระเบิด พิกัดสุ่มเหล่านี้อาจอยู่ด้านบนของดวงอาทิตย์
- ความเร็วสูงสุดของเรือรบคือ 15 พิกเซลต่อเฟรมภายใต้กำลังเครื่องยนต์และ 40 พิกเซลต่อเฟรมเมื่อเพิ่มแรงโน้มถ่วง
- เมื่อเดินทางเร็วกว่า 15 พิกเซลต่อเฟรมแรงขับของเครื่องยนต์อาจเปลี่ยนทิศทางหรือช้าลงเท่านั้น
- เกี่ยวกับขีปนาวุธ:
- ขีปนาวุธเดินทางเป็นเส้นตรง
- ขีปนาวุธอาจถูกยิงในอัตราสูงสุด 1 ต่อ 0.1 วินาที
- ขีปนาวุธมีอายุการใช้งาน 2.25 วินาที
- เรือแต่ละลำมีขีปนาวุธไม่เกิน 20 ลำ
- ขีปนาวุธเป็นอนุภาคจุดภายใน
- มีดวงอาทิตย์อยู่ตรงกลางซึ่งเป็นอันตรายอย่างยิ่งต่อเรือของคุณ การติดต่อเพียงเล็กน้อยนั้นเป็นอันตรายถึงชีวิต ดวงอาทิตย์นี้ยังทำลายขีปนาวุธ
- ดวงอาทิตย์มีแรงดึงดูด การเร่งความเร็วผลลัพธ์คือ 5000 / (ระยะทาง ^ 2) พิกเซล / เฟรม ^ 2 โดยที่ระยะทางเป็นพิกเซล ยานอวกาศและขีปนาวุธได้รับผลกระทบ
- เรือทั้งสองลำมีพื้นที่โจมตีสามส่วน: จมูก, ปีกซ้ายและปีกขวา
- การชกที่จมูกนั้นคือความตายทันที
- การโจมตีทั้งสองข้างจะช่วยลดอัตราการเลี้ยวของยานอวกาศและความเร่งของเครื่องยนต์ลงครึ่งหนึ่ง
- หากปีกทั้งสองถูกทำลายยานอวกาศจะไม่สามารถหลบหลีกและสามารถยิงขีปนาวุธได้
- เรืออาจชนกัน
- ผลกระทบจากจมูกจมูกนั้นร้ายแรงสำหรับเรือทั้งสองลำ
- การกระทบของปีกจมูกทำลายปีก
- ผลกระทบจากปีกหนึ่งข้างนั้นทำลายทั้งสองปีก
- เรือที่ตายแล้วนั้นจะแข็งและแข็งจนกระทั่งพวกมันจะระเบิด 1 วินาทีในภายหลัง
- หลังจากเรืออย่างน้อยหนึ่งลำเสียชีวิตสนามจะถูกรีเซ็ต 3 วินาทีในภายหลัง จนกว่าจะถึงตอนนั้นดวงอาทิตย์และขีปนาวุธที่เหลือก็ยังคงเป็นอันตราย
เกมดั้งเดิมยังมีดาวเคราะห์น้อยที่อันตรายและทำลายไม่ได้ แต่ฉันจะไม่รวมสิ่งเหล่านั้น
กฎระเบียบ
- บอตของคุณต้องเขียนด้วย JavaScript
- บอทของคุณควร จำกัด การตัดสินใจไว้ที่ประมาณ 10 มิลลิวินาที หากฉันสังเกตเห็นความล่าช้าที่สอดคล้องกันเนื่องจากบ็อตของคุณฉันจะตัดสิทธิ์และแจ้งให้คุณทราบเพื่อให้คุณสามารถแก้ไขได้
- บอตจะสามารถเข้าถึงสิ่งต่อไปนี้:
- ความกว้างของฟิลด์และความสูงของฟิลด์
- ตำแหน่งของดวงอาทิตย์และรัศมี
- ตำแหน่งการหมุนความเร็วรูปร่างสต็อกขีปนาวุธและสถานะอินเปอร์สเปซของเรือรบทั้งสองลำ
- ตำแหน่งและความเร็วของขีปนาวุธทั้งหมด
- เมื่อได้รับแจ้งบอตของคุณควรส่งคืนรายการสตริง
- สตริงเหล่านี้ควรจะเป็นหนึ่งต่อไปนี้:
turn left
,turn right
,fire engine
, ,fire missile
hyperspace
สตริงอื่น ๆ จะถูกละเว้น - หากมีการซ้ำซ้อนจะมีการจดบันทึกครั้งแรกเท่านั้น
hyperspace
จะมีความสำคัญมากกว่าคนอื่น ๆ ทั้งหมดturn left
และturn right
ในเวลาเดียวกันจะไม่มีผลกระทบfire engine
จะไม่มีผลกระทบหากเรือมีเพียงจมูกหรือตายfire missile
จะไม่มีผลใด ๆ หากมีการยิงขีปนาวุธเร็วเกินไป
- สตริงเหล่านี้ควรจะเป็นหนึ่งต่อไปนี้:
- ในการเปลี่ยนแปลงจากปกติบอทของคุณได้รับอนุญาตให้ใช้ประโยชน์จากพฤติกรรมของบอทอื่น ๆ ฉันต้องการส่งเสริม metagame
- บอตไม่สามารถเลียนแบบบ็อตอื่น ๆ (เช่นไม่มีการอ่านใจ)
- บอตไม่สามารถตั้งค่าตัวแปรใด ๆ ที่ใช้โดยเกมและรหัสฟิสิกส์ (เช่นไม่มีการโกง)
รายละเอียดการปฏิบัติ Bot
bot_<name>.js
ผมจะเก็บบอทของคุณในไฟล์จาวาสคริปต์ของตัวเองที่มีอยู่โดยอัตโนมัติที่มีชื่อไฟล์ ดังนั้นอย่าใส่ช่องว่างหรือตัวอักษรใด ๆ ที่จะเข้าไปยุ่งกับสิ่งนี้หรือตั้งชื่อฟังก์ชั่นใน JavaScript นั่นเป็นเพราะคุณควรกำหนดฟังก์ชั่นดังต่อไปนี้และ<name>_setup(team)
<name>_getActions(gameInfo, botVars)
ยิ่งไปกว่านั้นในหน้ามี textareas สำหรับuserbot อยู่ซึ่งคุณสามารถแก้ไขเพื่อทดสอบรหัสของคุณได้
<name>_setup(team)
ฟังก์ชั่นนี้มีไว้สำหรับให้คุณกำหนดตัวแปรใด ๆ ที่คุณต้องการคงอยู่ team
จะเป็นอย่างใดอย่างหนึ่งหรือ"red"
"blue"
ฟังก์ชั่นนี้จะต้องส่งคืนวัตถุ กำหนดตัวแปรดังนี้:
var vars = {};
vars['example'] = "example";
return vars;
vars
วัตถุนี้จะถูกส่งผ่านไปยังฟังก์ชั่นอื่น ๆ :
<name>_getActions(gameInfo, botVars)
botVars
<name>_setup(team)
เป็นวัตถุที่ส่งกลับโดย gameInfo
เป็นวัตถุที่มีตัวแปรดังต่อไปนี้:
redScore
blueScore
timeLeft
fieldWidth
fieldHeight
sun_x
sun_y
sun_r //sun's radius
gravityStrength //acceleration in pixels/frame^2 at 1 pixel away from the sun's center
engineThrust //acceleration in pixels/frame^2
speedLimit //maximum speed under engine power
maxSpeed //maximum speed from gravity boosts
red_x
red_y
red_rot //rotation in degrees
red_xv //x velocity
red_yv //y velocity
red_shape //one of "full ship", "left wing", "right wing", "nose only"
red_missileStock //the number of missiles red has left
red_inHyperspace //true if red is in hyperspace
red_exploded //until red explodes, it is still solid and hazardous
red_alive
// likewise for blue //
numMissiles
missiles //this is a list of objects, each with the following variables
x
y
xv
yv
บอทของคุณสามารถเข้าถึงสิ่งเหล่านี้ได้อย่างเต็มที่ ฉันค่อนข้างมั่นใจว่าคุณสามารถเขียนถึงพวกเขาและไม่ส่งผลกระทบต่อตัวแปรดั้งเดิม แต่ไม่ทำเช่นนั้น หมายเหตุเกี่ยวกับการหมุน:เรือรบชี้ไปที่ทิศทาง + y, ลงด้านล่างดังนั้นทุกสิ่งที่คุณต้องการจัดแนวกับยานจะต้องมีการชดเชย 90 องศา นอกจากนี้การหมุนในเชิงบวกตามเข็มนาฬิกา
ฟังก์ชั่นนี้จะต้องส่งคืนรายการสตริงที่แสดงถึงการกระทำของบอทของคุณ ตัวอย่างเช่น["turn right","thrust"]
. รายละเอียดเพิ่มเติมเกี่ยวกับสิ่งนี้อยู่ในส่วนของกฎ
รายละเอียดเพิ่มเติม
คุณอาจใช้สิ่งต่อไปนี้:
LineIntersection(L1, L2)
L1 และ L2 เป็นอาร์เรย์สององค์ประกอบของอาร์เรย์สององค์ประกอบ นั่นคือและL1 := [[x1,y1],[x2,y2]]
ฟังก์ชั่นนี้จะคำนวณจุดตัดของสองเส้นและผลตอบแทนนี้:L2 := [[u1,v1],[u2,v2]]
คือพิกัดของจุดตัดและเป็นอัตราส่วนคู่หนึ่งที่แสดงว่าจุดตัดกันแต่ละจุดนั้นยาวเท่าไหร่ ในขณะที่จะหมายความว่าจุดตัดเป็นหนึ่งในสี่ของวิธีการจากไปและเช่นเดียวกันสำหรับ หากไม่มีจุดตัดอาร์เรย์ว่างจะถูกส่งคืน[[x,y], [a,b]]
[x,y]
[a,b]
a = 0.25
[x1,y1]
[x2,y2]
b
window["shipShapes"]
var shipShapes = {
'full ship': [[-8,16],[0,-8],[8,16]],
'left wing': [[-8,16],[0,-8],[4,4],[0,8],[0,16]],
'right wing':[[-4,4],[0,-8],[8,16],[0,16],[0,8]],
'nose only': [[-4,4],[0,-8],[4,4],[0,8]]
};
นี่คือพิกัดของรูปหลายเหลี่ยมของเรือ เพื่อให้การรับพิกัดปัจจุบันง่ายขึ้นคุณอาจใช้ ...
getShipCoords(<color>)
getShipCoords("red")
จะส่งคืนพิกัดปัจจุบันของจุดยอดของเรือของ Red และเช่นเดียวกันกับgetShipCoords("blue")
และ Blue พิกัดเหล่านี้อยู่ในรายการดังนี้: [[x1,y1],[x2,y2],[x3,y3],...]
. รูปหลายเหลี่ยมถูกปิดโดยปริยายดังนั้นจึงมีเส้นแบ่งระหว่างคู่แรกและพิกัดสุดท้าย
คุณไม่สามารถเข้าถึงหรือแก้ไขตัวแปรหรือฟังก์ชั่นอื่น ๆ ที่ใช้งานโดยเกม / เว็บไซต์ และแน่นอนไม่ได้ตั้งชื่อฟังก์ชั่นของคุณเหมือนกัน ฉันไม่คิดว่านี่จะเป็นปัญหา แต่ถ้าบอตของคุณแตกรหัสเกม ไม่มีการบันทึกหรือตรวจจับข้อยกเว้น
การชนะ
- ทุกคู่ของบอทจะต้องเล่นอย่างน้อย 10 ครั้งทั้งสองวิธี (ดังนั้นอย่างน้อย 20 เกมทั้งหมด)
- มุ่งหวังที่จะมีอัตราส่วนแพ้ / ชนะสูงสุดโดยรวม หากบ็อตของคุณทำได้ดีมากเทียบกับบอทตัวอื่น แต่แพ้กับอีกบอทที่สามนั่นไม่ดีเท่าการชนะต่อสองและแพ้ต่อสอง (เหมือนกฎทั่วไปของหัวแม่มือ)
- ทุกบอทจะคำนวณอัตราส่วน (ชนะ + 1) / (ขาดทุน + 1) จากนั้นจะคำนวณค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐานของอัตราส่วนเหล่านี้ ค่าเฉลี่ยที่สูงกว่าจะมีลำดับความสำคัญและในกรณีที่ค่าเฉลี่ยอยู่ภายใน 1 หน่วยของกันและกันค่าความแปรปรวนต่ำกว่าจะมีลำดับความสำคัญ
- การให้คะแนนจะเริ่มในหนึ่งสัปดาห์นับจากวันนี้หรือหลังจากสามวันที่ไม่มีการส่งผลงานใหม่ นี่คือดังนั้นฉันไม่ต้องทำซ้ำการจับคู่ของบอท
เหนือสิ่งอื่นใดขอให้สนุก!
ลีดเดอร์บอร์ด (2016-01-08 05:15):
# Name Mean StdDev
1. Helios 13.625 6.852
2. EdgeCase 8.335 8.155
3. OpponentDodger 8.415 8.186
4. OrbitBot 5.110 6.294
5. SunAvoider 5.276 6.772
6. DangitBobby 3.320 4.423
7. SprayAndPray 3.118 4.642
8. Engineer 3.903 6.315
9. RighthandedSpasms 1.805 2.477
10. AttackAndComeBack 2.521 2.921
11. PanicAttack 2.622 3.102
12. FullSpeedAhead 2.058 3.295
13. UhhIDKWhatToCallThisBot 2.555 3.406
14. MissilesPlusScore 0.159 0.228
15. Hyper 0.236 0.332
16. RandUmmm 0.988 1.329
17. Kamikaze 0.781 1.793
หมายเหตุ:สิ่งนี้อาจเปลี่ยนแปลงได้เมื่อฉันเรียกใช้เกมมากขึ้น นอกจากนี้การเรียงลำดับ 9-13 ทำให้ฉันรำคาญใจดังนั้นฉันอาจปรับแต่งวิธีการให้คะแนนเพื่อให้ตรงกับสัญชาตญาณว่าควรจัดอันดับอย่างไร
(หมายถึงและส่วนเบี่ยงเบนมาตรฐานถูกปัดเศษเป็นทศนิยมสามหลักนอกจากนี้Hyper
ควรเป็นเช่นHYPER
นั้น แต่จะทำให้การไฮไลต์ยุ่งเหยิง: P)
LineIntersection
ที่ไม่ตัดกันจะส่งคืนอาร์เรย์ว่าง