আক্রমণ বনাম প্রতিরক্ষা এবং বিজয়ী কে? [বন্ধ]


12

আমি মোবাইলে একটি নতুন সাধারণ গেম তৈরি করার প্রক্রিয়াধীন এবং আমি নিম্নলিখিত অংশে বেশ কয়েক দিন ব্যয় করেছি।

সরলতার জন্য, বলি যে আমার দু'জন যোদ্ধা রয়েছে। তাদের একমাত্র বৈশিষ্ট্য হ'ল আক্রমণ এবং প্রতিরক্ষা। যখন প্রথম আক্রমণ, তখন একমাত্র বিষয়টি হ'ল তার আক্রমণ এবং প্রতিপক্ষের প্রতিরক্ষা। এবং বিপরীতভাবে.

তাদের কাছে সরঞ্জাম, আইটেম, স্ট্যামিনা বা স্বাস্থ্য নেই। জাস্ট অ্যাটাক বনাম প্রতিরক্ষা।

উদাহরণ:

  • যোদ্ধা 1:

    আক্রমণ: 50, প্রতিরক্ষা: 35

  • যোদ্ধা 2:

    আক্রমণ 20, প্রতিরক্ষা: 80

লড়াই প্রক্রিয়াটি কেবল একটি একক আক্রমণ যা বিজয়ী নির্ধারণ করবে। সুতরাং, একাধিক আক্রমণ বা রাউন্ড। আমি এটিকে নির্জনবাদী করতে চাই না, তবে অপ্রত্যাশিত একটি হালকা সংস্করণ যুক্ত করব। নিম্ন আক্রমণ সহ যোদ্ধা উচ্চতর প্রতিরক্ষা সহ অন্য যোদ্ধাকে জিততে সক্ষম হবে (তবে অবশ্যই প্রতিবার নয়)

আমার প্রথম ধারণাটি এটিকে রৈখিক করা এবং একটি অভিন্ন র্যান্ডম নম্বর জেনারেটর কল করা ছিল।

If Random() < att1 / (att1 + def2) {
    winner = fighter1
} else {
    winner = fighter2
} 

আক্রমণ 50 এবং প্রতিরক্ষা 80 এর উদাহরণ হিসাবে, আক্রমণকারী যোদ্ধার জিততে প্রায় 38% থাকবে। যাইহোক, আমার কাছে মনে হচ্ছে অপ্রত্যাশিত খুব দূরে এবং সবচেয়ে খারাপ যোদ্ধারা প্রচুর জয়ী হবে।

আমি ভাবছিলাম যে আপনি কীভাবে একই পরিস্থিতিতে কাজ করেছেন।

পিএস আমি এই কিউএনএ এবং অন্যান্য উত্সগুলিতে অনেক অনুসন্ধান করেছি এবং এসই এর পক্ষে খুব বিস্তৃত হিসাবে উল্লিখিত অনুরূপ প্রশ্নগুলি পেয়েছি। তবে এগুলির অনেকগুলি বৈশিষ্ট্য, অস্ত্র, আইটেম, শ্রেণী ইত্যাদি রয়েছে যা এটিকে খুব জটিল করে তুলতে পারে। আমি মনে করি আমার সংস্করণটি এসই এর কিউএনএ স্টাইলে এটি ফিট করার জন্য অনেক সহজ।


1
আপনি কিসের জন্য সন্ধান করছেন? আক্রমণ এবং প্রতিরক্ষার জন্য আপনি কতগুলি মূল্যবোধের দিকে তাকিয়ে রয়েছেন এবং এই ব্যাপ্তিতে কোনও দুটি সংখ্যার কোনও স্থির পরিণতি হওয়া উচিত? উদাহরণস্বরূপ, আক্রমণে থাকা কোনও যোদ্ধা 90 ডিফেন্সে কোনও যোদ্ধাকে পরাজিত করতে পারেন?
নিলস

@ ব্যবহারকারী 2645227 আমি বলতে পারি যে পরিসীমাটি 1 থেকে 400 এর মধ্যে রয়েছে No না, আমি কোনও সিদ্ধান্তবাদী সিদ্ধান্ত নিতে চাই না এবং 1 টি আক্রমণ করার সম্ভাবনাটি দিতে চাই না প্রতিরক্ষা 400, তবে সত্যই বিরল ক্ষেত্রে।
তাসোস

