Làm thế nào để tôi phân phối tài nguyên giữa các nhà máy một cách công bằng khi tài nguyên gần cạn kiệt?


12

Tài nguyên chính trong trò chơi của tôi là khối lượng , được lưu trữ dưới dạng số dấu phẩy động thay đổi theo thời gian. Các nút tài nguyên tăng khối lượng và các nhà máy thoát nó. Ví dụ: nếu tôi có một nút tài nguyên đạt năng suất 5 khối mỗi giây, tôi sẽ tăng 5 * deltaTkhối lượng mỗi bước trò chơi. Khối lượng được hiển thị làm tròn đến số nguyên gần nhất và các chỉ số lãi / lỗ được hiển thị bằng phần mười.

Làm thế nào tôi nên xử lý khối lượng bằng không? Điều này tạo ra một điều kiện chạy đua nếu nhiều nhà máy đang cố gắng xây dựng cùng một lúc: Các nhà máy đầu tiên trong hàng đợi hoặc tiêu tốn ít tài nguyên hơn được ưu tiên một khi có nhiều tài nguyên đến và do đó xây dựng nhanh hơn các nhà máy khác.

Làm thế nào tôi có thể đối phó với điều này? Tôi có nên bỏ qua bước hoàn toàn?


Bah, bình luận của tôi đã không lưu. Tôi đã có một giải thích tốt hơn. Về cơ bản tôi có một tài nguyên được truy cập từng bước bởi mọi đối tượng. Mỗi đối tượng thêm hoặc bớt từ tài nguyên. Vấn đề của tôi là nếu tài nguyên chạm 0 tôi không biết phải làm gì. Tôi có nên thực hiện một hàng đợi của một số loại? Tôi có nên bỏ qua bước của một đối tượng. Gì?
Mob

3
Vòng tròn. Vấn đề được giải quyết.
Patrick Hughes

Câu trả lời từ Roy dưới đây kết hợp với nhận xét cho nó mô tả một hệ thống robin phong nha, dễ bảo trì và điều chỉnh. Miễn là vấn đề thiết kế ngay lập tức của bạn được giải quyết, tất cả đều tốt =)
Patrick Hughes

Câu trả lời:


9

Tôi đồng ý với Petr: Không có cách nào để làm điều đó. Bạn muốn làm như thế nào là vấn đề bạn muốn thiết kế trò chơi của mình như thế nào.

Tuy nhiên, trong trường hợp này, tôi nghĩ ngay lập tức rõ ràng là loại cơ khí mà bạn đang cố gắng đạt được: bạn chỉ muốn mọi thứ sản xuất nhanh nhất có thể, trong khối lượng bạn có sẵn.

Sản xuất trong khả năng

Tôi sẽ rút một lá khỏi cuốn sách của Chỉ huy tối cao, vì bạn đang làm một hệ thống rất giống với chúng: Nếu bạn sản xuất trên công suất, cách gọn gàng nhất để đối phó với nó là sản xuất chậm lại. Giảm năng lực sản xuất thực sự khá đơn giản.

Một thợ cơ khí tốc độ sản xuất

Mỗi bước cập nhật, các nhà máy của bạn không chỉ tạo ra một số tiền đã đặt: họ vận hành theo tốc độ sản xuất , điều này quyết định mức độ tiến bộ của chúng trong mỗi bước và khối lượng chúng sử dụng. Khi bạn sản xuất với 75% công suất, các nhà máy của bạn sẽ đạt được 75% tiến độ mỗi bước và sử dụng tới 75% khối lượng so với 100% công suất.

Để tính tốc độ sản xuất, trước khi xây dựng bất cứ thứ gì, bạn nên truy vấn các nhà máy của mình để xác định tổng tài nguyên sẽ được sử dụng ở bước này với công suất tối đa. Sau đó, bạn thực hiện một phép tính đơn giản:

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

