Apakah ada teknik umum untuk menangani keadaan (secara umum) dalam bahasa pemrograman fungsional? Ada solusi dalam setiap bahasa pemrograman (fungsional) untuk menangani keadaan global, tetapi saya ingin menghindari ini sejauh yang saya bisa.
Semua status dengan cara fungsional murni adalah parameter fungsi. Jadi saya perlu menempatkan seluruh kondisi permainan (sebuah hashmap raksasa dengan dunia, pemain, posisi, skor, aset, musuh, ...)) sebagai parameter untuk semua fungsi yang ingin memanipulasi dunia pada input atau pemicu yang diberikan . Fungsi itu sendiri mengambil informasi yang relevan dari gumpalan gamestate, melakukan sesuatu dengannya, memanipulasi gamestate dan mengembalikan gamestate. Tapi ini sepertinya solusi yang buruk untuk masalah ini. Jika saya menempatkan keseluruhan gamestate ke semua fungsi, tidak ada manfaatnya bagi saya berbeda dengan variabel global atau pendekatan imperatif.
Saya bisa memasukkan informasi yang relevan ke dalam fungsi dan mengembalikan tindakan yang akan diambil untuk input yang diberikan. Dan satu fungsi tunggal menerapkan semua aksi ke gamestate. Tetapi sebagian besar fungsi membutuhkan banyak informasi "relevan". move()
perlu posisi objek, kecepatan, peta untuk tabrakan, posisi semua musuh, kesehatan saat ini, ... Jadi pendekatan ini tampaknya tidak berhasil juga.
Jadi pertanyaan saya adalah bagaimana saya menangani sejumlah besar negara dalam bahasa pemrograman fungsional - terutama untuk pengembangan game?
EDIT: Ada beberapa kerangka kerja game untuk membangun game di Clojure. Ada pendekatan untuk memecahkan masalah ini sebagian adalah dengan memasukkan semua objek dalam game sebagai "entitas" dan memasukkannya ke dalam tas besar. Sebuah Fungsi utama gigant memegang layar dan entitas dan peristiwa menangani ( :on-key-down
, :on-init
, ...) untuk entitas ini dan menjalankan tampilan loop utama. Tapi ini bukan solusi bersih yang saya cari.
sumber
move()
, Anda mungkin harus melewati objek 'saat ini' (atau pengidentifikasi untuknya), ditambah dunia yang sedang dilaluinya, dan hanya mendapatkan posisi dan kecepatan saat ini ... output kemudian seluruh dunia fisika, atau setidaknya daftar benda yang diubah.Jawaban:
Efek samping dan keadaan dalam bahasa pemrograman fungsional adalah masalah yang lebih luas dalam ilmu komputer. Jika Anda belum pernah menjumpai mereka sebelumnya, mungkin lihatlah monad . Namun berhati-hatilah: mereka adalah konsep yang cukup maju dan kebanyakan orang yang saya kenal (termasuk saya) berjuang untuk memahami mereka. Ada banyak, banyak tutorial online, dengan pendekatan dan persyaratan pengetahuan yang berbeda. Secara pribadi, saya suka yang terbaik dari Eric Lippert.
Eric Lippert di Monads
Beberapa hal yang perlu dipertimbangkan:
Beberapa pemikiran terakhir:
Secara keseluruhan, saya pikir bahkan jika itu bisa menarik secara akademis, saya ragu pendekatan ini praktis dan sepadan dengan usaha.
sumber
Saya telah menulis beberapa game menggunakan F # (multi-paradigma, tidak murni, bahasa fungsional-pertama), dengan pendekatan mulai dari OOP ke FRP . Ini adalah pertanyaan luas, tetapi saya akan melakukan yang terbaik.
Cara pilihan saya adalah memiliki jenis yang tidak dapat diubah yang mewakili seluruh permainan
State
. Saya kemudian memiliki referensi yang bisa berubah ke arusState
yang diperbarui setiap centang. Ini tidak sepenuhnya murni, tetapi menjaga mutabilitas terbatas pada satu tempat.Tidak benar. Karena
State
tipe ini tidak dapat diubah, Anda tidak dapat memiliki komponen lama yang mengubah dunia dengan cara yang tidak jelas. Ini memperbaiki masalah terbesar denganGameObject
pendekatan (dipopulerkan oleh Unity): sulit untuk mengontrol urutanUpdate
panggilan.Dan tidak seperti menggunakan global, ia mudah diuji unit dan diparalelkan,
Anda juga harus menulis fungsi pembantu yang menerima sub-properti negara untuk memecah masalah.
Sebagai contoh:
Di sini
update
bertindak pada seluruh negara, tetapiupdateSpaceShip
hanya bertindak pada individuSpaceShip
secara terpisah.Saran saya adalah membuat
Input
jenis yang memegang papan ketik, mouse, game-pad, dll. Anda kemudian dapat menulis fungsi yang mengambilState
danInput
mengembalikan yang berikutnyaState
:Untuk memberi Anda gambaran tentang bagaimana hal ini cocok, keseluruhan permainan mungkin terlihat seperti ini:
Untuk gim sederhana, Anda dapat menggunakan pendekatan di atas (fungsi pembantu). Untuk sesuatu yang lebih rumit, Anda mungkin ingin mencoba " lensa ".
Berlawanan dengan beberapa komentar di sini, saya sangat menyarankan untuk menulis game dalam bahasa pemrograman fungsional (tidak murni), atau setidaknya mencobanya! Saya menemukan ini membuat iterasi lebih cepat, basis kode lebih kecil dan bug lebih jarang.
Saya juga tidak berpikir Anda perlu belajar monad untuk menulis game dalam bahasa FP (tidak murni). Ini karena kode Anda kemungkinan besar akan memblokir dan berulir tunggal.
Ini terutama benar jika Anda menulis game multi-pemain. Maka hal-hal akan menjadi lebih mudah dengan pendekatan ini karena memungkinkan Anda untuk membuat serialisasi keadaan gim secara sepele dan mengirimkannya ke seluruh jaringan.
Adapun mengapa lebih banyak game tidak ditulis dengan cara ini ... Saya tidak bisa bilang. Namun, ini berlaku di semua domain pemrograman (kecuali mungkin keuangan), jadi saya tidak akan menggunakan ini sebagai argumen bahwa bahasa fungsional tidak cocok untuk pemrograman game.
Juga layak dibaca adalah Purg Fungsional Retrogames .
sumber
Apa yang Anda cari adalah pengembangan game FRP.
Beberapa Perkenalan Video:
"Mengontrol Waktu dan Ruang: memahami banyak formulasi FRP" oleh Evan Czaplicki
Bodil Stokke: Pengembangan Game Reaktif Untuk The Discerning Hipster [JSConf2014]
Love this talk with Carmack, menjelaskan pengalamannya dengan pemrograman murni fungsional dalam pengembangan permainan keynote John Carmack di Quakecon 2013 bagian 4
Ini 100% mungkin dan lebih baik untuk membuat logika permainan inti dengan cara yang sepenuhnya fungsional, industri secara keseluruhan hanya tertinggal, terjebak dalam satu paradigma pemikiran.
Mungkin untuk melakukannya di Unity juga.
Untuk menjawab pertanyaan, status permainan baru akan diperbarui / dibuat setiap kali sesuatu bergerak, seperti yang dikatakan carmack dalam ceramahnya, itu bukan masalah. Pengurangan drastis dalam overhead kognitif yang berasal dari arsitektur fungsional murni, sangat dapat dipelihara, jauh cara kinerja hit, jika ada sama sekali.
sumber