1
সুতরাং আপনি যদি Att (মিনিট) -def (সর্বাধিক) এবং Att (সর্বাধিক) -def (মিনিট) নেন তবে এটি আপনাকে 400 -400 থেকে 400 এর মধ্যে 800 রেঞ্জ দেয়। আপনি চাইলে আপনার এলোমেলো ব্যাপ্তি পুরো ব্যাপ্তিকে coverেকে দেবে প্রতিরক্ষা - আক্রমণ আপনাকে একটি চৌম্বক আকারে একটি স্কেলিং মার্জিন দেয় যা আপনাকে জিততে হিট করতে হবে। এটি এলোমেলোভাবে কিছুটা হ্রাস করা উচিত। ফলাফলগুলি আরও কেন্দ্রীভূত করার জন্য আপনি যে কার্ভটি সন্ধান করছেন তাতে আঘাত না করা পর্যন্ত আপনি ফিল্ডস উদাহরণ বা যেকোন প্রকারে ফিডাল ব্যবহার করতে পারেন।
নিলস

উত্তর:


24

আপনি যদি চান যে আপনার লড়াইয়ের ফলাফলগুলি আরও অনুমানযোগ্য হতে পারে তবে সম্পূর্ণ নির্মূলবাদী না হয়ে থাকে, সর্বোত্তম এন সিস্টেমটি করুন।

লড়াইয়ের nবার পুনরাবৃত্তি করুন (যেখানে nএকটি অসম সংখ্যা হওয়া উচিত) এবং যোদ্ধা যিনি আরও বেশিবার বিজয়ী হন তা ঘোষণা করুন। আপনার nযত কম বিস্ময়কর জয় এবং ক্ষতির জন্য আপনার মানটি তত বড় ।

const int FIGHT_REPETITONS = 5 // best 3 of 5. Adjust to taste.

int fighter1wins = 0;
int fighter2wins = 0;

for (int i = 0; I < FIGHT_REPETITONS; I++) {

    If (Random() < att1 / (att1 + def2)) {
        fighter1wins++;
    } else {
        fighter2wins++;
    } 

}

If (fighter1wins > fighter2wins) {
    winner = fighter1
} else {
    winner = fighter2
} 

এই সিস্টেমটি কেবলমাত্র বিশেষ ক্ষেত্রে কাজ করে যেখানে কোনও লড়াই জয় বা পরাজয়ের একটি সাধারণ বাইনারি ফলাফল। যখন কোনও লড়াইয়ের আরও জটিল ফলাফল হয়, যেমন বিজয়ী এখনও জয়টি কতটা কাছাকাছি তার উপর নির্ভর করে কিছু হিট পয়েন্ট হারিয়ে ফেলে, এই পদ্ধতির কাজ আর হয় না। আরও সাধারণ সমাধান হ'ল আপনার এলোমেলো সংখ্যা তৈরি করার পদ্ধতিটি পরিবর্তন করা। আপনি যখন একাধিক এলোমেলো সংখ্যা তৈরি করেন এবং তারপরে গড় নিয়ে যান, ফলাফলগুলি পরিসরের কেন্দ্রের কাছে ক্লাস্টার হবে এবং আরও চরম ফলাফল আরও বিরল হবে। উদাহরণ স্বরূপ:

double averagedRandom3() {
    return (Random() + Random() + Random()) / 3.0;
}

এর মতো বিতরণ বক্ররেখা থাকবে:

3 ডি 20/3 বিতরণ

( যোদ্ধার ছবি সৌজন্যে - গেম মেকানিক সূত্রগুলি ডিজাইন করার জন্য একটি সত্যিকারের দরকারী সরঞ্জাম যা কেবলমাত্র ট্যাবলেটপ গেমগুলির জন্য নয়)

আমার বর্তমান প্রকল্পে আমি একটি সহায়ক-ফাংশন ব্যবহার করছি যা একটি স্বেচ্ছাসেবী নমুনার আকার সেট করতে দেয়:

double averagedRandom(int averageness) {
     double result = 0.0;
     for (var i = 0; i < averageness; i++) {
         result += Random();
     }
     return result / (double)averageness;
}

