Bagaimana cara saya mendistribusikan sumber daya secara adil di antara pabrik ketika sumber daya hampir habis?

12

Sumber daya utama dalam gim saya adalah massa , disimpan sebagai angka floating point yang berubah seiring waktu. Node sumber daya menambah massa dan pabrik mengeringkannya. Misalnya, jika saya memiliki simpul sumber daya menghasilkan 5 massa per detik, saya akan mendapatkan 5 * deltaTmassa setiap langkah gim. Massa ditampilkan dibulatkan ke bilangan bulat terdekat, dan indikator untung / rugi ditampilkan oleh persepuluh.

Bagaimana saya harus menangani massa yang memukul nol? Ini menciptakan kondisi balapan jika banyak pabrik mencoba membangun sekaligus: Pabrik-pabrik pertama dalam antrian atau yang mengalirkan lebih sedikit sumber daya mendapat prioritas begitu beberapa sumber daya lebih banyak masuk dan karenanya membangun lebih cepat daripada yang lain.

Bagaimana saya bisa mengatasi ini? Haruskah saya melewatkan langkah ini sepenuhnya?

Massa
sumber
Bah, komentar saya tidak disimpan. Saya memiliki eksplorasi yang lebih baik. Pada dasarnya saya memiliki sumber daya yang diakses setiap langkah oleh setiap objek. Setiap objek menambah atau mengurangi dari sumber daya. Masalah saya adalah bahwa jika sumber daya mencapai 0 saya tidak tahu harus berbuat apa. Haruskah saya membuat semacam antrian? Haruskah saya melewatkan langkah objek. Apa?
Mob
3
Usul. Masalah terpecahkan.
Patrick Hughes
Jawaban dari Roy di bawah ini dikombinasikan dengan komentar untuknya menggambarkan sistem robin yang layak, mudah dirawat, dan disesuaikan. Selama masalah desain langsung Anda terpecahkan, itu semua baik =)
Patrick Hughes

Jawaban:

9

Saya setuju dengan Petr: Tidak ada cara yang pasti untuk melakukannya. Bagaimana Anda ingin melakukannya adalah masalah bagaimana Anda ingin merancang game Anda.

Dalam keadaan ini, bagaimanapun, saya pikir itu segera jelas jenis mekanik yang Anda coba selesaikan: Anda hanya ingin menghasilkan sesuatu secepat mungkin, dalam jumlah massa yang Anda miliki.

Memproduksi dalam kapasitas

Saya akan mengambil daun dari buku Panglima Tertinggi, karena Anda melakukan sistem yang sangat mirip dengan mereka: Jika Anda memproduksi di atas kapasitas, cara paling rapi untuk mengatasinya adalah memiliki produksi yang melambat di seluruh papan. Menurunkan kapasitas produksi sebenarnya cukup sederhana.

Mekanik kecepatan produksi

Setiap langkah pembaruan, pabrik Anda tidak hanya menghasilkan jumlah yang ditentukan: mereka beroperasi dengan kecepatan produksi , yang menentukan berapa banyak kemajuan yang mereka buat dalam setiap langkah dan berapa banyak massa yang mereka gunakan. Ketika Anda memproduksi pada kapasitas 75%, pabrik Anda menghasilkan kemajuan 75% setiap langkah dan menggunakan massa hingga 75% dibandingkan dengan kapasitas 100%.

Untuk menghitung kecepatan produksi, sebelum membangun apa pun, Anda harus meminta pabrik Anda untuk menentukan total sumber daya yang akan digunakan langkah ini dengan kapasitas penuh. Kemudian Anda melakukan perhitungan sederhana:

production speed = (total mass capacity / mass required this step)
if (production speed > 1.0) production speed = 1.0

