Ayo perang tank!
Sebagian terinspirasi oleh Hancurkan Mereka Dengan Lazers
Objektif
Tugas Anda adalah mengendalikan sebuah tangki. Bergerak dan tembak tank dan rintangan lain di medan perang 2D. Posisi tank terakhir akan menjadi pemenang!
Format peta
Tangki Anda akan berada di lapangan 2D didasarkan pada n
oleh n
jaringan unit kotak. Saya akan memutuskan apa n
yang didasarkan pada jumlah pengiriman. Setiap kotak hanya dapat berisi satu dari:
- Sebuah tank
- Pohon
- Sebuah batu
- Dinding
- Tidak ada
Semua rintangan dan tank sepenuhnya mengisi ruang mereka, dan mereka memblokir semua tembakan yang mengenai mereka untuk merusak barang-barang lebih jauh.
Berikut adalah contoh bidang dengan #
= tangki; T
= pohon; R
= batu; W
= dinding; .
= tidak ada dengan n
= 10
.....#....
..T....R..
WWW...WWWW
W......T..
T...R...Ww
W...W.....
W....W...T
WWWWWW...R
W.........
WWWWWWRT..
Koordinat berada dalam format di x, y
mana x
peningkatan dari kiri ke kanan dan y
naik dari bawah ke atas. Ruang kiri bawah memiliki koordinat0, 0
. Setiap tangki dapat bergerak ke ruang kosong apa pun dan menembak ke segala arah.
Dinamika Peta
Tank Anda tidak hanya harus menembak tank lain! Jika menembak sesuatu di peta, hal-hal bisa terjadi.
- Jika dinding tertembak, ia akan dihancurkan setelah beberapa tembakan, mulai dari 1 hingga 4
- Jika pohon ditembaki, ia akan segera dihancurkan
- Jika batu ditembak, tembakan akan melewatinya dan merusak benda berikutnya yang terkena
Setelah sesuatu dihancurkan, ia tidak lagi ada di peta (tidak akan diganti dengan apa pun). Jika tembakan menghancurkan penghalang, itu akan diblokir dan tidak akan merusak apa pun lebih jauh di sepanjang jalannya.
Dinamika tangki
Setiap tangki dimulai dengan life
= 100. Setiap tembakan di tangki akan mengurangi 20-30 life
berdasarkan jarak. Hal ini dapat dihitung dengan delta_life=-30+(shot_distance*10/diagonal_map_length)
(di mana diagonal_map_length
adalah (n-1)*sqrt(2)
). Selain itu, setiap tangki meregenerasi 1 life
per putaran.
Ternyata
Beberapa putaran akan dijalankan (saya akan memutuskan begitu saya memiliki kiriman). Di awal setiap putaran, peta akan dibuat secara acak, dan tank akan ditempatkan di sana di lokasi kosong acak. Selama setiap putaran, setiap tangki akan diberikan giliran, dalam urutan acak. Setelah setiap tangki diberikan putaran, mereka akan diberikan putaran lagi dalam urutan yang sama. Putaran berlanjut sampai hanya ada satu tangki yang tersisa. Tank itu akan menjadi pemenang, dan mereka akan menerima 1 poin. Pertandingan kemudian akan berlanjut ke babak berikutnya.
Setelah semua putaran telah dijalankan, saya akan memposting skor pada pertanyaan ini.
Selama giliran tangki, itu mungkin melakukan salah satu dari berikut ini
- Bergerak hingga 3 spasi dalam satu arah, baik secara horizontal maupun vertikal. Jika tangki terhalang oleh rintangan atau tangki lain, itu akan dipindahkan sejauh mungkin tanpa melalui rintangan atau tangki.
- Bidik dalam arah tertentu, diwakili oleh sudut titik mengambang dalam derajat. Sumbu x ruang lokal tangki Anda (horizontal kiri ke kanan, alias timur atau
TurnAction.Direction.EAST
) adalah 0 derajat, dan sudut bertambah berlawanan arah jarum jam. Bidikan tidak akurat, dan sudut pengambilan gambar yang sebenarnya mungkin 5 derajat lebih besar atau kurang dari sudut yang Anda pilih. - Tidak melakukan apapun.
Gilirannya tidak terbatas dalam waktu, tetapi ini tidak berarti Anda dapat dengan sengaja membuang waktu untuk menutup semuanya.
Pengajuan / Protokol
Setiap program yang dikirimkan akan mengendalikan satu tangki di lapangan. Program kontrol ada di Java, jadi program Anda harus di Java untuk saat ini (saya mungkin akan menulis pembungkus untuk bahasa lain di beberapa titik, atau Anda bisa menulis sendiri).
Program Anda akan mengimplementasikan Tank
antarmuka, yang memiliki metode berikut:
public interface Tank {
// Called when the tank is placed on the battlefield.
public void onSpawn(Battlefield field, MapPoint position);
// Called to get an action for the tank on each turn.
public TurnAction onTurn(Battlefield field, MapPoint position, float health);
// Called with feedback after a turn is executed.
// newPosition and hit will be populated if applicable.
public void turnFeedback(MapPoint newPosition, FieldObjectType hit);
// Called when the tank is destroyed, either by another tank,
// or because the tank won. The won parameter indicates this.
public void onDestroyed(Battlefield field, boolean won);
// Return a unique name for your tank here.
public String getName();
}
The Battlefield
kelas berisi array 2D obyek ( Battlefield.FIELD_SIZE
oleh Battlefield.FIELD_SIZE
) yang mewakili hal-hal di medan perang. Battlefield.getObjectTypeAt(...)
akan memberikan FieldObjectType
untuk objek pada koordinat yang ditentukan (salah satu FieldObjectType.ROCK
, FieldObjectType.TREE
, FieldObjectType.TANK
, FieldObjectType.WALL
, atau FieldObjectType.NOTHING
). Jika Anda mencoba untuk mendapatkan objek di luar jangkauan peta (koordinat <0 atau> = Battlefield.FIELD_SIZE
) maka sebuah IllegalArgumentException
akan dilempar.
MapPoint
adalah kelas untuk menentukan titik pada peta. Gunakan MapPoint.getX()
dan MapPoint.getY()
untuk mengakses koordinat.
EDIT: Beberapa metode utilitas telah ditambahkan: MapPoint.distanceTo(MapPoint)
, MapPoint.angleBetween(MapPoint)
, Battlefield.find(FieldObjectType)
, dan TurnAction.createShootActionRadians(double)
seperti yang disarankan oleh Wasmoo .
Info lebih lanjut dapat ditemukan di javadocs, lihat bagian di bawah.
Semua kelas (API publik) berada di bawah paket zove.ppcg.tankwar
.
Program Kontrol
Sumber lengkap dan javadocs dari program kontrol dan API tangki dapat ditemukan di repo GitHub saya: https://github.com/Hungary-Dude/TankWarControl
Jangan ragu untuk mengirim permintaan tarik dan / atau komentar jika Anda melihat bug atau ingin peningkatan.
Saya telah menulis dua program tangki sampel, RandomMoveTank
dan RandomShootTank
(namanya mengatakan itu semua).
Untuk menjalankan tangki Anda, tambahkan kelas tangki Anda yang memenuhi syarat (nama paket + nama kelas) ke tanks.list
(satu kelas per baris), edit pengaturan seperlunya di zove.ppcg.tankwar.Control
(tunda giliran, apakah akan menampilkan representasi GUI dari bidang, dll), dan larizove.ppcg.tankwar.Control
. Pastikan setidaknya ada 2 tank dalam daftar, atau hasilnya tidak ditentukan. (Gunakan tangki sampel jika perlu).
Program Anda akan dijalankan di mesin saya di bawah program kontrol ini. Saya akan menyertakan tautan ke sumber begitu saya menulisnya. Jangan ragu untuk menyarankan pengeditan ke sumber.
Aturan
- Kiriman Anda harus mengikuti pedoman di atas
- Program Anda mungkin tidak mengakses sistem file, jaringan, atau mencoba menyerang mesin saya dengan cara apa pun
- Program Anda tidak boleh mencoba mengeksploitasi program kontrol saya untuk menipu
- Tanpa trolling (seperti sengaja membuat program Anda membuang waktu untuk menutup semuanya)
- Anda mungkin memiliki lebih dari satu pengiriman
- Cobalah menjadi kreatif dengan kiriman!
- Saya berhak untuk mengizinkan atau tidak mengizinkan program secara sewenang-wenang
Semoga berhasil!
UPDATE: Setelah memperbaiki bug teleportasi dinding dan menerapkan regenerasi, saya menjalankan kiriman saat ini untuk 100 putaran denganBattlefield.FIELD_SIZE = 30
UPDATE 2: Saya menambahkan kiriman baru, RunTank, setelah bermain-main dengan Groovy sebentar ...
Hasil yang diperbarui:
+-----------------+----+
| RandomMoveTank | 0 |
| RandomShootTank | 0 |
| Bouncing Tank | 4 |
| Richard-A Tank | 9 |
| Shoot Closest | 19 |
| HunterKiller 2 | 22 |
| RunTank | 23 |
| Dodge Tank | 24 |
+-----------------+----+
Saat ini tangki meregenerasi 1 kehidupan per putaran. Haruskah itu ditingkatkan?
MapPoint
'sx
dany
floats
? Bukankah seharusnya begituints
?