একটি ভাল পদ্ধতির বলে মনে হচ্ছে। একটি প্রশ্ন. গড় রেন্ডোম 3 () ফাংশনে, আপনার +পরিবর্তে ব্যবহার করা উচিত *বা আমি যা করি তা ভুল বুঝেছি?
তাসোস

@ টাসো হ্যাঁ, + হওয়া উচিত, * নয়। আমার কাছে একটি এলোমেলো-ফাংশন রয়েছে যা একাধিক নমুনাগুলিকে গুন করে। এটি আপনাকে নিম্ন মানের জন্য একটি শক্তিশালী পক্ষপাত সহ একটি এলোমেলো সংখ্যা ফাংশন দেয় যা কিছু পরিস্থিতিতেও কার্যকর হতে পারে।
ফিলিপ

1
আমি প্রশ্নটি 1-2 দিনের জন্য উন্মুক্ত রাখব এবং যদি আমার আর উত্তর না থাকে তবে আমি আপনার চয়ন করব। আমি এটিকে উন্নত করে দিয়েছি তবে আপনি যদি কিছু মনে করেন না তবে অন্যান্য উত্তরের জন্যও সুযোগ দিতে চাই।
তাসোস

আমি মনে করি এই উত্তরটি ইতিমধ্যে যথেষ্ট ভোট পেয়েছে যা এই উত্তরটিকে উত্তর হিসাবে চিহ্নিত করার যোগ্য করে
হামজা হাসান

1
কিছু লোক যদি বিকল্প পদ্ধতির সাথে আসে তবে আমি কৌতূহলীও হব। এক ব্যক্তি এই উত্তরটিকে হ্রাস করেছেন। হতে পারে তারা একটি বিকল্প সরবরাহ করতে চান।
ফিলিপ

8

এটিই আমি আমার লর্ডস অফ কনকোস্ট ইমিটেটর অ্যাপলেটটিতে কোনও যুদ্ধের বিজয়ী নির্ধারণ করতে ব্যবহার করেছি। আপনার পরিস্থিতির মতো এই গেমটিতে কেবল একটি আক্রমণ মূল্য এবং প্রতিরক্ষা মান রয়েছে। আক্রমণকারীর যে সম্ভাবনা বেশি জেতা তার আক্রমণকারের যত বেশি পয়েন্ট থাকে এবং ডিফেন্সের যত কম পয়েন্ট থাকে, আক্রমণের 50% সম্ভাবনার সাফল্যের সমান মূল্যবোধ সহ।

অ্যালগরিদম

  1. একটি এলোমেলো মুদ্রা ফ্লিপ করুন।

    1A। শিরোনাম: প্রতিরক্ষা একটি পয়েন্ট হারায়।

    1B। লেজ: মাথা একটি পয়েন্ট হারায়।

  2. প্রতিরক্ষা এবং আক্রমণকারী উভয়ের যদি এখনও পয়েন্ট থাকে তবে 1 ধাপে ফিরে যান।

  3. যে 0 পয়েন্টের নীচে থাকে সে যুদ্ধটি হেরে যায়।

    3a। আক্রমণকারী 0-এ নেমে এসেছে: আক্রমণ ব্যর্থ হয়।

    3b। 0 এ প্রতিরক্ষা নিচে: আক্রমণ সফল হয়।

আমি এটি জাভাতে লিখেছি, তবে এটি অন্যান্য ভাষায় সহজে অনুবাদযোগ্য হওয়া উচিত।

Random rnd = new Random();
while (att > 0 && def > 0)
{
    if (rnd.nextDouble() < 0.5)
        def--;
    else
        att--;
}
boolean attackSucceeds = att > 0;

একটি উদাহরণ

উদাহরণস্বরূপ, আসুন যে সম্ভাবনা 50% কিনা তা নিশ্চিত করার জন্য এটি = 2 এবং ডিফ = 2 বলুন।

যুদ্ধের সিদ্ধান্ত নেওয়া হবে সর্বাধিক n = att + def - 1মুদ্রা উল্টানো, বা এই উদাহরণে 3 (এটি মূলত এখানে 3 এর মধ্যে সেরা)। এখানে আছে 2 হয় এন সম্ভাব্য সমাহার মুদ্রা ফ্লিপ। এখানে, "ডাব্লু" অর্থ আক্রমণকারী মুদ্রা ফ্লিপ জিতেছে এবং "এল" এর অর্থ আক্রমণকারী মুদ্রার ফ্লিপটি হারিয়েছে।