Katakanlah Anda membutuhkan 125 massa langkah ini untuk menghasilkan pada kapasitas penuh, tetapi hanya 100 massa langkah ini. Persamaan ini memberi Anda kecepatan produksi 0,8 (representasi desimal 80%). Ketika Anda memberi tahu pabrik-pabrik Anda untuk benar-benar melakukan pembangunan mereka , Anda menyerahkan nilai ini untuk memberi tahu mereka kecepatan apa yang sedang mereka bangun: dan sekarang produksi Anda melambat di seluruh papan.

Alternatif

Anda juga dapat mulai menutup pabrik untuk sementara hingga kapasitas produksinya berkurang, dan bisa sangat menarik untuk melihat bahwa terjadi pada pabrik yang jauh dari generator ketika kapasitasnya sangat rendah.

Berbagai sumber daya?

Terserah Anda bagaimana Anda menangani ini; ada banyak pilihan. Yang paling sederhana mungkin untuk menghitung kapasitas produksi untuk masing-masing sumber daya dan kemudian memilih yang terendah , sehingga sumber daya terlemah Anda menjadi hambatan bagi yang lainnya.

doppelgreener
sumber
Saya pikir Anda bahkan tidak perlu memberi tahu pabrik untuk memproduksi dengan kecepatan 80%, karena apa pun yang dibuat pabrik Anda menggunakan massa tetap. Misalnya: Anda membangun tangki yang membutuhkan 100 massa untuk membangun, biasanya pabrik dapat menggunakan 2 massa setiap siklus. Ini berarti dibutuhkan 50 siklus untuk menyelesaikan tangki dan setiap siklus Anda menambahkan 2 ke massa tangki saat ini. Sekarang, Anda hanya memiliki 1 massa yang tersedia, ini berarti siklus ini, tangki saat ini menghabiskan massa meningkat sebesar 1 bukannya 2. Setelah setiap siklus hanya memeriksa massa saat ini vs total massa yang diperlukan untuk melihat apakah tangki benar-benar membangun atau tidak.
Thomas
Jika Anda memiliki 0 massa yang tersedia, jangan tambahkan massa ke tangki. Waktu yang diperlukan untuk membangun sesuatu dengan cara ini dapat bervariasi tergantung pada penghasilan massal Anda. jika Anda memiliki 2 pabrik yang dapat menggunakan 2 massa / siklus dan hanya 3 pendapatan, tangki 1 dibangun dalam 50 siklus, tangki 2 dalam 100. Cara lain adalah dengan membagi jumlah total massa yang tersedia atas semua pabrik yang menggunakannya ( aktif membangun sesuatu). Jumlah total massa yang dapat digunakan pabrik dapat ditingkatkan dengan menambahkan level ke pabrik. Misalnya pada level 1 mereka dapat menghabiskan 2 massa, pada level 2: 3 massa dll.
Thomas
@ Thomas menambahkan massa ke produk dalam pembuatan tampaknya cara yang terlalu rumit dibandingkan dengan hanya menyelesaikan persentase dari produk. Terutama karena pabrik Anda harus tahu semua tentang sistem sumber daya Anda, bukan properti "tingkat produksi" sederhana. Jika hasil untuk pemain adalah sama, pertahankan implementasinya sesederhana mungkin. Itu juga membuatnya lebih mudah untuk membuat perubahan di masa depan, seperti ketika Anda menambah / menghapus sumber daya.
Hackworth
@ Hackworth Saya cenderung tidak setuju, pabrik tidak perlu tahu tentang sistem sumber daya. Pabrik hanya tahu apa yang sedang dibangun dan seberapa jauh. Sistem sumber daya hanya memberitahu pabrik menambahkan jumlah X ke build. Dengan cara ini Anda tidak perlu menghitung persentase pendapatan sumber daya yang dimiliki pabrik ini dan Anda tidak perlu menerjemahkan pendapatan sumber daya ke persentase penyelesaian tambahan.
Thomas
6

Walaupun saya menyukai jawaban Jonathan Hobbs, saya pikir sistem antrian lebih sederhana:

Queue<Factory> queue = ...;
int numFactories = ...;

