Jika Anda pernah bermain Spacewar! , Anda tahu itu adalah permainan yang menyenangkan. Jika belum, ketahuilah: ini adalah salah satu game komputer pertama dan terpenting. Dan itu masih menyenangkan! Klon tempat saya dibesarkan adalah yang ini , yang ternyata, dan sayangnya, hanya Windows. Jadi saya membuatnya kembali!
KotH di-host di sini: PPCG - Spacewar! King of the Hill . Saya mendorong Anda untuk bermain sebagai manusia melawan setidaknya satu bot lain untuk merasakan bagaimana permainan bekerja.
Permainan
- Satu frame adalah 30 milidetik (dengan demikian, sekitar 33 frame per detik).
- Bidang ini memiliki lebar 800 piksel dan tinggi 600 piksel.
- Medan tersebut berbentuk toroidal, artinya pesawat ruang angkasa dan rudal yang bergerak di luar medan muncul kembali di sisi yang berlawanan.
- Ada dua pesawat ruang angkasa, merah dan biru.
- Merah diposisikan pada x = 50 dan acak y antara 50, (tinggi bidang - 50) piksel.
- Biru diposisikan pada x = (lebar bidang - 50) dan acak y antara 50, (tinggi bidang - 50) piksel.
- Kedua muka x = (lebar bidang) / 2.
- Kontrol yang tersedia adalah:
- Belok kiri - 5 derajat per frame berlawanan arah jarum jam.
- Belok kanan - 5 derajat per frame searah jarum jam.
- Rudal api - bergerak dengan tambahan 10 piksel per bingkai di samping kecepatan kapal, ke arah yang ditunjuk kapal.
- Mesin pemadam kebakaran - mempercepat pesawat ruang angkasa di 0,30 piksel per frame ke arah yang ditunjuk pesawat ruang angkasa.
- Hyperspace jump - teleport ke beberapa koordinat acak di lapangan, dengan peluang meledak 25%. Koordinat acak ini mungkin berada di atas matahari.
- Kecepatan maksimum untuk kapal adalah 15 piksel per frame di bawah tenaga mesin dan 40 piksel per frame saat gravitasi ditingkatkan.
- Saat bepergian lebih cepat dari 15 piksel per frame, dorongan mesin hanya dapat mengubah arah atau memperlambat.
- Mengenai rudal:
- Rudal bepergian dalam garis lurus.
- Rudal dapat ditembakkan pada kecepatan maksimum 1 per 0,1 detik.
- Rudal memiliki masa hidup 2,25 detik.
- Kapal masing-masing memiliki maksimal 20 rudal.
- Rudal adalah partikel titik internal.
- Ada matahari di tengah yang sangat berbahaya bagi kapal Anda. The sedikit kontak fatal. Matahari ini juga menghancurkan rudal.
- Matahari memiliki gravitasi. Akselerasi yang dihasilkan adalah 5000 / (jarak ^ 2) piksel / bingkai ^ 2, di mana jarak berada dalam piksel. Pesawat ruang angkasa dan rudal terpengaruh.
- Kedua kapal memiliki tiga zona serang: hidung, sayap kiri, dan sayap kanan.
- Pukulan pada hidung adalah kematian instan.
- Sebuah pukulan di kedua sayap mengurangi tingkat putaran pesawat ruang angkasa dan akselerasi mesin hingga setengahnya.
- Jika kedua sayap hancur, pesawat ruang angkasa tidak bisa bermanuver dan hanya bisa menembakkan rudal.
- Kapal-kapal mungkin saling bertabrakan.
- Tumbukan hidung-hidung itu fatal bagi kedua kapal.
- Tabrakan sayap hidung menghancurkan sayap.
- Tumbukan sayap menghancurkan kedua sayap.
- Kapal mati padat dan beku sampai meledak 1 detik kemudian.
- Setelah setidaknya satu kapal mati, lapangan direset 3 detik kemudian. Sampai saat itu, matahari dan rudal yang tersisa masih berbahaya.
Game aslinya juga memiliki asteroid yang mematikan dan tidak bisa dihancurkan, tetapi saya tidak akan memasukkannya.
Aturan
- Bot Anda harus ditulis dalam JavaScript.
- Bot Anda harus membatasi keputusannya hingga sekitar 10 milidetik. Jika saya melihat kelambatan yang konsisten karena bot Anda , saya akan mendiskualifikasi dan memberi tahu Anda agar Anda dapat memperbaikinya.
- Bot akan memiliki akses ke yang berikut:
- Lebar bidang dan tinggi bidang
- Posisi dan jari-jari matahari
- Posisi, rotasi, kecepatan, bentuk, stok rudal, dan status dalam-hyperspace dari kedua kapal
- Posisi dan kecepatan semua rudal
- Saat diminta, bot Anda harus mengembalikan daftar string.
- String ini harus menjadi salah satu dari berikut:
turn left
,turn right
,fire engine
,fire missile
,hyperspace
. String lain akan diabaikan. - Jika ada duplikat, hanya yang pertama yang akan dicatat.
hyperspace
didahulukan dari yang lainnya.turn left
danturn right
pada saat yang sama tidak akan berpengaruh.fire engine
tidak akan berpengaruh jika kapal hanya memiliki hidung atau mati.fire missile
tidak akan berpengaruh jika rudal ditembakkan terlalu baru.
- String ini harus menjadi salah satu dari berikut:
- Dalam perubahan dari biasanya, bot Anda diizinkan untuk mengeksploitasi perilaku bot lain. Saya ingin mendorong metagame.
- Bot tidak boleh meniru bot lain. (Yaitu, tidak membaca pikiran.)
- Bot tidak boleh mengatur variabel apa pun yang digunakan oleh game dan kode fisika. (Yaitu, tidak ada kecurangan.)
Detail Implementasi Bot
Saya akan menyimpan bot Anda di file JavaScript sendiri yang disertakan secara otomatis, dengan nama file bot_<name>.js
. Jadi jangan letakkan spasi atau karakter apa pun yang akan mengganggu ini atau dengan penamaan fungsi dalam JavaScript. Itu karena Anda harus mendefinisikan fungsi-fungsi berikut: <name>_setup(team)
dan <name>_getActions(gameInfo, botVars)
. Lebih jauh ke bawah halaman, ada textareas untuk userbot , yang dapat Anda edit untuk menguji kode Anda.
<name>_setup(team)
Fungsi ini untuk Anda menentukan variabel apa pun yang ingin Anda pertahankan. team
akan menjadi "red"
atau "blue"
. Fungsi ini harus mengembalikan objek. Definisikan variabel seperti:
var vars = {};
vars['example'] = "example";
return vars;
vars
Objek ini akan diteruskan ke fungsi lainnya:
<name>_getActions(gameInfo, botVars)
botVars
adalah objek yang dikembalikan oleh <name>_setup(team)
. gameInfo
adalah objek yang berisi variabel berikut:
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
Bot Anda memiliki akses penuh ke ini. Saya cukup yakin bahwa Anda dapat menulis kepada mereka dan tidak mempengaruhi variabel asli, tetapi jangan lakukan itu. Catatan tentang rotasi: kapal menunjuk ke arah + y, ke bawah, jadi apa pun yang ingin Anda selaraskan dengan kapal perlu diimbangi dengan 90 derajat. Juga, rotasi positif searah jarum jam.
Fungsi ini harus mengembalikan daftar string, mewakili tindakan bot Anda. Sebagai contoh ["turn right","thrust"]
,. Rincian lebih lanjut tentang ini ada di bagian Aturan .
detil tambahan
Anda juga dapat menggunakan yang berikut ini:
LineIntersection(L1, L2)
L1 dan L2 adalah array dua elemen dari array dua elemen. Yaitu, L1 := [[x1,y1],[x2,y2]]
dan L2 := [[u1,v1],[u2,v2]]
. Fungsi ini menghitung persimpangan dua garis dan mengembalikan ini: [[x,y], [a,b]]
. [x,y]
adalah koordinat dari titik persimpangan dan [a,b]
merupakan sepasang rasio yang menyatakan seberapa jauh sepanjang setiap garis titik persimpangan. Seperti dalam, a = 0.25
akan berarti bahwa titik persimpangan adalah seperempat jalan dari [x1,y1]
ke [x2,y2]
, dan juga untuk b
. Jika tidak ada persimpangan, array kosong dikembalikan.
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]]
};
Ini adalah koordinat poligon kapal. Untuk membuat mendapatkan koordinat saat ini lebih mudah, Anda juga dapat menggunakan ...
getShipCoords(<color>)
getShipCoords("red")
akan mengembalikan koordinat saat ini dari simpul kapal Merah, dan juga untuk getShipCoords("blue")
dan Biru. Koordinat ini berada dalam daftar seperti: [[x1,y1],[x2,y2],[x3,y3],...]
. Poligon tertutup secara implisit, jadi ada garis antara pasangan koordinat pertama dan terakhir.
Anda tidak boleh mengakses atau mengubah variabel atau fungsi lain apa pun yang digunakan oleh game / situs web. Dan jelas tidak menyebutkan fungsi Anda sama. Saya tidak melihat bahwa ini akan menjadi masalah, tetapi jika bot Anda melanggar kode permainan, itu satu kemungkinan. Tidak ada penebangan atau penangkapan pengecualian.
Kemenangan
- Setiap pasangan bot harus dimainkan setidaknya 10 kali, keduanya. (Jadi, setidaknya total 20 pertandingan.)
- Bertujuan untuk memiliki rasio win / loss tertinggi secara keseluruhan . Jika bot Anda bekerja sangat baik melawan satu bot lainnya, tetapi kalah melawan tiga bot lainnya, itu tidak sebagus menang melawan dua dan kalah melawan dua (seperti aturan umum).
- Untuk setiap bot, rasio (menang +1) / (kerugian +1) akan dihitung, maka rata-rata dan standar deviasi rasio ini akan dihitung. Rata-rata yang lebih tinggi akan memiliki prioritas, dan dalam hal rata-rata berada dalam 1 unit satu sama lain, varian yang lebih rendah akan memiliki prioritas.
- Penilaian akan dimulai dalam seminggu dari hari ini atau setelah tiga hari tanpa kiriman baru. Ini jadi saya tidak perlu mengulangi pasangan bot.
Yang terpenting, bersenang-senanglah!
Papan Peringkat (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
Catatan: Ini dapat berubah saat saya menjalankan lebih banyak game. Plus, urutan peringkat 9-13 mengganggu saya, jadi saya dapat mengubah metode penilaian agar lebih sesuai dengan intuisi seseorang tentang bagaimana peringkat mereka.
(Berarti dan standar deviasi dibulatkan menjadi tiga angka desimal. Juga, Hyper
harus HYPER
tapi itu mengacaukan penyorotan.: P)
LineIntersection
segmen yang tidak memotong akan mengembalikan array kosong.