https://en.wikipedia.org/wiki/Connect_Four
Apakah ada yang ingat permainan 2 pemain terhubung 4? Bagi mereka yang tidak melakukannya adalah papan 6x7 yang berdiri vertikal di atas permukaan. Tujuan dari connect 4 adalah untuk, well connect 4! Koneksi dihitung jika horisontal, diagonal, atau vertikal. Anda meletakkan potongan-potongan Anda di papan tulis dengan memasukkan potongan di bagian atas kolom di mana ia jatuh ke bagian bawah kolom itu. Aturan kami mengubah 3 hal yang terhubung 4.
- Ubah # 1 Menang didefinisikan sebagai pemain dengan poin terbanyak. Anda mendapatkan poin dengan menghubungkan 4 suka dalam aturan - lebih lanjut tentang itu nanti.
- Ubah # 2 Anda memiliki 3 pemain setiap putaran.
- Ubah # 3 Ukuran papan adalah 9x9.
Mencetak:
Skor didasarkan pada berapa banyak yang Anda dapatkan secara berturut-turut. Jika Anda memiliki 4 dalam grup baris, Anda mendapatkan 1 poin. Jika Anda memiliki 5 di grup baris, Anda mendapatkan 2 poin, 6 di baris 3, dan seterusnya.
Contoh:
Catatan o
dan x
diganti dengan #
dan ~
masing - masing, untuk kontras yang lebih baik
Contoh papan kosong: (semua contoh adalah papan ukuran standar 2 pemain)
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | | | | | | |
1 |_|_|_|_|_|_|_|
Jika kita menjatuhkan sepotong coll d
, itu akan mendarat di lokasi 1d
.
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | | | | | | |
1 |_|_|_|#|_|_|_|
Jika kita sekarang menjatuhkan sepotong coll d
lagi, itu akan mendarat di lokasi 2d
. Berikut adalah contoh dari 4 posisi berturut-turut:
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | |~| | | |
3 | | |~|#| | | |
2 | |~|#|~| |#| |
1 |~|#|~|#|_|#|_|
Dalam hal ini x
mendapat 1 poin secara diagonal ( 1a 2b 3c 4d
).
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | |#| | | |
3 | | | |#| | | |
2 | | | |#| | | |
1 |_|~|_|#|~|_|~|
Dalam hal ini, o
dapatkan 1 poin secara vertikal ( 1d 2d 3d 4d
).
a b c d e f g
6 | | | | | | | |
5 | | | | | | | |
4 | | | | | | | |
3 | | | | | | | |
2 | | |#|#|#|#| |
1 |_|_|~|~|~|~|~|
Dalam hal ini o
mendapat 2 poin secara horizontal ( 1c 1d 1e 1f 1g
) dan x
mendapat 1 poin secara horizontal ( 2c 2d 2e 2f
).
a b c d e f g
6 | | |#| | | | |
5 | | |#| | | | |
4 | | |#| | | | |
3 | | |#| | |~| |
2 |~| |#| | |#|~|
1 |~|_|#|~| |~|~|
Kali ini x
mendapat 3 poin untuk 6 berturut-turut ( 1c 2c 3c 4c 5c 6c
).
Input output
Anda akan memiliki akses ke papan melalui array 2d. Setiap lokasi akan diwakili dengan int
id pemain yang mewakili. Anda juga akan memiliki id pemain Anda diteruskan ke fungsi Anda. Anda bergerak dengan mengembalikan coll yang ingin Anda masukkan. Setiap ronde 3 pemain akan dipilih untuk dimainkan. Di akhir permainan, semua pemain akan memainkan jumlah pertandingan yang genap.
Untuk saat putaran 100k akan dijalankan (perhatikan ini membutuhkan waktu yang lama , Anda mungkin ingin menguranginya untuk pengujian turnaround cepat). Secara keseluruhan pemenangnya adalah pemain dengan kemenangan terbanyak.
Pengontrol dapat ditemukan di sini: https://github.com/JJ-Atkinson/Connect-n/tree/master .
Menulis bot:
Untuk menulis bot, Anda harus memperluas Player
kelas. Player
abstrak dan memiliki satu metode untuk diterapkan int makeMove(void)
,. Dalam makeMove
Anda akan memutuskan coll Anda ingin meletakkan bola Anda ke dalam. Jika Anda memilih coll yang tidak valid (mis. Coll tidak ada, coll sudah terisi), giliran Anda akan dilewati . Di Player
kelas Anda memiliki banyak metode penolong yang berguna. Daftar yang paling penting adalah sebagai berikut:
boolean ensureValidMove(int coll)
: Kembalikan true jika coll ada di papan tulis dan coll belum terisi.int[] getBoardSize()
: Mengembalikan array int di mana[0]
jumlah kolom, dan[1]
jumlah baris.int[][] getBoard()
: Kembalikan salinan papan. Anda harus mengaksesnya seperti ini:[coll number][row number from bottom]
.- Untuk menemukan yang lainnya, lihat
Player
kelasnya. EMPTY_CELL
: Nilai sel kosong
Karena ini akan multi-threaded, saya juga menyertakan random
fungsi jika Anda membutuhkannya.
Debugging bot Anda:
Saya telah memasukkan beberapa hal dalam controller untuk membuatnya lebih mudah untuk men-debug bot. Yang pertama adalah Runner#SHOW_STATISTICS
. Jika ini diaktifkan, Anda akan melihat hasil cetak dari grup pemain yang dimainkan, termasuk hitungan bot yang menang. Contoh:
OnePlayBot, PackingBot, BuggyBot,
OnePlayBot -> 6
PackingBot -> 5
BuggyBot -> 3
Draw -> 1
Anda juga dapat membuat permainan khusus dengan connectn.game.CustomGame
kelas, Anda dapat melihat skor dan pemenang dari setiap babak. Anda bahkan dapat menambahkan diri Anda ke dalam campuran UserBot
.
Menambahkan bot Anda:
Untuk menambahkan bot Anda ke barisan, pergi ke PlayerFactory
blok statis dan tambahkan baris berikut:
playerCreator.put(MyBot.class, MyBot::new);
Hal-hal lain yang perlu diperhatikan:
- Simulasi multi-threaded. Jika Anda ingin mematikannya, buka
Runner#runGames()
dan komentari baris ini (.parallel()
). - Untuk mengubah jumlah game, atur
Runner#MINIMUM_NUMBER_OF_GAMES
sesuai keinginan Anda.
Ditambahkan nanti:
- Komunikasi di antara bot tidak diizinkan.
Terkait: Play Connect 4!
================================
Papan Skor: (100.000 permainan)
MaxGayne -> 22662
RowBot -> 17884
OnePlayBot -> 10354
JealousBot -> 10140
Progressive -> 7965
Draw -> 7553
StraightForwardBot -> 7542
RandomBot -> 6700
PackingBot -> 5317
BasicBlockBot -> 1282
BuggyBot -> 1114
FairDiceRoll -> 853
Steve -> 634
================================
sumber
Player
kelas untuk melihat semua metode yang tersedia.ensureValidMove
(kecuali strategi Anda adalah untuk melewati belokan ini tentu saja).Jawaban:
MaxGayne
Bot ini memberikan skor untuk setiap posisi, terutama berdasarkan panjang bagian yang terhubung. Terlihat 3 langkah dalam memeriksa 3 gerakan terbaik di setiap tahap, dan memilih satu dengan skor maksimum yang diharapkan.
sumber
UserBot
dan bot Anda adalah bahwa setelah beberapa titikMaxGayne
akan membuang bergantian (misalnya setelah 15 bergerak itu melompati setiap belokan sampai permainan berakhir).javafx.util.Pair
tidak berfungsi di Eclipse karena itu tidak dianggap sebagai bagian dari API publik. Dan saya tidak tahu ke mana harus mencarisun.plugin.dom.exception.InvalidStateException
. Anda mungkin bermaksudjava.lang.IllegalStateException
.Pair
, itu sedekat yang saya bisa dengan tipe data yang saya inginkan tanpa menggulir sendiri, jadi kecuali gerhana tidak akan dikompilasi, saya pikir tidak apa-apa. Sedangkan untuk # 3, Anda benar, autocomplete saya di IntelliJ tidak selalu benar. (sebagian besar waktu itu, itu sebabnya saya tidak memeriksa)Pair
masalahnya benar-benar mencegah kompilasi di Eclipse, kecuali Anda tahu solusinya .RowBot
Lihat ke segala arah dan tentukan kolom optimal. Mencoba menghubungkan bagiannya, sementara tidak membiarkan lawannya melakukan hal yang sama.
sumber
OnePlayBot
Bot ini hanya memiliki satu permainan - letakkan potongannya di sel paling kiri yang valid. Anehnya itu cukup bagus;)
sumber
RandomBot
Cukup masukkan sepotong di mana saja yang valid.
sumber
StraightForwardBot
Mirip dengan OnePlayBot tetapi memperhitungkan langkah terakhir dan memainkan kolom berikutnya yang valid.
sumber
JealousBot
Bot ini membenci pemain lain. Dan dia tidak suka bahwa dia menjatuhkan potongan di papan tulis. Jadi dia mencoba menjadi yang terakhir yang menjatuhkan sepotong di kolom.
Ini pertama kalinya saya di CodeGolf, jadi saya harap jawaban ini cukup baik. Saya belum bisa mengujinya, jadi tolong maafkan saya jika ada kesalahan.
EDIT : Menambahkan baris untuk memecahkan yang kedua
for
.EDIT 2 : Mengetahui mengapa
while
itu tidak terbatas. Sekarang sudah lengkap dan bisa digunakan!sumber
if(board[col][row]!=null && board[col][row]!=id)
harus diubah menjadiif(board[col][row]!=-1....
. Periksa di game.Game.genBoard () di github OP jika Anda ingin yakin. Saya juga tidak tahu apakah Andarandom()
akan melakukan apa yang Anda inginkan, mungkin menggunakan(int)Math.random()*col
?random()
metode adalah diPlayer
kelas! Jadi saya pikir ini akan berhasil =) Tapi ya, saya tidak percaya diri dengan kondisi saya. Saya tidak menemukan cara mendefinisikannya dalam kode OP, tetapi saya akan memeriksanya lagi. Terima kasih banyak!public double random() {return ThreadLocalRandom.current().nextDouble();}
. Saya tidak tahu persis bagaimana cara kerjanya, tapi saya menganggapnya mengembalikan nilai antara 0 dan 1, jadi mungkin perlu dilakukan(int)random()*col
:)nextDouble
mengembalikan nomor antara0
dan1
. Saya memasukkannya karena simulasi dijalankan secara paralel, danMath.random()
tidak aman untuk thread.BasicBlockBot
Bot blok sederhana (dan naif). Dia tidak tahu Anda bisa membuat 4 berturut-turut secara horizontal atau diagonal!
sumber
Progresif
Progresif adalah ... progresif. Dia suka melihat semuanya , dan beberapa! (Saya tidak yakin dengan metodologi ini. Ini bekerja melawan teman, sekali.) Dan, untuk beberapa alasan, itu berfungsi dengan baik.
sumber
FairDiceRoll
Selalu mengembalikan 4.
sumber
BuggyBot
Bot sampel untuk dikalahkan (FYI: tidak sulit;)
sumber
PackingBot
Bot ini tidak bertujuan untuk mendapatkan poin secara langsung. Dia mencoba mengemas token maksimum hingga papan terisi. Dia mengerti bahwa hanya naik lagi dan lagi itu bodoh, jadi dia akan secara acak menempatkan token di sekitar "domain" -nya.
Dia seharusnya bisa mendapatkan beberapa poin di semua arah, tetapi tidak akan menjadi yang terbaik!
(Tidak diuji)
sumber
Steve
sumber
BasicBlockBot
.