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?
sumber
MapPoint
'sx
dany
floats
? Bukankah seharusnya begituints
?Jawaban:
HunterKiller
Pemburu yang cerdas ini akan berusaha menemukan posisi aman di mana ia dapat menembak dengan tepat pada satu sasaran. (Dan dengan demikian, hanya satu target yang bisa menembaknya)
Berfungsi paling baik ketika ada banyak penutup.
Dan itu saja. Saya dihabiskan.
sumber
Tank lurus ke depan ini menemukan tank musuh terdekat dan menembaknya. Akan lebih baik jika
find
,,distance
danangle
dibangun di, dan jikacreateShootAction
menerima rangkap dalam radian (yaitu hasilangle
)Sunting: Kelas ditulis ulang untuk memasukkan metode utilitas baru
sumber
Would be nice if find, distance, and angle were built in, and if createShootAction accepted a double in radians (i.e. the result of angle)
- Ide bagus, saya akan menambahkannya.Saya tidak pandai dalam hal ini, tetapi saya pikir saya masih akan mencobanya, Anda tahu, berlatih dan semacamnya.
Tank saya akan secara acak memutuskan untuk bergerak atau menembak. Ketika memutuskan untuk menembak, ia akan mencoba menembak target terdekat yang tersedia.
Kode lengkap termasuk program kontrol dapat ditemukan di sini .
sumber
Direction.getRandom()
Dodge Tank
Tangki ini akan menembak ke tangki terdekat. Sering kali, tergantung pada kesehatannya dan terakhir kali ia bergerak, ia akan mencoba untuk bergerak tegak lurus ke tangki terdekat dalam upaya untuk menghindari lasernya.
sumber
Ini jauh lebih rumit daripada yang saya pikir ..
Ini adalah entri saya di groovy, Anda perlu groovy diinstal dan kompilasi dengannya
Untuk menyebutnya, Anda perlu menambahkan $ GROOVY_HOME / Groovy / Groovy-2.3.4 / lib / groovy-2.3.4.jar (atau versi apa pun) ke classpath.
Saya bisa mengirimkan Anda file .class yang dikompilasi dan perpustakaan jika Anda tidak ingin menginstalnya.
Tampaknya ada situasi di mana tank tidak bisa melihatnya, saya tidak tahu apakah itu dimaksudkan. Itu menyebabkan kebuntuan saat pengujian.
Pokoknya di sini adalah RunTank: RunTank berani maju dalam arah yang berlawanan dari tangki terdekat jika itu adalah tangki terdekat dengan tangki terdekat atau lebih dari satu tangki dalam FIELD_SIZE / 3. Saya harap masuk akal, saya mabuk :)
Saya punya satu saran: Tambahkan warna ke tangki, dan metode untuk menerapkannya. Label juga akan menyenangkan di GUI :)
sumber
def RandomMoveTank() {}
- Apakah itu dimaksudkan untuk berada di sana? (Saya tidak tahu asyik)Yang ini adalah varian pada Shoot-Closest di mana, setiap belokan lainnya, ia bergerak ke arah hingga tidak bisa lagi. Ia menembak setiap belokan lainnya.
Ini memiliki utilitas praktis
path
, yang dapat digunakan untuk mengidentifikasi semua titik (dan dengan demikian objek) antara dua titik.sumber