Update()
{
    int resources = GetAllResourcesForThisStep();
    for(int i = 0; i < numFactories; i++)
    {
        if(queue.Peak().RequiredResources <= resources)
        {
            Factory f = queue.Pop();
            resources -= f.RequiredResources;
            queue.Push(f);
        }
        else
        {
            break;
        }
    }
}

Ini mungkin akan bekerja rata-rata dengan cara yang sama dengan implementasi Jonathan. Namun solusi Jonathan mungkin memberikan masalah jika kecepatan kerja ditetapkan sangat rendah dan implementasi saya dapat memiliki pabrik dengan sumber daya yang sangat tinggi untuk frame ini, membuatnya memblokir pabrik lain untuk beberapa frame.

Roy T.
sumber
+1 Saya mengembangkan game dengan sumber daya ganda, seperti dalam pertanyaan, dan ketika saya menyelesaikan masalah kunci pasokan, saya berencana untuk menggunakan sesuatu yang mirip dengan ini. Bukan kode yang tepat, tetapi ide di baliknya. Konsumen yang dapat menggunakan sumber daya dalam satu tick akan mendapatkan prioritas yang lebih rendah selama tick berikut. Saya juga berencana untuk menambahkan bendera untuk menunjukkan apakah konsumen ini memiliki prioritas tinggi, dan memberikan kendali atas bendera itu kepada pengguna.
John McDonald
Waspadalah terhadap kelaparan jika Anda memberi mereka prioritas terpisah. :)
Roy T.
Kelaparan dengan prioritas terpisah akan menjadi tujuan. Pernah memainkan Settlers 4 atau Knights & Merchants? Jika Anda lebih-konstruk bangunan, sumber daya yang terbatas pergi ke bangunan acak dan dibutuhkan selamanya sampai akhir apa-apa. Tetapi mereka juga memungkinkan Anda untuk memilih apakah sebuah bangunan itu penting atau tidak, dalam hal ini, sumber daya akan pergi ke bangunan-bangunan penting itu terlebih dahulu. Kuncinya adalah untuk tidak pernah membangun berlebihan, atau jika Anda melakukannya, membangun sesedikit mungkin.
John McDonald
5

Saya sedang mengembangkan sistem pasokan yang serupa dalam permainan saya sendiri, jadi saya juga telah memikirkan bagaimana menyelesaikan masalah kunci-pasokan, dan favoritisme. Untuk menggambarkan masalah, saya akan membuat contoh sederhana:

Jika Anda memiliki daftar: [producer1, consumer1, consumer2, consumer3] dan Anda memperbarui secara berurutan, mulai dari persediaan = 0, Anda akan mendapatkan ini:

producer1 produces 5 mass. You now have 5 mass
consumer1 wants 3 mass. Success, you now have 2 mass
consumer2 wants 3 mass. Fail
consumer3 wants 3 mass. Fail
[next tick]
producer1 produces 5 mass. You now have 7 mass
consumer1 wants 3 mass. Success, you now have 4 mass
consumer2 wants 3 mass. Success, you now have 1 mass
consumer3 wants 3 mass. Fail
etc...

konsumen1 mendapatkan semua kesenangan, sementara konsumen 2 dan 3 kelaparan sampai konsumen 1 telah puas. Bergantung pada gim Anda, ini mungkin tidak diinginkan. Saya tahu dalam permainan saya, bukan. Ketika saya menyiasatinya, saya akan membuat antrian di mana konsumen yang telah diberi makan dalam satu centang akan pindah ke belakang antrian untuk centang berikutnya, yang saya percaya adalah apa yang didapat Roy T. Contoh di atas akan terlihat seperti ini:

producer1 produces 5 mass. You now have 5 mass
consumer1 wants 3 mass. Success, you now have 2 mass. <-- Move to end of queue
consumer2 wants 3 mass. Fail
consumer3 wants 3 mass. Fail
[next tick]
producer1 produces 5 mass. You now have 7 mass
consumer2 wants 3 mass. Success, you now have 4 mass  <-- Note the order change
consumer3 wants 3 mass. Success, you now have 1 mass
consumer1 wants 3 mass. Fail
etc...

