Saya mencoba untuk merasakan bagaimana merancang dan berpikir dengan cara Berorientasi Objek dan ingin mendapatkan umpan balik dari komunitas tentang topik ini. Berikut contoh game catur yang ingin saya desain secara OO. Ini adalah desain yang sangat luas dan fokus saya pada tahap ini hanya untuk mengidentifikasi siapa yang bertanggung jawab atas pesan apa dan bagaimana objek berinteraksi satu sama lain untuk mensimulasikan permainan. Harap tunjukkan jika ada elemen dengan desain yang buruk (kopling tinggi, kohesi buruk, dll.) Dan cara memperbaikinya.
Permainan Catur memiliki kelas-kelas berikut
- Naik
- Pemain
- Bagian
- Kotak
- Permainan catur
Papan terdiri dari bujur sangkar sehingga Papan dapat diberi tanggung jawab untuk membuat dan mengelola objek Persegi. Tiap bidak juga ada di bujur sangkar sehingga setiap bidak juga memiliki referensi ke bujur sangkar tempatnya berada. (Apakah ini masuk akal?). Masing-masing bagian kemudian bertanggung jawab untuk berpindah dari satu kotak ke kotak lainnya. Kelas pemain memegang referensi ke semua bidak yang dimilikinya dan juga bertanggung jawab atas pembuatannya (Haruskah pemain membuat Bidak?). Pemain memiliki metode takeTurn yang pada gilirannya memanggil metode movePiece yang termasuk dalam Kelas bidak yang mengubah lokasi bidak dari lokasi saat ini ke lokasi lain. Sekarang saya bingung tentang apa sebenarnya kelas Dewan harus bertanggung jawab. Saya berasumsi bahwa hal itu diperlukan untuk menentukan status game saat ini dan mengetahui kapan game tersebut selesai. Tapi ketika sepotong mengubahnya ' Lokasi bagaimana seharusnya papan diperbarui? haruskah itu mempertahankan array terpisah dari kotak di mana potongan ada dan yang mendapat pembaruan saat potongan bergerak?
Selain itu, ChessGame pada awalnya membuat objek Papan dan pemain yang pada gilirannya membuat kotak dan bidak masing-masing dan memulai simulasi. Singkatnya, mungkin seperti inilah tampilan kode di ChessGame
Player p1 =new Player();
Player p2 = new Player();
Board b = new Board();
while(b.isGameOver())
{
p1.takeTurn(); // calls movePiece on the Piece object
p2.takeTurn();
}
Saya tidak jelas tentang bagaimana status papan akan diperbarui. Haruskah sepotong memiliki referensi ke papan? Dimana seharusnya tanggung jawab itu berada? Siapa yang memegang referensi apa? Tolong bantu saya dengan masukan Anda dan tunjukkan masalah dalam desain ini. Saya sengaja tidak fokus pada algoritme apa pun atau detail lebih lanjut dari permainan game karena saya hanya tertarik pada aspek desain. Semoga komunitas ini bisa memberikan wawasan yang berharga.
takeTurn()
jika langkah p1 mengakhiri permainan. Kurang komentar rewel: Saya merasa lebih alami untuk memanggil para pemainwhite
danblack
.canMove()
. Dan ketika pemindahan selesai, semua bagian lainnya memperbarui salinan papan dalamnya sendiri. Saya tahu ini tidak optimal, tapi menarik saat itu belajar C ++. Belakangan, seorang teman non-pemain catur memberi tahu saya bahwa dia akan memilikiclasses
untuk setiap kotak, bukan setiap bidak. Dan komentar itu menurut saya sangat menarik.Jawaban:
Saya sebenarnya baru saja menulis implementasi C # lengkap dari papan catur, bidak, aturan, dll. Berikut ini kira-kira bagaimana saya memodelkannya (implementasi sebenarnya dihapus karena saya tidak ingin menghilangkan semua kesenangan dari pengkodean Anda):
Ide dasarnya adalah Game / Board / dll hanya menyimpan status game. Anda dapat memanipulasinya untuk misalnya mengatur posisi, jika itu yang Anda inginkan. Saya memiliki kelas yang mengimplementasikan antarmuka IGameRules saya yang bertanggung jawab untuk:
Memisahkan aturan dari kelas game / papan juga berarti Anda dapat menerapkan varian dengan relatif mudah. Semua metode antarmuka aturan mengambil
Game
objek yang dapat diperiksa untuk menentukan gerakan mana yang valid.Perhatikan bahwa saya tidak menyimpan informasi pemain di
Game
. Saya memiliki kelas terpisahTable
yang bertanggung jawab untuk menyimpan metadata permainan seperti siapa yang bermain, kapan permainan berlangsung, dll.EDIT: Perhatikan bahwa tujuan jawaban ini tidak benar-benar memberi Anda kode template yang dapat Anda isi - kode saya sebenarnya memiliki lebih banyak informasi yang disimpan pada setiap item, lebih banyak metode, dll. Tujuannya adalah untuk memandu Anda menuju tujuan yang ingin Anda capai.
sumber
Move
adalah kelas sehingga Anda dapat menyimpan seluruh riwayat gerakan dalam daftar langkah, dengan notasi dan informasi tambahan seperti bidak apa yang ditangkap, bidak apa yang mungkin dipromosikan, dll.Game
delgasi ke pelaksanaIGameRules
atau Anda menegakkan aturan di luar objek? Yang terakhir tampaknya tidak pantas karena game tidak dapat melindungi negaranya sendiri, bukan?Inilah ide saya, untuk permainan catur yang cukup mendasar:
sumber
Saya baru-baru ini membuat program catur dalam PHP ( klik situs web di sini , klik sumber di sini ) dan saya membuatnya berorientasi objek. Ini kelas yang saya gunakan.
generate_legal_moves()
kode saya di sini. Metode itu diberi papan, yang gilirannya, dan beberapa variabel untuk mengatur tingkat detail output, dan itu menghasilkan semua langkah hukum untuk posisi itu. Ini mengembalikan daftar ChessMoves.int
s.Saat ini saya mencoba mengubah kode ini menjadi AI catur, jadi harus CEPAT. Saya telah mengoptimalkan
generate_legal_moves()
fungsi dari 1500ms menjadi 8ms, dan saya masih mengerjakannya. Pelajaran yang saya pelajari dari itu adalah ...int
jika memungkinkan. Itulah mengapaChessSquare
menyimpan peringkat dan file sebagaiint
, daripada juga menyimpan alfanumerikstring
dengan notasi kotak catur yang dapat dibaca manusia seperti "a4".Saya tahu ini sudah tua, tapi semoga ini membantu seseorang. Semoga berhasil!
sumber