L,L,L - Attacker loses
L,L,W - Attacker loses
L,W,L - Attacker loses
L,W,W - Attacker wins
W,L,L - Attacker loses
W,L,W - Attacker wins
W,W,L - Attacker wins
W,W,W - Attacker wins

আক্রমণকারী 4/8 বা 50% মামলায় জয়ী হয়।

ম্যাথ

এই সাধারণ অ্যালগরিদম থেকে উদ্ভূত গাণিতিক সম্ভাবনাগুলি নিজেই অ্যালগরিদমের চেয়ে জটিল।

সংশ্লেষের সংখ্যাটি যেখানে সঠিকভাবে x এলএস সংমিশ্রণ কার্য দ্বারা দেওয়া হয়:

C(n, x) = n! / (x! * (n - x)!)

আক্রমণকারী জয়লাভ করে যখন সেখানে 0এবং att - 1এলএস এর মধ্যে থাকে । বিজয়ী সংমিশ্রণের সংখ্যাটি একটি সংখ্যামূলক দ্বিপদী বিতরণ 0মাধ্যমে সংমিশ্রণের যোগফলের সমান att - 1:

    (att - 1)
w =     Σ     C(n, x)
      x = 0

আক্রমণকারী সম্ভাবনা বিজয়ী W 2 দ্বারা বিভক্ত এন , একটি ক্রমবর্ধমান বাইনমিয়াল সম্ভাব্যতা:

p = w / 2^n

স্বেচ্ছাসেবী attএবং defমানগুলির জন্য এই সম্ভাবনাটি গণনা করার জন্য এখানে জাভা কোডটি রয়েছে :

/**
 * Returns the probability of the attacker winning.
 * @param att The attacker's points.
 * @param def The defense's points.
 * @return The probability of the attacker winning, between 0.0 and 1.0.
 */
public static double probWin(int att, int def)
{
    long w = 0;
    int n = att + def - 1;
    if (n < 0)
        return Double.NaN;
    for (int i = 0; i < att; i++)
        w += combination(n, i);

    return (double) w / (1 << n);
}

/**
 * Computes C(n, k) = n! / (k! * (n - k)!)
 * @param n The number of possibilities.
 * @param k The number of choices.
 * @return The combination.
 */
public static long combination(int n, int k)
{
    long c = 1;
    for (long i = n; i > n - k; i--)
        c *= i;
    for (long i = 2; i <= k; i++)
        c /= i;
    return c;
}

পরীক্ষার কোড:

public static void main(String[] args)
{
    for (int n = 0; n < 10; n++)
        for (int k = 0; k <= n; k++)
            System.out.println("C(" + n + ", " + k + ") = " + combination(n, k));

    for (int att = 0; att < 5; att++)
        for (int def = 0; def < 10; def++)
            System.out.println("att: " + att + ", def: " + def + "; prob: " + probWin(att, def));
}

আউটপুট:

att: 0, def: 0; prob: NaN
att: 0, def: 1; prob: 0.0
att: 0, def: 2; prob: 0.0
att: 0, def: 3; prob: 0.0
att: 0, def: 4; prob: 0.0
att: 1, def: 0; prob: 1.0
att: 1, def: 1; prob: 0.5
att: 1, def: 2; prob: 0.25
att: 1, def: 3; prob: 0.125
att: 1, def: 4; prob: 0.0625
att: 1, def: 5; prob: 0.03125
att: 2, def: 0; prob: 1.0
att: 2, def: 1; prob: 0.75
att: 2, def: 2; prob: 0.5
att: 2, def: 3; prob: 0.3125
att: 2, def: 4; prob: 0.1875
att: 2, def: 5; prob: 0.109375
att: 2, def: 6; prob: 0.0625
att: 3, def: 0; prob: 1.0
att: 3, def: 1; prob: 0.875
att: 3, def: 2; prob: 0.6875
att: 3, def: 3; prob: 0.5
att: 3, def: 4; prob: 0.34375
att: 3, def: 5; prob: 0.2265625
att: 3, def: 6; prob: 0.14453125
att: 3, def: 7; prob: 0.08984375
att: 4, def: 0; prob: 1.0
att: 4, def: 1; prob: 0.9375
att: 4, def: 2; prob: 0.8125
att: 4, def: 3; prob: 0.65625
att: 4, def: 4; prob: 0.5
att: 4, def: 5; prob: 0.36328125
att: 4, def: 6; prob: 0.25390625
att: 4, def: 7; prob: 0.171875
att: 4, def: 8; prob: 0.11328125