Giả sử bạn cần 125 khối lượng bước này để sản xuất hết công suất, nhưng chỉ có 100 khối lượng bước này. Phương trình này cung cấp cho bạn tốc độ sản xuất là 0,8 (đại diện thập phân là 80%). Khi bạn nói với các nhà máy của bạn để thực sự thực hiện tòa nhà của họ , bạn đưa cho họ giá trị này để cho họ biết tốc độ họ đang xây dựng là bao nhiêu: và bây giờ việc sản xuất của bạn bị chậm lại.

Lựa chọn thay thế

Bạn cũng có thể bắt đầu đóng cửa các nhà máy tạm thời cho đến khi năng lực sản xuất giải phóng, và sẽ rất thú vị khi thấy điều đó xảy ra với các nhà máy ở xa máy phát điện khi công suất cực thấp.

Nhiều tài nguyên?

Tùy thuộc vào cách bạn xử lý việc này; có rất nhiều lựa chọn. Cách đơn giản nhất có lẽ là tính toán năng lực sản xuất cho từng tài nguyên và sau đó chọn mức thấp nhất , sao cho tài nguyên yếu nhất của bạn trở thành nút cổ chai cho tất cả các tài nguyên còn lại.


Tôi nghĩ bạn thậm chí không cần yêu cầu nhà máy sản xuất với tốc độ 80%, bởi vì bất cứ điều gì nhà máy của bạn tạo ra đều sử dụng một khối lượng cố định. Ví dụ: bạn xây dựng một chiếc xe tăng cần 100 khối lượng để xây dựng, thông thường nhà máy có thể sử dụng 2 khối lượng mỗi chu kỳ. Điều này có nghĩa là phải mất 50 chu kỳ để hoàn thành bể và mỗi chu kỳ bạn thêm 2 vào khối lượng hiện tại của bể. Bây giờ, bạn chỉ có sẵn 1 khối lượng, điều này có nghĩa là chu kỳ này, các bể hiện đang tiêu tốn khối lượng tăng thêm 1 thay vì 2. Sau mỗi chu kỳ, chỉ cần kiểm tra khối lượng hiện tại so với tổng khối lượng cần thiết để xem bể có hoàn toàn xây dựng hay không.
Thomas

Nếu bạn có sẵn 0 khối lượng, chỉ cần không thêm bất kỳ khối lượng nào vào bể. Thời gian cần thiết để xây dựng một cái gì đó theo cách này có thể thay đổi tùy thuộc vào thu nhập hàng loạt của bạn. Nếu bạn có 2 nhà máy có thể sử dụng 2 khối lượng / chu kỳ và chỉ có 3 thu nhập, bể 1 được xây dựng theo 50 chu kỳ, bể 2 trong 100. Một cách khác là chia tổng khối lượng có sẵn cho tất cả các nhà máy sử dụng nó ( tích cực xây dựng đôi khi). Tổng khối lượng mà một nhà máy có thể sử dụng có thể được nâng cấp bằng cách thêm các cấp cho nhà máy. Ví dụ: ở cấp 1, họ có thể tiêu tốn 2 khối lượng, ở cấp 2: 3, v.v.
Thomas

@Thomas Thêm khối lượng vào một sản phẩm trong quá trình sản xuất dường như là một cách quá phức tạp so với việc chỉ hoàn thành một tỷ lệ phần trăm của sản phẩm. Đặc biệt là vì nhà máy của bạn phải biết tất cả về hệ thống tài nguyên của bạn thay vì một tài sản "tỷ lệ sản xuất" đơn giản. Nếu kết quả cho người chơi là như nhau, hãy giữ việc thực hiện càng đơn giản càng tốt. Điều đó cũng giúp dễ dàng thực hiện các thay đổi trong tương lai, chẳng hạn như khi bạn thêm / xóa tài nguyên.
Hackworth

@Hackworth Tôi có xu hướng không đồng ý, nhà máy không cần biết về hệ thống tài nguyên. Nhà máy chỉ biết những gì nó xây dựng và bao xa. Hệ thống tài nguyên chỉ cho nhà máy thêm số tiền X vào bản dựng. Bằng cách này, bạn không cần tính phần trăm thu nhập tài nguyên mà nhà máy này có và bạn không cần dịch thu nhập tài nguyên sang phần trăm hoàn thành.
Thomas