Dengan cara ini, semua orang akan mendapatkan bagian yang adil dari sumber daya.

Saya juga berencana untuk mengimplementasikan antrian tambahan untuk digunakan sebagai antrian prioritas sehingga pengguna dapat memilih struktur tertentu untuk mendapat prioritas sumber daya. Antrian prioritas akan selalu dilayani sebelum antrian standar. Pastikan semua produsen diperbarui terlebih dahulu, lalu konsumsi semua sumber daya kedua, jika tidak antrian akan mogok ketika Anda menghasilkan sumber daya sebagian melalui tanda centang dan beberapa konsumen sudah kelaparan.

Jadi, rekaplah: Perbarui produsen, kemudian antrian prioritas, pindahkan konsumen ke akhir antrian prioritas, kemudian perbarui antrian standar, pindahkan konsumen ke akhir antrian standar.

John McDonald
sumber
Diambil hingga batasnya, itu bisa berarti bahwa tidak ada konsumen yang selesai sampai setiap konsumen bisa selesai. Dalam skenario rantai produksi yang realistis, itu sangat tidak mungkin, dan bisa sangat berbahaya jika seseorang ingin memiliki antrian pembangunan untuk pasukan besar-besaran. Dia akan praktis pasukan-kurang selama seluruh pasukan sedang dibangun.
Cardin
Jawaban itu adalah pemikiran awal saya ketika saya membaca pertanyaan itu. Juga, Perlu dicatat bahwa massa yang dikonsumsi per kutu tidak selalu merupakan massa untuk membuat unit yang lengkap, melainkan biaya unit dari waktu yang diperlukan, jadi saya tidak yakin bahwa kekhawatiran @ Cardin valid, kecuali unit Anda biaya per tick sangat dekat dengan total tingkat pengumpulan Anda. Saya hanya akan memiliki antrian prioritas yang dikelola secara eksplisit oleh pemain, sehingga ia dapat memutuskan siapa yang kelaparan.
brice
@Ardin, Anda cukup benar, tetapi juga dapat digunakan sebagai mekanik game. Pemukim 4, Ksatria & Pedagang, Penghancuran Total, Panglima Tertinggi adalah game yang saya tahu melakukan hal ini. Kuncinya adalah untuk tidak mencapai kunci pasokan ini, dan jika Anda melakukannya, pastikan Anda keluar dari kunci persediaan secepatnya. Menambahkan antrian prioritas memungkinkan orang cara untuk keluar dengan lebih mudah.
John McDonald
3

Yah, saya akan memperluas ide John, karena kami membahas ini sedikit dalam obrolan .

sunting: Solusi ini sebenarnya hanya lebih disukai jika jumlah yang dikonsumsi relevan dengan seberapa sering pabrik harus mendapatkan sejumlah sumber daya. Jika semuanya sama, maka Anda memang bisa saja menggunakan antrian.

Solusi saya: semua pabrik terdaftar dalam antrian prioritas. Prioritas ditingkatkan karena pabrik menderita kelaparan. Kelaparan, prioritas, set ke nol ketika pabrik menghabiskan sumber daya. Prioritas utama selalu akan mendapatkan kumpulan sumber daya berikutnya.

Saat menentukan pabrik mana yang mendapatkan sumber daya apa, dalam beberapa jenis kode semu:

iterator i = factoryqueue.start()
bool starvation = false
while(i.next())
  if(i.ready)
    if (!starvation) 
      if (i.consumeAmount < resource.count) starvation = true
      else 
        i.consume(resource)
        i.priority = 0
    if (starvation)
      i.priority += 1

Dengan cara ini pabrik Anda akan membuat 1 produk masing-masing pada gilirannya, jika Anda ingin menyesuaikan dengan memperhitungkan akun konsumsi sehingga produk yang lebih murah dibuat lebih sering, Anda dapat meningkatkan prioritas dengan 1 / mengkonsumsi Akun misalnya.