পর্যবেক্ষণ

0.0আক্রমণকারীটির 0পয়েন্ট থাকলে সম্ভাবনাগুলি হ'ল , 1.0আক্রমণকারীটির পয়েন্ট থাকলেও ডিফেন্সের 0পয়েন্ট 0.5থাকে, পয়েন্ট সমান 0.5হলে আক্রমণকারীর ডিফেন্সের চেয়ে কম পয়েন্ট 0.5থাকে এবং আক্রমণকারীর ডিফেন্সের চেয়ে বেশি পয়েন্ট থাকলে তার চেয়ে বেশি হয় ।

টেকিং att = 50এবং def = 80আমি স্যুইচ করা প্রয়োজন BigDecimalএড়ানোর ওভারফ্লো থেকে গুলি, কিন্তু আমি 0,0040 সম্পর্কে একটি সম্ভাব্যতা পেতে।

মান এবং মানগুলির attগড় হিসাবে মান পরিবর্তন করে আপনি সম্ভাব্যতা 0.5 এর কাছাকাছি করতে পারেন । Att = 50, Def = 80 হয়ে যায় (65, 80), যা 0.1056 এর সম্ভাব্যতা দেয়।attdef


1
আরেকটি আকর্ষণীয় পদ্ধতির। অ্যালগরিদমটি সহজেই ভিজ্যুয়ালাইজ করা যায়, যা বেশ আকর্ষণীয় দেখাতে পারে look
ফিলিপ

5

আপনি কোনও সাধারণ বন্টন থেকে নমুনাযুক্ত এলোমেলো সংখ্যা দ্বারা আক্রমণটিকে পরিবর্তন করতে পারেন। এইভাবে বেশিরভাগ সময় ফলাফলটি আপনি প্রত্যাশা মতোই হন তবে মাঝে মাঝে একটি উচ্চতর আক্রমণ একটি নিম্ন প্রতিরক্ষার বিরুদ্ধে হেরে যায় বা নিম্ন আক্রমণটি উচ্চতর প্রতিরক্ষার বিরুদ্ধে জিততে পারে। আক্রমণ এবং প্রতিরক্ষা ব্যবস্থার পার্থক্য বাড়ার সাথে সাথে এই ঘটনার সম্ভাবনা আরও কম হবে।

if (att1 + norm(0, sigma) - def2 > 0) {
  winner = fighter1;
}
else {
  winner = fighter2;
}

ফাংশনটি norm(x0, sigma)স্ট্যান্ডার্ড বিচ্যুতি সিগমা সহ x0 কেন্দ্রিক একটি সাধারণ বিতরণ থেকে নমুনাযুক্ত একটি ফ্লোট ফেরত দেয়। বেশিরভাগ প্রোগ্রামিং ল্যাঙ্গুয়েজ এ জাতীয় ফাংশন সহ একটি লাইব্রেরি সরবরাহ করে তবে আপনি যদি এটি তৈরি করতে চান তবে এই প্রশ্নটি একবার দেখুন । আপনাকে সিগমাটি এমনভাবে সামঞ্জস্য করতে হবে যে এটি 'ঠিক মনে করে', তবে 10-20 এর মান শুরু করার জন্য ভাল জায়গা হতে পারে।

কয়েকটি সিগমা মানগুলির জন্য, প্রদত্ত বিজয়ের সম্ভাবনাটি att1 - def2এরকম দেখাচ্ছে: জয়ের সম্ভাবনা


এটি উল্লেখ করার মতোও হতে পারে যে সাধারণ বিতরণকৃত মানগুলির কোনও সত্যিকারের সীমানা নেই, সুতরাং কোনও খেলায় সাধারণ-বিতরণ করা এলোমেলো মানগুলি ব্যবহার করার সময় ফলাফলটি বাছাই করা বুদ্ধিমান হতে পারে তবে অত্যন্ত চূড়ান্ত মানগুলির অসম্ভব তবে অসম্ভব পরিস্থিতি এড়ানো যায় না যা খেলা ভাঙ্গতে পারে।
ফিলিপ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.