6

Mặc dù tôi thích câu trả lời của Jonathan Hobbs nhưng tôi nghĩ một hệ thống xếp hàng thậm chí còn đơn giản hơn:

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;
        }
    }
}

Điều này có thể sẽ hoạt động trung bình giống như cách thực hiện của Jonathan. Tuy nhiên, giải pháp của Jonathan có thể gây ra vấn đề nếu tốc độ làm việc được đặt ở mức rất thấp và việc triển khai của tôi có thể có một nhà máy có khả năng phục hồi rất cao cho khung này khiến nó chặn các nhà máy khác trong một số khung.


+1 Tôi đang phát triển một trò chơi có tài nguyên kép, giống như trong câu hỏi và khi tôi giải quyết vấn đề khóa cung cấp, tôi dự định sử dụng một cái gì đó tương tự như thế này. Không phải mã chính xác, nhưng ý tưởng đằng sau nó. Người tiêu dùng có thể sử dụng tài nguyên trong một tích tắc sẽ được ưu tiên thấp hơn trong lần đánh dấu sau. Tôi cũng có kế hoạch thêm một cờ để cho biết người tiêu dùng này có ưu tiên cao hay không và trao quyền kiểm soát cờ đó cho người dùng.
John McDonald

Coi chừng đói nếu bạn dành cho họ những ưu tiên riêng biệt. :)
Roy T.

Mặc dù đói với các ưu tiên riêng biệt sẽ là mục đích. Bạn đã từng chơi Settlers 4 hay Knight & Merchants chưa? Nếu bạn xây dựng quá mức các tòa nhà, tài nguyên giới hạn sẽ chuyển đến các tòa nhà ngẫu nhiên và phải mất mãi mãi để hoàn thành mọi thứ. Nhưng họ cũng cho phép bạn chọn xem một tòa nhà có quan trọng hay không, trong trường hợp đó, tài nguyên sẽ được chuyển đến những tòa nhà quan trọng đó trước tiên. Điều quan trọng là không bao giờ xây dựng quá mức, hoặc nếu bạn làm, xây dựng quá ít nhất có thể.
John McDonald

5

Tôi đang phát triển một hệ thống cung cấp tương tự trong trò chơi của riêng mình, vì vậy tôi cũng đã suy nghĩ về cách giải quyết vấn đề khóa cung và sự thiên vị. Để minh họa vấn đề, tôi sẽ tạo một ví dụ đơn giản:

Nếu bạn có một danh sách: [nhà sản xuất1, người tiêu dùng1, người tiêu dùng2, người tiêu dùng3] và bạn cập nhật theo thứ tự, bắt đầu từ cung cấp = 0, bạn sẽ nhận được điều này:

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...

Consumer1 nhận được tất cả niềm vui, trong khi người tiêu dùng 2 và 3 chết đói cho đến khi người tiêu dùng 1 hài lòng. Tùy thuộc vào trò chơi của bạn, điều này có thể không được mong muốn. Tôi biết trong trò chơi của mình, không phải vậy. Khi tôi tiếp cận nó, tôi sẽ tạo ra một hàng đợi nơi người tiêu dùng được cho ăn trong một tích tắc sẽ di chuyển đến phía sau hàng đợi cho lần đánh dấu tiếp theo, mà tôi tin là những gì Roy T. đang nhận được. Ví dụ trên sẽ như thế này:

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...

Bằng cách này, mọi người sẽ nhận được phần tài nguyên của họ.

Tôi cũng có kế hoạch triển khai một hàng đợi bổ sung được sử dụng làm hàng đợi ưu tiên để người dùng có thể chọn một số cấu trúc nhất định để có mức độ ưu tiên tài nguyên. Hàng đợi ưu tiên sẽ luôn được phục vụ trước hàng đợi tiêu chuẩn. Đảm bảo rằng tất cả các nhà sản xuất được cập nhật trước, sau đó tiêu thụ tất cả tài nguyên thứ hai, nếu không hàng đợi sẽ bị hỏng khi bạn sản xuất tài nguyên một phần thông qua một tích tắc và một số người tiêu dùng đã bị bỏ đói.