Toni
sumber
Saya ingin memperbaiki ini tetapi saya tidak yakin apa yang harus dilakukan - ini melacak kelaparan, tetapi sebaliknya (mungkin) hanya berputar melalui antrian persis seperti biasa, dan baik kelaparan dan prioritas tidak pernah berakhir muncul untuk melakukan apa saja.
doppelgreener
perbedaannya menjadi jelas jika Anda meningkatkan prioritas dengan + = 1 / jumlah ThisFactoryConsumes, maka yang membutuhkan lebih banyak sumber daya untuk membuat suatu produk akan tertinggal sedikit, memungkinkan yang lebih murah mengambil lebih banyak sumber daya secara proporsional. Ini bahkan akan keluar rasio sumber daya per pabrik. Namun, ini bukan bukti yang bodoh, karena angka kelaparan diatur ke angka ajaib 0 setiap kali sumber daya dikonsumsi oleh pabrik, jadi itu tidak akan menjadi quarenteed untuk dibagikan secara merata tepat ketika pembaruan sumber daya gagal.
Toni
Sebenarnya saya sekarang tidak begitu yakin apakah itu sebenarnya tidak dijamin. Saya perlu menggambar beberapa grafik dan mengujinya untuk memastikan.
Toni
oh, dan prioritas adalah kualitas antrian prioritas itu sendiri. Saya tidak akan repot menjelaskan bagaimana membangunnya. Antrian prioritas itu sendiri selalu disortir sesuai dengan nilai prioritas anggotanya.
Toni
+1 Memahami bahwa ini adalah antrian prioritas, kerjanya sekarang terlihat sederhana: menyaring seluruh antrian dan memilih hal tercepat yang dapat menghabiskan sumber daya. Jika kapasitas sangat terbagi (Anda memiliki 1.000 sumber daya kutu ini, tetapi seratus 100 sumber daya membangun) ini seharusnya tidak menjadi masalah, dan segala sesuatunya diberi makan dengan cukup baik. Bahkan jika ada sesuatu yang jauh di atas sumber daya Anda, centang ini pada akhirnya mungkin menghemat cukup banyak untuk membuat sedikit kemajuan - yang memiliki dampak memperlambatnya, atau menutup hal-hal besar sepenuhnya demi hal-hal kecil yang merupakan hal yang baik. Saya suka ini BANYAK. :)
doppelgreener
2

Pertanyaan aneh.

Masalah saya adalah bahwa jika sumber daya mencapai 0 saya tidak tahu harus berbuat apa. Haruskah saya membuat semacam antrian? Haruskah saya melewatkan langkah objek. Apa?

Apa yang perlu Anda lakukan, tergantung pada logika permainan yang Anda buat. Anda dapat melakukan antrian, Anda dapat melewati. Bergantung pada bagaimana Anda berpikir game Anda seharusnya berperilaku. Koreksi saya, jika saya salah dengan pertanyaan Anda.

Petr Abdulin
sumber
1

Anda dapat menyimpan sejumlah permintaan sumber daya total per centang untuk semua konstruksi. Jika satu penyimpanan sumber daya mencapai kurang dari jumlah yang disyaratkan ini, maka semua konstruksi akan berhenti sepenuhnya sampai penyimpanan telah mengumpulkan cukup untuk mendukung setidaknya 1 centang produksi. Kemudian produksi dapat dilanjutkan.

Jadi, alih-alih menyimpan laju produksi sebagai pelampung, ini biner - baik yang diproduksi pabrik Anda dengan kecepatan penuh atau tidak.

Yang sedang berkata, pendekatan ini pada dasarnya sama dengan jawaban Jonathan, untuk kasus-kasus khusus tingkat produksi 0,0 dan 1,0 - float f sewenang-wenang dengan 0,0 <= f <= 1,0 mungkin lebih elegan karena Anda tidak mendapatkan pergerakan jumlah penyimpanan dendeng , tetapi logikanya harus sedikit lebih sederhana.

Hackworth
sumber