Vì vậy, để tóm tắt: Cập nhật các nhà sản xuất, sau đó xếp hàng ưu tiên, di chuyển người tiêu dùng được cung cấp đến cuối hàng ưu tiên, sau đó cập nhật hàng đợi tiêu chuẩn, di chuyển người tiêu dùng được cung cấp đến cuối hàng đợi tiêu chuẩn.


Đưa đến giới hạn, điều đó có nghĩa là không có người tiêu dùng nào kết thúc cho đến khi mọi người tiêu dùng có thể kết thúc. Trong một kịch bản chuỗi sản xuất thực tế, điều đó khá khó xảy ra, và có thể khá thảm họa nếu ai đó muốn có một hàng đợi xây dựng cho một đội quân đông đảo. Anh ta thực tế sẽ không có quân đội trong toàn bộ thời gian quân đội đang được xây dựng.
Cardin

Câu trả lời đó là suy nghĩ ban đầu của tôi khi tôi đọc câu hỏi. Ngoài ra, cần lưu ý rằng khối lượng tiêu thụ trên mỗi tích tắc không nhất thiết là khối lượng để tạo ra một đơn vị hoàn chỉnh, mà là chi phí đơn vị theo thời gian cần thiết, vì vậy tôi không chắc chắn rằng các lo ngại của @ Cardin là hợp lệ, trừ khi đơn vị của bạn chi phí cho mỗi đánh dấu là rất gần với tổng tỷ lệ thu thập của bạn. Tôi chỉ đơn giản là có hàng đợi ưu tiên được quản lý rõ ràng bởi người chơi, để anh ta quyết định ai sẽ chết.
brice

@Cardin, bạn khá đúng, nhưng nó cũng có thể được sử dụng như một cơ chế trò chơi. Settlers 4, Knight & Merchants, Total Annihilation, Supreme Commander là những trò chơi mà tôi biết đã làm điều này. Bí quyết là không đạt được khóa cung cấp này, và nếu bạn làm vậy, hãy chắc chắn rằng bạn thoát khỏi khóa cung cấp càng sớm càng tốt. Thêm một hàng đợi ưu tiên cho phép mọi người một cách để thoát ra dễ dàng hơn.
John McDonald

3

Chà, tôi sẽ mở rộng ý tưởng của John, vì chúng tôi đã thảo luận điều này một chút trong trò chuyện .

chỉnh sửa: Giải pháp này thực sự chỉ thích hợp hơn nếu tiêu thụ có thể liên quan đến tần suất nhà máy sẽ nhận được một lô tài nguyên. Nếu tất cả đều giống nhau, thì bạn thực sự có thể sử dụng một hàng đợi.

Giải pháp của tôi: tất cả các nhà máy được liệt kê trong một hàng đợi ưu tiên. Ưu tiên tăng lên khi một nhà máy đang bị đói. Đói, ưu tiên, đặt thành không khi nhà máy đã tiêu thụ tài nguyên. Ưu tiên hàng đầu là luôn luôn có được các nguồn tài nguyên tiếp theo.

Về việc xác định nhà máy nào nhận được tài nguyên gì, trong một số loại mã giả:

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

Bằng cách này, các nhà máy của bạn sẽ lần lượt tạo ra 1 sản phẩm, nếu bạn muốn điều chỉnh bằng cách tính đến mức tiêu thụ để sản phẩm rẻ hơn được sản xuất thường xuyên hơn, bạn có thể tăng mức độ ưu tiên lên 1 / tiêu dùng.


Tôi muốn nâng cao điều này nhưng tôi không chắc điều này có nghĩa là gì - nó theo dõi tình trạng đói, nhưng nếu không (có lẽ) chỉ xoay qua hàng đợi chính xác như bình thường, và cả sự đói khát và ưu tiên sẽ không bao giờ xuất hiện để làm bất cứ điều gì
doppelreener

sự khác biệt sẽ trở nên rõ ràng nếu bạn tăng mức độ ưu tiên lên + = 1 / lượng ThisFactoryConsume, sau đó những người yêu cầu nhiều tài nguyên hơn để tạo ra một sản phẩm sẽ tụt lại phía sau một chút, cho phép những người ít tốn kém hơn lấy được nhiều lô tài nguyên tương ứng. Điều này thậm chí sẽ ra tài nguyên trên mỗi tỷ lệ nhà máy. Tuy nhiên, đây vẫn chưa phải là bằng chứng chính xác, vì số chết đói được đặt thành ma thuật số 0 mỗi khi tài nguyên được sử dụng bởi nhà máy, do đó, sẽ không được phân phối chính xác khi đổi mới tài nguyên.
Toni

Trên thực tế bây giờ tôi không chắc chắn nếu nó thực sự không được đảm bảo. Tôi sẽ cần phải vẽ một số biểu đồ và kiểm tra nó để chắc chắn.
Toni

oh, và ưu tiên là chất lượng của chính hàng đợi ưu tiên. Tôi sẽ không bận tâm giải thích làm thế nào để xây dựng một. Bản thân hàng đợi ưu tiên luôn được sắp xếp theo giá trị ưu tiên của các thành viên.
Toni

+1 Hiểu rằng đó là một hàng đợi ưu tiên, hoạt động của nó bây giờ có vẻ đơn giản: sàng lọc qua hàng đợi và chọn ra thứ sớm nhất có thể tiêu thụ tài nguyên. Nếu công suất bị phân chia nhiều (Bạn có 1.000 tài nguyên đánh dấu này, nhưng một trăm bản dựng 100 tài nguyên) thì đây không phải là vấn đề và mọi thứ được cung cấp khá tốt. Ngay cả khi thứ gì đó vượt quá tài nguyên của bạn, thì cuối cùng nó cũng có thể tiết kiệm đủ để đạt được một chút tiến bộ - có tác động làm chậm nó, hoặc loại bỏ những thứ lớn hoàn toàn có lợi cho những thứ nhỏ hơn là một điều tốt. Tôi thích nó rất nhiều. :)
doppelgreener

2

Câu hỏi lạ.

Vấn đề của tôi là nếu tài nguyên chạm 0 tôi không biết phải làm gì. Tôi có nên thực hiện một hàng đợi của một số loại? Tôi có nên bỏ qua bước của một đối tượng. Gì?

Những gì bạn cần làm, phụ thuộc vào logic trò chơi bạn tạo. Bạn có thể làm một hàng đợi, bạn có thể bỏ qua. Phụ thuộc vào cách bạn nghĩ rằng trò chơi của bạn nên cư xử. Đúng tôi, nếu tôi sai về câu hỏi của bạn.


1

Bạn có thể giữ một số lượng tổng nhu cầu tài nguyên trên mỗi đánh dấu cho tất cả các công trình. Nếu một bộ lưu trữ tài nguyên đạt ít hơn số lượng yêu cầu này, thì tất cả việc xây dựng sẽ dừng hoàn toàn cho đến khi bộ lưu trữ được thu thập đủ để hỗ trợ ít nhất 1 tick sản xuất. Sau đó sản xuất có thể tiếp tục.

Vì vậy, thay vì lưu trữ tốc độ sản xuất dưới dạng nổi, nó là nhị phân - hoặc nhà máy của bạn sản xuất ở tốc độ tối đa hoặc không.

Điều đó đang được nói, cách tiếp cận này về cơ bản giống như câu trả lời của Jonathan, đối với các trường hợp đặc biệt về tỷ lệ sản xuất 0,0 và 1,0 - một số float tùy ý với 0,0 <= f <= 1.0 có thể thanh lịch hơn khi bạn không bị dịch chuyển số lượng lưu trữ giật , nhưng logic nên đơn giản hơn một chút.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.