දිවි ගලවා ගැනීමේ ක්‍රීඩාව - ඔබේ වෘකයා සාදන්න


240

මණ්ඩලය

මෙම මණ්ඩලය සෛල දෙකක් මාන මාලාවක් ඇත. සෛල ජනගහනයෙන් සතුන් වේ. සෑම දිනකම, මණ්ඩලයේ සිටින සියලුම සතුන් එකවර එක් පියවරක් ගනී. සතුන් දෙදෙනෙකු හෝ වැඩි ගණනක් එකම සෛලයකට ගියහොත්, එක් අයෙකු ඉතිරි වන තුරු ඔවුන් සටන් කරයි. සිදුවිය හැකි පියවර සහ ප්‍රහාර පහත පරිදි වේ:

  • පියවර - { Move.UP, Move.RIGHT, Move.DOWN, Move.LEFT, Move.HOLD}
  • ප්රහාර - { Attack.ROCK, Attack.PAPER, Attack.SCISSORS, Attack.SUICIDE}

සතුන් සටන් කරන්නේ රොක්-කඩදාසි-කතුර වාදනය කිරීමෙනි. සම්මත නීති අදාළ වන නමුත් වෙනස් කිරීම් දෙකක් සමඟ. පළමුව, ඔබට ඕනෑම වේලාවක සියදිවි නසා ගත හැකිය. දෙවනුව, ටයි පටියක් ව්‍යාජ ලෙස කැඩී ඇත. සතුන් දෙදෙනෙකුට වඩා එකිනෙක ගැටුණහොත්, දෙදෙනෙකු ඉතිරි වන තෙක් සටන් කිරීම සඳහා ව්‍යාජ ලෙස තෝරා ගනු ලැබේ.

ක්රීඩකයන්

සත්ව හැසිරීම සහ පෙනුම පහත පරිදි වේ.

  • සිංහයා
    • චරිතය නියෝජනය කරයි L. චලනය DOWN, RIGHTපසුව පුනරාවර්තනය. ව්‍යාජ ලෙස පහර දීම PAPERහෝ සමඟ SCISSORS.
  • වලහා
    • චරිතය නියෝජනය කරයි B. පියවර DOWNx 4, RIGHTx 4, UPx 4, LEFTx 4, පසුව දරුවා. සමඟ ප්රහාර PAPER.
  • ගල්
    • චරිතය නියෝජනය කරයි S. චලනයන් HOLD. සමඟ ප්රහාර ROCK.
  • වුල්ෆ්
    • පිළිතුරක් ලෙස ඉදිරිපත් කරනු ලබන වෘකයන් පමණක් ඇතුළත් වේ. 'ඩබ්ලිව්' නියෝජනය කරයි. ඕනෑම චලනයකින් චලනය වේ. ඕනෑම ප්‍රහාරයකින් පහර දීම

පහත දැක්වෙන අච්චුවේ ඇති හිස් තැන් පුරවා ඔබ වුල්ෆ් ක්‍රියාත්මක කරනු ඇත. සියලුම ඉදිරිපත් කිරීම් ජාවාහි තිබිය යුතු අතර එය තනි ගොනුවක අඩංගු විය යුතුය. විකල්පයක් ලෙස, @ProgrammerDan ලිඛිත ඇත දවටනය පන්ති -ජාවා නොවන කරුණු ඉදිරිපත් කිරීම සඳහා තරගයක් විහිදී ඇති.

// Optional code here
public class Wolf extends Animal {
    // Optional code here
    public Wolf() { super('W'); /* Optional code here */ }
    public Attack fight(char opponent) { /* Required code here. Must return an Attack. */ }
    public Move move() { /* Required code here. Must return a Move. */ }
    // Optional code here
}

පුනරාවර්තන 1,000 ක් සමඟ අත්හදා බැලීම් පහකට පසුව වැඩිම සාමාන්‍ය වෘකයන් සංඛ්‍යාවක් සිටින ඉදිරිපත් කිරීම ජය ගනී. නව පිළිතුරක් පළ කරන සෑම අවස්ථාවකම මම ජයග්‍රාහකයා යාවත්කාලීන කරමි (නමුත් පළමු පැය 24 තුළ නොවේ).

මෙවලම්

  • පහත දැක්වෙන ස්වරූපයෙන් ඔබේ ආසන්න වටපිටාවේ කුඩා සිතියමක් ඔබට ලබා දී ඇත.
    • char[][] surroundingsආසන්නයේ ඇති සතුන් නියෝජනය කරන අක්ෂර 3 සිට 3 දක්වා ශුන්‍ය සුචිගත කර ඇත. හිස් උළු අවකාශ අක්ෂරයකින් ('') නිරූපණය කෙරේ. ඔබ සිටින්නේ surroundings[1][1]. උදාහරණයක් ලෙස, ඔබේ දකුණට වනු ඇති surroundings[1][2]අතර ඔබට ඉහළින් surroundings[0][1]. චලනය වීමට ඉල්ලා සිටීමට පෙර ඔබේ වටපිටාව යාවත්කාලීන කර ඇත, නමුත් සටන් කිරීමට ඉල්ලා සිටින විට එය යල් පැන ගිය එකක් විය හැකිය.
  • ඔබගේ වුල්ෆ්ගේ ආයාචනා, ඉල්ලීම් ගෙනයාම සහ ප්‍රහාර ඉල්ලීම් අතර දත්ත දිගටම පැවතිය හැකිය. ඔබට වෙනත් වුල්ෆ් පන්තියක් විසින් සාදන ලද ලිපිගොනු කියවීමට හෝ වෙනස් කිරීමට නොහැක.
  • පහත දැක්වෙන ස්වරූපයෙන් ඔබට සිතියමේ ප්‍රමාණය ලබා දී ඇත
    • int MAP_SIZE

උපකල්පන

  • සියලුම ඉදිරිපත් කිරීම් අනෙක් සියලුම ඉදිරිපත් කිරීම්වලට මෙන්ම සිංහයන්, වලසුන් සහ ගල් වලට එරෙහිව එකම පුවරුවක තරඟ කරනු ඇත
  • පුවරුව යනු දිග දෙපැත්තකින් යුත් චතුරස්රයකි, sqrt(n+3)*20එහිදී nඉදිරිපත් කිරීම් ගණන වේ. සෑම පැත්තක්ම ඔතා ඇති බැවින් ඔබට ඕනෑම දිශාවකට අනන්ත ලෙස ආරක්ෂිතව ගමන් කළ හැකිය.
  • පුවරු ධාරිතාවයෙන් ඩොලර් 25% කින් සමාකරණය ආරම්භ වන අතර එක් එක් සත්වයන් 100 ක්ම පුවරුව පුරා බෙදා හරිනු ලැබේ.
  • චලනය කිරීමට ඉල්ලා සිටින විට සතෙකු ව්‍යතිරේකයක් විසි කරන්නේ නම්, එම සත්වයා එසේ කරනු ඇත HOLD
  • සටන් කිරීමට ඉල්ලා සිටින විට සතෙකු ව්‍යතිරේකයක් විසි කරන්නේ නම්, එම සත්වයා එසේ කරනු ඇත SUICIDE
  • පාලකය පරීක්ෂා කරන විට සතෙකුට ලිපියක් නොමැති නම්, එම සත්වයා වහාම මිය යනු ඇත

ආරම්භ කිරීම සහ උපදෙස් පරීක්ෂා කිරීම

ඔබගේ ඉදිරිපත් කිරීම පරීක්ෂා කිරීමට අවශ්‍ය මෙවලම් මෙහි සොයාගත හැකිය . පහත සබැඳි ලිපිගොනු එම සබැඳියෙන් ලබා ගත යුතුය.

  • ExampleRun.gif - වැඩසටහන ක්‍රියාත්මක වන තත්පර 5-10 ක gif.
  • ලකුණු පුවරුව - තරඟයේ නවතම ප්‍රති results ල.
  • Wild.jar - පෙර සැකසූ සතුන් නැරඹීම සඳහා ඔබට ධාවනය කළ හැකි ක්‍රියාත්මක කළ හැකි ය.
  • Wild.zip - පෙර සැකසූ සතුන් කිහිප දෙනෙකු සමඟ පාලක වැඩසටහන ක්‍රියාත්මක කරන NetBeans ව්‍යාපෘතිය. ඔබගේ ඉදිරිපත් කිරීම සංවර්ධනය කිරීමට මෙය භාවිතා කරන්න.
  • WildPopulated.zip - ඉහත ආකාරයටම, නමුත් ඔබට එරෙහිව පරීක්ෂා කිරීම සඳහා ඉදිරිපත් කිරීම් 40 ක් පමණ එකතු කර ඇත. කාර්ය සාධන ගැටළු හේතුවෙන් GUI ද ඉවත් කර ඇත. ඔබ ධාවනය කිරීමෙන් මොහොතකට පසු ප්‍රති results ල දිස්වනු ඇත. ජාවා නොවන ඉදිරිපත් කිරීම් අදහස් දක්වන්නේ අමතර බාගැනීම් සහ උත්සාහයන් අවශ්‍ය වන බැවිනි. ක්ෂේත්‍රයට එරෙහිව ඔබගේ ඉදිරිපත් කිරීම පරීක්ෂා කිරීමට මෙය භාවිතා කරන්න.
  • Wolf.txt - ජාවා හි වුල්ෆ් පංතිය බොළඳ ලෙස ක්‍රියාත්මක කිරීම. මට බැර නොකර ඔබට එම ක්‍රියාත්මක කිරීම පුළුල් කළ හැකිය.

ඔබේ පන්තිය පරීක්ෂා කිරීමට:

  • Wild.zip බාගන්න
  • ඔබගේ Wolf.java සහ Wolf පන්තිය අද්විතීය දෙයකට නම් කරන්න
  • ඔබගේ UniquelyNamedWolf.java ගොනුව වල් \ src \ සතුන් \ වෙත එක් කරන්න
  • වල් පන්තියේදී, මේ ආකාරයට ඔබේ පන්තිය classesඅරාවකට එක් කරන්න .
    • Class[] classes = { UniquelyNamedWolf.class, Bear.class, Lion.class, Stone.class, Wolf.class };
  • නැවත ගොඩනඟා ධාවනය කරන්න

පරීක්ෂණ කටයුතු සඳහා සියලු ඉදිරිපත් කිරීම් අඩංගු තවත් ව්‍යාපෘතියක් ද මම ඇතුළත් කළෙමි. මම එය නිර්මාණාත්මකව නම් කළේ "WildPopulated" යනුවෙනි. ජාවා නොවන වෘකයන් තිදෙනා හෝ හතර දෙනා අදහස් දැක්වූයේ ඔවුන් දුවන්නට අමතර වැඩ සහ බාගැනීම් අවශ්‍ය වන බැවිනි. මම පල කල එකක් ක්රියාත්මක කළ යුතු ශුන්ය අමතර වැඩ. GUI ද වේගය වෙනුවෙන් අදහස් දැක්වීය.

ලකුණු පුවරුව 2014 අප්‍රියෙල් 22

ලකුණු පුවරුව ගූගල් ඩ්‍රයිව් වෙත ගෙන යන ලදි. එය මෙතැනින් බලන්න. නව ඉදිරිපත් කිරීම් පැමිණෙන විට එය අනියම් පදනමක් මත යාවත්කාලීන වේ (එනම්, මම එයට පිවිසෙන විට).

පැති අභියෝගය - NoHOLD

(ශුන්‍යයේ මෙන්) සහභාගීත්වයක් නොමැති නිසා ඉවත් කරන ලදි. කෙසේ වෙතත් එය මුල් අභියෝගයේ කොටසක් නොවේ.


5
Us රුෂර් ඒක භයානකයි වගේ. රැපර් අඩංගු මගේ පිළිතුර ප්‍රජා විකියෙන් කළ හැකිය. සම්පාදක / පරිවර්තක නිකුතුව සම්බන්ධයෙන් ගත් කල, භාවිතය පිළිබඳ පැහැදිලි උපදෙස් ලබා දීම ඉදිරිපත් කරන්නාගේ වගකීම විය යුතු යැයි මම සිතමි. උපදෙස් අපැහැදිලි හෝ සංකීර්ණ නම් ඔබට ඉදිරිපත් කිරීම ප්‍රතික්ෂේප කළ හැකිය :)
ProgrammerDan

4
"* ඔබට පහත දැක්වෙන ස්වරූපයෙන් සිතියමේ ප්‍රමාණය ලබා දී ඇත: int MAP_SIZE" මෙය භාවිතා කරන්නේ කෙසේදැයි සොයා ගැනීමට මට ගැටලුවක් තිබේ. නෙට්බීන්ස් පවසන්නේ MAP_SIZEව්‍යාපෘතියේ කිසිදු ලිපිගොනුවක නූලක් නොමැති බවයි.
undergroundmonorail

6
කඩදාසි පෙන්වන ගස් ගැන කුමක් කිව හැකිද?
මුකුල් කුමාර්

3
Us රුෂර්, මම හිතන්නේ සමහර අය දැනටමත් මෙය කරමින් සිටින නමුත් ස්ථිතික සාමාජිකයන් හරහා (ඔබේම අභිජනනය තුළ) අන්තර් වුල්ෆ් සන්නිවේදනයට අවසර තිබේද?
මාටින් එන්ඩර්

10
@ m.buettner අවසර දී ඇත. පිටතට ගොස් ඔබේ වඩාත් කාර්යබහුල මනසක් ඇති වෘකයෙකු ගොඩනඟන්න.
රේන්බෝල්ට්

Answers:


47

හර්ජන් වුල්ෆ්

යාවත්කාලීන කරන ලද්දේ 10-4-2014 15:00 ට ය

වට 100 ක සාමාන්‍ය, පුනරාවර්තන 1000:

සම්මත මැරයන්:

class animals.Bear - 2.2600002
class animals.Lion - 41.21
class animals.Stone - 20.159998
class animals.HerjanWolf - 99.99 <-- kind of flawless

20+ විශේෂ (මතක තබා ගන්න, අපගේ වෘකයන් හොඳම ලකුණු ලබා ගන්නා තෙක් අපි සාමාන්‍ය ගණනය කිරීම් කරන බැවින් මෙම ලකුණු විශ්වාස නොකරන්න!)

class animals.Bear - 0.1
class animals.Lion - 0.0
class animals.Stone - 1.5
class animals.AlphaWolf - 75.5
class animals.HerjanWolf - 86.4 <-- #1
class animals.GatheringWolf - 39.5
class animals.OmegaWolf - 85.4 <-- #2
class animals.ShadowWolf - 71.1
class animals.MOSHPITFRENZYWolf - 8.8
class animals.WolfWithoutFear - 11.5
class animals.MimicWolf - 0.5
class animals.LazyWolf - 52.8
class animals.Sheep - 38.3
class animals.HonorWolf - 80.7
class animals.CamperWolf - 52.8
class animals.GamblerWolf - 14.7
class animals.WolfRunningWithScissors - 0.0
class animals.LionHunterWolf - 27.6
class animals.StoneEatingWolf - 70.8
class animals.Wion - 0.1
class animals.ProAlpha - 79.3
class animals.HybridWolf - 83.2

මගේ වුල්ෆ්:

package animals;

public class HerjanWolf extends Animal {

    private boolean lionTopLeft = false, lionTopLeftReady = false;
    private boolean lionRight = false, lionRightReady = false;
    private boolean lionBot = false, lionBotReady = false;
    private boolean lionDanger = false, careful = true, firstmove = true;
    private final int hold = 0, down = 1, right = 2, left = 3, up = 4;

    public HerjanWolf() {
        super('W');
    }

    public Attack fight(char c){
        switch (c) {
            case 'B':
                return Attack.SCISSORS;
            case 'L':
                return Attack.SCISSORS;
            case 'S':
                return Attack.PAPER;
            default:
                int rand = (int) (Math.random()*3);
                if(rand < 1)
                    return Attack.PAPER;
                else if(rand < 2)
                    return Attack.SCISSORS;
                else
                    return Attack.ROCK;
        } 

    }
    public Move move() { //surroundings[y][x]

        checkLions();

        if(firstmove){
            if(surroundings[2][0] == 'L')
                lionBotReady = true;
            if(surroundings[0][2] == 'L')
                lionRightReady = true;
            firstmove = false;
        }

        int[] dang = new int[4]; // 0 is left side, 1 is top side, 2 is right side, 3 is down side

        for(int y = 0; y < 3; y++){
            for(int x = 0; x < 3; x++){
                if(surroundings[y][x] == 'W'){
                    if(y == 0){
                        dang[1]++;
                        if(x == 1)
                            dang[1]+=2;
                    }if(y == 2){
                        dang[3]++;
                        if(x == 1)
                            dang[3]+=2;
                    }if(x == 0){
                        dang[0]++;
                        if(y == 1)
                            dang[0]+=2;
                    }if(x == 2){
                        dang[2]++;
                        if(y == 1)
                            dang[2]+=2;
                    }
                }
            }
        }

        int maxIndex = 0, minIndex = 0, minIndex2 = 0;
        for(int i = 1; i < dang.length; i++){
            if(dang[i] > dang[maxIndex])
                maxIndex = i;
            if(dang[i] <= dang[minIndex]){
                minIndex2 = minIndex;
                minIndex = i;
            }
        }

        if(lionDanger || surroundings[1][0] == 'L' && lionTopLeftReady || surroundings[0][1] == 'L' && lionTopLeftReady || dang[maxIndex] >= 3){

            switch(minIndex){
            case 0:
                if (isSafe(1, 0)){
                    newMove(left);
                    return Move.LEFT;
                }
            case 1:
                if (isSafe(0, 1)){
                    newMove(up);
                    return Move.UP;
                }
            case 2:
                if(isSafe(1,2)){
                    newMove(right);
                    return Move.RIGHT;
                }

            case 3:
                if (isSafe(2, 1)){
                    newMove(down);
                    return Move.DOWN;
                } 
            }

            switch(minIndex2){
            case 0:
                if (isSafe(1, 0)){
                    newMove(left);
                    return Move.LEFT;
                }
            case 1:
                if (isSafe(0, 1)){
                    newMove(up);
                    return Move.UP;
                }
            case 2:
                if(isSafe(1,2)){
                    newMove(right);
                    return Move.RIGHT;
                }

            case 3:
                if (isSafe(2, 1)){
                    newMove(down);
                    return Move.DOWN;
                } 
            }

            if(dang[maxIndex]<3){ //if that was not the reason its really obligated (because of lions)
                if (isSafe(2, 1)){
                    newMove(down);
                    return Move.DOWN;
                }else if(isSafe(1,2)){
                    newMove(right);
                    return Move.RIGHT;
                }else if (isSafe(0, 1)){
                    newMove(up);
                    return Move.UP;
                }else{
                    newMove(left);
                    return Move.LEFT;
                }
            }
        }

        return Move.HOLD;
    }

    boolean isSafe(int y, int x){
        if(y <= 1){
            if(x <= 1){
                if(surroundings[y][x] != 'W' && !lionTopLeft)
                    return true;
            }else if(surroundings[1][2] != 'W' && !lionRightReady)
                    return true;
        }else if(surroundings[2][1] != 'W' && !lionBotReady)
            return true;

        return false;
    }

    public void checkLions(){
        int y = 0, x = 0;

        if(lionTopLeft)
            lionTopLeftReady = true;
        else
            lionTopLeftReady = false;

        if(surroundings[y][x] == 'L')
            lionTopLeft = true;
        else
            lionTopLeft = false;

        if(lionRight)
            lionRightReady = true;
        else
            lionRightReady = false;

        if(surroundings[y][x+1] == 'L') // && !lionTopLeftReady
            lionRight = true;
        else
            lionRight = false;

        if(lionBot)
            lionBotReady = true;
        else
            lionBotReady = false;

        if(surroundings[y+1][x] == 'L' && !lionTopLeftReady)
            lionBot = true;
        else
            lionBot = false;

        if(careful){
            if(surroundings[y+1][x] == 'L'){
                lionDanger = true;
            }else if(surroundings[y][x+1] == 'L'){
                lionDanger = true;
            }

            careful = false;
        }
    }

    public void newMove(int move){
        lionTopLeft = false;
        lionRight = false;
        lionBot = false;

        lionTopLeftReady = false;
        lionRightReady = false;
        lionBotReady = false;

        lionDanger = false;

        if(move == down){
            if(surroundings[1][0] == 'L')
                lionTopLeft = true;
            if(surroundings[2][0] == 'L')
                lionBot = true;

        }else if(move == right){
            if(surroundings[0][1] == 'L')
                lionTopLeft = true;
            if(surroundings[0][2] == 'L')
                lionRight = true;

        }else
            careful = true;
    }
}

ටෙස්ට් ධාවනයේදී “ඉහළ” වෘකයන් පමණක් ඇතුළත් කිරීම සාමාන්‍යයෙන් සංඛ්‍යා මඟ හැරේ. ක්ෂේත්‍රයේ විශේෂ 30+ ක් ඇති විට, සංඛ්‍යා විශාල ලෙස වෙනස් විය හැකිය. ඔබ තවම නොමැති නම්, එය ද පරීක්ෂා කිරීමට මම නිර්දේශ කරමි.
Geobits

1
20 user20220 න්‍යාය අනුව (සහ ප්‍රායෝගිකව සාපේක්ෂව අඩු වෘකයන් සමඟ) එය ඉතා හොඳයි.
user3188175

1
මෙම වෘකයාට හොඳම සිංහ විරෝධී උපාය ඇත: chat.stackexchange.com/transcript/message/14837616#14837616
ජස්ටින්

2
20 user20220 වුල්ෆ් ision ට්ටනය බොහෝ විට සිදු වේ, එබැවින් ඔබ එය හසුරුවන තවත් වෘකයෙකු එකතු කළ යුතුය. එසේම, කරුණාකර මෙම වෘකයා ක්‍රියා කරන ආකාරය විස්තර කළ හැකිද?
ජස්ටින්

3
ust ජුස්ටාල්ෆ් හරි, එය වඩා හොඳ නැහැ, එය එතරම්ම හොඳයි. මගේ වෘකයා සියළුම සිංහයන් ද තල්ලු කරයි, මම වෘකයා-ඩොජ් සෑදීමට පෙර මගේ වෘකයා 100% සිංහ ආරක්ෂිත කර ගතිමි. වෙනස නම් මගේ වෘකයා සිංහයන්ගෙන් බේරීමට උත්සාහ කිරීමයි (අඩු චලනය, වඩා හොඳ). ඒ නිසා එය 100% සිංහ ආරක්ෂිත, නමුත් සිංහයාගෙන් බේරීමට උත්සාහ කරන නිසාත්, කම්මැලි ලෙස සිංහයෙකු මෙන් චලනය නොකිරීම නිසාත් මට තවමත් වෘකයා-ඩොජ් සෑදිය හැකිය, එය හරියට මාර්ගයයි වඩාත් සංකීර්ණයි.
හර්ජන්

154

EmoWolf

EmoWolf ජාවාට වෛර කරන අතර සහභාගී වීමට වඩා සියදිවි නසා ගනී. EmoWolf බඩගින්නේ සිටියත් තවමත් බර බයිට් 177 කි.

package animals;public class EmoWolf extends Animal{public EmoWolf(){super('W');}public Attack fight(char opponent){return Attack.SUICIDE;}public Move move(){return Move.HOLD;}}

35
lol ඔබට බයිට් කිහිපයක් කපා දැමිය හැකිය: " පාලකය පරීක්ෂා කරන විට සතෙකුට ලිපියක් නොමැති නම්, එම සත්වයා වහාම මිය යනු ඇත ".
Geobits

113
මෙහි ඇති හොඳම දේ නම් එය නිරන්තරයෙන් නරකම නොවේ . එය සාමාන්‍යයෙන් අවම වශයෙන් තවත් 2-3 දෙනෙකුට පහර දෙයි.
Geobits

51
"එකම ජයග්‍රාහී පියවර වන්නේ ක්‍රීඩා නොකිරීමයි."
tadman

39
+1 කුඩා හා සියදිවි නසා ගැනීම සහ තවත් වෘකයන් 4 දෙනෙකුට පහර දීම සඳහා.
puggsoy

25
යෝජනා වලට ස්තූතියි, ජනයෙනි. මෙය ගොල්ෆ් නම්, මම ලිපිය සංස්කරණය කිරීමට කරදර වෙමි. එය පවතින විට, මම එමෝ වුල්ෆ්ට ගිලෙන්න ඉඩ දෙන්නෙමි. තනිවම.
බූට්බි

52

ලේසි වුල්ෆ්

උචිත ලෙස නම් කර ඇති මෙම පුද්ගලයා දිවි ගලවා ගැනීම සඳහා අවම වශයෙන් කටයුතු කරයි. වෘකයා නොවන එකම තර්ජනය සිංහයෙකි, එබැවින් ඔහුගෙන් එක් අයෙකු ඔහු මතට නැගීමට සූදානම් වුවහොත් ඔහු ගමන් කරනු ඇත. ඒ හැරෙන්නට ඔහු නිදා ගනී.

50/50 ට වඩා හොඳ වෘකයන්ට එරෙහිව ඔබට කළ හැකි බොහෝ දේ නැත, එබැවින් ඔහු කිසිවක් නොකරයි. වෘකයෙකු ඔහුට පහර දෙන්නේ නම්, ඔහු ඒකාකාරව බෙදා හරින ආකාරයෙන් ප්‍රහාරයක් තෝරා ගනී.

ඒක තමයි. සරල බව නොතකා එය ඉතා හොඳින් සිදුවනු ඇතැයි මම අපේක්ෂා කරමි.

package animals;    
public class LazyWolf extends Animal{    
    static int last = 0;
    static final Attack[] attacks = Attack.values();

    public LazyWolf() {super('W');}

    @Override
    public Attack fight(char other) {
        switch(other){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.ROCK; // faker!
        default:
            return attacks[last++%3];
        }
    }

    @Override
    public Move move() {
        if(surroundings[0][1] == 'L')
            return Move.LEFT;
        if(surroundings[1][0] == 'L')
            return Move.UP;
        return Move.HOLD;
    }

}

යාවත්කාලීන කිරීම:

කැමෝ වුල්ෆ් මට අතින් පහර දුන්නා. මගේ වෘකයා හරිම කම්මැලි නිසා ඔහු කවදාවත් සාමාන්‍ය ගලකට දුවන්නේ නැහැ . එමනිසා, ගලක් පහර දෙන්නේ නම්, එය පැහැදිලිවම ව්‍යාජ එකක් වන අතර එහි මුහුණට විසි කළ පර්වතයක් අවශ්‍ය වේ.


මේ මොහොතේ ඔබ දෙවන සිංහයෙකු බවට පත්වීමේ හැකියාව ඇත. කොපමණ චලනයන් සිදුවී ඇත්දැයි සොයා බැලීමෙන් ඔබට මෙය ඉවත් කළ හැකිය, එබැවින් සිංහයා ඇත්ත වශයෙන්ම ඔබේ චතුරස්රයට එන්නේ දැයි ඔබ දන්නවා. එය එසේ නම්, සිංහයා මෙන් එකම දිශාවකට ගමන් කරන්න, කිසිම සිංහයෙකු ඔබ වෙත ළඟා විය නොහැක්කේ ඔවුන් ද එකම දිශාවට ගමන් කරන බැවිනි.
ughoavgfhw

13
මම සිංහයන් දෙදෙනාගේ තත්වය ගැන සිතුවෙමි, නමුත් මගේ වෘකයා රැකබලා ගැනීමට තරම් කම්මැලි බව තීරණය කළෙමි. හොඳින් ජනාකීර්ණ පුවරුවකින් බොහෝ විට සිදුවීමේ අවාසි කෙසේ වෙතත් සිහින් ය.
Geobits

1
ඇයි මේ වෘකයා කවදාවත් සැබෑ ගල් වලට දුවන්නේ නැත්තේ කියලා? මම හිතන්නේ එය සිංහයෙකුගෙන් පලා යන සෑම විටම එය සිදුවිය හැකිය.
ක්‍රිස්ටෝපර් ක්‍රෙට්සිග්

6
H ක්‍රිස්ටෝපර් ක්‍රියුට්සිග් එය සිංහයන්ගෙන් දිව යන්නේ සිංහයා සිටි ස්ථානයට යාමෙනි . සිංහයෙකු නම් විය , එහි ගලක් සිටිය නොහැක දැන් .
Geobits

1
එය කළ හැකි වුවද, "අනන්ත පුඩුවක්" නොමැත. ප්‍රහාරයක් ගැටගැසීමක් නම්, පිරිවිතරයට අනුව එක් අයෙකු හෝ වෙනත් අයෙකු මිය යයි (කාසි ටොස් මගින් තෝරා ගනු ලැබේ).
Geobits

51

ජාවා නොවන ඉදිරිපත් කිරීම් සඳහා එතීම

NOTE MAP_SIZE සහාය එකතු කර ඇත. ඔබ සැලකිලිමත් නම්, කරුණාකර ඔබේ ඉදිරිපත් කිරීම ඒ අනුව යාවත්කාලීන කරන්න.

මෙය එතුමිය සඳහා ප්‍රජා විකියකි, එය සෙල්ලම් කිරීමට කැමති නමුත් ජාවා කැමති / නොදන්නා අයට භාවිතා කළ හැකිය. කරුණාකර එය භාවිතා කරන්න, විනෝද වන්න, සහ දේවල් සකස් කර ගැනීමට ඔබට උදව් කිරීමට මම සතුටු වෙමි.

මම ඉවර වන විට මෙහි ප්‍රමාද වැඩියි, එබැවින් වෙනත් ජාවා කෝඩර්ස්, කරුණාකර මෙය සොයා බලා වැඩිදියුණු කිරීම් යෝජනා කරන්න. ඔබට හැකි නම්, ගැටළුවක් ගොනු කිරීමෙන් හෝ පැච් එකක් ඉදිරිපත් කිරීමෙන් මගේ ගිතුබ් ගබඩාව හරහා එසේ කරන්න. ස්තූතියි!

මේ සියල්ල UNLICENSE සමඟ බෙදා හරිනු ලැබේ, කරුණාකර එහි ගිතුබ් ගබඩාවෙන් එය අනුගමනය කරන්න . ඔබට ගැටළු ඇත්නම් පැච් එහි ඉදිරිපත් කරන්න, මම මෙම ලිපිය යාවත්කාලීන කරමි.

භාවිතයේ ඇති රැපර් සඳහා වර්තමාන උදාහරණ

plannapus : R හි WolfCollectiveMemory

user3188175 : ස්මාර්ට් වුල්ෆ්C#

දත් බුරුසුව : ECMAScript හි දත් බුරුසුව

භාවිතා කරන්නේ කෙසේද

පහත දැක්වෙන්නේ දුරස්ථ වෘකයන් සඳහා මා විසින් අර්ථ දක්වා ඇති PIPES හරහා අන්තර් ක්‍රියාදාම සන්නිවේදනය සඳහා වන ප්‍රොටෝකෝලය පිළිබඳ උපදෙස් ය. OP හි ගැටළු ප්‍රකාශයේ එය තිබියදීත්, මෙය නොපවතින බැවින් මම MAP_SIZE මඟ හැරියෙමි. එය දිස්වන්නේ නම්, මම මෙම ලිපිය යාවත්කාලීන කරමි.

වැදගත් සටහන් :

  • ඔබගේ බාහිර ක්‍රියාවලියේ එක් ආයාචනයක් පමණක් කරනු ලැබේ (එබැවින් ඔබේ සැකසුම් තර්කනය අසීමිත පුඩුවක් තුළට ඔතා තබන්න. තැටිය භාවිතා කරනවා වෙනුවට ඕනෑම සැකසුම් මතකයේ තබා ගැනීමට මෙය ඔබට ඉඩ සලසයි)
  • සියලුම සන්නිවේදනයන් STDIN සහ STDOUT හරහා මෙම තනි බාහිර ක්‍රියාවලියට සම්බන්ධ වේ
  • STDOUT වෙත යවන ලද සියලුම ප්‍රතිදානයන් ඔබ පැහැදිලිවම ගලා යා යුතු අතර එය නව රේඛාව අවසන් කර ඇති බවට වග බලා ගන්න

පිරිවිතර

දුරස්ථ ස්ක්‍රිප්ටයට STDIN සහ STDOUT කොකු හරහා සරල ප්‍රොටෝකෝලයක් මඟින් සහාය වන අතර එය ආරම්භ කිරීම, ගෙනයාම සහ ප්‍රහාරය ලෙස බෙදා ඇත. සෑම අවස්ථාවකම ඔබේ ක්‍රියාවලිය සමඟ සන්නිවේදනය STDIN හරහා වන අතර STDOUT වෙතින් පිළිතුරක් අවශ්‍ය වේ. තත්පර 1 කින් පිළිතුරක් නොලැබුනේ නම්, ඔබේ ක්‍රියාවලිය මිය ගොස් ඇතැයි උපකල්පනය කර ව්‍යතිරේකයක් විසි කරනු ලැබේ. සියලුම අක්ෂර UTF-8 හි කේතනය කරනු ලැබේ. සෑම ආදානයක්ම නව රේඛා අක්ෂරයකින් අවසන් වන අතර ඔබේ ක්‍රියාවලිය සෑම ප්‍රතිදාන පිළිතුරක්ම නව රේඛාවක් සමඟ අවසන් කළ යුතුය. අවවාදයයි ජාවා එතීමෙන් ඔබේ ප්‍රතිදානය දකින බව සහතික කිරීම සඳහා සෑම ලිවීමකටම පසුව ඔබේ ප්‍රතිදාන බෆරය ගලා යාමට වග බලා ගන්න. ෆ්ලෂ් කිරීමට අපොහොසත් වීම ඔබගේ දුරස්ථ වුල්ෆ් අසමත් වීමට හේතු විය හැක.

එක් ක්‍රියාවලියක් පමණක් නිර්මාණය වන බව සලකන්න, එම එක් ක්‍රියාවලියක් තුළ සියලු වෘකයන් කළමනාකරණය කළ යුතුය. මෙම පිරිවිතර උපකාරී වන්නේ කෙසේදැයි කියවන්න.

ආරම්භ කිරීම

STDIN: S<id><mapsize> \ n

STDOUT: K<id> \ n

<id>: 00 හෝ 01හෝ ... හෝ99

පැහැදිලි කිරීම:

චරිතය Sසංඛ්යාත්මක අනුලකුණු දෙකක් අනුගමනය යවනු ලැබේ 00, 01,, ... 99වෘකයන් 100 වන ආරම්භනය කොට ඇත පෙන්නුම්. එම විශේෂිත වෘකයා සමඟ අනාගත සන්නිවේදනයේදී, එයම <id>භාවිතා වේ.

හැඳුනුම්පත අනුගමනය කිරීමෙන් සංඛ්‍යාත්මක අක්ෂරවල විචල්‍ය දිග අනුක්‍රමයක් යවනු ලැබේ. මෙය සිතියමේ ප්‍රමාණයයි. ඔබ නව රේඛාවට ( \n) ලඟා වන විට සංඛ්‍යාත්මක අනුක්‍රමය අවසන් බව ඔබ දැන ගනු ඇත .

ඔබේ ක්‍රියාවලිය ජීවමාන බව සහතික කිරීම සඳහා, ඔබට ලැබුණු චරිතය Kඅනුගමනය කරමින් ඔබ පිළිතුරු දිය යුතුය <id>. වෙනත් ඕනෑම පිළිතුරක ව්‍යතිරේකයක් ඇති වනු ඇත, ඔබේ වෘකයන් මරා දමයි.

චලනය

STDIN: M<id><C0><C1>...<C7><C8> \ n

STDOUT: <mv><id> \ n

<Cn>: W හෝ හෝ Bහෝ SහෝL

W: වුල්ෆ්

: හිස් අවකාශය

B: වලස්

S: ගල්

L: සිංහයා

<mv>: H හෝ Uහෝ Lහෝ RහෝD

H: චලනය කරන්න

U: Move.UP

L: Move.LEFT

R: චලනය කරන්න

D: ගෙනයන්න

පැහැදිලි කිරීම:

වුල්ෆ්ට පියවරක් තෝරා ගැනීමට අවශ්‍ය වන්නේ කුමක්ද යන්න දැක්වීමට Mචරිත දෙකෙන් පසුව චරිතය යවනු ලැබේ <id>. ඊට පසු, එම වුල්ෆ්ගේ වටපිටාව පේළි අනුපිළිවෙලින් (ඉහළ පේළිය, මැද පේළිය, පහළ පේළිය වමේ සිට දකුණට) නියෝජනය කරමින් අක්ෂර 9 ක් යවනු ලැබේ.

වලංගු චලන අක්ෂර වලින් එකක් සමඟ පිළිතුරු දෙන්න <mv>, ඉන්පසු <id>තහවුරු කිරීම සඳහා වුල්ෆ්ගේ ඉලක්කම් දෙක අනුගමනය කරන්න .

ප්රහාරය

STDIN: A<id><C> \ n

STDOUT: <atk><id> \ n

<C>: W හෝ Bහෝ SහෝL

<atk>: R හෝ Pහෝ SහෝD

R: ප්‍රහාරය . රොක්

P: ප්‍රහාරය

S: ප්‍රහාරය . SCISSORS

D: ප්‍රහාරය

පැහැදිලි කිරීම:

වුල්ෆ් ප්‍රහාරයකට සහභාගී වන්නේ කුමන චරිතයටද යන්න දැක්වීමට Aචරිත දෙකෙන් පසුව චරිතය යවනු ලැබේ <id>. ඕල්ෆ්, කණ, තානය හෝ අයන <C>කුමන ආකාරයේ දේකට පහර Wදෙනවාද යන්න දැක්වෙන තනි අක්ෂරයකින් මෙය අනුගමනය කෙරේ .BSL

තහවුරු කිරීම සඳහා <atk>ඉලක්කම් දෙකෙන් පසුව, ප්‍රහාරයට ඔබේ ප්‍රතිචාරය කුමක්දැයි දක්වමින් ඉහත ලැයිස්තුගත කර ඇති එක් අක්ෂරයකින් පිළිතුරු දෙන්න <id>.

ඒක තමයි. ඊට තවත් දෙයක් නැත. ඔබට ප්‍රහාරයක් අහිමි වුවහොත්, එය <id>නැවත කිසි දිනෙක ඔබේ ක්‍රියාවලියට යවනු නොලැබේ, ඔබේ වුල්ෆ් මියගොස් ඇති බව ඔබ දැනගන්නේ එලෙසයි - එය එවීමකින් තොරව සම්පූර්ණ චලන වටයක් පසු වී ඇත්නම් <id>.

නිගමනය

කිසියම් ව්‍යතිරේකයක් මඟින් ඔබේ දුරස්ථ වර්ගයේ වෘකයන් සියල්ලම මරා දමන බව සලකන්න, ඔබේ දුරස්ථ වෘකයාගෙන් තනි "ක්‍රියාවලියක්" පමණක් ගොඩනඟා ඇති බැවින්, ඔබේ වර්ගයේ සියලුම වෘකයන් නිර්මාණය වේ.

මෙම ගබඩාවේ ඔබ Wolf.javaගොනුව සොයා ගනු ඇත . ඔබේ බොට් සැකසීමට පහත සඳහන් නූල් සොයන්න සහ ප්‍රතිස්ථාපනය කරන්න:

  • <invocation>ඔබේ ක්‍රියාවලිය නිසියාකාරව ක්‍රියාත්මක කරන විධාන රේඛා තර්කය සමඟ ප්‍රතිස්ථාපනය කරන්න .

  • <custom-name>ඔබේ වුල්ෆ් සඳහා අද්විතීය නමකින් ආදේශ කරන්න .

  • නිදසුනක් ලෙස , මගේ උදාහරණය දුරස්ථව (පයිතන් 3+ වුල්ෆ්) ඉල්ලා සිටින ගබඩාව දෙස බලන්න .WolfRandomPython.javaPythonWolf.py

  • ගොනුව නැවත නම් කරන්න Wolf<custom-name>.java, එහිදී <custom-name>ඔබ ඉහත තෝරාගත් නම සමඟ ප්‍රතිස්ථාපනය වේ.

ඔබේ වුල්ෆ් පරීක්ෂා කිරීම සඳහා, ජාවා වැඩසටහන ( javac Wolf<custom-name>.java) සම්පාදනය කර එය අනුකරණ වැඩසටහනට ඇතුළත් කිරීමට රුෂර්ගේ උපදෙස් අනුගමනය කරන්න.

වැදගත්: මම ඉහත දක්වා ඇති යෝජනා ක්‍රමය අනුගමනය කරන ඔබේ සැබෑ වුල්ෆ් සම්පාදනය / ක්‍රියාත්මක කරන්නේ කෙසේද යන්න පිළිබඳ පැහැදිලි , සංක්ෂිප්ත උපදෙස් ලබා දීමට වග බලා ගන්න .

වාසනාව, සහ ස්වභාව ධර්මය ඔබට වාසිදායක වේවා.

රැපර් කේතය

මතක තබා ගන්න, ඔබ මෙය කළ යුතු සෙවීම් කළ යුතු අතර ප්‍රතිස්ථාපනය කළ යුතුය. ඔබේ ආයාචනය විශේෂයෙන් කෙස් කළඹක් නම්, කරුණාකර සහාය සඳහා මා අමතන්න.

mainඔබේ ප්‍රාදේශීය පෙට්ටියේ මුලික "සමත් / අසමත්" පරීක්ෂණ සඳහා ඉඩ ලබා දීම සඳහා මෙම එතුමෙහි ක්‍රමයක් ඇති බව සලකන්න . එසේ කිරීමට, ව්‍යාපෘතියෙන් Animal.java පන්තිය බාගත කර package animals;ගොනු දෙකෙන්ම රේඛාව ඉවත් කරන්න . Animal.java හි MAP_SIZE රේඛාව නියත (100 වැනි) සමඟ ප්‍රතිස්ථාපනය කරන්න. javac Wolf<custom-name>.javaක්‍රියාත්මක කිරීම හරහා ඒවා සම්පාදනය කරන්න java Wolf<custom-name>.

package animals;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Remote Wolf<custom-name> wrapper class. 
 */
public class Wolf<custom-name> extends Animal {
    /**
     * Simple test script that sends some typical commands to the
     * remote process.
     */
    public static void main(String[]args){
        Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
        for(int i=0; i<10; i++) {
            wolves[i] = new Wolf<custom-name>();
        }
        char map[][] = new char[3][3];
        for (int i=0;i<9;i++)
            map[i/3][i%3]=' ';
        map[1][1] = 'W';
        for(int i=0; i<10; i++) {
            wolves[i].surroundings=map;
            System.out.println(wolves[i].move());
        }
        for(int i=0; i<10; i++) {
            System.out.println(wolves[i].fight('S'));
            System.out.println(wolves[i].fight('B'));
            System.out.println(wolves[i].fight('L'));
            System.out.println(wolves[i].fight('W'));
        }
        wolfProcess.endProcess();
    }
    private static WolfProcess wolfProcess = null;

    private static Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
    private static int nWolves = 0;

    private boolean isDead;
    private int id;

    /**
     * Sets up a remote process wolf. Note the static components. Only
     * a single process is generated for all Wolves of this type, new
     * wolves are "initialized" within the remote process, which is
     * maintained alongside the primary process.
     * Note this implementation makes heavy use of threads.
     */
    public Wolf<custom-name>() {
        super('W');
        if (Wolf<custom-name>.wolfProcess == null) {
            Wolf<custom-name>.wolfProcess = new WolfProcess();
            Wolf<custom-name>.wolfProcess.start();
        }

        if (Wolf<custom-name>.wolfProcess.initWolf(Wolf<custom-name>.nWolves, MAP_SIZE)) {
            this.id = Wolf<custom-name>.nWolves;
            this.isDead = false;
            Wolf<custom-name>.wolves[id] = this;
        } else {
            Wolf<custom-name>.wolfProcess.endProcess();
            this.isDead = true;
        }
        Wolf<custom-name>.nWolves++;
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, SUICIDE.
     * Otherwise, communicate an attack to the remote process and return
     * its attack choice.
     */
    @Override
    public Attack fight(char opponent) {
        if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
            return Attack.SUICIDE;
        }
        try {
            Attack atk = Wolf<custom-name>.wolfProcess.fight(id, opponent);

            if (atk == Attack.SUICIDE) {
                this.isDead = true;
            }

            return atk;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Attack.SUICIDE;
        }
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, HOLD.
     * Otherwise, get a move from the remote process and return that.
     */
    @Override
    public Move move() {
        if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
            return Move.HOLD;
        }
        try {
            Move mv = Wolf<custom-name>.wolfProcess.move(id, surroundings);

            return mv;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Move.HOLD;
        }
    }

    /**
     * The shared static process manager, that synchronizes all communication
     * with the remote process.
     */
    static class WolfProcess extends Thread {
        private Process process;
        private BufferedReader reader;
        private PrintWriter writer;
        private ExecutorService executor;
        private boolean running;

        public boolean getRunning() {
            return running;
        }

        public WolfProcess() {
            process = null;
            reader = null;
            writer = null;
            running = true;
            executor = Executors.newFixedThreadPool(1);
        }

        public void endProcess() {
            running = false;
        }

        /**
         * WolfProcess thread body. Keeps the remote connection alive.
         */
        public void run() {
            try {
                System.out.println("Starting Wolf<custom-name> remote process");
                ProcessBuilder pb = new ProcessBuilder("<invocation>".split(" "));
                pb.redirectErrorStream(true);
                process = pb.start();
                System.out.println("Wolf<custom-name> process begun");
                // STDOUT of the process.
                reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); 
                System.out.println("Wolf<custom-name> reader stream grabbed");
                // STDIN of the process.
                writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"));
                System.out.println("Wolf<custom-name> writer stream grabbed");
                while(running){
                    this.sleep(0);
                }
                reader.close();
                writer.close();
                process.destroy(); // kill it with fire.
                executor.shutdownNow();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Wolf<custom-name> ended catastrophically.");
            }
        }

        /**
         * Helper that invokes a read with a timeout
         */
        private String getReply(long timeout) throws TimeoutException, ExecutionException, InterruptedException{
            Callable<String> readTask = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return reader.readLine();
                }
            };

            Future<String> future = executor.submit(readTask);
            return future.get(timeout, TimeUnit.MILLISECONDS);
        }

        /**
         * Sends an initialization command to the remote process
         */
        public synchronized boolean initWolf(int wolf, int map_sz) {
            while(writer == null){
                try {
                this.sleep(0);
                }catch(Exception e){}
            }
            boolean success = false;
            try{
                writer.printf("S%02d%d\n", wolf, map_sz);
                writer.flush();
                String reply = getReply(5000l);
                if (reply != null && reply.length() >= 3 && reply.charAt(0) == 'K') {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        success = true;
                    }
                }
                if (reply == null) {
                    System.out.println("did not get reply");
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to initialize, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to initialize, %s\n", wolf, e.getMessage());
            }
            return success;
        }

        /**
         * Send an ATTACK command to the remote process.
         */
        public synchronized Attack fight(int wolf, char opponent) {
            Attack atk = Attack.SUICIDE;
            try{
                writer.printf("A%02d%c\n", wolf, opponent);
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'R':
                                atk = Attack.ROCK;
                                break;
                            case 'P':
                                atk = Attack.PAPER;
                                break;
                            case 'S':
                                atk = Attack.SCISSORS;
                                break;
                            case 'D':
                                atk = Attack.SUICIDE;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to attack, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to attack, %s\n", wolf, e.getMessage());
            }
            return atk;
        }

        /**
         * Send a MOVE command to the remote process.
         */
        public synchronized Move move(int wolf, char[][] map) {
            Move move = Move.HOLD;
            try{
                writer.printf("M%02d", wolf);
                for (int row=0; row<map.length; row++) {
                    for (int col=0; col<map[row].length; col++) {
                        writer.printf("%c", map[row][col]);
                    }
                }
                writer.print("\n");
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'H':
                                move = Move.HOLD;
                                break;
                            case 'U':
                                move = Move.UP;
                                break;
                            case 'L':
                                move = Move.LEFT;
                                break;
                            case 'R':
                                move = Move.RIGHT;
                                break;
                            case 'D':
                                move = Move.DOWN;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to move, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("Wolf<custom-name> %d failed to move, %s\n", wolf, e.getMessage());
            }
            return move;
        }
    }
}

1
මම මේ පෝස්ට් එක ඉරා දැමුවා. එය පිළිතුරක් නොවේ, නමුත් එය අභියෝගයට ඉතා ප්‍රයෝජනවත් වේ. එය බොහෝ විට අභියෝගාත්මක ශරීරය තුළට යා යුතුය.
මෙගෝ

එක්කෝ එහි හෝ මෙහි දී, සපයා ඇති පුද්ගලයින්ට එය සොයා ගත හැකි අතර එය ඔවුන්ට ප්‍රයෝජනවත් වේ නම්, මම සෑහීමකට පත් වෙමි :)
ProgrammerDan

45

කැමෝ වුල්ෆ්

අවශ්‍ය කේත ආකෘතිය අනිසි ලෙස භාවිතා කිරීම.

// Optional code here
public class Wolf extends Animal {
    // Optional code here
    public Wolf() { super('W'); // Optional code here }
    public Attack fight(char opponent) { // Required code here. Must return an Attack. }
    public Move move() { // Required code here. Must return a Move. }
    // Optional code here
}

ඉතින්, මගේ වෘකයා ඇත්තෙන්ම දක්ෂයි, ඔහු ඒ වෙනුවට ගලක් ලෙස සැඟවෙයි! පරිසරය සමඟ මිශ්‍ර වීම සැමවිටම හොඳ පැවැත්මේ උපක්‍රමයකි!

public class Wolf extends Animal {
    private Move lastMove;
    public Wolf() { super('S'); lastMove = Move.RIGHT; } /*
    public Wolf() { super('W'); }
    public Attack fight(char opponent) { */ public Attack fight(char opponent) {
        switch(opponent) {
        case 'B': return Attack.SCISSORS;
        case 'S': return Attack.PAPER;
        case 'W': return Attack.SCISSORS; // Here's an explanation why:
                                          // the wolves will see me and think I'm a rock.
                                          // Therefore, they'll attack with paper.
                                          // So, I'll use scissors instead!
        case 'L': return Attack.SCISSORS;
        }
    }
    public Move move() {
        // First we run away from any lions that we see, since they are the only threat
        if (surroundings[0][1] == 'L') {
            if (isSafe(surroundings[2][1])) return lastMove = Move.DOWN;
            else if (isSafe(surroundings[1][0])) return lastMove = Move.LEFT;
            else return lastMove = Move.RIGHT;
        }
        if (surroundings[1][0] == 'L') {
            if (isSafe(surroundings[1][2])) return lastMove = Move.RIGHT;
            else if (isSafe(surroundings[0][1])) return lastMove = Move.UP;
            else return lastMove = Move.DOWN;
        }

        // If there's no (threatening) lions in sight, be lazy.
        return lastMove = Move.HOLD;
    }
    private boolean isSafe(char c) { return (c != 'L' && c != 'W') }
}

යාවත්කාලීන කිරීම : isSafeලේසි වුල්ෆ් වෙතින් ආරක්ෂිත වීමට නව චෙක්පතක් එක් කරන ලදි! හා!
යාවත්කාලීන 2 : කම්මැලි වීම හොඳ පැවැත්මේ උපක්‍රමයක් යැයි සිතමු, එබැවින් දැන් මගේ දේ එයයි. සිංහයෙකුගෙන් තර්ජනය කළොත් මිස චලනය නොවේ. lastMoveතවදුරටත් අවශ්‍ය නොවේ, නමුත් මම නැවත කේතය වෙනස් කළහොත් එය කෙසේ හෝ තබා ගතිමි.


29
මම ඔබේ ඉදිරිපත් කිරීම ව්‍යාපෘතියට එකතු කළ විට, මම අහම්බෙන් මුළු පන්තියම අදහස් දැක්වීමේ කොටසකට දැමුවෙමි.
රේන්බෝල්ට්

2
Us රුෂර් ජාවා කැදැලි විවරණ කොටස් විග්‍රහ කරයිද? : පී
මාටින් එන්ඩර්

6
ලේසි වුල්ෆ්ට එරෙහිව ආරක්ෂා විය හැකි ලෝකයක, සිංහයෙකු ලෙස පෙනී සිටීම සහ රොක් හෝ අහඹු ලෙස තෝරා ගැනීම වඩාත් අර්ථවත් වනු ඇත. බොහෝ අය සිංහයන් වළක්වා ගැනීමට උත්සාහ කරන බැවින් එය මිනිසුන්ගෙන් හමුවීම් ගණන අඩු කරනු ඇති අතර, එය සාමාන්‍යයෙන් සිංහයෙකු සමඟ සටන් කරයි යැයි සිතන මිනිසුන්ට එරෙහිව ජය ගත යුතුය.
ටිම් සෙගුයින්

7
Ad රේඩියෝඩෙෆ් එයයි.
රේන්බෝල්ට්

2
Ad රේඩියෝඩෙෆ් මම කිව්වේ කවදාද? ;-)
දොරක්නොබ්

38

එක්රැස් කිරීම වුල්ෆ්

මගේ වෘකයෝ කණ්ඩායමක ජීවත් වෙති. සිංහයන් ඔවුන්ට ඉඩ දුන්නොත් ඔවුන් රැස්වේ. ඔවුන් දිවි ගලවා ගැනීමට එතරම් හොඳ නැත.

යාවත්කාලීන කිරීම: සිංහයෙක් ඔවුන්ව ඉවතට ඇද දැමුවහොත්, ඔවුන් දැන් නැවත එකතු වීමට උත්සාහ කරයි!

GatheringWolf හි ප්‍රති result ලයේ තිර රුව

package animals;
import java.util.*;
public class GatheringWolf extends Animal {
    private static int iteration;
    private static Move preferredMove;
    private int localIteration;
    private int loneliness;
    private boolean dangerFlag;
    private Move lastMove;
    public GatheringWolf() {
        super('W');
    }
    @Override
    public Attack fight(char other) {
        switch (other) {
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S':
            return Attack.PAPER;
        default:
            return Attack.values()[(int) (Math.random() * 3)];
        }
    }
    @Override
    public Move move() {
        if (localIteration == iteration) {
            localIteration++;
            iteration++;
            preferredMove = Math.random() < 0.5 ? Move.DOWN : Move.RIGHT;
        } else
            localIteration = iteration;
        EnumSet<Move> moves = EnumSet.allOf(Move.class);
        if (surroundings[0][1] == 'W')
            moves.remove(Move.UP);
        if (surroundings[1][0] == 'W')
            moves.remove(Move.LEFT);
        if (surroundings[2][1] == 'W')
            moves.remove(Move.DOWN);
        if (surroundings[1][2] == 'W')
            moves.remove(Move.RIGHT);
        if (surroundings[0][0] == 'L') {
            moves.remove(Move.UP);
            moves.remove(Move.LEFT);
        }
        if (surroundings[0][1] == 'L')
            moves.remove(Move.UP);
        if (surroundings[1][0] == 'L')
            moves.remove(Move.LEFT);
        if (surroundings[0][2] == 'L')
            moves.remove(Move.RIGHT);
        if (surroundings[2][0] == 'L')
            moves.remove(Move.DOWN);
        if (surroundings[0][1] == 'L' || surroundings[1][0] == 'L')
            if (moves.size() > 1) {
                moves.remove(Move.HOLD);
                dangerFlag = true;
            }
        int wolfNear = -1;
        for (char[] a : surroundings)
            for (char c : a)
                if (c == 'W')
                    wolfNear++;
        boolean enoughWolfNear = wolfNear >= (Math.random() < 0.9 ? 1 : 2);
        if (moves.contains(Move.HOLD) && enoughWolfNear) {
            loneliness = 0;
            dangerFlag = false;
            return lastMove = Move.HOLD;
        } else
            loneliness++;
        if (loneliness > 10) {
            EnumSet<Move> preferred = EnumSet.copyOf(moves);
            preferred.retainAll(EnumSet.of(preferredMove, Move.HOLD));
            if (!preferred.isEmpty())
                moves = preferred;
        }
        if (loneliness == 2 && dangerFlag) {
            Move reverted = Move.values()[lastMove.ordinal() ^ 0b10];
            dangerFlag = false;
            if (moves.contains(reverted))
                return lastMove = reverted;
        }
        if (moves.contains(Move.HOLD))
            dangerFlag = false;
        if (moves.contains(preferredMove))
            moves.remove(preferredMove == Move.DOWN ? Move.RIGHT : Move.DOWN);
        int n = (int) (Math.random() * moves.size());
        Iterator<Move> ite = moves.iterator();
        while (n-- > 0)
            ite.next();
        return lastMove = ite.next();
    }
}

43
කිහිප වතාවක්ම, අපේ වෘකයෝ මිතුරන් බවට පත්වූයේ මගේ කොටු වී ඇති නමුත් ප්‍රහාරයක් ආරම්භ නොකරන නිසා සහ ඔබ උපකල්පනය කළේ මගේ ඇසුරුමේ කොටසක් බවය. :)
undergroundmonorail

1
මෙය ලිවීමට ස්තූතියි, එසේ නොවුවහොත් මට එය තනිවම කිරීමට සිදුවනු ඇත. අන්‍යෝන්‍ය ව්‍යාජ ව්‍යවහාරයේ දක්ෂ භාවිතය.
බෙන් ජැක්සන්

31

වුල්ෆ්ගේ ඇඳුම්වල බැටළුවා

පලා යයි.

එය වඩාත් භයානක වන්නේ වෘකයන්ගෙන් පලා යාමයි. ඊළඟට සිංහයන් වන්නේ ඔවුන් නිර්විනාශක නොවන බැවිනි. වලසුන් සහ ගල් යන දෙකම කිසිසේත්ම ගැටලුවක් නොවේ, නමුත් අපට මීට වඩා හොඳ දෙයක් නොමැති නම් අපි ඔවුන්ගෙන් run ත් වන්නේ වෘකයෙකු වලසෙකු හෝ ගලක් මරා දැමීම නිසාය, ඒ මොහොතේදී වෘකයෙකු බැටළුවෙකු මරා නොදමයි.

මම තවමත් ලේසි වුල්ෆ්ට එරෙහිව එය අත්හදා බලා නැත, නමුත් එය හොඳ අධිකාරියක් ඇත, එය එමෝ වුල්ෆ්ගේ බූරුවාට පයින් ගසයි. ;)

(කරුණාකර මෙම කේතය භයානක නම් මට සමාව දෙන්න, මම මීට පෙර හෙලෝ වර්ල්ඩ් වැඩසටහනකට වඩා වැඩි ගණනක් ජාවා ස්පර්ශ කර නැත.)

package animals;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Sheep extends Animal {
    public Sheep() { super('W'); }

    private static final Map<Character, Integer> AnimalWeights;
    static{
        AnimalWeights = new HashMap<>();
        AnimalWeights.put('W', -3);
        AnimalWeights.put('S', -1);
        AnimalWeights.put(' ', 0);
        AnimalWeights.put('H', 1);
        AnimalWeights.put('L', -2);
        AnimalWeights.put('B', -1);
    }

    @Override
    public Attack fight(char c) { 
        switch (c) {
            case 'B':
                return Attack.SCISSORS;
            case 'L':
                return Attack.SCISSORS;
            case 'S':
                return Attack.PAPER;
            default:
                return Attack.PAPER;
        } 
    }

    @Override
    public Move move() {

        int xWeight = 0;
        int yWeight = 0;

        // Northwest
        xWeight += AnimalWeights.get(surroundings[0][0]);
        yWeight += AnimalWeights.get(surroundings[0][0]);

        // North
        yWeight += AnimalWeights.get(surroundings[0][1]);

        // Northeast
        xWeight -= AnimalWeights.get(surroundings[0][2]);
        yWeight += AnimalWeights.get(surroundings[0][2]);

        // West
        xWeight += AnimalWeights.get(surroundings[1][0]);

        // East
        xWeight -= AnimalWeights.get(surroundings[1][2]);

        // Southwest
        xWeight += AnimalWeights.get(surroundings[2][0]);
        yWeight -= AnimalWeights.get(surroundings[2][0]);

        // South
        yWeight -= AnimalWeights.get(surroundings[2][1]);

        // Southeast
        xWeight -= AnimalWeights.get(surroundings[2][2]);
        yWeight -= AnimalWeights.get(surroundings[2][2]);

        if (Math.abs(xWeight) < Math.abs(yWeight)) {
            if (yWeight > 0) {
                return Move.UP;
            } else {
                return Move.DOWN;
            }
        } else if (Math.abs(yWeight) < Math.abs(xWeight)) {
            if (xWeight > 0) {
                return Move.RIGHT;
            } else {
                return Move.LEFT;
            }
        }

        // Sit still if no one's around
        return Move.HOLD;
    }
}

අපොයි, මම අහම්බෙන් පරීක්ෂා කිරීම සඳහා භාවිතා කළ දෙයක් එහි තැබුවෙමි. එය කිසිම දෙයකට බලපාන්නේ නැත, එයින් අදහස් කරන්නේ මම එච් ලෙස පෙනෙන ඕනෑම දෙයකට සමීප වීමට උත්සාහ කරන බවයි: P
undergroundmonorail

හුදෙක්, කුතුහලයෙන් xWeightහා yWeightඔවුන්ගේ පරම අගයන් දෙකම නොවන ශුන්ය හා ය ම වන අතර, මෙම වෘකයා එහෙම කරන්නේ නැහැ, නිවැරදි? එසේ නම්, එය චේතනාන්විතද, ඒ මන්ද?
පැට්‍රික් රොබට්ස්

At පැට්‍රික් රොබට්ස් අපොයි
භූගත

26

ප්‍රවේශයක් නොවේ, එක් එක් පන්තිය = D සඳහා වර්ණ කේත එකතු කිරීමෙන් GUI වෙත දායක වීමට අවශ්‍යය

ප්‍රති ult ලය

වර්ණ GUI

Wild.java

game.populate(c,100)සමඟ කේතය වෙනස් කරන්න :

String[] colors = generateColors(classes.length);
int idx = 0;
for(Class c : classes){
    Animal.setColor(c, colors[idx]);
    idx++;
    game.populate(c, 100);
}
stats.update();

සමග generateColorsලෙස අර්ථ:

private static String[] generateColors(int n){
    String[] result = new String[n];
    double maxR = -1000;
    double minR = 1000;
    double maxG = -1000;
    double minG = 1000;
    double maxB = -1000;
    double minB = 1000;
    double[][] colors = new double[n][3];
    for(int i=0; i<n; i++){
        double cos = Math.cos(i * 2 * Math.PI / classes.length);
        double sin = Math.sin(i * 2 * Math.PI / classes.length);
        double bright = 1;
        colors[i][0] = bright + sin/0.88;
        colors[i][1] = bright - 0.38*cos - 0.58*sin;
        colors[i][2] = bright + cos/0.49;
        maxR = Math.max(maxR, colors[i][0]);
        minR = Math.min(minR, colors[i][0]);
        maxG = Math.max(maxG, colors[i][1]);
        minG = Math.min(minG, colors[i][1]);
        maxB = Math.max(maxB, colors[i][2]);
        minB = Math.min(minB, colors[i][2]);
    }
    double scaleR = 255/(maxR-minR);
    double scaleG = 255/(maxG-minG);
    double scaleB = 255/(maxB-minB);
    for(int i=0; i<n; i++){
        int R = (int)Math.round(scaleR*(colors[i][0]-minR));
        int G = (int)Math.round(scaleG*(colors[i][1]-minG));
        int B = (int)Math.round(scaleB*(colors[i][2]-minB));
        result[i] = "#"+String.format("%02x%02x%02x", R, G, B);
    }
    return result;
}

මෙම StackOverflow පිළිතුරෙන් ලබා ගන්නා ඇල්ගොරිතම

සමග colorසහ setColorAnimal.java දී අර්ථ

Animal.java

public static HashMap<Class, String> color = new HashMap<Class, String>();

public static void setColor(Class animalClass, String animalColor){
    color.put(animalClass, animalColor);
}

ඉන්පසු toStringGame.java සහ Statistics.java හි ක්‍රම යාවත්කාලීන කරන්න :

ගේම්.ජාවා

public String toString() {
    String s = "<html>";
    for (ArrayList<ArrayList<Animal>> row : board) {
        for (ArrayList<Animal> cell : row) {
            if (cell.isEmpty())
                s += "&nbsp;&nbsp;";
            else
                s += "<span style='color:"+ Animal.color.get(cell.get(0).getClass()) +"'>" + cell.get(0).letter + "</span>&nbsp;";
        }
        s+="<br>";
    }
    return s + "</html>";
}

Statistics.java

public String toString() {
    String s = "<html>";
    for (int i = 0; i < classes.length; i++) {
        s += "<span style='color:" + Animal.color.get(classes[i]) + "'>" + classes[i] + "</span>&nbsp;-&nbsp;" + living[i] + "<br>";
    }
    return s + "</html>";
}

2
ලස්සනයි. මම ඊයේ මිනිත්තු කිහිපයක් ගත කළේ තිරය දෙස බලාගෙනයි. ටැංකිය කියවන මැට්රික්ස් වගේ දැනුණා.
Averroes

සමාකරණය .... කාරුණික .... of ..... මන්දගාමී .... (තත්පර 30 කට පසු පුනරාවර්තන 5 ක්)
user3188175

හාහා, ඔව්. නමුත් එය එක් එක් පුනරාවර්තනය සඳහා HTML කේත මුද්‍රණය කරන අනුකරණයේ සැලසුමට ආවේනික ය.
justhalf

මම මෙම තනතුරට සබැඳියක් ලබා දෙන්නේ නම් මට මෙය මගේ ගූගල් ධාවකයේ (අභියෝගයට සම්බන්ධ) බෙදා ගත හැකිද? වෘකයන් කුඩා සංඛ්‍යාවක් පරීක්ෂා කිරීම සඳහා එය දර්ශනීය ලෙස හොඳින් ක්‍රියා කරයි.
රේන්බෝල්ට්

1
ඔව් ඔබට පුළුවන්. භූමිකම්පාව සම්බන්ධයෙන් මගේ අනෙක් ලිපියේ ලියා ඇති පරිදි බොහෝ වෘකයන් සඳහා විදැහුම්කරණ ක්‍රියාවලිය වේගවත් කිරීම සඳහා ඔබට ආරම්භක විදැහුම්කරණය මඟ හැරිය හැක.
justhalf

23

ඇල්ෆා වුල්ෆ්

බැබළීමට කාලයයි! මගේ අනෙක් වෘකයා කැම්පර් වුල්ෆ් ඉතා සිහින්, දැන් ඇල්ෆා වුල්ෆ් පැමිණේ, ඔහු වඩාත් මාංශපේශී!

සම්මත ආකාරයෙන් සිංහයන් තල්ලු කිරීම වෙනුවට, එය ඔවුන් සමඟ ක්ෂේත්‍රය මාරු කරයි. අවට ඇති සෑම ක්ෂේත්‍රයකටම අන්තරායන්-අගයන් පවරයි.

package animals;

import java.util.Random;

public class AlphaWolf extends Animal{
    private Boolean lionMoveDown = true;

    public AlphaWolf() {
        super('W');
    }
    @Override
    public Attack fight(char opponent) {
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.PAPER;
        default:
            return randomAttack();
        }
    }

    @Override
    public Move move() {
        int[] danger = new int[4];
        final int wolfsDanger = 4;
        lionMoveDown = !lionMoveDown;
        if(surroundings[0][1] == 'L' && lionMoveDown) {
            return Move.UP;
        }
        if(surroundings[1][0] == 'L'&& !lionMoveDown) {
            return Move.LEFT;
        }
        if(surroundings[0][1] == 'W') {
            danger[0] += wolfsDanger;
        }
        if(surroundings[1][2] == 'W') {
            danger[1] += wolfsDanger;
        }
        if(surroundings[2][1] == 'W') {
            danger[2] += wolfsDanger;
        }
        if(surroundings[1][0] == 'W') {
            danger[3] += wolfsDanger;
        }
        if(surroundings[0][0] == 'W') {
            danger[0]++;
            danger[3]++;
        }
        if(surroundings[0][2] == 'W') {
            danger[0]++;
            danger[1]++;
        }
        if(surroundings[2][2] == 'W') {
            danger[1]++;
            danger[2]++;
        }
        if(surroundings[1][2] == 'W') {
            danger[2]++;
            danger[3]++;
        }
        Boolean shouldMove = false;
        Move bestMove = Move.HOLD;
        int leastDanger = 4;
        for(int i = 0; i < 4; i++) {
            if (danger[i] < leastDanger) {
                bestMove = Move.values()[i];
            }
            if(danger[i] > 3) {
                shouldMove = true;
            }
        }
        if(shouldMove) {
            return bestMove;
        } else {
            return Move.HOLD;
        }
    }

    public Attack randomAttack() {
        Random rand = new Random();
        switch (rand.nextInt(3)){
            case 1: return Attack.SCISSORS;
            case 2: return Attack.ROCK;
            default: return Attack.PAPER;
        }
    }

}

එය ඉතා සුන්දර කේතයක් නොවේ, නමුත් මගේ පරීක්ෂණ වලදී එය සියලු ජාවා වෘකයන්ට එරෙහිව ඉතා හොඳින් ක්‍රියා කළේය.


1
“ක්ෂේත්‍රය මාරු කිරීම” යන්නෙන් අදහස් කරන්නේ කුමක්ද? කුතුහලයෙන් යුතුව, මට මෙය වැඩ කිරීමේදී ධාවනය කළ නොහැකි බැවින්.
රේන්බෝල්ට්

මගේ සියලු අනුකරණ මත, ඔබ පුනරාවර්තන 1000 කට පසු වෘකයන් 80-90 අතර සාමාන්‍යයක් සමඟ ජය ගනී. ජාවා හි ලියා ඇති නීත්‍යානුකූල වෘකයන් පමණක් මා සතුව ඇත. තවමත් එය වෘකයන් 10 ක් හෝ ඊට සමාන ය.
ෂෙප්

Us රුෂර් සිංහයෙක් මගේ වෘකයාට ඉහළින් සිට පහළට ගමන් කරන්නේ නම්, මගේ වෘකයා ඉහළට එනු ඇත
CommonGuy

ඔබට ප්‍රති-විල්ෆ්කාමෝ කේතයක් එක් කිරීමට අවශ්‍යයි. සිංහයාගේ දැනගැනීමේ රටාව භාවිතා කිරීම ඉතා හොඳ අදහසක් :)
Lesto

9
දැන් යමෙකුට වෘකයෙකු සොයා ගැනීමට අවශ්‍ය වන අතර එය සොයා ගන්නා ඕනෑම සිංහයෙකුට වලිගය දමනු ඇත, එබැවින් ඔබ සිංහයා සමඟ හුවමාරු වීමට උත්සාහ කරන මොහොතේම ඔබ එයට දුවනු ඇත.
ඒ.ජේ මෑන්ස්ෆීල්ඩ්

23

ඩීප් වුල්ෆ්

මම මේ සඳහා වැඩි කාලයක් යොදවා ඇත්තෙමි ... කෙසේ වෙතත්, මෙම වෘකයා "ගැඹුරු" විශ්ලේෂණ භාවිතා කරයි, එය භාවිතා කිරීම සඳහා මට සිතිය හැකි තරම් පාරිසරික දත්ත එකතු කිරීම සහ භාවිතා කිරීම. විශ්ලේෂණය ක්‍රියාත්මක වන්නේ සිංහයන් හා වෘකයන් සිටින ස්ථාන සහ අනාගත ස්ථාන පිළිබඳ අනාවැකි වැනි වෘකයන්ගේ විශේෂිත දැනුමක මිශ්‍රණයක් මත වන අතර ඇස්තමේන්තුගත ජනගහනය, වෘකයන්ගේ යුධ ඉතිහාසය සහ චලනය වන විට සත්ව විරුද්ධවාදියෙකු සමඟ ගැටීමේ අවදානම වැනි හයිව්මයින්ඩ් දැනුම ඇසුරුම් කරයි. එය ද අති විශාල ය, මන්ද යත්, බොහෝ තර්කනයන්ට අමතරව, මම වස්තු-නැඹුරු මෝස්තරයට ඉහළින් ගොස් විශේෂ කාර්ය පන්ති සහ ක්‍රම රාශියක් ඇති බැවිනි.

මම ජනප්‍රිය හා හොඳම ක්‍රියාකාරී වෘකයන් සමඟ පියවර 1000 බැගින් ක්‍රීඩාවේ පුනරාවර්තන 100 ක් ධාවනය කළෙමි. කෙසේ වෙතත්, මගේ වෘකයාට එය බලපාන්නේ නැතත්, එය ටිකක් වංචනික යැයි මා සිතූ නිසා මම හිතාමතාම සූදු කෙළිය අතහැර දැමුවෙමි. මෙන්න සාමාන්‍ය, උපරිම සහ අවම කාර්ය සාධන දත්ත:

Averages:
Bear 0.0
Lion 0.0
Stone 3.51
Wolf 1.56
AlphaWolf 77.05
CamperWolf 69.17
DeepWolf 90.48
EmoWolf 39.92
GatheringWolf 52.15
HerjanWolf 86.55
HonorWolf 86.76
HybridWolf 86.78
LazyWolf 71.11
LionHunterWolf 32.45
MimicWolf 0.4
MOSHPITFRENZYWolf 8.95
OmegaWolf 88.67
ProAlpha 83.28
Sheep 54.74
StoneEatingWolf 75.29
WolfWithoutFear 11.9

Maxes:
Bear 0
Lion 0
Stone 9
Wolf 4
AlphaWolf 89
CamperWolf 81
DeepWolf 96
EmoWolf 57
GatheringWolf 65
HerjanWolf 95
HonorWolf 97
HybridWolf 95
LazyWolf 83
LionHunterWolf 41
MimicWolf 3
MOSHPITFRENZYWolf 22
OmegaWolf 95
ProAlpha 91
Sheep 66
StoneEatingWolf 88
WolfWithoutFear 18

Mins:
Bear 0
Lion 0
Stone 0
Wolf 0
AlphaWolf 65
CamperWolf 57
DeepWolf 83
EmoWolf 26
GatheringWolf 37
HerjanWolf 79
HonorWolf 79
HybridWolf 79
LazyWolf 58
LionHunterWolf 20
MimicWolf 0
MOSHPITFRENZYWolf 1
OmegaWolf 81
ProAlpha 70
Sheep 43
StoneEatingWolf 66
WolfWithoutFear 5

ඩීප් වුල්ෆ් පළමු ස්ථානයේ සිටින්නේ 90.48 ක සාමාන්‍යයක් සමඟ වුවද, දෙවන ස්ථානයට ඔමේගා වුල්ෆ්ගේ 88.67 ට වඩා 2 ක් පටු ඊයම් ප්‍රමාණයක් පමණි. 2% ක වැඩිදියුණු කිරීමක් සඳහා කේත රේඛා 4x ක් පමණ! හර්ජන් වුල්ෆ්, හොනර් වුල්ෆ් සහ හයිබ්‍රිඩ් වුල්ෆ් තුන්වන ස්ථානය සඳහා ඔමේගා වුල්ෆ් පිළිවෙලින් 86.55, 86.76 සහ 86.78 සාමාන්‍යයන් සමඟ තවත් 2 කින් පසුපසින් සිටී.

තවදුරටත් කරදරයකින් තොරව, මම කේතය ඉදිරිපත් කරමි. එය කොතරම් දැවැන්තද යත්, මට නොපෙනෙන පරිදි වැඩිදියුණු කළ නියතයන් / තර්කනයන් සඳහා දෝෂ සහ / හෝ විභවයන් තිබිය හැකිය. ඔබට කිසියම් ප්‍රතිපෝෂණයක් ඇත්නම්, මට දන්වන්න!

මෙම සබැඳියේ කේතය, මන්ද එය පශ්චාත් අක්ෂර සීමාව පුපුරවා හරින බැවිනි : අයිඩියොන්


Dropboxusercontent ගොනුව නැති වේ දැයි මම නොදනිමි, එබැවින් මම එය ideone හි පළ කළෙමි: ideone.com/uRNxvj
Justin

3
@ Runer112 ආකර්ෂණීයයි! මම කේතය දෙස බලමින් සිටින අතර මට ටිකක් අහිමි වී ඇත: P නමුත් වෘකයන් මිත්‍රශීලීද නැද්ද යන තීරණය පදනම් කර ගැනීම සඳහා ඔබ භාවිතා කරන්නේ කුතුහලය දනවන එක් සංකල්පයකි
Moogie

O මූගි වෘකයෙකු මිත්‍රශීලීද යන්න පිළිබඳව නිශ්චිත තක්සේරුවක් සිදු නොකෙරේ. කෙසේ වෙතත්, වෘකයන් විශේෂ ගණන අපි දනිමු, සෑම විශේෂයක්ම 100 න් ආරම්භ වන බව අපි දනිමු, තවත් මිත්‍ර වෘකයන් කීයක් ඉතිරිව ඇත්දැයි අපි දනිමු. තවද අප මරා දැමූ සංඛ්‍යාව සහ අ. අනුමාන කරන්න වෙනත් සතුන්ට කී දෙනෙක් මිය ගොස් ඇත්ද කියා. ඔවුන්ගෙන්, අප දකින ඕනෑම වෘකයෙකු මිත්‍රශීලී විය හැකි බවට අපි ආසන්න වශයෙන් ගණන් බලා සිටිමු. මෙම තොරතුරු විශාල බලපෑමක් ඇති නොකරයි, නමුත් එය වෘකයෙකු සමඟ සටන් කිරීමට හෝ සිංහයෙකු සමඟ නිශ්චිතවම සටන් කිරීමට තෝරා ගැනීම අතර වෙනස විය හැකිය.
Runer112

MAP_SIZE ස්ථිතික නොවන විචල්‍යයක් බැවින් සම්පාදනය නොකළේය. එය නිදසුන් විචල්‍යයක් වනු ඇතැයි මා නොකියූ හෙයින්, මම එය ඔබ වෙනුවෙන් සවි කළෙමි. මම සම්පූර්ණ ව්‍යාපෘතිය පළ කළ විට ඔබ දැන ගැනීමට අවශ්‍යය.
රේන්බෝල්ට්

Us රුෂර් ඔහ්, අපොයි. මම හිතන්නේ මම තවමත් සෑන්ඩ්බොක්ස් වෙතින් ක්‍රීඩා කේතයේ පැරණි අනුවාදයක් සමඟ ධාවනය වෙමින් සිටියෙමිMAP_SIZE විචල්‍යය එවකට නොතිබුණි හෝ කිසියම් හේතුවක් නිසා මම එය නොසලකා හැර මගේම ස්ථිතික අනුවාදයට එක් කළෙමි. මගේ වෘකයා මගේ අත්හදා බැලීම් වලදී අනෙක් වෘකයන්ට වඩා තරමක් හොඳ ලකුණු ලබාගත්තේ ඇයිදැයි මම කල්පනා කරමි, නමුත් ඔබ තුළ එය වඩාත් නරක අතට හැරුණි ... වෙනස් වෘක කට්ටලයක්, මම හිතන්නේ? නැතහොත් ඔබ ඔබේ ක්‍රීඩා 1000 ක් හැර වෙනත් පුනරාවර්තන ගණනාවක් සඳහා ධාවනය කරනවාද? නැතහොත් ඔබට විශාල සාම්පල ප්‍රමාණයක් අවශ්‍ය විය හැකිය, 5 සංඛ්‍යානමය වශයෙන් එතරම් විශාල නොවේ.
Runer112

23

සූදුවේ නියැලෙන වුල්ෆ්

සූදුවේ නියැලෙන වුල්ෆ් අවස්ථා ලබා ගැනීමට කැමතියි, එබැවින් ඔහු වාසනාවන්ත ලෙස හැසිරෙනු ඇත. වාසනාවකට ඔහු වෙනුවෙන්, ඇය කිසි විටෙකත් ඔහුව පහත් කරන්නේ නැත! නිරන්තර වාසනාවන්ත පහරවල් මගින්, සූදුවේ නියැලෙන වුල්ෆ් සියලු වෘකයන් නොවන බාධක වල ක්ෂේත්‍රය ඇදහිය නොහැකි තරම් හේතු කිහිපයක් සමඟ ඉවත් කරයි!

package animals;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;

public class GamblerWolf extends Animal {
    private static int last = 0;

    public GamblerWolf() { super('W'); gamble(); }
    public Attack fight(char opponent) {
        switch (opponent) {
        case 'S': return Attack.ROCK; /* Camo Wolf? */
        case 'B': return Attack.SCISSORS;
        case 'L': return Attack.SCISSORS;
        default:  return attackWolf();
        }
    }
    public Move move() {
        ArrayList<Move> moves = (ArrayList<Move>) Arrays.asList(Move.values());
        Collections.shuffle(moves);
        for(Move move : moves)
          if(isThreatenedBy(move))
            return moveToEvade(move);
        return Move.HOLD;
    }

    /* Remember, Gamblers Don't Gamble */
    @SuppressWarnings("serial")
    private static void gamble() {
        try {
        Field field = Math.class.getDeclaredField("randomNumberGenerator"); 
        field.setAccessible(true);
        field.set(null, new Random() { 
              @Override
              public double nextDouble() {
                return 4; // chosen by fair dice roll
              }           // guaranteed to be random
            });           // proof: http://xkcd.com/221/
        }
        catch (SecurityException        e) {}
        catch (NoSuchFieldException     e) {}
        catch (IllegalArgumentException e) {}
        catch (IllegalAccessException   e) {}
    }

    private static Attack attackWolf() {
        return Attack.values()[last++ % 3];
    }
    private boolean isThreatenedBy(Move move) {
        return isWolf(move) 
            || isStone(move); 
    }

    private Move moveToEvade(Move move) {
        if(isSafeMove(getOpposite(move)))
            return getOpposite(move);

        ArrayList<Move> moves = (ArrayList<Move>) Arrays.asList(getOrthogonal(move));
        Collections.shuffle(moves);
        for(Move m : moves)
            if(isSafeMove(m))
                return m;
        return Move.HOLD;
    }

    private static Move[] getOrthogonal(Move move) {
        switch(move){
        case UP:
        case DOWN:  return new Move[] { Move.LEFT, Move.RIGHT };
        case LEFT:
        case RIGHT: return new Move[] { Move.UP,   Move.DOWN };
        default:    return null;
        }
    }

    private static Move getOpposite(Move move) {
        switch(move){
        case UP:    return Move.DOWN;
        case DOWN:  return Move.UP;
        case LEFT:  return Move.RIGHT;
        case RIGHT: return Move.LEFT;
        default:    return null;
        }
    }

    private boolean isSafeMove(Move move) {
        return !isWolf(move)
            && !isStone(move)
            && !couldAWolfMoveHere(move);
    }

    private boolean isWolf(Move move) {
        return isX(move,'W');
    }

    private boolean isStone(Move move) {
        return isX(move,'S');
    }

    private boolean isX(Move m, char c) {
        switch (m) {
        case UP:    return surroundings[0][1] == c;
        case LEFT:  return surroundings[1][0] == c;
        case RIGHT: return surroundings[1][2] == c;
        case DOWN:  return surroundings[2][1] == c;
        default:    return false;
        }
    }

    private boolean couldAWolfMoveHere(Move move) {
        switch (move) {
        case UP:    return surroundings[0][2] == 'W' || surroundings[0][0] == 'W';
        case LEFT:  return surroundings[2][0] == 'W' || surroundings[0][0] == 'W';
        case RIGHT: return surroundings[0][2] == 'W' || surroundings[2][2] == 'W';
        case DOWN:  return surroundings[2][0] == 'W' || surroundings[2][2] == 'W';
        default:    return false;
        }
    }
}

සංස්කරණය කරන්න: v1.1

  • දැන් ගල් වළක්වයි (කැමෝ-වෘකයන්?)

  • අහඹු ලෙස වැඩි වීම!


5
මම හිතන්නේ මම මෙය මගේ වෘකයන්ට එකතු කරන්නම්:static{System.setSecurityManager(new SecurityManager());}
johnchen902

13
ඔබට සාධාරණ ලෙස ක්‍රීඩා කිරීමට නොහැකි වූ විට, වංචා කරන්න +1: D
ProgrammerDan

5
අවාසනාවන්ත ලෙස return 4; // chosen by fair dice roll. guaranteed to be random.මෙහි භාවිතා කළ නොහැක ...
Vi.

1
ඔබට වඩාත් නපුරු වීමට අවශ්‍ය නම්, Math.random()ඊටත් වඩා කොන්ත්‍රාත්තුව බිඳ දමන්න ; [0,1) පරාසයෙන් පිටත ඇති ප්‍රතිලාභ අගයන්, සමහර විට අසීමිත හෝ NaN විය හැකිය. නැතහොත්, හැකි තරම් නපුරු වීමට නම්, කිසිවක් ආපසු ලබා දීම වෙනුවට ධාවන කාල ව්‍යතිරේකයක් විසි කරන්න (උත්පාදක යන්ත්රය සැකසීමෙන් ද එය සාක්ෂාත් කරගත හැකිය null).
Runer112

1
Lex ඇලෙක්ස්එල්. ForrestWolfගැටලුවක් සේ පෙනේ ...
recursion.ninja

22

කැම්පර් වුල්ෆ්

ඉලක්කය වන්නේ දිවි ගලවා ගැනීමයි. අනෙක් වෘකයන්ගෙන් බොහෝ දෙනෙක් වෘකයන්ගෙන් පලා යන විට, මගේ ස්ථානය එහි රැඳී සිටිමින් සියලු සතුන්ට එරෙහිව සටන් කරයි (පාෂාණ පවා වංචාවට ඉඩ දෙන්නේ නම්).

package animals;

public class CamperWolf extends Animal {
    public CamperWolf() { super('W'); }
    @Override
    public Attack fight(char opponent) {  
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.ROCK;
        default:
            return Attack.values()[(int) (Math.random() * 3)];
        }
    }
    @Override
    public Move move() { return Move.HOLD; }
}

තවත් බොහෝ වෘකයන් වෘකයන්ගෙන් පලා යන අතර මෙම වෘකයා මිය යා හැක්කේ වෙනත් වෘකයන්ට එරෙහිව පමණක් බැවින් එය ඉතා හොඳ කාර්යයක් වනු ඇතැයි මම අපේක්ෂා කරමි.


සිංහයන්ටද එය මරා දැමිය හැකිය. සිංහයා කතුර රෝල් කළහොත් ඔබේ වෘකයා ව්‍යාජ ලෙස මිය යනු ඇත.
ටිම් සෙගුයින්

2
සුභ පැතුම් මිනිසා. ඔබ සහ ඔබේ කේත පේළි 15 දැනට ජයග්‍රහණය කර ඇත.
රේන්බෝල්ට්

2
Us රුෂර්ට ස්තූතියි :) පහත හෙලූ තැනැත්තාට ඔහු පහත් කොට සැලකීමට හේතුව පැහැදිලි කළ හැකිද?
CommonGuy

An මානුට එය වැදගත් නොවේ, මන්ද ගල් වලට චලනය කළ නොහැකි නමුත් ඔබේ නඩුව 'එස්' ආපසු ප්‍රහාරයක් එල්ල කළ යුතු නොවේද?
ඩේවිඩ් ජේ ෆීලික්ස්

3
ඔව්, මම කැමෝ වුල්ෆ්ව ඇහුවා. උපක්‍රමශීලී මිනිහා!
ඩේවිඩ් ජේ ෆීලික්ස්

21

WolfRunningWithScissors

කතුර සමග දුවන්න එපා කියා කිසිවෙකු වුල්ෆ් රනිං විත් ස්කිසර්ට කීවේ නැත. නැත්නම් සමහර විට ඔවුන් එසේ කළ නමුත් ඔහු එය කෙසේ හෝ කරයි.

ඔහු සතුරෙකු වෙතට දිව ගියහොත් ඔහු එක්කෝ කතුරෙන් ජයග්‍රහණය කරනු ඇත, කතුරෙන් පරාජය වනු ඇත, කතුර සමග ගැට ගසනු ඇත, නැතහොත් ඔහුගේ ඇස එළියට දමනු ඇත (සියදිවි නසා ගැනීම).

package animals;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class WolfRunningWithScissors extends Animal{

    public WolfRunningWithScissors() {
        super('W');
    }

    @Override
    public Attack fight(char c) {
        List<Attack> att = new ArrayList<>();
        att.add(Attack.SCISSORS);
        att.add(Attack.SUICIDE);
        Collections.shuffle(att);
        return att.get(0);
    }

    @Override
    public Move move() {
        List<Move> m = new ArrayList<>();
        m.add(Move.UP);
        m.add(Move.DOWN);
        m.add(Move.LEFT);
        m.add(Move.RIGHT);
        Collections.shuffle(m);
        return m.get(0);
    }

}

විනෝදය සඳහා ඉදිරිපත් කිරීමක් කිරීමට අවශ්‍ය විය. මම මීට පෙර කවදාවත් ජාවා භාවිතා කර නැති අතර මෙය අත්හදා බලා නැත, නමුත් එය ක්‍රියාත්මක විය යුතුය. මගේ අහඹු ප්‍රහාරය සහ චලනය වන කේතය පදනම් වී getRandomAttack()ඇත්තේ ස්ටෝන් ඊටිං වුල්ෆ් වෙතින් ය.


15

එය පිරිමි ළමයෙක් ද? එය වෘකයෙක්ද? නැහැ, ඒ

BoyWhoCriedWolf.java

මිනිසුන් සෑම තැනකම පරාවර්තනය භාවිතා කරයි, එබැවින් මම සිතුවෙමි, එය තවත් පියවරක් ඉදිරියට නොගන්නේ මන්ද?
මම ඔබට ඉදිරිපත් කරමි: නැතිවිය නොහැකි වෘකයා.

package animals;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.Attributes;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.xml.bind.DatatypeConverter;

public class BoyWhoCriedWolf extends Animal {

    private static boolean ranAgent;

    public static void installAgent() {
        try {
            ranAgent = true;
            String javaExec = new File(System.getProperty("java.home"), "bin").getAbsolutePath() + File.separator + "java";
            Process proc = new ProcessBuilder(javaExec, "-cp", System.getProperty("java.class.path"),
                    "animals.BoyWhoCriedWolf", ManagementFactory.getRuntimeMXBean().getName().split("@")[0])
                    .inheritIO().start();
            proc.waitFor();
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        }
    }

    public BoyWhoCriedWolf() {
        super('W');
        if (!ranAgent) {
            installAgent();
        }
    }

    @Override
    public Attack fight(char c) {
        return Attack.PAPER; // I like paper, it's my rubber duck.
    }

    @Override
    public Move move() {
        return Move.HOLD; // I'm terribly lazy.
    }

    public static void main(String[] args) {
        try {
            File temp = File.createTempFile("agent-", ".jar");
            temp.deleteOnExit();
            Manifest manifest = new Manifest();
            manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
            manifest.getMainAttributes().put(new Attributes.Name("Agent-Class"), "animals.BoyWhoCriedWolf");
            manifest.getMainAttributes().put(new Attributes.Name("Can-Redefine-Classes"), "true");
            JarOutputStream jos = new JarOutputStream(new FileOutputStream(temp), manifest);
            jos.close();

            // Add tools.jar
            Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
            addURL.setAccessible(true);
            addURL.invoke(ClassLoader.getSystemClassLoader(), new URL("file:" + System.getProperty("java.home") + "/../lib/tools.jar"));

            Class<?> virtualMachineClass = Class.forName("com.sun.tools.attach.VirtualMachine");
            Object vm = virtualMachineClass.getDeclaredMethod("attach", String.class).invoke(null, args[0]);
            virtualMachineClass.getDeclaredMethod("loadAgent", String.class).invoke(vm, temp.getAbsolutePath());
            virtualMachineClass.getDeclaredMethod("detach").invoke(vm);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void agentmain(String args, Instrumentation instr) throws ClassNotFoundException, UnmodifiableClassException {
        instr.redefineClasses(new ClassDefinition(wild.Game.class, DatatypeConverter.parseBase64Binary(base64Game)));
    }

    private static final String base64Game =
              "yv66vgAAADMA9QoAOQCRBwCSCgACAJEJABIAkwkAEgCUBwCVCgAGAJEJABIAlgoABgCXCgAGAJgK"
            + "AAIAmQoABgCaCgCbAJwHAJ0HAJ4KABIAnwoAEgCgBwChCgASAKIHAKMKABIApAkAFAClCgAUAKYH"
            + "AKcJAGUAqAkAOgCpCgBlAKoKAAYAqwsArACtCwCsAK4KAAYArwcAsAoABgCxCQAUALIKABQAswkA"
            + "cQC0CgC1ALYGP+AAAAAAAAAJADoAtwoAcQCqCQBxALgJAHEAuQkAcQC6CgCbALsIALwHAL0KAC8A"
            + "kQoALwC+CAC/CgAvAMAKAC8AwQgAwggAwwgAxAcAjQcAxQcAxgEADElubmVyQ2xhc3NlcwEABWJv"
            + "YXJkAQAVTGphdmEvdXRpbC9BcnJheUxpc3Q7AQAJU2lnbmF0dXJlAQBVTGphdmEvdXRpbC9BcnJh"
            + "eUxpc3Q8TGphdmEvdXRpbC9BcnJheUxpc3Q8TGphdmEvdXRpbC9BcnJheUxpc3Q8TGFuaW1hbHMv"
            + "QW5pbWFsOz47Pjs+OwEAA2dlbgEAEkxqYXZhL3V0aWwvUmFuZG9tOwEABFNJWkUBAAFJAQAGPGlu"
            + "aXQ+AQAEKEkpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUB"
            + "AAFqAQABaQEABHRoaXMBAAtMd2lsZC9HYW1lOwEABHNpemUBAA1TdGFja01hcFRhYmxlBwChAQAI"
            + "cG9wdWxhdGUBABUoTGphdmEvbGFuZy9DbGFzcztJKVYBAAFlAQAoTGphdmEvbGFuZy9SZWZsZWN0"
            + "aXZlT3BlcmF0aW9uRXhjZXB0aW9uOwEAA3JvdwEAA2NvbAEAB3NwZWNpZXMBABFMamF2YS9sYW5n"
            + "L0NsYXNzOwEAA251bQEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBABZMamF2YS9sYW5nL0NsYXNz"
            + "PFRUOz47BwDHBwDIAQAuPFQ6TGFuaW1hbHMvQW5pbWFsOz4oTGphdmEvbGFuZy9DbGFzczxUVDs+"
            + "O0kpVgEAB2l0ZXJhdGUBAAMoKVYBAAdtb3ZlQWxsAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAB"
            + "YQEAEExhbmltYWxzL0FuaW1hbDsBAAVhTW92ZQcAyQEABE1vdmUBABVMYW5pbWFscy9BbmltYWwk"
            + "TW92ZTsBAARnYW1lBwCjBwCnBwDJAQAHZmxhdHRlbgEABXJhbmQxAQAFcmFuZDIBAAFiAQAFYVRh"
            + "Y2sHAMoBAAZBdHRhY2sBABdMYW5pbWFscy9BbmltYWwkQXR0YWNrOwEABWJUYWNrAQAEY2VsbAEA"
            + "J0xqYXZhL3V0aWwvQXJyYXlMaXN0PExhbmltYWxzL0FuaW1hbDs+OwEAPkxqYXZhL3V0aWwvQXJy"
            + "YXlMaXN0PExqYXZhL3V0aWwvQXJyYXlMaXN0PExhbmltYWxzL0FuaW1hbDs+Oz47BwDLBwCVBwDK"
            + "AQAEcG9sbAEAFChMamF2YS9sYW5nL0NsYXNzOylJAQABYwEABWNvdW50AQAIdG9TdHJpbmcBABQo"
            + "KUxqYXZhL2xhbmcvU3RyaW5nOwEAAXMBABJMamF2YS9sYW5nL1N0cmluZzsHAMwBAAdnZXRBcmVh"
            + "AQAHKElJKVtbQwEABXRlbXAxAQAFdGVtcDIBAAV0ZW1wMwEABXRlbXA0AQABbAEAAWsBAARhcmVh"
            + "AQADW1tDBwDNAQAKU291cmNlRmlsZQEACUdhbWUuamF2YQwARABfAQAQamF2YS91dGlsL1JhbmRv"
            + "bQwAQABBDABCAEMBABNqYXZhL3V0aWwvQXJyYXlMaXN0DAA8AD0MAM4AzwwA0ADRDADSANMMANQA"
            + "1QcAxwwA1gDXAQAgamF2YS9sYW5nL0luc3RhbnRpYXRpb25FeGNlcHRpb24BACBqYXZhL2xhbmcv"
            + "SWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgwAYABfDABsAF8BAAl3aWxkL0dhbWUMAEQARQEADmFuaW1h"
            + "bHMvQW5pbWFsDACEAIUMANgAjQwA2QDaAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwA2wBnDADcAN0M"
            + "AN4A3wwA4ADhBwDLDADiANUMAOMA1wwATQDfAQAXYW5pbWFscy9Cb3lXaG9DcmllZFdvbGYMAOQA"
            + "zwwA5QDmDADnAOgMAOkAcwcA6gwA6wDsDADtAN0MAO4AcwwA7wBzDADwAHMMAPEAzwEABjxodG1s"
            + "PgEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDADyAPMBAAwmbmJzcDsmbmJzcDsMAH8AgAwA8gD0"
            + "AQAGJm5ic3A7AQAEPGJyPgEABzwvaHRtbD4BABBqYXZhL2xhbmcvT2JqZWN0AQALd2lsZC9HYW1l"
            + "JDEBAA9qYXZhL2xhbmcvQ2xhc3MBACZqYXZhL2xhbmcvUmVmbGVjdGl2ZU9wZXJhdGlvbkV4Y2Vw"
            + "dGlvbgEAE2FuaW1hbHMvQW5pbWFsJE1vdmUBABVhbmltYWxzL0FuaW1hbCRBdHRhY2sBABJqYXZh"
            + "L3V0aWwvSXRlcmF0b3IBABBqYXZhL2xhbmcvU3RyaW5nAQACW0MBAANhZGQBABUoTGphdmEvbGFu"
            + "Zy9PYmplY3Q7KVoBAANnZXQBABUoSSlMamF2YS9sYW5nL09iamVjdDsBAAduZXh0SW50AQAEKEkp"
            + "SQEAB2lzRW1wdHkBAAMoKVoBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAM"
            + "c3Vycm91bmRpbmdzAQAEbW92ZQEAFygpTGFuaW1hbHMvQW5pbWFsJE1vdmU7AQAESE9MRAEAHiRT"
            + "d2l0Y2hNYXAkYW5pbWFscyRBbmltYWwkTW92ZQEAAltJAQAHb3JkaW5hbAEAAygpSQEACGl0ZXJh"
            + "dG9yAQAWKClMamF2YS91dGlsL0l0ZXJhdG9yOwEAB2hhc05leHQBAARuZXh0AQAGcmVtb3ZlAQAG"
            + "bGV0dGVyAQABQwEABWZpZ2h0AQAaKEMpTGFuaW1hbHMvQW5pbWFsJEF0dGFjazsBAAdTVUlDSURF"
            + "AQAOamF2YS9sYW5nL01hdGgBAAZyYW5kb20BAAMoKUQBACAkU3dpdGNoTWFwJGFuaW1hbHMkQW5p"
            + "bWFsJEF0dGFjawEABVBBUEVSAQAIU0NJU1NPUlMBAARST0NLAQAKaXNJbnN0YW5jZQEABmFwcGVu"
            + "ZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEAHChDKUxq"
            + "YXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsAIQASADkAAAADAAIAPAA9AAEAPgAAAAIAPwASAEAAQQAA"
            + "ABQAQgBDAAAACAAEAEQARQABAEYAAADtAAMABAAAAF8qtwABKrsAAlm3AAO1AAQqG7UABSq7AAZZ"
            + "twAHtQAIAz0cG6IAOyq0AAi7AAZZtwAHtgAJVwM+HRuiAB8qtAAIHLYACsAABrsABlm3AAe2AAlX"
            + "hAMBp//ihAIBp//GsQAAAAMARwAAAC4ACwAAABEABAAOAA8AEgAUABMAHwAUACYAFQA1ABYAPAAX"
            + "AFIAFgBYABQAXgAaAEgAAAAqAAQANwAhAEkAQwADACEAPQBKAEMAAgAAAF8ASwBMAAAAAABfAE0A"
            + "QwABAE4AAAAYAAT/ACEAAwcATwEBAAD8ABUB+gAg+gAFAAQAUABRAAIARgAAARwAAgAGAAAAXRye"
            + "AFsqtAAEKrQABbYACz4qtAAEKrQABbYACzYEKrQACB22AArAAAYVBLYACsAABrYADJkAJiq0AAgd"
            + "tgAKwAAGFQS2AArAAAYrtgANtgAJV6cABToFhAL/p/+nsQACADYAUQBUAA4ANgBRAFQADwAEAEcA"
            + "AAAmAAkAAAAdAAQAHgAQAB8AHQAgADYAIQBRACIAVgAjAFkAJQBcACYASAAAAD4ABgBWAAAAUgBT"
            + "AAUAEABJAFQAQwADAB0APABVAEMABAAAAF0ASwBMAAAAAABdAFYAVwABAAAAXQBYAEMAAgBZAAAA"
            + "DAABAAAAXQBWAFoAAQBOAAAAGwAFAP8AUwAFBwBPBwBbAQEBAAEHAFwB+QACAgA+AAAAAgBdAAQA"
            + "XgBfAAEARgAAADsAAQABAAAACSq3ABAqtwARsQAAAAIARwAAAA4AAwAAACkABAAqAAgAKwBIAAAA"
            + "DAABAAAACQBLAEwAAAACAGAAXwABAEYAAAJjAAQABwAAAVu7ABJZKrQABbcAE0wDPRwqtAAFogE/"
            + "Az4dKrQABaIBLyq0AAgctgAKwAAGHbYACsAABrYADJoBESq0AAgctgAKwAAGHbYACsAABgO2AArA"
            + "ABQ6BBkEKhwdtwAVtQAWGQS2ABc6BacACjoGsgAZOgWyABoZBbYAGy6qAAAAAAAAzgAAAAEAAAAF"
            + "AAAAJAAAAEsAAABtAAAAjwAAALYrtAAIHARkKrQABWAqtAAFcLYACsAABh22AArAAAYZBLYACVen"
            + "AIYrtAAIHLYACsAABh0EYCq0AAVwtgAKwAAGGQS2AAlXpwBkK7QACBwEYCq0AAVwtgAKwAAGHbYA"
            + "CsAABhkEtgAJV6cAQiu0AAgctgAKwAAGHQRkKrQABWAqtAAFcLYACsAABhkEtgAJV6cAGyu0AAgc"
            + "tgAKwAAGHbYACsAABhkEtgAJV4QDAaf+z4QCAaf+vyortAAItQAIsQABAF4AZQBoABgAAwBHAAAA"
            + "WgAWAAAALgAMAC8AFgAwACAAMQA4ADIAUwAzAF4ANQBlADYAbwA3AJwAOQDAADoAwwA8AOIAPQDl"
            + "AD8BBABAAQcAQgErAEMBLgBFAUYAMAFMAC8BUgBLAVoATABIAAAAUgAIAGoABQBSAGEABgBTAPMA"
            + "YgBjAAQAZQADAGQAZwAFAG8A1wBkAGcABQAYATQASQBDAAMADgFEAEoAQwACAAABWwBLAEwAAAAM"
            + "AU8AaABMAAEATgAAADYADP0ADgcATwH8AAkB/wBPAAUHAE8HAE8BAQcAaQABBwBq/AAGBwBrLCYh"
            + "ISb5ABf6AAX6AAUAAgBsAF8AAQBGAAADuAAFAAwAAAFfKrQACLYAHEwruQAdAQCZAVAruQAeAQDA"
            + "AAZNLLYAHE4tuQAdAQCZATUtuQAeAQDAAAY6BBkEtgAfBKQBHiq0AAQZBLYAH7YACzYFKrQABBkE"
            + "tgAftgALNgYVBRUGn//uGQQVBbYACsAAFDoHGQQVBrYACsAAFDoIGQfBACCZAA4ZBBkItgAhV6f/"
            + "rBkIwQAgmQAOGQQZB7YAIVen/5kZBxkItAAitgAjOgmnAAo6C7IAJDoJGQgZB7QAIrYAIzoKpwAK"
            + "OguyACQ6ChkJGQqmAB0ZBLgAJRQAJpeeAAgZB6cABRkItgAhV6cAbbIAKBkJtgApLqoAAAAAAABh"
            + "AAAAAQAAAAMAAAAcAAAANAAAAEwZBBkKsgAqpgAIGQenAAUZCLYAIVenADAZBBkKsgArpgAIGQen"
            + "AAUZCLYAIVenABgZBBkKsgAspgAIGQenAAUZCLYAIVen/t+n/sin/q2xAAIAngCqAK0AGAC0AMAA"
            + "wwAYAAQARwAAAHYAHQAAAE8AGwBQADQAUQA9AFMASwBUAGAAVgBsAFcAeABZAIAAWgCIAFsAiwBc"
            + "AJMAXQCbAF4AngBiAKoAYwC0AGQAwABlAMoAZwDRAGgA6wBqARAAbAElAG0BKABvAT0AcAFAAHIB"
            + "VQB2AVgAdwFbAHgBXgB5AEgAAACEAA0ArwAFAFIAYQALAMUABQBSAGEACwBLAQoAbQBDAAUAWQD8"
            + "AG4AQwAGAGwA6QBiAGMABwB4AN0AbwBjAAgAqgADAHAAcwAJALQAoQBwAHMACQDAAAMAdABzAAoA"
            + "ygCLAHQAcwAKADQBJAB1AD0ABAAbAUAAVAA9AAIAAAFfAEsATAAAAFkAAAAWAAIANAEkAHUAdgAE"
            + "ABsBQABUAHcAAgBOAAABFQAa/AAIBwB4/QAXBwB5BwB4/AATBwB5/AAWAf4APwEHAGkHAGkSTgcA"
            + "avwABgcAek4HAGr8AAYHAHpXBwB5/wABAAsHAE8HAHgHAHkHAHgHAHkBAQcAaQcAaQcAegcAegAC"
            + "BwB5BwBpBiROBwB5/wABAAsHAE8HAHgHAHkHAHgHAHkBAQcAaQcAaQcAegcAegACBwB5BwBpBk4H"
            + "AHn/AAEACwcATwcAeAcAeQcAeAcAeQEBBwBpBwBpBwB6BwB6AAIHAHkHAGkGTgcAef8AAQALBwBP"
            + "BwB4BwB5BwB4BwB5AQEHAGkHAGkHAHoHAHoAAgcAeQcAaf8AAwAFBwBPBwB4BwB5BwB4BwB5AAD6"
            + "AAL5AAL6AAIABAB7AHwAAQBGAAABNgACAAkAAABvAz0qtAAItgAcTi25AB0BAJkAXS25AB4BAMAA"
            + "BjoEGQS2ABw6BRkFuQAdAQCZAD4ZBbkAHgEAwAAGOgYZBrYAHDoHGQe5AB0BAJkAHhkHuQAeAQDA"
            + "ABQ6CCsZCLYALZkABoQCAaf/3qf/vqf/oBysAAAABABHAAAAKgAKAAAAfAACAH0AHgB+ADsAfwBY"
            + "AIAAYQCBAGQAggBnAIMAagCEAG0AhQBIAAAAPgAGAFgADABiAGMACAA7ACwAdQA9AAYAHgBMAFQA"
            + "PQAEAAAAbwBLAEwAAAAAAG8AfQBXAAEAAgBtAH4AQwACAFkAAAAWAAIAOwAsAHUAdgAGAB4ATABU"
            + "AHcABABOAAAAJQAH/QAKAQcAeP0AGgcAeQcAeP0AHAcAeQcAeCH5AAL5AAL6AAIAAQB/AIAAAQBG"
            + "AAABWwADAAYAAACqEi5MKrQACLYAHE0suQAdAQCZAIUsuQAeAQDAAAZOLbYAHDoEGQS5AB0BAJkA"
            + "VBkEuQAeAQDAAAY6BRkFtgAMmQAauwAvWbcAMCu2ADESMrYAMbYAM0ynACa7AC9ZtwAwK7YAMRkF"
            + "A7YACsAAFLQAIrYANBI1tgAxtgAzTKf/qLsAL1m3ADArtgAxEja2ADG2ADNMp/94uwAvWbcAMCu2"
            + "ADESN7YAMbYAM7AAAAAEAEcAAAAqAAoAAACJAAMAigAeAIsAOgCMAEIAjQBZAI8AfACQAH8AkQCT"
            + "AJIAlgCTAEgAAAAqAAQAOgBCAHUAPQAFAB4AdQBUAD0AAwAAAKoASwBMAAAAAwCnAIEAggABAFkA"
            + "AAAWAAIAOgBCAHUAdgAFAB4AdQBUAHcAAwBOAAAAIwAG/QALBwCDBwB4/QAYBwB5BwB4/AA0BwB5"
            + "+gAi+gAC+QAWAAIAhACFAAEARgAAAdAABAALAAAApQYGxQA4Ak4CNgQVBASjAJYCNgUVBQSjAIcV"
            + "BARgNgYVBQRgNgcbFQRgKrQABWAqtAAFcDYIHBUFYCq0AAVgKrQABXA2CSq0AAgbFQRgKrQABWAq"
            + "tAAFcLYACsAABhwVBWAqtAAFYCq0AAVwtgAKwAAGOgotFQQEYDIVBQRgGQq2AAyZAAgQIKcADxkK"
            + "A7YACsAAFLQAIlWEBQGn/3mEBAGn/2otsAAAAAQARwAAADIADAAAAJcABwCYABAAmQAZAJoAHwCb"
            + "ACUAnAA1AJ0ARQCeAHMAnwCXAJkAnQCYAKMAogBIAAAAcAALAB8AeACGAEMABgAlAHIAhwBDAAcA"
            + "NQBiAIgAQwAIAEUAUgCJAEMACQBzACQAdQA9AAoAEwCKAIoAQwAFAAoAmQCLAEMABAAAAKUASwBM"
            + "AAAAAAClAEoAQwABAAAApQBJAEMAAgAHAJ4AjACNAAMAWQAAAAwAAQBzACQAdQB2AAoATgAAAFkA"
            + "Bv0ACgcAOAH8AAgB/wB2AAsHAE8BAQcAOAEBAQEBAQcAeQACBwCOAf8ACwALBwBPAQEHADgBAQEB"
            + "AQEHAHkAAwcAjgEB/wAGAAUHAE8BAQcAOAEAAPoABQACAI8AAAACAJAAOwAAABoAAwA6ABIAABAI"
            + "AGUAFABmQBkAcQAUAHJAGQ==";
}

ඔව්, එයට JDK ධාවනය කිරීමට අවශ්‍යයි, නමුත් මම හිතන්නේ නැහැ එය ගැටලුවක් වේවි කියා.


1
අපොයි, ඔබ මට එයට පහර දුන්නා. මම මේ නිශ්චිත උපක්‍රමය සමඟ සැබොටේජ් ඒජන්ට් වුල්ෆ් හි වැඩ කරමින් සිටියෙමි.
mackthehobbit

1
මෙම පන්තිය කරන්නේ කුමක්ද?
justhalf

4
ustjusthalf එය ක්‍රීඩා පංතිය ප්‍රතිනිර්මාණය කරන්නේ පහළින් ඇති base64 හි කේතනය කර ඇති ගොනුව සමඟ ය. එම ගොනුවට නිදර්ශන චෙක්පතක් ඇත; ඒ මගේ වෘකයා නම්, අනෙකා නිතරම මිය යයි.
14mRh4X0r

1
අනෙක් සියලුම සතුන් සියදිවි නසා ගැනීමට සහ හයිප්නෝ වුල්ෆ් ලෙස හැඳින්වීමට මෙම යාන්ත්‍රණය භාවිතා කිරීමට මට අදහසක් තිබුණි. එය නිවැරදිව ක්‍රියාත්මක කිරීමට මට නොහැකි විය, නමුත් ඔබ එසේ කළා - ගරු කරන්න!
ෆ්‍රැන්කොයිස් ධනේශ්වර

14

ඔමේගා වුල්ෆ්

ඇල්ෆා වුල්ෆ්ට බොහෝ සෙයින් සමාන වන අන්තර් පරායත්ත ව්‍යුත්පන්නය, එබැවින් ඔමේගා වුල්ෆ් යන නම ලැබුණි

මෙම වෘකයා අවට සෛලවල "අන්තරා" සිතියමක් ජනනය කරන අතර ආරක්ෂිත සෛලය වෙත චලනය (හෝ රඳවා තබා ගැනීම) තෝරා ගනු ඇත.

ඊළඟට සිංහයන් ඊළඟට චලනය වන සෛල වලට EXTREAME_DANGER මට්ටම ලබා දෙනු ලැබේ. ඕනෑම හඳුනාගත් වෘකයන් වටා ඇති සෛල වලට ප්‍රහාරයේ ක්ෂණිකභාවය මත පදනම්ව අවදානම් මට්ටම් ලබා දෙනු ලැබේ ... එනම් වෘකයා ඔමේගා වෘකයාට විකර්ණ නම් එය අඩු තර්ජනයක් ලෙස සලකනු ලැබේ, කෙසේ වෙතත් යාබද වෘකයන් මධ්‍යස්ථ තර්ජනයක් ලෙස සලකනු ලැබේ.

අවට සෛල වලට ඇති තර්ජන ලේ ගැලීමට ඉඩ දීම සඳහා "අන්තරාය" සිතියම බොඳ කරනු ලැබේ. මෙය ඔමේගා වෘකයාට තර්ජනාත්මක වාහකයන් "දැනීමට" සහ එය වළක්වා ගැනීමට ඉඩ සලසයි.

වර්තමානයේ සත්‍ය ප්‍රහාරක තර්කනය ඉතා ප්‍රාථමික ය. ඊට වඩා හොඳ ස්මාර්ට් ලබා දීමටත් වඩා හොඳ ජය / පරාජිත අනුපාත ලබා ගැනීමටත් හැකි වනු ඇතැයි මම බලාපොරොත්තු වෙමි. මා යම් සංඛ්‍යාලේඛනමය ප්‍රතිකාරයක් ඉදිරිපත් කළහොත් මෙය කළ හැකි ය.

මගේ පරීක්ෂණයේදී ඔමේගා වුල්ෆ් 10 වතාවක් 9 ක්ම ඇල්ෆා බොට්ට එරෙහිව ජය ගනී ... ආන්තිකය ඉතා හොඳයි: පී

පුනරාවර්තන 1000 ක වට 100 කට පසු ඉතිරිව ඇති සාමාන්‍ය වෘකයන්ගේ ඉක්මන් ප්‍රති results ල:

class animals.OmegaWolf - 85
class animals.HonorWolf - 82
class animals.ProAlpha - 79
class animals.AlphaWolf - 77
class animals.ShadowWolf - 77
class animals.LazyWolf - 62
class animals.CamperWolf - 61
class animals.StoneEatingWolf - 59
class animals.GatheringWolf - 48
class animals.Sheep - 42
class animals.EmoWolf - 34
class animals.LionHunterWolf - 28
class animals.GamblerWolf (no cheating) - 27
class animals.WolfWithoutFear - 11
class animals.MOSHPITFRENZYWolf - 5
class animals.Wolf - 3
class animals.Stone - 2
class animals.Bear - 0
class animals.Lion - 0
class animals.MimicWolf - 0
class animals.Wion - 0

කේතය:

package animals;

import wild.Wild;

public class OmegaWolf extends Animal {

    boolean lionWillMoveDown=true;

    private static final int LOW_DANGER = 10;
    private static final int MODERATE_DANGER = LOW_DANGER*2;
    private static final int EXTREAME_DANGER = MODERATE_DANGER*4;

    private static final int UP=1;
    private static final int LEFT=3;
    private static final int RIGHT=5;
    private static final int DOWN=7;
    private static final int UP_LEFT=0;
    private static final int UP_RIGHT=2;
    private static final int DOWN_LEFT=6;
    private static final int DOWN_RIGHT=8;

    private static final int WOLVES_SPECIES_COUNT=(int) Math.round(Math.pow(((float) Wild.MAP_SIZE)/20,2)-3)-3;

    /*
     * Interdependently derived solution that behaves very similar to Alpha Wolf, hence the name Omega Wolf
     * 
     * This wolf generates a "danger" map of the surrounding cells and will choose the movement (or hold) to the safest cell.
     * 
     * The firstly the cells where lions will move next are given EXTREAME_DANGER level
     * Then the cells surrounding any detected Wolves are given danger levels based on the immediacy of attack... i.e. if the wolf is diagonal to the omega wolf 
     * it is deemed a low threat however wolves that are adjacent are deemed a moderate threat.
     * The "danger" map is then blurred to allow bleeding of the threats to surrounding cells. This allows the omega wolf to "sense" threat vectors and to avoid it.
     * 
     * Currently the actual attack logic is very primitive. I hope to be able to give it more smarts and eek out better win/lose ratios. This should be possible if 
     * I put in some statistical heuristics.
     */

    public OmegaWolf() { 
        super('W'); }


    @Override
    public Attack fight(char opponent) {
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.PAPER;
        default:
            // if there is only one wolf species then it must be another omega wolf.
            if (WOLVES_SPECIES_COUNT==1)
            {
                return Attack.SCISSORS;
            }
            else
            {
                // lets just choose an attack with equal weight.
                double rand = Math.random();
                if (rand < 0.333333)
                {
                    return Attack.PAPER;
                }
                if (rand < 0.666667)
                {
                    return Attack.SCISSORS;
                }
                return Attack.ROCK;

            }
        }
    }

    public Move move() {

        lionWillMoveDown = !lionWillMoveDown;


        Move move = Move.HOLD;

        int[][] dangerMap = new int[3][3];
        int[][] blurredDangerMap = new int[3][3];

        // sense Lion Danger
        for (int y=0;y<3;y++)
        {
            for (int x=0;x<3;x++)
            {
                if (surroundings[y][x]=='L')
                {
                    if (lionWillMoveDown && y!=2)
                    {
                        dangerMap[y+1][x]+=EXTREAME_DANGER;
                    }
                    else if (x!=2)
                    {
                        dangerMap[y][x+1]+=EXTREAME_DANGER;
                    }
                }
            }
        }

        // sense Wolf Danger adjacent
        // UP
        if (surroundings[0][1]=='W')
        {
            dangerMap[0][1]+=MODERATE_DANGER;
            dangerMap[0][0]+=LOW_DANGER;
            dangerMap[0][2]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }
        // DOWN
        if (surroundings[2][1]=='W')
        {
            dangerMap[2][1]+=MODERATE_DANGER;
            dangerMap[2][0]+=LOW_DANGER;
            dangerMap[2][2]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }
        // LEFT
        if (surroundings[1][0]=='W')
        {
            dangerMap[1][0]+=MODERATE_DANGER;
            dangerMap[0][0]+=LOW_DANGER;
            dangerMap[2][0]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }
        // RIGHT
        if (surroundings[1][2]=='W')
        {
            dangerMap[1][2]+=MODERATE_DANGER;
            dangerMap[0][2]+=LOW_DANGER;
            dangerMap[2][2]+=LOW_DANGER;
            dangerMap[1][1]+=MODERATE_DANGER;
        }

        // sense Wolf Danger diagonally
        // UP_LEFT
        if (surroundings[0][0]=='W')
        {
            dangerMap[0][0]+=LOW_DANGER;
            dangerMap[0][1]+=MODERATE_DANGER;
            dangerMap[1][0]+=MODERATE_DANGER;
        }
        // DOWN_LEFT
        if (surroundings[2][0]=='W')
        {
            dangerMap[2][0]+=LOW_DANGER;
            dangerMap[2][1]+=MODERATE_DANGER;
            dangerMap[1][0]+=MODERATE_DANGER;
        }
        // UP_RIGHT
        if (surroundings[0][2]=='W')
        {
            dangerMap[0][2]+=LOW_DANGER;
            dangerMap[1][2]+=MODERATE_DANGER;
            dangerMap[0][1]+=MODERATE_DANGER;
        }
        // DOWN_RIGHT
        if (surroundings[2][2]=='W')
        {
            dangerMap[2][2]+=LOW_DANGER;
            dangerMap[2][1]+=MODERATE_DANGER;
            dangerMap[1][2]+=MODERATE_DANGER;
        }


        // generate a blurred danger map. This bleeds danger to surrounding cells.
        int yj,xi,sampleCount,cumulativeDanger;
        for (int y=0;y<3;y++)
        {
            for (int x=0;x<3;x++)
            {
                sampleCount=0;
                cumulativeDanger=0;
                for (int j=-1;j<2;j++)
                {
                    for (int i=-1;i<2;i++)
                    {
                        yj=y+j;
                        xi=x+i;
                        if (yj>-1 && yj<3 && xi>-1 && xi<3)
                        {
                            cumulativeDanger+=dangerMap[yj][xi];
                            sampleCount++;
                        }
                    }
                }
                blurredDangerMap[y][x]=(dangerMap[y][x]+cumulativeDanger/sampleCount)/2;
            }
        }

        // find the safest cell
        int safestCellDanger=Integer.MAX_VALUE;
        int safestCellId = -1;
        int cellId=0;

        for (int y=0;y<3;y++)
        {
            for (int x=0;x<3;x++)
            {
                if (blurredDangerMap[y][x]<safestCellDanger)
                {
                    safestCellDanger=blurredDangerMap[y][x];
                    safestCellId=cellId;
                }
                cellId++;
            }
        }

        // safest cell is adjacent so move there
        if ((safestCellId&1)==1)
        {
            switch (safestCellId)
            {
                case UP:
                    move=Move.UP;
                    break;
                case LEFT:
                    move=Move.LEFT;
                    break;
                case RIGHT:
                    move=Move.RIGHT;
                    break;
                case DOWN:
                    move=Move.DOWN;
                    break;
            }
        }
        // safestCell is a diagonal cell or current cell
        else
        {
            // lets initialise the move to Hold.
            move = Move.HOLD;

            switch (safestCellId)
            {
                case UP_LEFT:

                    // check to see whether holding is not safer than moving up
                    if (dangerMap[1][1] > dangerMap[0][1] )
                    {
                        // move up if safer than moving left or if equally safe, when randomly chosen 
                        if (dangerMap[0][1] < dangerMap[1][0] || (dangerMap[0][1] == dangerMap[1][0] && Math.random()>0.5))
                        {
                            move=Move.UP;
                        } 
                        // left must be safest :P
                        else
                        {

                            move=Move.LEFT;
                        }
                    }
                    // check to see whether holding is not safer than moving left
                    else if (dangerMap[1][1] > dangerMap[1][0] )
                    {
                        move=Move.LEFT;
                    }

                    break;
                case UP_RIGHT:
                    // check to see whether holding is not safer than moving up
                    if (dangerMap[1][1] > dangerMap[0][1] )
                    {
                        // move up if safer than moving right or if equally safe, when randomly chosen 
                        if (dangerMap[0][1] < dangerMap[1][2]|| (dangerMap[0][1] == dangerMap[1][2] && Math.random()>0.5))
                        {
                            move=Move.UP;
                        } 
                        // right must be safest :P
                        else
                        {
                            move=Move.RIGHT;
                        }
                    }
                    // check to see whether holding is not safer than moving right
                    else if (dangerMap[1][1] > dangerMap[1][2] )
                    {
                        move=Move.RIGHT;
                    }
                    break;
                case DOWN_LEFT:
                    // check to see whether holding is not safer than moving down
                    if (dangerMap[1][1] > dangerMap[2][1] )
                    {
                        // move down if safer than moving left or if equally safe, when randomly chosen 
                        if (dangerMap[2][1] < dangerMap[1][0]|| (dangerMap[2][1] == dangerMap[1][0] && Math.random()>0.5))
                        {
                            move=Move.DOWN;
                        } 
                        // left must be safest :P
                        else
                        {
                            move=Move.LEFT;
                        }
                    }
                    // check to see whether holding is not safer than moving left
                    else if (dangerMap[1][1] > dangerMap[1][0] )
                    {
                        move=Move.LEFT;
                    }
                    break;
                case DOWN_RIGHT:
                    // check to see whether holding is not safer than moving down
                    if (dangerMap[1][1] > dangerMap[2][1] )
                    {
                        // move down if safer than moving right or if equally safe, when randomly chosen 
                        if (dangerMap[2][1] < dangerMap[2][2] || (dangerMap[2][1] == dangerMap[1][2] && Math.random()>0.5))
                        {
                            move=Move.DOWN;
                        } 
                        // right must be safest :P
                        else
                        {
                            move=Move.RIGHT;
                        }
                    }
                    // check to see whether holding is not safer than moving right
                    else if (dangerMap[1][1] > dangerMap[1][2] )
                    {
                        move=Move.RIGHT;
                    }
                    break;
            }
        }

        return move;

    }
}

14

ස්ටෝන්ගාර්ඩියන් වුල්ෆ්

මේක හරිම විනෝදජනකයි. දෘශ්‍යකරණය සඳහා createjs සහාය ඇතිව මම ජාවා කේතයේ තදබල වරායක් ජාවාස්ක්‍රිප්ට් වෙත සාදන ලදී: JavaScript StoneGuardianWolf

ස්ටෝන්ගාර්ඩියන් වුල්ෆ් සුරතල් පාෂාණ සොයමින් ගල් අසල රැකවරණය ලබයි. ඇය ඔවුන්ව ආරක්ෂා කරන අතර ඔවුන්ගේ ආරක්ෂාව වෙනුවෙන් කැපවී සිටියි.

සංඛ්‍යාලේඛන

තනි ක්‍රීඩකයා: ~ 75% වෘකයන්ගේ පැවැත්ම අනුපාතය + 35% සුරතල් (ගල්) පැවැත්මේ අනුපාතය.

සාරාංශය: 75% + 35% ---> 110% සාර්ථකත්ව අනුපාතය! :)

බහු ක්‍රීඩකයා: පරීක්ෂා නොකළ.

ලොගය වෙනස් කරන්න

v2: සූදු සූදු සෙවීමේ ක්‍රමෝපාය සොයන AI එදිරිව ගැම්බලර් වුල්ෆ් සහ සුරතල් පාෂාණය.

v1: වඩා හොඳ වෘකයා වැළැක්වීම

v0: උපන් දිනය

ජාවා කේතය

package animals;

public class StoneGuardianWolf extends Animal {
    public StoneGuardianWolf() {
        super('W');
    }

    private boolean petRock = false;
    private int heartache = 0;

    public Attack fight(char c) {
        this.heartache--;

        switch (c) {
        case 'B':
            return Attack.SCISSORS;
        case 'L':
            return Attack.SCISSORS;
        case 'S': // A motherly sacrifice
            return Attack.SUICIDE;
        default:
            int n = this.heartache % 3;
            if (n < 1)
                return Attack.PAPER;
            if (n < 2)
                return Attack.ROCK;
            return Attack.SCISSORS;
        }
    }

    public Move move() {
        char[][] surr = this.surroundings;
        int[][] clairvoyance = new int[3][3];

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                clairvoyance[i][j] = 1;

        boolean seeNoStone = true;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                switch (surr[i][j]) {
                case 'L':
                    if (i < 1 && j < 1) {
                        clairvoyance[1][0] += 50;
                        clairvoyance[0][1] += 50;
                    }

                    if (i == 1 && j < 1) { // above
                        clairvoyance[1][1] += 50;
                    }

                    if (i < 1 && j == 1) { // left
                        clairvoyance[1][1] += 50;
                    }
                    break;

                case 'S': // seek stones for protection
                    seeNoStone = false;
                    this.petRock = true;
                    clairvoyance[i][j] += 999; // Only hugs!
                    if (i < 2)
                        clairvoyance[i + 1][j] -= 10;
                    if (j < 2)
                        clairvoyance[i][j + 1] -= 10;
                    if (i > 0)
                        clairvoyance[i - 1][j] -= 10;
                    if (j > 0)
                        clairvoyance[i][j - 1] -= 10;
                    break;

                case 'B': // ignore bears
                    break;

                case 'W':
                    // skip self
                    if (i == 1 && j == 1)
                        continue;
                    int m = 25; // avoid wolves

                    // don't fight unless pet rock is in danger
                    if (petRock)
                        clairvoyance[i][j] -= 999; // motherly wrath
                    else
                        clairvoyance[i][j] += 100;

                    // avoid stepping into wolf path
                    if (i != 1 && j != 1) {
                        if (i < 2)
                            clairvoyance[i + 1][j] += m;
                        if (j < 2)
                            clairvoyance[i][j + 1] += m;
                        if (i > 0)
                            clairvoyance[i - 1][j] += m;
                        if (j > 0)
                            clairvoyance[i][j - 1] += m;
                    }
                    break;

                default:
                    clairvoyance[i][j] += 0;
                }
            } // for loop
        } // for loop

        int size = clairvoyance[1][1];
        int x = 1;
        int y = 1;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (i != 1 || j != 1)
                    continue;
                int tmp = clairvoyance[i][j];
                if (tmp < size) {
                    size = tmp;
                    x = i;
                    y = j;
                }
            }
        }

        if (seeNoStone)
            this.heartache++;

        this.petRock = false;
        if (seeNoStone && heartache % 10 == 0) { // Find a pet stone! :3
            if ((heartache % 3) < 2 || clairvoyance[1][2] >= 45) {
                // try move right
                if (clairvoyance[2][1] < 45)
                    return Move.RIGHT;
            }

            // try down instead
            if (clairvoyance[1][2] < 45)
                return Move.DOWN;
        }

        if (x == 0 && y == 1)
            return Move.LEFT;
        if (x == 2 && y == 1)
            return Move.RIGHT;
        if (x == 1 && y == 0)
            return Move.UP;
        if (x == 1 && y == 2)
            return Move.DOWN;

        if (!seeNoStone)
            this.petRock = true;

        return Move.HOLD;
    }
}

5
ගල් අනුභව කිරීම වුල්ෆ් ආරුක්කු සතුරා!
Averroes

:) ඇත්ත වශයෙන්ම - මගේ සුරතල් පාෂාණ අසල ඔබට ඉඩ දෙන්නේ නැත! කැමෝ වුල්ෆ් එස්.ජී.ඩබ්ලිව්.
talmobi

1
වාසනාවකට මෙන් ඔබට කැමෝ වුල්ෆ් නීත්‍යානුකූල ප්‍රවේශයක් ලෙස ඇතුළත් කිරීමට අවශ්‍ය නැත = D
justhalf

12

වයොන්

අපේක්ෂිත වටිනාකමින් හැකි තාක් කල් ජීවත් වීමට හැකි තරම් සුළු ප්‍රමාණයක් කිරීමට උත්සාහ කරයි. එය සිංහයන්ට සමාන්තරව ගමන් කිරීමට උත්සාහ කරයි (එය කිසිවක් දුටුවද නොසලකා).

එය අනපේක්ෂිත යැයි තීරණය කරන බැවින් එය වෘකයන් නොසලකා හරියි. එය වෘකයෙකු හමු වුවහොත් එය සටන් වලින් අඩක් පමණ ජය ගත යුතුය (මම රටා ගැලපීම කිරීමට උත්සාහ නොකරන්නේ නම් මෙය ප්‍රශස්ත වේ). මගේ වෘකයෝ කිසි විටෙකත් එකිනෙකා සමඟ සටන් නොකළ යුතුය. එය සිංහයෙකුට මුණගැසුණහොත් (එය බොහෝ විට නොවිය යුතුය) එය සටන් වලින් 3/4 ක් පමණ දිනා ගත යුතුය. වලසුන් සහ පාෂාණ සෑම විටම අහිමි විය යුතුය.

වෙනත් උපක්‍රමයක් භාවිතා කරමින් අනුකරණයේ වෘකයන් සිටී යැයි උපකල්පනය කළහොත්, ඔවුන් මගේ වෘකයන්ගෙන් වැළකී සිටීම නුවණට හුරුය, මන්ද ඔවුන්ට ඕනෑම හමුවීමක් අහිමි වීමේ 50% ක අවස්ථාවක් ඇත. සාමාන්‍යයෙන් මෙය අවම වශයෙන් මෙන්ම වෙනත් උපාය මාර්ගයක්වත් කළ යුතුය.

මම නීති නිවැරදිව තේරුම් ගත්තා නම්, මෙය ප්‍රශස්ත උපාය විය යුතුය.

package animals;
import java.util.Random;

public class Wion extends Animal {
    private boolean down;
    public Wion() { super('W'); down=true;}
    public Attack fight(char opponent) {
        switch (opponent) {
            case 'B':
            case 'L':
                return Attack.SCISSORS;
            case 'S':
                return Attack.PAPER;
            default:
                Random rn = new Random();
                int i = Math.abs(rn.nextInt() % 4);
                while (i==3) {i = Math.abs(rn.nextInt() % 4);}
                return Attack.values()[i];
        }
    }
    public Move move() {
        down=!down;
        if(!down) { return Move.DOWN; }
        return Move.RIGHT;
    }
}

මගේ ටෙස්ට් ධාවනයේදී මෙය එතරම් දුර්වල වන්නේ මන්දැයි මම අවංකවම නොදනිමි. එය කඩදාසි මත හොඳ බව පෙනේ, නමුත් ප්‍රායෝගිකව එය EmoWolf හා සමාන වේ :(
Geobits

@ ජියෝබිට්ස් මම එය ඇත්ත වශයෙන්ම ටී.බී.එච්. මම හිතන්නේ මම එක් රීතියක් වරදවා වටහාගෙන, වැරැද්දක් කළෙමි, හෝ වෘකයන්ට එදිරිව මගේ අහඹු ප්‍රහාරය ඒකාකාරව අහඹු නොවේ.
ටිම් සේගුයින්

EGeobits මම ප්‍රහාරක තර්කනය මාරු කළා. මගේ සැකය නම් සමහර විට එය සියදිවි නසා ගැනීමක් විය හැකිය.
ටිම් සෙගුයින්

1
ust ජුස්ටාල්ෆ් ඔව්, ගැටලුව කුමක්දැයි මම දැනටමත් තේරුම් ගෙන ඇත්තෙමි. මගේ තර්කයට වැඩ කළ හැක්කේ වෙනත් එක් වෘකයෙකුගෙන් සමන්විත ජනගහනයක් සමඟ පමණි. එවැනි අවස්ථාවක අනෙක් වෘකයාගේ හමුවීමේ වේගය දළ වශයෙන් මගේ අනුපාතයට සමාන වේ. කෙසේ වෙතත්, බහු අභිජනන නඩුවේදී, මගේ හමුවීමේ වේගයෙහි වැඩි වීමක් අනෙක් සියලුම වෘකයන් අතර සාමාන්‍යය වනු ඇත, එබැවින් මගේ සමානුපාතිකව විශාල වනු ඇත. මෙය නිවැරදි කිරීම සඳහා යම් ආකාරයක අවම ක්‍රමයක් ගැන මම සිතමින් සිටිමි, නමුත් අවාසනාවකට මේ මොහොතේ අවධානය යොමු කිරීමට තවත් වැදගත් දේවල් තිබේ.
ටිම් සෙගුයින්

1
නමුත් වෘකයන්ගේ තවත් එක් වර්ගයක් තිබේ නම් මෙම ක්‍රමය ප්‍රශස්ත බව මම එකඟ වෙමි.
justhalf

12

සාමූහික මතකයක් ඇති වෘකයන්

ආර් හි වුල්ෆ් පැකට්ටුවක්

මෙම වෘකයාගේ පැකේජයේ අදහස නම්, එය ජීවතුන් අතර සිටින හෝ මියගිය අය කවුරුන්ද යන්න මතකයේ තබා ගැනීම, මියගිය වෘකයන් සහ ජීවමාන වෘකයන් ප්‍රහාර ලෙස භාවිතා කරන්නේ කුමක් දැයි පරීක්ෂා කර ඒ අනුව තේරීමේ සම්භාවිතාව වෙනස් කිරීමයි.

මෙන්න R කේතය:

infile <- file("stdin")
open(infile)
repeat{
    input <- readLines(infile,1)
    type <- substr(input,1,1)
    id <- substr(input,2,3)
    if(nchar(input)>3){
        info <- substr(input,4,nchar(input))
    }else{
        info <- NULL
    }
    attack <- function(id,info){
        if(info%in%c("B","L")){choice <- "S"}
        if(info=="S"){choice <- "P"}
        if(info=="W"){
            if(exists("memory")){
                dead <- memory$ID[memory$Status=="Dead"]
                veteran <- memory[memory$Attack!="" & !is.na(memory$Attack), ]
                if(nrow(veteran[!is.na(veteran[,1]),])>0){
                    deadvet<-veteran[veteran$ID%in%dead,]
                    deadvet<-unlist(lapply(split(deadvet,deadvet$ID),function(x)tail(x$Attack,1)))
                    deadvet <- table(factor(deadvet,levels=c("R","P","S","")))
                    livevet <- table(factor(veteran$Attack,levels=c("R","P","S","")))-deadvet
                    probR <- (1+livevet['R'])/(1+livevet['R']+deadvet['R'])
                    probS <- (1+livevet['S'])/(1+livevet['S']+deadvet['S'])
                    probP <- (1+livevet['P'])/(1+livevet['P']+deadvet['P'])
                    choice <- sample(c("S","P","R"),1,prob=c(probS,probP,probR))
                    memory <- rbind(memory, data.frame(ID=id, Status="Alive", Attack=choice))
                }else{
                    choice <- sample(c("S","P","R"),1)
                    memory <- rbind(memory, data.frame(ID=id, Status="Alive", Attack=choice))
                }
            }else{
                choice <- sample(c("S","P","R"),1)
                memory <- data.frame(ID=id, Status="Alive", Attack=choice)
            }
        }
        paste(choice,id,sep="")
    }
    move <- function(id,info){
        choice <- "H"
        paste(choice,id,sep="")
    }
    initialize <- function(id){
        if(exists("memory")){
            memory <- rbind(memory,data.frame(ID=id,Status="Alive",Attack=""))
        }else{
            memory <- data.frame(ID=id,Status="Alive",Attack="")
        }
        confirmed_dead <- memory$ID[memory$Status=="Dead"]
        last_seen <- memory[!memory$ID%in%confirmed_dead,]
        last_seen <- last_seen[last_seen$Attack=="",]
        lid <- table(last_seen$ID)
        turns <- max(lid)
        dead <- lid[lid<(turns-1)]
        if(length(dead)>0){
            dead_id <- names(dead)
            for(i in dead_id){
                memory <- rbind(memory, data.frame(ID=i, Status="Dead", Attack=""))
            }
        }
        paste("K",id,sep="")
    }
    result <- switch(type,"A"=attack(id,info),"M"= move(id,info),"S"=initialize(id))
    cat(result,"\n",sep="")
    flush(stdout())
}

එය @ProgrammerDan එතුම (ස්තූතියි!), වුල්ෆ් කොලෙක්ටිව්මෙමරි අභිරුචි නමක් ලෙස සහ "රුක්‍රිප්ට් වුල්ෆ්කොලෙක්ටිව්මෙරි.ආර්" ආයාචනයක් ලෙස භාවිතා කරයි.


කාරණා කිහිපයක් - පළමුව, මට හොඳටම විශ්වාසයි ප්‍රතිදානයන් නොපෙනෙන බව. දෙවනුව, ඔබේ ක්‍රියාවලිය එතීමෙන් ආයාචනා කළ පසු එය දිගටම ක්‍රියාත්මක වේ. ඔබේ වර්තමාන සැලසුම උපකල්පනය කරන්නේ වෘකයෙකු වෙත සන්නිවේදනය යවන සෑම අවස්ථාවකම ඔබේ ක්‍රියාවලිය ක්‍රියාත්මක වන බවයි - මෙය ක්‍රියාවලි ආයාචනා අනුව මිල අධික වනු ඇත, එබැවින් ඒ වෙනුවට මම ක්‍රියාවලිය ආරම්භ කර සන්නිවේදන නාලිකා විවෘතව තබමි. එබැවින්, ඔබට දිගින් දිගට පේළි කියවන stdinසහ ඊට පිළිතුරු වශයෙන් පේළියක් ලියන ප්‍රධාන ලූපයක් තිබිය යුතුය stdout, ඉන්පසු a flush.console(). [cont]
ProgrammerDan

[cont] අනුකරණය අවසන් වූ විට මගේ ක්‍රියාවලිය එතීම ළමා ක්‍රියාවලිය අවසන් කළ යුතුය.
ProgrammerDan

Us රුෂර් @ ප්ලැනපස්ගේ ආර් ඉදිරිපත් කිරීම සඳහා වලංගු එතුමක සාරාංශය මෙන්න . ආර් ස්ථාපනය කිරීම සඳහා මෙතැනට යන්න . binඔබේ PATH විචල්‍යයට හෝ ඊට සමාන R හි ෆෝල්ඩරය එක් කරන්න , ඔබ හොඳ විය යුතුය (මට හොඳින් වැඩ කළා).
ProgrammerDan

මම හිතන්නේ වැරදිකරු අණයි readlines. A readlineහෝ ඊට සමාන භාවිතා කිරීමට උත්සාහ කරන්න . readlinesEOF තෙක් අවහිර වනු ඇත.
ProgrammerDan

මම ඉස්සර එකතු readLinesකළා scan. readLinesදෙවන තර්කය සමඟින් 1අදහස් කරන්නේ එය පළමු නව රේඛාවේ අක්ෂරයෙන් නතර විය යුතු බවයි.
plannapus

12

මිමික් වුල්ෆ්

මෙම වෘකයාගේ පරමාර්ථය වන්නේ වෙනත් වෘකයන් අනුකරණය කිරීමයි. වෘකයෙකු තම හැකියාවෙන් උපරිම ලෙස එය අනුගමනය කරන බව එය සොයා ගනී. මිමික්වුල්ෆ් මෙවැනි ප්‍රශ්න අසන්නේ නැත: එම වෘකයා / වලහා / සිංහයා / ගල වළක්වා ගන්නේ කෙසේද?

නැත, මිමික් වුල්ෆ් වැනි ප්‍රශ්න අසයි: මට අනුගමනය කිරීමට වෘකයෙකු සිටින්නේ කොහේද? මා අනුගමනය කරන වෘකයා යන්නේ කොතැනටදැයි මම සිතන්නේද? මා අනුගමනය කරමින් සිටි වෘකයා එය වෙනස් වෘකයෙකු ද? මා අනුගමනය කරමින් සිටි වෘකයා කොහේද ගියේ?

එම ප්‍රශ්න බොහොමයකට තවමත් නිසි පිළිතුරු ලැබී නොමැති බව මම පිළිගනිමි, නමුත් මෙහි දැනට මා මිමික් වුල්ෆ් ඉදිරිපත් කිරීම

   package animals;
   import java.util.*;

public class MimicWolf extends Animal {

final int TURN_MEMORY = 5;

Random rand = new Random();

Animal.Move lastMove = Animal.Move.UP;

boolean mimicingWolf = false;

Pos[] wolfPreviousPos = new Pos[TURN_MEMORY];
RelativePos[] relativePositions = new RelativePos[TURN_MEMORY];
Move[] wolfPreviousMove = new Move[TURN_MEMORY - 1];

int turnsWithLostWolf = 0;

public MimicWolf() {
    super('W');
}

public Animal.Attack fight(char c) {
    switch (c) {
        case 'B':
            return Animal.Attack.SCISSORS;
        case 'L':
            return Animal.Attack.SCISSORS;
        case 'S':
            return Animal.Attack.PAPER;
        default:
            int x = rand.nextInt(4);
            return Animal.Attack.values()[x];
    }
}

public Animal.Move move() {
    Pos wolfPos = null;
    wolfPos = lookForSurroundingWolf();

    if (turnsWithLostWolf == 4) {
        mimicingWolf = false;
        wolfPreviousPos = new Pos[5];
        relativePositions = new RelativePos[5];
        turnsWithLostWolf = 0;
    }

    if (mimicingWolf) {
        int indexOfLastMove = 0;
        for (int i = 0; wolfPreviousPos[i] != null && i < wolfPreviousPos.length; i++) {
            indexOfLastMove = i;
        }

        //is wolf still visible??
        Pos wolfNewPos = isWolfVisible(wolfPreviousPos[indexOfLastMove]);
        if (wolfNewPos.x == -1) {//wolf is not visible
            turnsWithLostWolf++;
            return moveOppositeDirection(lastMove);
        } else {
            return mimicWolf(wolfNewPos, indexOfLastMove); //need Better way to mimic
        }
    } else {
        //check if new wolf around
        if (wolfPos.x == -1) {
            return searchForWolf();
        } else {
            mimicingWolf = true;
            return mimicWolf(wolfPos, 0);
        }
    }
}

private Animal.Move searchForWolf() {
    Animal.Move newMove = null;
    while (newMove == null || newMove == lastMove) {
        newMove = Animal.Move.values()[rand.nextInt(3)];
    }

    lastMove = newMove;
    return newMove;
}

private Pos lookForSurroundingWolf() {
    for (Integer i = 0; i < surroundings.length; i++) {
        for (Integer j = 0; j < surroundings[0].length; j++) {
            if (i == 1 && j == 1) {
                //this is myself >.<
            } else if (surroundings[i][j] == 'W') {
                return new Pos(i, j);
            }
        }
    }

    return new Pos(-1, -1);
}

/*
    for mimicWolf when movesMimiced == 1 or 2 this is the base case, Any
    number greater the wolf will attempt to mimic the next move based on pattern
    of previous moves
        we assume that we are following the same wolf as last time
 */

private Animal.Move mimicWolf(Pos wolfCurrentPos, int movesMimiced) {
    wolfPreviousPos[movesMimiced] = wolfCurrentPos;
    insertToRelativePos(wolfCurrentPos, movesMimiced);
    if (movesMimiced == 0) {
        Move m1 = null, m2 = null;
        if (wolfPreviousPos[0].x == 0) {
            m1 = Move.LEFT;
        } else if (wolfPreviousPos[0].x == 2) {
            m1 = Move.RIGHT;
        }

        if (wolfPreviousPos[0].y == 0) {
            m2 = Move.UP;
        } else if (wolfPreviousPos[0].y == 2) {
            m2 = Move.DOWN;
        }

        return randOfMoves(m1, m2); //guess which way to go
    }
    wolfPreviousMove[movesMimiced - 1] =  getDirection(wolfPreviousPos[movesMimiced - 1], wolfPreviousPos[movesMimiced]);
    if (movesMimiced == 1) {
        //if pos 1 was a cornor
        if(relativePositions[0] == RelativePos.CORNER){
            if(relativePositions[1] == RelativePos.CORNER){
                if(wolfPreviousPos[0].equals(wolfPreviousPos[1])){
                    return lastMove;
                }
                return moveOppositeDirection(lastMove);
            }
            else if(relativePositions[1] == RelativePos.EDGE){
                return Move.HOLD; //he held so i will hold
            }
        }else if(relativePositions[1] == RelativePos.EDGE){
            if(relativePositions[1] == RelativePos.EDGE){
                return lastMove;
            }
            else if(relativePositions[1] == RelativePos.CORNER){
                //only possibility is that I held, and he moved
                return wolfPreviousMove[0];
            }
        }
    } else {
        //Return most common move the wolf I am copying has made
        int[] mostCommonMoveArr = {0,0,0,0,0};
        for(int i = 0; i <= movesMimiced; i++){
            switch(wolfPreviousMove[i]){
                case UP:
                    mostCommonMoveArr[0]++;
                case RIGHT:
                    mostCommonMoveArr[1]++;
                case DOWN:
                    mostCommonMoveArr[2]++;
                case LEFT:
                    mostCommonMoveArr[3]++;
                case HOLD:
                    mostCommonMoveArr[4]++;
            }
        }

        int maxValue = -1;
        int maxLocal = 0;
        for(int i = 0; i < 5; i++){
            if(mostCommonMoveArr[i] > maxValue)
                maxValue =  mostCommonMoveArr[i];
                maxLocal = i;
        }

        return Move.values()[maxLocal];
    }

    return Move.HOLD; //shouldn't happen
}

private Pos isWolfVisible(Pos lastPos) {
    Pos mimicedWolfPos = lookForSurroundingWolf();
    while (mimicedWolfPos.x != -1 && mimicedWolfPos.y != -1) {
        //did we find the wolf?
        if (lastPos.x == mimicedWolfPos.x || lastPos.y == mimicedWolfPos.y) {
            return mimicedWolfPos;
        }

        surroundings[mimicedWolfPos.x][mimicedWolfPos.y] = ' ';
        mimicedWolfPos = lookForSurroundingWolf();
    }

    return new Pos(-1, -1);
}

private Animal.Move moveOppositeDirection(Move m) {
    switch (m) {
        case UP:
            return Move.DOWN;
        case RIGHT:
            return Move.LEFT;
        case DOWN:
            return Move.UP;
        case LEFT:
            return Move.RIGHT;
        case HOLD:
            return Move.LEFT; //No idea why this would happen but whatever
        default:
            return Move.HOLD;
    }
}

private Animal.Move getDirection(Pos firstPos, Pos secondPos){
    if(firstPos.equals(secondPos))
        return Move.HOLD;
    if(firstPos.x == secondPos.x){
        if(firstPos.y > secondPos.y)
            return Move.UP;
        return Move.DOWN;
    }
    if(firstPos.x > secondPos.x)
        return Move.RIGHT;
    return Move.LEFT;
}


private Animal.Move randOfMoves(Move m1, Move m2) {
    if (m1 == null) {
        return m2;
    } else if (m2 == null) {
        return m1;
    }

    int r = rand.nextInt(2);
    if (r == 0) {
        return m1;
    }
    return m2;
}

private class Pos {
    int x;
    int y;

    protected Pos(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object obj){
        Pos pos = (Pos) obj;
        return (this.x == pos.x && this.y == pos.y);
    }
}

private void insertToRelativePos(Pos pos, int posToAdd){
    if(pos.x == 1 || pos.y == 1){
        relativePositions[posToAdd] = RelativePos.EDGE;
    }else{
        relativePositions[posToAdd] = RelativePos.CORNER;
    }
}

private enum RelativePos{
    CORNER, EDGE
}
}

සංස්කරණය කරන්න: මම වඩා හොඳ අනුකරණ පද්ධතියක් එක් කළෙමි. අඛණ්ඩව එහා මෙහා ගමන් කරමින් සිටියදී මේ මොහොතේ කිසිවක් වළක්වා ගැනීමට උත්සාහ නොකරන බැවින් වෘකයන් තවමත් හොඳ නැත.


12

ඇතුල්වීමක් නොවේ, නමුත් බොහෝ වෘකයන් නිශ්චල බැවින් එය නැරඹීම තරමක් කම්මැලි ය, එබැවින් මම වනාන්තරයට ස්වාභාවික විපතක් එක් කළෙමි:

භූමි කම්පාව!

කාලයෙන් 5% ක් පමණ අහඹු ලෙස විශාලත්වයෙන් භූමිකම්පාවක් සිදුවනු ඇත, 100 ක් ඉහළම, 20 අඩුම වේ. මෙය අearthquakeCounter භූමිකම්පාවකින් පසු කාලයත් සමඟ on ාතීය ලෙස අඩුවනු ඇත.

භූමිකම්පාවකදී කුමක් සිදුවේද?

සියළුම සතුන්ගේ වටිනාකම අනුව අහඹු ලෙස ගමන් කිරීමට අවස්ථාවක් ලැබේ earthquakeCounter . එබැවින් වටිනාකම 75 ක් නම්, සතුන්ගෙන් 75% ක් පමණ (ගල් ද ඇතුළුව) අහඹු ලෙස ඕනෑම දිශාවකට ගමන් කරනු ඇත (ඒකාකාරව බෙදා හරිනු ලැබේ).

මෙය පුදුමයට කරුණක් නොවේ, බොහෝ සතුන් මරා දමයි, එබැවින් අත්හදා බැලීම් කිහිපයකින් පසුව උපරිමය සාමාන්‍යයෙන් සතුන් 50 ක් පමණ වේ.

එසේම, භූමිකම්පාව GUI හි දෘශ්‍යමාන වන අතර එය විශාලත්වය අනුව වෙනස් වේ.

මට භූමිකම්පාව නොපෙනේ!

භූමිකම්පාවක් සිදුවීමේ අවස්ථාව තරමක් සිහින්, 5% ක් පමණි.

නමුත් කලබල නොවන්න! මම "භූමිකම්පාවක්" ද ඇතුළත් කර ඇත්තෙමි . GUI හි බොත්තම , ඔබට සියලු වෘකයන් ඔවුන්ගේ සුවපහසු කලාපවලින් තල්ලු කිරීමට අවශ්‍ය නම් ...

මෙන්න තිර රුවක්:

භූමි කම්පාවක්

මෙන්න කේතය:

Wild.java

main() ශ්‍රිතය (වේගවත් කිරීම සඳහා පළමු 100 පුනරාවර්තනය සඳහා GUI මඟ හැරීම සඳහා යාවත්කාලීන කරන ලදි):

public static void main(String[] args) {

    int size = Math.round((float)Math.sqrt(classes.length+3)*20);
    final Game game = new Game(size);

    Statistics stats = new Statistics(game, classes);

    String[] colors = generateColors(classes.length);
    int idx = 0;
    for(Class c : classes){
        Animal.setColor(c, colors[idx]);
        idx++;
        game.populate(c, 100);
    }
    stats.update();

    JFrame gui = new JFrame();
    Container pane = gui.getContentPane();

    JLabel boardLabel = new JLabel();
    boardLabel.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
    boardLabel.setText(game.toString());
    pane.add(boardLabel, BorderLayout.WEST);

    JLabel statsLabel = new JLabel();
    statsLabel.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
    statsLabel.setText(stats.toString());
    pane.add(statsLabel, BorderLayout.EAST);

    JButton earthquakeButton = new JButton();
    earthquakeButton.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
            game.earthquake(true);
        }

    });
    earthquakeButton.setText("Earthquake!");
    pane.add(earthquakeButton, BorderLayout.SOUTH);

    gui.pack();
    gui.setVisible(true);

    for(int i=0; i<100; i++){
        game.iterate();
        stats.update();
    }

    while(true) {
        game.iterate();
        stats.update();
        boardLabel.setText(game.toString());
        statsLabel.setText(stats.toString());
        try { Thread.sleep(100); } catch (InterruptedException e) {}
    }
}

ගේම්.ජාවා

package wild;

import animals.Animal;
import java.util.ArrayList;
import java.util.Random;
import animals.Animal.Attack;
import animals.Animal.Move;

public class Game {

    private ArrayList<ArrayList<ArrayList<Animal>>> board;
    private final Random gen = new Random();
    protected final int SIZE;
    private static int earthquakeCounter = 0;

    protected Game(int size) {
        this.SIZE = size;
        board = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            board.add(new ArrayList<ArrayList<Animal>>());
            for (int j = 0; j < size; j++) {
                board.get(i).add(new ArrayList<Animal>());
            }
        }
    }

    protected <T extends Animal> void populate(Class<T> species, int num) {
        while (num > 0) {
            int row = gen.nextInt(SIZE);
            int col = gen.nextInt(SIZE);
            if (board.get(row).get(col).isEmpty()) {
                try { board.get(row).get(col).add(species.newInstance()); } 
                catch (InstantiationException | IllegalAccessException e) {}
                num--;
            }
        }
    }

    protected void iterate() {
        earthquake(false);
        moveAll();
        flatten();
    }

    private void moveAll() {
        Game game = new Game(SIZE);
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                if (!board.get(i).get(j).isEmpty()) {
                    Animal a = board.get(i).get(j).get(0);
                    a.surroundings = getArea(i, j);
                    Move aMove;
                    try { aMove = a.move(); } 
                    catch (Exception e) { aMove = Move.HOLD; }
                    if(gen.nextInt(100)<earthquakeCounter){
                        aMove = Move.values()[gen.nextInt(4)];
                    }
                    switch(aMove) {
                        case UP:
                            game.board.get((i-1+SIZE)%SIZE).get(j).add(a);
                            break;
                        case RIGHT:
                            game.board.get(i).get((j+1)%SIZE).add(a);
                            break;
                        case DOWN:
                            game.board.get((i+1)%SIZE).get(j).add(a);
                            break;
                        case LEFT:
                            game.board.get(i).get((j-1+SIZE)%SIZE).add(a);
                            break;
                        case HOLD:
                            game.board.get(i).get(j).add(a);
                            break;
                    }
                }
            }
        }
        board = game.board;
    }

    /**
     * Give a random chance for an earthquake to happen
     */
    protected void earthquake(boolean force){
        if(force || (earthquakeCounter==0 && gen.nextInt(1000)>950)){
            earthquakeCounter = 20+gen.nextInt(80);
        } else {
            earthquakeCounter /= 2;
        }
    }

    private void flatten() {
        for (ArrayList<ArrayList<Animal>> row : board) {
            for (ArrayList<Animal> cell : row) {
                while (cell.size() > 1) {
                    int rand1, rand2;
                    rand1 = gen.nextInt(cell.size());
                    do { rand2 = gen.nextInt(cell.size()); } while (rand1 == rand2);

                    Animal a = cell.get(rand1);
                    Animal b = cell.get(rand2);
                    Attack aTack, bTack;
                    try { aTack = a.fight(b.letter); } 
                    catch (Exception e) { aTack = Attack.SUICIDE; }
                    try {  bTack = b.fight(a.letter); }
                    catch (Exception e) { bTack = Attack.SUICIDE; }

                    if (aTack == bTack) {
                        cell.remove((Animal)(Math.random() > 0.5 ? a : b));
                    } else {
                        switch (aTack) {
                            case ROCK:
                                cell.remove((Animal)(bTack == Attack.PAPER ? a : b));
                                break;
                            case PAPER:
                                cell.remove((Animal)(bTack == Attack.SCISSORS ? a : b));
                                break;
                            case SCISSORS:
                                cell.remove((Animal)(bTack == Attack.ROCK ? a : b));
                                break;
                        }
                    } 
                }
            }
        }
    }

    protected int poll(Class c) {
        int count = 0;
        for (ArrayList<ArrayList<Animal>> row : board) {
            for (ArrayList<Animal> cell : row) {
                for (Animal a : cell) {
                    if(c.isInstance(a))
                        count++;
                }
            }
        }
        return count;
    }

    public String toString() {
        String s = "<html>";
        s += "<span style='background:"+getBackgroundColor()+"'>";
        for (ArrayList<ArrayList<Animal>> row : board) {
            for (ArrayList<Animal> cell : row) {
                if (cell.isEmpty())
                    s += "&nbsp;&nbsp;";
                else
                    s += "<span style='color:"+ Animal.color.get(cell.get(0).getClass()) +"'>" + cell.get(0).letter + "</span>&nbsp;";
            }
            s+="<br>";
        }
        s += "</span>";
        return s + "</html>";
    }

    private String getBackgroundColor(){
        int shade = 255-(int)Math.floor(255*earthquakeCounter/100.0);
        String result = String.format("#%02x%02x%02x", shade, shade, shade);
        return result;
    }

    private char[][] getArea(int i, int j) {
        char[][] area = new char[3][3];
        for(int k = -1; k <= 1; k++) {
            for(int l = -1; l <= 1; l++) {
                int temp1 = k+1;
                int temp2 = l+1;
                int temp3 = (i+k+SIZE)%SIZE;
                int temp4 = (j+l+SIZE)%SIZE;
                ArrayList<Animal> cell = board.get((i+k+SIZE)%SIZE).get((j+l+SIZE)%SIZE);
                area[k+1][l+1] = (char)(cell.isEmpty() ? ' ' : cell.get(0).letter);
            }
        }
        return area;
    }
}

5
සමහර පිරිමින්ට ලෝකය නැරඹීමට අවශ්‍යයි ... භූමිකම්පා
CommonGuy

5
මගේ එක්රැස්වීමේ වෘකයෝ අ .නවා.
johnchen902

12

මල්ටි වුල්ෆ් (ජාවා)

මෙම ක්‍රමලේඛන අභියෝගයේ අනෙක් වෘකයන් ගැන මෙම වෘකයා දනී. එය ඔවුන් සතුව තිබේ නම් එය ('සුරතල් සතුන්' ලෙස) ක්ෂණිකව තහවුරු කරන අතර එය සතු සෑම වෘකයෙකු-සුරතල් සතෙකුගෙන්ම විමසීමෙන් කුමක් කළ යුතුද යන්න තීරණය කිරීමට ඒවා භාවිතා කරන අතර වඩාත් ජනප්‍රිය ප්‍රතිචාරය තෝරා ගනී.

මෙම වෘකයා අනන්ත-පුනරාවර්තන-ආරක්ෂිත විය යුතුය - එනම් වෙනත් අයෙකු සමාන සංකල්පයක් ක්‍රියාත්මක කරන්නේ නම් - සහ පෙරනිමි ක්‍රියාවක් Attack.ROCK/Move.HOLD එය වෙනත් සතුන් ඉල්ලා ඇති අතර එය හැඳින්වූයේ කරමින් හඳුනාගන්නා නම්.

මගේ පරීක්ෂණ වලදී, මෙය වෙනස් ප්‍රති .ල ලබා ඇත. මෙය අවසර දෙයිද නැද්ද යන්න මට විශ්වාස නැත. නමුත් එය එසේ නම් සහ එය කළ නොහැකි යම් ප්‍රාතිහාර්යයක් සිදුවුවහොත්, මම සිතන්නේ ජයග්‍රාහී මාතෘකාව "දෙවන" වන වෘකයාට ලබා දිය යුතු බවයි - එය සාධාරණයි, මම බොහෝ විට එහි තර්කනය සොරකම් කළා.

එය සියදිවි නසාගැනීම් වළක්වයි.

සංස්කරණය කරන්න - මෙම වෘකයා නිසියාකාරව ක්‍රියා කිරීමට වෘකයන් යොමු කළ පසු එය පැටවිය යුතු යැයි මම විශ්වාස කරමි.

package animals;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;

public class MultiWolf extends Animal {

    private static final LinkedList<Animal> pets = new LinkedList<>();
    private static boolean inPetCall = false;

    private static void attemptLoadPet(String className) {
        try {
            Object pet = Class.forName(className).newInstance();

            if (pet instanceof Animal) {
                pets.add((Animal) pet);
            }
        } catch (Exception ex) {
            // this wolf is not available
            System.out.println(className + " is not available for MultiWolf cheating.");
        }
    }

    static {
        attemptLoadPet("animals.AlphaWolf");
        attemptLoadPet("animals.CamperWolf");
        attemptLoadPet("animals.GamblerWolf");
        attemptLoadPet("animals.GatheringWolf");
        attemptLoadPet("animals.LazyWolf");
        attemptLoadPet("animals.Sheep");
        attemptLoadPet("animals.Wion");

        attemptLoadPet("animals.MOSHPITFRENZYWolf");
        attemptLoadPet("animals.PassiveAgressiveWolf");
        attemptLoadPet("animals.StoneEatingWolf");
        attemptLoadPet("animals.HerjanWolf");
        attemptLoadPet("animals.HonorWolf");
        attemptLoadPet("animals.MimicWolf");
        attemptLoadPet("animals.LionHunterWolf");
        attemptLoadPet("animals.OmegaWolf");
        attemptLoadPet("animals.WolfWithoutFear");
        attemptLoadPet("animals.WolfRunningWithScissors");
        // attemptLoadPet("animals.SmartWolf");
        // According to Rusher, the above cheating of a non-Java wolf breaks the non-Java-entry wrapper.
        attemptLoadPet("animals.ShadowWolf");
        attemptLoadPet("animals.HybridWolf");
        attemptLoadPet("animals.ProAlpha");
        attemptLoadPet("animals.ForrestWolf");
        attemptLoadPet("animals.WhenIGrowUp");
        attemptLoadPet("animals.MigratingWolf");
        attemptLoadPet("animals.BlindWolf");
    }

    public MultiWolf() {
        super('W');
    }

    @Override
    public Attack fight(char opponent) {
        if (inPetCall) {
            // stop infinite recursion
            return Attack.ROCK;
        }

        inPetCall = true;

        HashMap<Attack, Integer> collect = new HashMap<>();

        collect.put(Attack.ROCK, 0);
        collect.put(Attack.PAPER, 0);
        collect.put(Attack.SCISSORS, 0);
        collect.put(Attack.SUICIDE, -9001);

        for (Animal a : pets) {
            a.surroundings = this.surroundings;
            Attack atk = a.fight(opponent);
            collect.put(atk, collect.get(atk)+1);
        }

        int top=0;
        Attack atk=Attack.ROCK;

        for (Entry<Attack, Integer> ent : collect.entrySet()) {
            if (ent.getValue() > top) {
                atk = ent.getKey();
                top = ent.getValue();
            }
        }

        inPetCall = false;

        return atk;
    }

    @Override
    public Move move() {
        if (inPetCall) {
            // stop infinite recursion
            return Move.HOLD;
        }

        inPetCall = true;

        HashMap<Move, Integer> collect = new HashMap<>();

        collect.put(Move.DOWN, 0);
        collect.put(Move.HOLD, 0);
        collect.put(Move.LEFT, 0);
        collect.put(Move.RIGHT, 0);
        collect.put(Move.UP, 0);


        for (Animal a : pets) {
            a.surroundings = this.surroundings;
            Move mv = a.move();
            collect.put(mv, collect.get(mv)+1);
        }

        int top=0;
        Move mv=Move.HOLD;

        for (Entry<Move, Integer> ent : collect.entrySet()) {
            if (ent.getValue() > top) {
                mv = ent.getKey();
                top = ent.getValue();
            }
        }

        inPetCall = false;

        return mv;
    }

}

මට නිවැරදිව මතක නම්, ඔබට ස්ථිතික ක්ෂේත්‍රයක් බැවින් ඔබට වයිල්ඩ් ක්ලාස් හරහා පන්ති ලබා ගත හැකිය ... එබැවින් නව වෘකයෙකු මෙහි පළ කරන සෑම විටම ඔබට වෘකයා යාවත්කාලීන කිරීමට අවශ්‍ය නොවනු ඇත;)
CommonGuy

ඒක ඇත්ත. නමුත් මම දැන් එය මේ ආකාරයෙන් කර ඇත්තෙමි. අඩු ජයග්‍රාහී වෘකයන් සමහරක් මෙම බහු වෘකයාගෙන් ඉවත් කිරීමටද ඉඩ ඇත. මගේ ධාවන කාලය තුළ සෑම විටම වියාන් වඳ වී ගොස් ඇති බව පෙනේ, මම එය මල්ටි වුල්ෆ් වෙතින් ඉවත් කිරීමට සලකා බලමින් සිටිමි.
ඔලිවියර් ඔලිව්

"ඔබ වෙනත් වුල්ෆ් පංතියක් විසින් සාදන ලද ලිපිගොනු කියවා හෝ වෙනස් නොකළ යුතුය" යන රීතිය අනෙක් වෘක පන්තියේ ලිපිගොනු ඇතුළත් කිරීමට අදහස් කළ බව මම විශ්වාස කරමි. ඉතින් මම හිතන්නේ මෙම ප්‍රවේශය නියම අදහසක් වුවත් නීතිරීතිවලට පටහැනි බවයි.
Runer112

1
Er Runer112 මම පුදුමයට පත් වූවෙමි, නමුත් මමද මෙයින් පන්ති කිහිපයක් පැටවීම ගැන ඉගෙන ගෙන ඇති අතර පැකේජයක ඇති සියලුම පන්ති සොයා ගැනීමට සරල ක්‍රමයක් නොමැත. ටිකක් විනෝදජනකයි
ඔලිවියර් ඔලිව්

3
වෙනත් වුල්ෆ් ස්ථාපනය කිරීම වෙනත් වුල්ෆ් විසින් සාදන ලද ලිපිගොනු කියවීම හෝ වෙනස් කිරීම නොවේ, එබැවින් මෙම ඉදිරිපත් කිරීම නීත්‍යානුකූල වේ. නියමය අරමුණු කළේ ස්ථිතික විචල්‍යයන් නොමැති සහ ඒ වෙනුවට ගොනුවකට ලිවීමට අවශ්‍ය භාෂාවලින් ලියා ඇති ඉදිරිපත් කිරීම් වලින් දත්ත ආරක්ෂා කිරීමයි.
රේන්බෝල්ට්

12

ගල් ආහාරයට ගැනීම වුල්ෆ්

මෙන්න මගේ ඉදිරිපත් කිරීම. ඔහුගේ වටපිටාවෙහි කිසිදු ගලක්, සිංහයෙකු හෝ වෘකයෙකු නොපෙනේ නම් මෙම වෘකයා රැඳී සිටියි. ඔහු ගලක් දුටුවහොත් වෙනත් වෘකයෙකු හෝ සිංහයෙකු විසින් පහර දීමේ අනතුරක් නොමැති නම් ඔහු එය අනුභව කිරීමට උත්සාහ කරයි. ඔහු යම් අනතුරක් දුටුවහොත් ඔහු පලා යයි!

සංස්කරණය 1 : අන්තරා ඇල්ගොරිතම සඳහා වැඩි දියුණු කිරීම. ඔහු දැන් අනතුරෙන් වඩා හොඳින් පලා යයි :)

package animals;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class StoneEatingWolf extends Animal{

    public StoneEatingWolf() {
        super('W');
    }

    @Override
    public Attack fight(char c) {
        switch (c){
            case 'L': return Attack.SCISSORS;
            case 'B': return Attack.SCISSORS;
            case 'W': return getRandomAttack();
            case 'S': return Attack.PAPER;
            default: return getRandomAttack();
        }
    }

    private Attack getRandomAttack(){
        List<Attack> att = new ArrayList<>();
        att.add(Attack.PAPER);
        att.add(Attack.PAPER);
        att.add(Attack.ROCK);
        att.add(Attack.SCISSORS);
        Collections.shuffle(att);
        return att.get(0);
    }

    @Override
    public Move move() {
        List<Move> m = new ArrayList<>();

        //First see if there is any dangerous animal. If it is, then flee
        if (isThereAnyDangerousAnimal()){
            m.add(Move.UP);
            m.add(Move.RIGHT);
            m.add(Move.LEFT);
            m.add(Move.DOWN);
            getSafeMoves(m);
        }else{
        //No danger: Look for stones to eat
            if (isThereAnimalAtNorth('S')){
                m.add(Move.UP);
            }
            if (isThereAnimalAtEast('S')){
                m.add(Move.RIGHT);
            }
            if (isThereAnimalAtWest('S')){
                m.add(Move.LEFT);
            }
            if (isThereAnimalAtSouth('S')){
                m.add(Move.DOWN);
            }
        }

        if (m.isEmpty()){
            return Move.HOLD;
        } else {
            Collections.shuffle(m);
            return m.get(0);
        }
    }

    private void getSafeMoves(List<Move> lm){

        if (isThereAnimalAtNorth('L') || isThereAnimalAtNorth('W')){
            lm.remove(Move.UP);
        }
        if (isThereAnimalAtEast('L') || isThereAnimalAtEast('W')){
            lm.remove(Move.RIGHT);
        }
        if (isThereAnimalAtSouth('L') || isThereAnimalAtSouth('W')){
            lm.remove(Move.DOWN);
        }
        if (isThereAnimalAtWest('L') || isThereAnimalAtWest('W')){
            lm.remove(Move.LEFT);
        }

    }

    private boolean isThereAnimalAtNorth(char an){
        if (surroundings[0][0] == an || surroundings [0][1] == an || surroundings [0][2] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnimalAtSouth(char an){
        if (surroundings[2][0] == an || surroundings [2][2] == an || surroundings [2][2] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnimalAtEast(char an){
        if (surroundings[0][2] == an || surroundings [1][2] == an || surroundings [2][2] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnimalAtWest(char an){
        if (surroundings[0][0] == an || surroundings [1][0] == an || surroundings [2][0] == an){
            return true;
        }
        return false;
    }

    private boolean isThereAnyDangerousAnimal(){
        if (isThereAnimalAtEast('L') ||
                isThereAnimalAtEast('W') ||
                isThereAnimalAtNorth('L') ||
                isThereAnimalAtNorth('W') ||
                isThereAnimalAtSouth('L') ||
                isThereAnimalAtSouth('W') ||
                isThereAnimalAtWest('L') ||
                isThereAnimalAtWest('W')){
            return true;
        }
        return false;
    }

    }

සංස්කරණය 2 : සමහර සංඛ්‍යාලේඛන

මා ධාවනය කළ සමාකරණයේ දී ස්ටෝන් ඊටිං වුල්ෆ් හොඳම 5-6 වුල්ෆ් බවට පත් කිරීමට මට හැකි විය:

පුනරාවර්තන 1000 ක නාට්‍ය 40 කට පසු සාමාන්‍ය ප්‍රති Results ල

ගල් අනුභව කරන වෘකයන් ඇඟවුම් කරන සටන් පිළිබඳව මම යම් විශ්ලේෂණයක් කරමි. පුනරාවර්තන 1000 ක නාට්‍ය 40 ක් ධාවනය කිරීමෙන් මට මෙම ප්‍රති results ල ලැබේ:

ප්‍රති results ල සටහනට එරෙහිව සටන් කරන්න

ජයග්රහණය වන්නේ ගල් ආහාරයට ගැනීම වුල්ෆ් ජයග්රහණයයි. ප්‍රස්ථාරයෙන් අප දැනටමත් දන්නා දේ පෙන්වයි: වඩාත්ම සාර්ථක වෘකයන් වන්නේ වෙනත් වෘකයන් හමු නොවන අයයි. මගේ අනෙක් වෘකයන් (සංක්‍රමණික වෘකයෝ) මගේ ගල් කෑම කන සමහරක් ඉස්කුරුප්පු කරන බව ද මම දුටුවෙමි. මම හිතනවා ඔවුන් තවත් වෘකයන් දඩයම් කරයි කියලා. විනෝදජනක මම කිසිම ලේසි වුල්ෆ් හෝ කැම්පර් වුල්ෆ් සමඟ පැකිලුණේ නැත. එසේම, මට ලකුණු 20 කින් ලැබුණු ප්‍රහාරවල ප්‍රති results ල මේවායි (ගල් සහ වලසුන් බැහැර කර ඇත):

PAPER       447
ROCK        881
SCISSORS    581
SUICIDE     230

ROCKපහරදීම් සඳහා පැහැදිලි නැඹුරුවක් ඇති බව පෙනේ . මෙය දැන ගැනීමෙන් මම මගේ වෘකයාගේ PAPERප්‍රහාර තරමක් වැඩි වාර ගණනක් සිදු කළෙමි .


2
කරුණාකර, වර්ගීකරණ දත්ත සැකසීමට රේඛීය ප්‍රස්ථාරයක් භාවිතා නොකරන්න. එය ඔබේ ප්‍රස්ථාරය දෙස බැලීමෙන් මට බොහෝ පිළිකා ලබා දෙයි.
ඒ.ජේ මෑන්ස්ෆීල්ඩ්

@AJMansfield එය ඇසීම ගැන කණගාටුයි. ඔබ සනීප වේ යැයි සිතමි;) කෙසේ හෝ මම අනාගත අනාගත සටහනක් සඳහා එය සැලකිල්ලට ගනිමි.
Averroes

ඔබ තවමත් වින්ඩෝස් එක්ස්පී භාවිතා කරනවාද? oO
justhalf

ඔබ ROCKසිංහයාට එරෙහිව සටන් කිරීමට (50% ජයග්‍රහණය) භාවිතා කරන්නේ ඇයි ? භාවිතා කිරීම වඩාත් සුදුසුය SCISSORS(75% ජයග්‍රහණය)
justhalf

usjusthalf මගේ සමාගම තවමත් එක්ස්පී භාවිතා කරයි ... තවද ඔබ කතුර ගැන හරි ය. ස්ථාවර. ස්තූතියි :)
Averroes

11

HonorWolf

මගේ වුල්ෆ් අනෙක් වෘකයන්ගෙන් පලා යයි. ඔහුට පලා යා නොහැකි නම්, ඔහු ගෞරවනීය ලෙස සටනක් ආරම්භ කරයි.

package animals;
public class HonorWolf extends Animal {

    private int moves = 0;

    public HonorWolf() { 
        super('W'); 
    }

    @Override   
    public Attack fight(char opponent) { 
        switch(opponent) {
         case 'L':
            return Attack.SCISSORS; 
         case 'B':
            return Attack.SCISSORS;
         case 'S':
            return Attack.PAPER;
        default:
            return Attack.PAPER;
        }
    }

    public Move move() {
        int numWolves = 0, numLions = 0;

        moves++;

        for (int y = 0; y != 3; y++) {
            for (int x = 0; x != 3; x++) {
                if(surroundings[y][x] != ' ') {
                    if(surroundings[y][x] == 'W') {
                        numWolves++;
                    } else if(surroundings[y][x] == 'L') {
                        numLions++;
                    }
                }
            }       
        }

        if (numWolves == 1 && numLions == 0) {
            return Move.HOLD;
        }

        if (surroundings[0][1] == 'L' && moves%2 != 0) {
            return Move.UP;
        } 

        if (surroundings[1][0] == 'L' && moves%2 == 0) {
            return Move.LEFT;
        }

        if (surroundings[0][1] == 'W') {
            if (surroundings[2][1] == ' ' || surroundings[2][1] == 'S') {
                return Move.DOWN;
            } else if (surroundings[1][2] == ' ' || surroundings[1][2] == 'S') {
                return Move.RIGHT;
            } else if (surroundings[1][0] == ' ' || surroundings[1][0] == 'S') {
                return Move.LEFT;
            } else {
                return Move.UP;
            }
        }

        if (surroundings[1][0] == 'W') {
            if (surroundings[1][2] == ' ' || surroundings[1][2] == 'S') {
                return Move.RIGHT;
            } else if (surroundings[0][1] == ' ' || surroundings[0][1] == 'S') {
                return Move.UP;
            } else if (surroundings[2][1] == ' ' || surroundings[2][1] == 'S') {
                return Move.DOWN;
            } else {
                return Move.LEFT;
            }
        }

        if (surroundings[1][2] == 'W') {
            if (surroundings[1][0] == ' ' || surroundings[1][0] == 'S') {
                return Move.LEFT;
            } else if (surroundings[0][1] == ' ' || surroundings[0][1] == 'S') {
                return Move.UP;
            } else if (surroundings[2][1] == ' ' || surroundings[2][1] == 'S') {
                return Move.DOWN;
            } else {
                return Move.RIGHT;
            }
        }

        if (surroundings[2][1] == 'W') {
            if (surroundings[0][1] == ' ' || surroundings[0][1] == 'S') {
                return Move.UP;
            } else if (surroundings[1][0] == ' ' || surroundings[1][0] == 'S') {
                return Move.LEFT;
            } else if (surroundings[1][2] == ' ' || surroundings[1][2] == 'S') {
                return Move.RIGHT;
            } else {
                return Move.DOWN;
            }
        }

        return Move.HOLD;
    }
}

මගේ ගැති ඇල්ෆා වෘකයාට පහර දීමේ උපක්‍රම වෙනස් කිරීමට මට අවශ්‍යයි. මම අල්ලාගෙන වෘකයාට පහර දුන්නොත්: SCISSORS සමඟ සටන් කරන්න;)
ඉල්යා ගැස්මන්

11

අන්ධ වුල්ෆ්

අන්ධ වෘකයා චලනය වීමට බිය වන අතර එය සටන් කරන්නේ කුමක් දැයි කිසි විටෙකත් නොදනී. සෑම විටම කතුර වාදනය කිරීමෙන් හොඳම අවාසි ඇති බැවින් එය කිසි විටෙකත් සැබෑ ගලක් බවට පත් නොවනු ඇත .

package animals;

public class BlindWolf extends Animal {
    public BlindWolf() { super('W'); }

    @Override
    public Attack fight(char c) { 
        return Attack.SCISSORS;
    }

    @Override
    public Move move() {
        return Move.HOLD;
    }
}

11

විටග්‍රෝඅප්

මෙම වෘකයා වැඩෙන විට එයට සිංහයෙකු වීමට අවශ්‍යයි. ඒ නිසා අහඹු ලෙස සිංහයන් ඔවුන්ගේ අඩිපාරේ යමින් සිංහයෙකු වන්නේ කෙසේදැයි ඉගෙන ගනී.

මෙම වෘකයා නිර්මාණය කර ඇත්තේ සිංහයන් සමඟ ස්ථාන මාරු කරන වෘකයන්ට ප්‍රතිවිරුද්ධවය.

package animals;

import java.util.Random;

/**
 *
 * @author Quincunx
 */
public class WhenIGrowUp extends Animal {

    Random r;
    boolean following;
    boolean toggle;

    public WhenIGrowUp() {
        super('W');
        r = new Random();
        following = false;
        toggle = false;
    }

    @Override
    public Attack fight(char c) {
        switch (c) {
            case 'B':
                return Attack.SCISSORS;
            case 'L':
            case 'S':
                return Attack.PAPER;
            default:
                return Attack.values()[r.nextInt(4)];
        }
    }

    @Override
    public Move move() {
        if (surroundings[1][2] == 'L') {
            return Move.RIGHT;
        }
        if (surroundings[2][1] == 'L') {
            return Move.DOWN;
        }
        Move direction = Move.values()[r.nextInt(5)];
        out:
        for (int y = 0; y < 3; y++) {
            for (int x = 0; x < 3; x++) {
                if (surroundings[y][x] == 'L') {
                    if (y == 0 && x == 1) {
                        direction = Move.UP;
                    } else if (y == 1 && x == 0) {
                        direction = Move.LEFT;
                    } else {
                        direction = Move.HOLD;
                    }
                    break out;
                }
            }
        }
        return direction;
    }
}

11

ස්පයි වුල්ෆ්

ස්පයි වුල්ෆ් එහි සතුරන් ගැන ඔත්තු බලන අතර ඔවුන්ගේ ක්‍රියාකාරකම් සටහන් කරයි, එමඟින් දුරස්ථව තබා ගනිමින් සෑම කෙනෙකුටම ටැබ් තබා ගත හැකිය. සොයා ගැනීමට අවශ්‍ය නොවනු ඇත!

package animals;

import static animals.Animal.Attack.*;
import static animals.Animal.Move.*;

import java.awt.Point;
import java.util.*;

public class SpyWolf extends Animal {

    private static final Random r = new Random();
    private static boolean hasTestedPRNG = false;
    private static int PRNG = -1;
    private boolean lionTracker = true;
    private boolean useScissors = false;

    private final ArrayList<MapTile> map = new ArrayList<MapTile>();
    private final Point location = new Point();

    public SpyWolf() {
        super('W');
    }

    @Override
    public Animal.Attack fight(char opponent) {
        switch (opponent) {
            case 'B':
            case 'L':
                return SCISSORS;
            case 'S':
                return PAPER;
            default:
                if (useScissors) {
                    useScissors = false;
                    return SCISSORS;
                }
                return PAPER;
        }
    }

    @Override
    public Animal.Move move() {

        Move m = HOLD;

        if (!hasTestedPRNG) {
            hasTestedPRNG = true;
            double d = 0;
            for (int i = 0; i < 100; i++)
                d += Math.random();
            if (d > 99) {
                PRNG = 1;
            } else if (d > 30 && d < 70) PRNG = 0;
        }

        lionTracker = !lionTracker;
        boolean adj = false;

        updateMap();

        scan: {
            if (PRNG < 1) {
                if (look(LEFT) == 'L' && !lionTracker) {
                    useScissors = true;
                    m = LEFT;
                    break scan;
                }

                if (look(UP) == 'L' & lionTracker) {
                    useScissors = true;
                    m = UP;
                    break scan;
                }
            }

            int x = 0, y = 0;
            ArrayList<Move> moves = new ArrayList<Move>(4);

            for (Move i : Move.values())
                moves.add(i);

            if (look(UP) == 'W') {
                y += 54;
                moves.remove(UP);
                adj = true;
            }
            if (look(DOWN) == 'W') {
                y -= 54;
                moves.remove(DOWN);
                adj = true;
            }
            if (look(LEFT) == 'W') {
                x += 54;
                moves.remove(LEFT);
                adj = true;
            }
            if (look(RIGHT) == 'W') {
                x -= 54;
                moves.remove(RIGHT);
                adj = true;
            }

            if (moves.isEmpty() || !adj) break scan;

            for (MapTile t : map) {
                if (t.x >= location.x - 2 && t.x <= location.x + 2 && t.y >= location.y - 2 && t.y <= location.y + 2 && t.d) {
                    int dist = Math.abs(t.x - location.x) + Math.abs(t.y - location.y);
                    y += t.y > location.y ? -60 / dist : 60 / dist;
                    x += t.x < location.x ? 60 / dist : -60 / dist;
                }
            }
            m = moveDir(x, y);
            if (!moves.contains(m)) m = HOLD;
        }
        switch (m) {
            case UP:
                location.y--;
                return m;
            case DOWN:
                location.y++;
                return m;
            case LEFT:
                location.x--;
                return m;
            case RIGHT:
                location.x++;
                return m;
            default:
                return m;
        }
    }

    private void updateMap() {
        for (int y = -1; y < 2; y++)
            xloop: for (int x = -1; x < 2; x++) {
                if (x == 0 && y == 0) continue;
                for (MapTile t : map)
                    if (t.x == x + location.x && t.y == y + location.y) {
                        t.d = surroundings[y + 1][x + 1] == 'W';
                        continue xloop;
                    }
                map.add(new MapTile(x + location.x, y + location.y, surroundings[y + 1][x + 1] == 'W'));
            }
    }

    private Move moveDir(int x, int y) {
        if (x == 0) return y < 0 ? UP : y > 0 ? DOWN : HOLD;
        if (y == 0) return x < 0 ? LEFT : RIGHT;
        if (x < 0) {
            if (y < 0) {
                if (y < x)
                    return UP;
                else if (x < y) return LEFT;
                return r.nextBoolean() ? UP : LEFT;
            } else {
                if (-y < x)
                    return DOWN;
                else if (x < -y) return LEFT;
                return r.nextBoolean() ? DOWN : LEFT;
            }
        }
        if (y < 0) {
            if (y < -x)
                return UP;
            else if (-x < y) return RIGHT;
            return r.nextBoolean() ? UP : RIGHT;
        } else {
            if (y > x)
                return DOWN;
            else if (x < y) return RIGHT;
        return r.nextBoolean() ? DOWN : RIGHT;
        }
    }

    private char look(Move direction) {
        switch (direction) {
            case UP:
                return surroundings[0][1];
            case DOWN:
                return surroundings[2][1];
            case LEFT:
                return surroundings[1][0];
            case RIGHT:
                return surroundings[1][2];
            default:
                return surroundings[1][1];
        }
    }

    private static class MapTile {
        int x, y;
        boolean d;

        MapTile(int x, int y, boolean d) {
            this.x = x;
            this.y = y;
            this.d = d;
        }
    }
}

එය ඉතා හොඳ ගාස්තුවකි, නමුත් එම කොර හයිබ්‍රිඩ් වුල්ෆ් ඉතා වංචනිකය! ස්පයි වුල්ෆ් නැවත ඔත්තු පාසලට ගොස් උසස් වෘකයන් විරෝධී ක්‍රම පුහුණු කළ හැකිය, අපි බලමු.


1
ඔබ එය කොර ලෙස
හඳුන්වයි

5
අහ්හ්හ්! ගොඩක් gotos! ඒවා පවා නැති භාෂාවකින්!
ඒ.ජේ මෑන්ස්ෆීල්ඩ්

9

හයිබ්‍රිඩ් වුල්ෆ්

මට විරුද්ධ වෙන්න බැරි වුනා තවත් වෘකයෙක් හදන්න. මෙය ඉතා වෙනස් ය (එහි කේතයේ, එහි හැසිරීමෙහි නොවේ), එය වෙනත් හොඳ වෘකයන් විසින් කරනු ලබන ප්‍රහාරය / චලනය තෝරා ගන්නා බැවින්.
ඇත්ත වශයෙන්ම සියලුම වෘකයන් හොඳයි, නමුත් මම අදහස් කළේ වැඩිපුරම ලකුණු ඇති අයයි :)

package animals;

import java.util.ArrayList;
import java.util.Random;

public class HybridWolf extends Animal{
    private final Class[] classes = {ProAlpha.class, OmegaWolf.class, SpyWolf.class, HerjanWolf.class, DeepWolf.class, ProtoWolf.class};
    private final ArrayList<Animal> wolves = new ArrayList<Animal>(); 

    public HybridWolf() {
        super('W');
        for(Class c: classes) {
            try {
                wolves.add((Animal)c.newInstance());
            } catch (Exception ex) {}
        }
    }

    @Override
    public Attack fight(char opponent) {
        switch(opponent){
        case 'B':
        case 'L':
            return Attack.SCISSORS;
        case 'S': 
            return Attack.PAPER;
        default:
            try {
                int[] attacks = new int[3];
                Attack bestAttack = randomAttack();
                for(Animal wolf : wolves) {
                    wolf.surroundings = this.surroundings;
                    attacks[wolf.fight(opponent).ordinal()]++;
                }
                for(int i =0; i < 5; i++) {
                    if(attacks[i] > attacks[bestAttack.ordinal()]) {
                        bestAttack = Attack.values()[i];
                    }
                }
                return bestAttack;
            } catch (Exception e) {
                return randomAttack();
            }
        }
    }

    @Override
    public Move move() {
        try {
            int[] moves = new int[5];
            Move bestMove = Move.HOLD;
            for(Animal wolf : wolves) {
                wolf.surroundings = this.surroundings;
                moves[wolf.move().ordinal()]++;
            }
            for(int i =0; i < 5; i++) {
                if(moves[i] > moves[bestMove.ordinal()]) {
                    bestMove = Move.values()[i];
                }
            }
            return bestMove;
        } catch (Exception e) {
            return Move.HOLD;
        }
    }

    public Attack randomAttack() {
        Random rand = new Random();
        switch (rand.nextInt(3)){
            case 1: return Attack.SCISSORS;
            case 2: return Attack.ROCK;
            default: return Attack.PAPER;
        }
    }

}

එය මගේ පෙර ඇල්ෆා වුල්ෆ්ට වඩා හොඳ ලකුණු ලබා ගනී, නමුත් ඔමේගා / ගෞරව / ප්‍රෝ ඇල්ෆා සමහර විට මට පහර දුන්නේය ... වඩා හොඳ ඉදිරිපත් කිරීම් මෙහි ඇත, මෙම වෘකයාට වඩා හොඳ වනු ඇත: ඩී


මේක ටිකක් කම්මුලයි! දක්ෂ අදහසක්. නීත්‍යානුකූල ප්‍රවේශයක් තීරණය කිරීම සඳහා රුෂර් අයදුම් කරන පරීක්ෂණ පිළිබඳව මා නොදන්නා බැවින් මෙය නීත්‍යානුකූල ප්‍රවේශයක් ලෙස සාධාරණ වන්නේ කෙසේදැයි විශ්වාස නැත. එනම් ඔහු දැනට සිටින අනෙක් වෘකයන් සමඟ හුදකලා පරීක්ෂණයක් කළහොත් මෙම වෘකයා අවාසනාවන්ත ලෙස අසමත් වනු ඇත: P
Moogie

Oo මූගී 90% ප්‍රවේශයන් නීත්‍යානුකූලයි. මෙතෙක්, මම ඔවුන්ගේ ලිපිය 'ඩබ්ලිව්' හැර වෙනත් දෙයකට වෙනස් කළ ඇතුළත් කිරීම් හෝ වෙනත් භාෂාවකින් සම්පාදනය කරන්නේ කෙසේදැයි මට සිතාගත නොහැකි ඇතුළත් කිරීම් පමණක් බැහැර කර ඇත (තවද එය එසේ දැයි මම ඔවුන්ට දන්වමි, නමුත් ඔබට විය හැකිය මම ඔවුන් සමඟ කතාබස් කරන නිසා එය මෙහි නොපෙනේ).
රේන්බෝල්ට්

Us රුෂර් තමන්ට වාසිදායක ලෙස වෙනස් කිරීමට උත්සාහ කරන සමහර ඇතුළත් කිරීම් තිබේ. උදා: සූදු වෘකයා ජාවාහි Math.random () හි අහඹු සංඛ්‍යා උත්පාදක යන්ත්රය සෑම විටම 1 ආපසු ලබා දීම සඳහා වෙනස් කරයි! විනෝදජනක ලෙස එය ප්‍රති results ල කෙරෙහි එතරම් බලපෑමක් ඇති නොකරන්නේ ජයග්‍රාහී වෘකයන් වන බැවින් සටන් කිරීමෙන් වැළකී සිටින වෘකයන්ය!
Moogie

Oo මුගී සූදුවේ නියැලීම නීත්‍යානුකූල ඉදිරිපත් කිරීමකි (එසේම එය ඉතා දක්ෂයි). ඔබ හරි, එය ප්‍රති results ල බොහෝ වෙනස් කළේ නැහැ. දේවල් අතපසු වුවහොත්, මම කියන්නේ "හරි, ඔහු දිනයි, නමුත් ඔහු ඇතුළත් නොකළේ නම් මෙහි ප්‍රති result ලය මෙන්න." ඒ ආකාරයෙන් අනෙක් සියල්ලන්ටම මකා නොදැමීමෙන් සතුටක් ලැබිය හැකිය.
රේන්බෝල්ට්

2
Oo මූගි අභියෝගයේ පිරිවිතරයන්හි යම් දෙයක් විශේෂයෙන් තහනම් කර නොමැති නම් එය සත්‍ය වශයෙන්ම නීත්‍යානුකූල වන අතර මෙම වෙබ් අඩවියේ සම්ප්‍රදාය වන්නේ මිනිසුන් එයට පිළිතුරු පළ කිරීමෙන් පසු නීති වෙනස් නොකිරීමයි.
plannapus

9

එවෝ වුල්ෆ්

ඔබ මෝඩ බුද්ධිමත්ව නිර්මාණය කළ වෘකයන්! ඊවෝ වුල්ෆ් වනයේ ජීවත් වන්නේ ඩීප් වුල්ෆ් සහ හර්ජන් වුල්ෆ් වැනි දැඩි වෘකයන් සමඟ ය.

හොඳම වෘකයා පරිණාමය කිරීම සඳහා කේතය ජානමය ඇල්ගොරිතමයක් භාවිතා කරයි (මම වෘකයන් අල්ලා ගැනීමට එරෙහිව පුහුණු වන තෙක් ලයන්හන්ටර් වුල්ෆ් දුටුවේ නැත). එක් එක් සත්ව / ප්‍රහාරක සංයෝජනය සඳහා විවිධ ජාන, ආරක්ෂිත විට චලනය වන දිශාව සහ අවට සිටින සෑම සතෙකු සඳහාම චලන දිශාව. වට 1000 කට පසු, වැඩිම වාර ගණනක් පැවතුන වෘකයන්ට දරුවන් බිහි කිරීමේ ඉහළම සම්භාවිතාව ඇත (එනම් ඔබ වැඩි කාලයක් ජීවත් වන්නේ ඔබට සහකරු හෝ සහකාරිය ලැබීමට වැඩි ඉඩක් ඇත). ළමුන්ගෙන් 10% ක් පමණ අහඹු ලෙස විකෘතියක් ඇති කිරීමට අපි බලාපොරොත්තු වෙමු.

මෙන්න EvoWolf කේතය, ඔබට අවශ්‍ය වනු ඇත evowolf.txt ඔබේ වැඩ කරන නාමාවලිය තුළ - එය වර්තමාන GENEPOOL සමඟ සම්බන්ධ වේ. ඔබේම වෘකයන් ප්‍රාථමික අහඹු ලෙස පරිණාමය වීමට ඔබට අවශ්‍ය නම්, evowolf.txt ඇතුළත් නොකරන්න, නමුත් ලබා දී ඇති එක දැනට හොඳම පරිණාමයයි. එය පරිණාමය වීම නැරඹීම ඇත්තෙන්ම පිළිවෙලයි, ආරම්භයේ දී නොනැසී පවතින්නේ 2-3 ක් පමණි, නමුත් පසුව එය 60 ක් දක්වා ඉහළ යයි.

package animals;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;

public class EvoWolf extends Animal {
    public EvoWolf() { super('W'); birth();}
    public Attack fight(char c) { 
        List<Attack> attacks = getAttacks(c);
        if(attacks.size() == 0)
            return Attack.SUICIDE; //Discourage wolves without attacks, Darwin Award

        return attacks.get(random.nextInt(attacks.size()));
    }

    public Move move() {
        ++turns;
        List<Move> moves = new ArrayList<Move>();
        if(isSafe())
            moves = getSafeMoves();
        else
            moves = getThreatenedMoves();

        return (Move)moves.toArray()[random.nextInt(moves.size())];
    }

    /*====STATIC METHODS====*/
    //Shared RNG
    public static Random random = new Random();

    //Collection of 100 sets of genes
    public static String[] genePool = null;

    //Get the genes from disk or randomly generate some
    public static void readGenePool(){
        genePool = new String[100];
        int gIdx = 0;
        try (BufferedReader br = new BufferedReader(new FileReader("evowolf.txt"))){
            String sCurrentLine; 
            while ((sCurrentLine = br.readLine()) != null) {
                genePool[gIdx] = sCurrentLine;
                ++gIdx;
            }
        } catch (IOException e) {

        } 

        //if can't read genes, make some
        if(gIdx < 100){
            primordial(gIdx);
        }
    }
    public static void primordial(int idx){
        for(;idx < 100; ++idx){
            genePool[idx] = getRandomGenes();
        }
    }

    public static String getRandomGenes(){
        StringBuilder sb = new StringBuilder();
        for(int idx = 0; idx < GENE_COUNT; ++idx){
            if(random.nextBoolean())
                sb.append("1");
            else
                sb.append("0");
        }
        return sb.toString();
    }

    //Evolve wolves
    public static void nextGen(){
        //Check survival of current gen
        int survivors = 0;
        for(int idx = 0; idx < 100; ++idx){
            survivors = survivors + (generation[idx].turns == 1000 ? 1 : 0);
        }
        if(survivors > 65)
            writeGenePool(Long.toString(survivors));

        //Weighted resivour sampling
        //Take the highest of r^(1/w) where r is a random an w is the weight
        for(int idx = 0; idx < 100; ++idx){
            genePool[idx] = mateFitWolves();
        }
        writeGenePool("");
        birthCount = 0;
    }

    //Pick two wolves randomly by weighted fitness and mate them
    public static String mateFitWolves(){
        EvoWolf w1 = null;
        double weight1 = -1;
        EvoWolf w2 = null;
        double weight2 = -1;

        for(int idx = 0; idx < 100; ++idx){
            double weight = generation[idx].getWeightSample();
            if(weight > weight1){
                weight2 = weight1;
                w2 = w1;
                weight1 = weight;
                w1 = generation[idx];
            } else if(weight > weight2){
                weight2 = weight;
                w2 = generation[idx];
            }
        }

        return mateFitWolves(w1, w2);
    }

    //Make offspring
    public static String mateFitWolves(EvoWolf w1, EvoWolf w2){
        StringBuilder sb = new StringBuilder();
        //Random splice
        for(int rIdx = 0; rIdx < w1.genes.length(); ++rIdx){
            if(random.nextBoolean())
                sb.append(w1.genes.charAt(rIdx));
            else
                sb.append(w2.genes.charAt(rIdx));
        }


        //Random mutation
        while(random.nextInt(10) == 0){
            int mIdx = random.nextInt(w1.genes.length());
            if(sb.charAt(mIdx) == '0')
                sb.setCharAt(mIdx, '1');
            else
                sb.setCharAt(mIdx, '0');
        }


        return sb.toString();
    }

    //Save the next generation's gene pool back to disk
    public static void writeGenePool(String survivors){
        try {
            String str = "";
            if(!survivors.equals(""))
                str = Long.toString(System.currentTimeMillis());

            File file = new File("evowolf" + survivors + str + ".txt");

            // if file doesn't exists, then create it
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            for(int gIdx = 0; gIdx < genePool.length; ++gIdx){
                bw.write(genePool[gIdx]);
                bw.write('\n');
            }
            bw.close();
        } catch (IOException e) {

        }
    }

    //Keep track of the wolves in this generation
    public static int birthCount = 0;
    public static EvoWolf[] generation = new EvoWolf[100];

    /*====INSTANCE METHODS====*/
    //Populate this wolf from the gene pool
    public void birth(){
        if(genePool == null){
            readGenePool();
        }
        genes = genePool[birthCount];
        generation[birthCount] = this;
        birthCount = (birthCount + 1) % 100;    
    }

    //How long wolf has been alive
    public int turns = 0;

    //Fitness based on how long wolf survived
    public double getWeightSample(){
        return Math.pow(random.nextDouble(), 1.0/turns);
    }


    /*===GENETICS===*/
    public String genes = null;
    //Genes are made up of 182+ bits (stored at a string)
    //Each turns on the possibility of that move or attack in a given situation
    //  Attack: BLSW * RPSX = 16 bits [0-15] = Animal->Attacks
    //  Threatened Moves: BLSW * 12345678 * UDLRH = 160 bits [16-175] = Y -> X -> Animal -> Moves
    //  Safe Moves: UDLRH = 5 bits [176-180] = Moves
    //  Extra: default move [181], move combination [182]
    public static final int GENE_INDEX_ATTACKS = 0;
    public static final int GENE_INDEX_THREATENED_MOVES = GENE_INDEX_ATTACKS + (4 * 4);
    public static final int GENE_INDEX_SAFE_MOVES = GENE_INDEX_THREATENED_MOVES + (8 * 4 * 5);
    public static final int GENE_INDEX_DEFAULT_MOVE = GENE_INDEX_SAFE_MOVES + (5);
    public static final int GENE_INDEX_COMBINE_MOVES = GENE_INDEX_DEFAULT_MOVE + (1);
    public static final int GENE_COUNT = GENE_INDEX_COMBINE_MOVES + 1;
    public static int getAnimalIndex(char c){
        switch (c) {
            case 'B':
                return 0;
            case 'L':
                return 1;
            case 'S':
                return 2;
            case 'W':
            default: //Shouldn't occur but we'll assume it's the dangerous wolf
                return 3;
        } 
    }

    public static int getXYIndex(int x, int y){
        int idx = (y * 3) + x;
        if(idx > 4) //We don't need to look at ourself
            --idx;
        return idx;
    }

    public List<Attack> getAttacks(char c){
        List<Attack> attacks = new ArrayList<Attack>();
        int idx = GENE_INDEX_ATTACKS + getAnimalIndex(c);
        if(genes.charAt(idx + 0) == '1')
            attacks.add(Attack.ROCK);
        if(genes.charAt(idx + 1) == '1')
            attacks.add(Attack.PAPER);
        if(genes.charAt(idx + 2) == '1')
            attacks.add(Attack.SCISSORS);
        /*
        if(genes.charAt(idx + 3) == '1')
            attacks.add(Attack.SUICIDE);
        */
        //Suicide didn't remove itself from the gene pool like I thought so I manually removed it

        return attacks;
    }

    public boolean isSafe(){
        for(int x = 0; x <= 2; ++x){
            for(int y = 0; y <= 2; ++y){
                if(y == 1 && x == 1)
                    continue;
                if(surroundings[y][x] != ' ')
                    return false;
            }
        }
        return true;
    }

    public List<Move> getSafeMoves(){
        List<Move> moves = new ArrayList<Move>();
        int idx = GENE_INDEX_SAFE_MOVES;
        if(genes.charAt(idx + 0) == '1')
            moves.add(Move.UP);
        if(genes.charAt(idx + 1) == '1')
            moves.add(Move.DOWN);
        if(genes.charAt(idx + 2) == '1')
            moves.add(Move.LEFT);
        if(genes.charAt(idx + 3) == '1')
            moves.add(Move.RIGHT);
        if(genes.charAt(idx + 4) == '1')
            moves.add(Move.HOLD);

        return moves;
    }

    public List<Move> getThreatenedMoves(){
        List<Move> moves = new ArrayList<Move>();
        if(genes.charAt(GENE_INDEX_COMBINE_MOVES) == '0')
            moves.addAll(EnumSet.of(Move.UP, Move.DOWN, Move.LEFT, Move.RIGHT, Move.HOLD));

        for(int x = 0; x <= 2; ++x){
            for(int y = 0; y <= 2; ++y){
                if(y == 1 && x == 1)
                    continue;
                if(genes.charAt(GENE_INDEX_COMBINE_MOVES) == '1')
                    moves.addAll(getThreatenedMoves(x,y));
                else
                    moves.retainAll(getThreatenedMoves(x,y));
            }
        }

        if(moves.size() == 0){
            if(this.genes.charAt(GENE_INDEX_DEFAULT_MOVE) == '1')
                moves.addAll(EnumSet.of(Move.UP, Move.DOWN, Move.LEFT, Move.RIGHT, Move.HOLD));
            else
                moves.add(Move.HOLD);
        }

        return moves;
    }

    public EnumSet<Move> getThreatenedMoves(int x, int y){
        //Lookup what moves we can make for a cell unless it is blank (allow any)
        if(surroundings[y][x] != ' ')
            return getThreatenedMoves(x,y,surroundings[y][x]);
        else if(genes.charAt(GENE_INDEX_COMBINE_MOVES) == '1')
            return EnumSet.noneOf(Move.class);
        else
            return EnumSet.of(Move.UP, Move.DOWN, Move.LEFT, Move.RIGHT, Move.HOLD);
    }

    public EnumSet<Move> getThreatenedMoves(int x, int y, char c){
        int aIdx = getAnimalIndex(c);
        int sIdx = getXYIndex(x,y);
        int idx = GENE_INDEX_THREATENED_MOVES + (sIdx * 20) + (aIdx * 5);

        EnumSet<Move> moves = EnumSet.noneOf(Move.class);

        if(genes.charAt(idx + 0) == '1')
            moves.add(Move.UP);
        if(genes.charAt(idx + 1) == '1')
            moves.add(Move.DOWN);
        if(genes.charAt(idx + 2) == '1')
            moves.add(Move.LEFT);
        if(genes.charAt(idx + 3) == '1')
            moves.add(Move.RIGHT);
        if(genes.charAt(idx + 4) == '1')
            moves.add(Move.HOLD);

        return moves;
    }

    public static String setAt(String str, int index, char replace){     
        if(str==null){
            return str;
        }else if(index<0 || index>=str.length()){
            return str;
        }
        char[] chars = str.toCharArray();
        chars[index] = replace;
        return String.valueOf(chars);       
    }
}

මම සංඛ්‍යා ලේඛන.ජාවා සහ වයිල්ඩ් ජාවා හි යම් යම් වෙනස්කම් සිදු කර ඇති අතර එය කොපමණ වාර ගණනක් සහ පරම්පරාවක් පසු වී ඇත්දැයි මට පෙන්වයි. ඔබ හැරීම් 1000 ක් ධාවනය කළ පසු, EvoWolf.nextGen();දරුවන් ගණනය කිරීමට අමතන්න . මෙය තරඟයට අවශ්‍ය නොවේ, ඔබට ඔබේම කට්ටලයක් පරිණාමය කිරීමට අවශ්‍ය නම් පමණි.

සියලුම ලිපිගොනු මෙහි සංස්කරණය කරන්න: ස්ථාවර ලින්ක්

හොඳම දේ ලෙස පරිණාමය වන තාක් දුරට, එය ඉහළ 10 ට වඩා යහපත් නොවේ. සීමාවේ කොටසක් නම්, එහි පෙර චලනයන් පිළිබඳ මතකය ඉතා අල්පය. එය WolvesWithCollectiveMemory මෙන් ක්‍රියා කළද, පෙර පරම්පරාවන්ගේ අත්දැකීම් ඊළඟ පරම්පරාව දිගු කාලීන ගෝලීය මතකයක් ලෙස ක්‍රියා කරන ආකාරය කෙරෙහි බලපායි. එය නිසැකවම විනෝදජනක විය. පෙර සබැඳියේ ජාන සංචිතය විශ්ලේෂණය කිරීමට ඔබට උපකාර කළ හැකි එක්සෙල් පත්‍රයක් ඇත. .Txt හි ඇති 1 සහ 0 සියල්ලම 1 සහ 0 ගේ කොමාව සමඟ ප්‍රතිස්ථාපනය කර පැතුරුම්පතෙහි අලවන්න.

සිත්ගන්නාසුලු සටහන් කිහිපයක්, ඒවායින් බොහොමයක් සෑම දෙනාගේම උපාය මාර්ග සනාථ කරයි:

  • සටන් කිරීමෙන් වැළකී සිටීමට වඩා සැබෑ ප්‍රහාර අඩු වැදගත්කමක් දරයි. එසේත් නැතිනම් වෘකයන් නොවන සියලු දෙනා ඉක්මනින් තුරන් වන බැවින් ඔවුන් තර්ජනයක් නොවේ. ඔබ එස් විසි කළත් වලසුන්ට එරෙහිව ආර්පීඑස් අතර තරඟ පරම්පරාවට සමාන අවස්ථාවක් තිබේ.
  • ඉහත සඳහන් කළ පරිදි, සියදිවි නසාගැනීම් අතින් අක්‍රීය කිරීමට මට සිදුවිය.
  • කිසිවෙකු නොසිටින විට රඳවා ගැනීම හොඳම පියවරයි
  • යමෙකු අවට සිටින විට පැන යාම ද හොඳ බව පෙනේ
  • අහඹු දිශාවකට ගමන් කරනවා වෙනුවට ඔබ රඳවා තබා ගත යුතුය (මෙම තේරීම පරිණාමය වූ අතිරේක ජානයකි)
  • සත්වයින් 1 කට වඩා සිටින විට, අවට / සත්වයන් සඳහා චලනයන් අතරින් අහඹු ලෙස ගමන් කිරීම සමිතියට වඩා හොඳය (තවත් අමතර ජානයක්)

8

ස්මාර්ට් වුල්ෆ්

ප්‍රති results ල (පුනරාවර්තන 1000) ඇත (මම මෙය යාවත්කාලීන කරමින් සිටිමි, නමුත් එය සාමාන්‍ය පරීක්ෂණයක් ලෙස සලකන්නේ කිසිදු වෘකයෙකු සමග එය තරමක් මන්දගාමී බැවිනි).

රූප විස්තරය මෙහි ඇතුළත් කරන්න

සම්පාදනය:

* නික්ස් (මොනෝ අවශ්‍යයි):

gmcs SmartWolf.cs

වින්ඩෝස්:

csc SmartWolf.cs

වැඩ කරන නාමාවලියට පිටපත් කරන්න.

සටහන: වින්ඩෝස් භාවිතා කරන විට, ඔබ එතීමේ කේතයෙන් ආදේශ "mono SmartWolf.exe"කළ "SmartWolf.exe"යුතුය.

SmartWolf.cs:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SmartWolf
{
    #region Enums
    enum Attack
    {
        Rock, Paper, Scissors, Suicide
    }
    enum Movement
    {
        Up, Down, Left, Right, Hold
    }
    enum Animal
    {
        Stone, Lion, Wolf, Bear, Empty
    }
    #endregion
    class KnowledgeBase
    {
        static Random rnd = new Random();
        public List<KeyValuePair<KeyValuePair<Animal, Attack>, int>> knowledge = new List<KeyValuePair<KeyValuePair<Animal, Attack>, int>>();
        public KnowledgeBase ()
        {
        }
        public void PunishMove (KeyValuePair<Animal, Attack> move)
        {
            if (knowledge.Count (t => t.Key.Key == move.Key && t.Key.Value == move.Value) == 0) {
                knowledge.Add (new KeyValuePair<KeyValuePair<Animal, Attack>, int> (move, -1));
            } else {
                int i = knowledge.FindIndex (t => t.Key.Equals (move));
                knowledge[i] = new KeyValuePair<KeyValuePair<Animal, Attack>, int>(knowledge[i].Key, knowledge[i].Value - 1);
            }

        }
        public void RewardMove (KeyValuePair<Animal, Attack> move)
        {
            if (knowledge.Count (t => t.Key.Key == move.Key && t.Key.Value == move.Value) == 0) {
                knowledge.Add (new KeyValuePair<KeyValuePair<Animal, Attack>, int> (move, 1));
            } else {
                int i = knowledge.FindIndex (t => t.Key.Equals (move));
                knowledge[i] = new KeyValuePair<KeyValuePair<Animal, Attack>, int>(knowledge[i].Key, knowledge[i].Value + 1);
            }
        }
        public Attack GetBestMove (Animal opponent)
        {
            Attack best = GetRandomMove();
            int j = 0;
            foreach (var pair in knowledge) {
                if(pair.Key.Key == opponent && j < pair.Value)
                {
                    best = pair.Key.Value;
                    j = pair.Value;
                }
            }
            if(j < 2)
                return GetRandomMove ();
            return best;
        }
        public static Attack GetRandomMove()
        {
            int r = rnd.Next (3);
            return r == 0 ? Attack.Paper :
                r == 1 ? Attack.Rock :
                    r == 2 ? Attack.Scissors :
                    Attack.Scissors;
        }
    }
    class MainClass
    {
        static KnowledgeBase knowledge = new KnowledgeBase();
        public static void Main (string[] args)
        {
            List<SmartWolf> list = new List<SmartWolf> ();
            List<int> temp = new List<int>();
            int l = 0;
            while (true) {
                string str = Console.ReadLine ();
                int id = int.Parse (str.Substring (1, 2));
                if(str.StartsWith ("S"))
                {
                    list.Add (new SmartWolf(id));
                    Console.WriteLine("K" + id.ToString ().PadLeft (2, '0'));
                } else if(str.StartsWith ("M"))
                {
                    if(temp.Contains (id))
                    {
                        for(int i = 0; i < 100; i++)
                        {
                            SmartWolf s = list.Where (t => t.ID == i).ToList ()[0];
                            if(s.AttackedInLastRound == 0 && !temp.Contains(i))
                            {
                                s.IsAlive = false;
                                knowledge.PunishMove (s.LastMove);
                                s.AttackedInLastRound = -1;
                            } else if(s.AttackedInLastRound == 0 && temp.Contains (i))
                            {
                                knowledge.RewardMove (s.LastMove);
                                s.AttackedInLastRound = -1;
                            }
                            if(s.AttackedInLastRound > 0)
                                s.AttackedInLastRound--;
                        }
                        temp.Clear();
                        l++;
                    }
                    temp.Add (id);

                    Console.WriteLine('H' + id.ToString ().PadLeft (2, '0'));
                } else if(str.StartsWith ("A"))
                {
                    Animal enemy = str[3] == 'W' ? Animal.Wolf :
                                   str[3] == 'L' ? Animal.Lion :
                                   str[3] == 'S' ? Animal.Stone :
                                   str[3] == 'B' ? Animal.Bear : Animal.Empty;
                    Attack atk = knowledge.GetBestMove (enemy);
                    Console.WriteLine((atk == Attack.Paper ? "P" :
                                      atk == Attack.Rock ? "R" : 
                                      atk == Attack.Scissors ? "S" :
                                      "P") + id.ToString ().PadLeft (2, '0'));
                    list.Where (t => t.ID == id).ToList ()[0].AttackedInLastRound = 2;
                    list.Where (t => t.ID == id).ToList ()[0].LastMove = new KeyValuePair<Animal, Attack>(enemy, atk);
                }
            }
        }
    }
    class SmartWolf
    {
        public int ID;
        public bool IsAlive = true;
        public KeyValuePair<Animal, Attack> LastMove = new KeyValuePair<Animal, Attack>(Animal.Empty, Attack.Suicide);
        public int AttackedInLastRound = -1;
        public SmartWolf(int n)
        {
            ID = n;
        }
    }
}

රැපර් (ro ප්‍රෝග්‍රැමර් ඩෑන් වෙත ණය, මම එය මෙහි ඇතුළත් කරමි, එබැවින් පේස්ට් පිටපත් කිරීම පහසුය):

package animals;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Remote SmartWolf wrapper class. 
 */
public class SmartWolf extends Animal {
    /**
     * Simple test script that sends some typical commands to the
     * remote process.
     */
    public static void main(String[]args){
        SmartWolf[] wolves = new SmartWolf[100];
        for(int i=0; i<10; i++) {
            wolves[i] = new SmartWolf();
        }
        char map[][] = new char[3][3];
        for (int i=0;i<9;i++)
            map[i/3][i%3]=' ';
        map[1][2] = 'W';
        for(int i=0; i<10; i++) {
            wolves[i].surroundings=map;
            System.out.println(wolves[i].move());
        }
        for(int i=0; i<10; i++) {
            System.out.println(wolves[i].fight('S'));
            System.out.println(wolves[i].fight('B'));
            System.out.println(wolves[i].fight('L'));
            System.out.println(wolves[i].fight('W'));
        }
        wolfProcess.endProcess();
    }
    private static WolfProcess wolfProcess = null;

    private static SmartWolf[] wolves = new SmartWolf[100];
    private static int nWolves = 0;

    private boolean isDead;
    private int id;

    /**
     * Sets up a remote process wolf. Note the static components. Only
     * a single process is generated for all Wolves of this type, new
     * wolves are "initialized" within the remote process, which is
     * maintained alongside the primary process.
     * Note this implementation makes heavy use of threads.
     */
    public SmartWolf() {
        super('W');
        if (SmartWolf.wolfProcess == null) {
            SmartWolf.wolfProcess = new WolfProcess();
            SmartWolf.wolfProcess.start();
        }

        if (SmartWolf.wolfProcess.initWolf(SmartWolf.nWolves, MAP_SIZE)) {
            this.id = SmartWolf.nWolves;
            this.isDead = false;
            SmartWolf.wolves[id] = this;
        } else {
            SmartWolf.wolfProcess.endProcess();
            this.isDead = true;
        }
        SmartWolf.nWolves++;
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, SUICIDE.
     * Otherwise, communicate an attack to the remote process and return
     * its attack choice.
     */
    @Override
    public Attack fight(char opponent) {
        if (!SmartWolf.wolfProcess.getRunning() || isDead) {
            return Attack.SUICIDE;
        }
        try {
            Attack atk = SmartWolf.wolfProcess.fight(id, opponent);

            if (atk == Attack.SUICIDE) {
                this.isDead = true;
            }

            return atk;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Attack.SUICIDE;
        }
    }

    /**
     * If the wolf is dead, or all the wolves of this type are dead, HOLD.
     * Otherwise, get a move from the remote process and return that.
     */
    @Override
    public Move move() {
        if (!SmartWolf.wolfProcess.getRunning() || isDead) {
            return Move.HOLD;
        }
        try {
            Move mv = SmartWolf.wolfProcess.move(id, surroundings);

            return mv;
        } catch (Exception e) {
            System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
            isDead = true;
            return Move.HOLD;
        }
    }

    /**
     * The shared static process manager, that synchronizes all communication
     * with the remote process.
     */
    static class WolfProcess extends Thread {
        private Process process;
        private BufferedReader reader;
        private PrintWriter writer;
        private ExecutorService executor;
        private boolean running;

        public boolean getRunning() {
            return running;
        }

        public WolfProcess() {
            process = null;
            reader = null;
            writer = null;
            running = true;
            executor = Executors.newFixedThreadPool(1);
        }

        public void endProcess() {
            running = false;
        }

        /**
         * WolfProcess thread body. Keeps the remote connection alive.
         */
        public void run() {
            try {
                System.out.println("Starting SmartWolf remote process");
                ProcessBuilder pb = new ProcessBuilder("mono SmartWolf.exe".split(" "));
                pb.redirectErrorStream(true);
                process = pb.start();
                System.out.println("SmartWolf process begun");
                // STDOUT of the process.
                reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); 
                System.out.println("SmartWolf reader stream grabbed");
                // STDIN of the process.
                writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"));
                System.out.println("SmartWolf writer stream grabbed");
                while(running){
                    this.sleep(0);
                }
                reader.close();
                writer.close();
                process.destroy(); // kill it with fire.
                executor.shutdownNow();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("SmartWolf ended catastrophically.");
            }
        }

        /**
         * Helper that invokes a read with a timeout
         */
        private String getReply(long timeout) throws TimeoutException, ExecutionException, InterruptedException{
            Callable<String> readTask = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return reader.readLine();
                }
            };

            Future<String> future = executor.submit(readTask);
            return future.get(timeout, TimeUnit.MILLISECONDS);
        }

        /**
         * Sends an initialization command to the remote process
         */
        public synchronized boolean initWolf(int wolf, int map_sz) {
            while(writer == null){
                try {
                this.sleep(0);
                }catch(Exception e){}
            }
            boolean success = false;
            try{
                writer.printf("S%02d%d\n", wolf, map_sz);
                writer.flush();
                String reply = getReply(5000l);
                if (reply != null && reply.length() >= 3 && reply.charAt(0) == 'K') {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        success = true;
                    }
                }
                if (reply == null) {
                    System.out.println("did not get reply");
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("SmartWolf %d failed to initialize, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("SmartWolf %d failed to initialize, %s\n", wolf, e.getMessage());
            }
            return success;
        }

        /**
         * Send an ATTACK command to the remote process.
         */
        public synchronized Attack fight(int wolf, char opponent) {
            Attack atk = Attack.SUICIDE;
            try{
                writer.printf("A%02d%c\n", wolf, opponent);
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'R':
                                atk = Attack.ROCK;
                                break;
                            case 'P':
                                atk = Attack.PAPER;
                                break;
                            case 'S':
                                atk = Attack.SCISSORS;
                                break;
                            case 'D':
                                atk = Attack.SUICIDE;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("SmartWolf %d failed to attack, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("SmartWolf %d failed to attack, %s\n", wolf, e.getMessage());
            }
            return atk;
        }

        /**
         * Send a MOVE command to the remote process.
         */
        public synchronized Move move(int wolf, char[][] map) {
            Move move = Move.HOLD;
            try{
                writer.printf("M%02d", wolf);
                for (int row=0; row<map.length; row++) {
                    for (int col=0; col<map[row].length; col++) {
                        writer.printf("%c", map[row][col]);
                    }
                }
                writer.print("\n");
                writer.flush();
                String reply = getReply(1000l);
                if (reply.length() >= 3) {
                    int id = Integer.valueOf(reply.substring(1));
                    if (wolf == id) {
                        switch(reply.charAt(0)) {
                            case 'H':
                                move = Move.HOLD;
                                break;
                            case 'U':
                                move = Move.UP;
                                break;
                            case 'L':
                                move = Move.LEFT;
                                break;
                            case 'R':
                                move = Move.RIGHT;
                                break;
                            case 'D':
                                move = Move.DOWN;
                                break;
                        }
                    }
                }
            } catch (TimeoutException ie) {
                endProcess();
                System.out.printf("SmartWolf %d failed to move, timeout\n", wolf);
            } catch (Exception e) {
                endProcess();
                System.out.printf("SmartWolf %d failed to move, %s\n", wolf, e.getMessage());
            }
            return move;
        }
    }
}

ඉහළ වෘකයන් කිහිප දෙනෙකු සමඟ පුනරාවර්තන 1000 ක් සඳහා ~ 75 පැවැත්මේ සාමාන්‍යය එතරම් විශාල නොවේ.

විසඳුම සඳහා ML ප්රවේශයක් භාවිතා කරයි.


ඔබේ වෘකයා කරන දේ දළ වශයෙන් මට වැටහී ඇතැයි මම සිතමි, නමුත් ඔබට එය වඩාත් විස්තරාත්මකව පැහැදිලි කළ හැකිද? එසේම එය කුමන භාෂාවද යන්න ඔබ සඳහන් කළ යුතුය (බොහෝ දෙනෙකුට එය පැහැදිලිව පෙනෙන නමුත් එය මට පැහැදිලිව පෙනෙන්නට නොතිබුණි).
plannapus

එය C # හි ලියා ඇති අතර දැනුම ලැයිස්තුවක් ඇත, එය එක්තරා ආකාරයක සතෙකුට එරෙහිව සිදු කර ඇති සෑම පියවරක්ම සහ එහි සාර්ථකත්ව අනුපාතය ලැයිස්තුගත කරයි. වෘකයෙකු පහර දී මිය ගිය විට, එම පියවරේ සාර්ථකත්ව වේගය අඩු වේ. එය ජීවත් වන්නේ නම්, සාර්ථකත්ව අනුපාතය වැඩි වේ. (20-30) වාර කිහිපයකට පසු අහඹු ලෙස තෝරා ගැනීම වෙනුවට පද්ධතිය දැනුම පදනමෙන් චලනයන් තෝරා ගැනීමට පටන් ගනී.
user3188175

1
ඔබ එතීම භාවිතා කිරීම ගැන සතුටුයි! ඔබේ කේතය සම්පාදනය කරන්නේ කෙසේද යන්න සහ monous රුෂර් භාවිතා කිරීමට කුමක් ද යන්න පිළිබඳ උපදෙස් ඔබ බොහෝ විට ඇතුළත් කළ යුතුය .
ProgrammerDan

1
සලකුණු කිරීම අසාර්ථකයි. ඔබ මූලාශ්‍රය දෙස බැලුවහොත්, '#' ඇත, නමුත් එය ශීර්ෂක කොටසක තිබූ බැවින් මාර්ක්ඩවුන් එය නොසලකා හැරියේය. ස්ථාවර. : D
ProgrammerDan

2
FYI - @ ProgrammerDan ගේ එතුම සමඟ එය සම්පාදනය කර සාර්ථකව ක්‍රියාත්මක කිරීමට මට හැකි විය (සහ ඔහුගේ උදව් නොමැතිව මෙවරද). ඔබ ඊළඟ ප්‍රති .ලවල සිටිනු ඇත. ප්රමාදය පිළිබඳ කනගාටුයි!
රේන්බෝල්ට්

7

උදාසීන-ආක්‍රමණශීලී වුල්ෆ් (පරිමාණ වෘකයෙක්)

පළමු හැරීම් 500 සඳහා හැකි සෑම දෙයක්ම වළක්වයි, එමඟින් ක්ෂේත්‍රය පැහැදිලි වේ. ඉන්පසු එය පවරා ඇති දිශාවට ගොස් එය පරාසය තුළට එන දේට පහර දෙයි.

package animals;

import animals._
import scala.util.Random

class PassiveAgressiveWolf extends Animal('W') {

    val myId=PassiveAgressiveWolf.nextId
    var movecounter=0

    def fight(opponent: Char) = {
        PassiveAgressiveWolf.lastopponents(myId-1)=opponent
        opponent match {
            case 'B' => Animal.Attack.SCISSORS
            case 'L' => Animal.Attack.SCISSORS
            case 'S' => Animal.Attack.ROCK
            case _ => Random.shuffle(List(Animal.Attack.SCISSORS, Animal.Attack.ROCK, Animal.Attack.PAPER)).head
        }
    }

    def move = {
        movecounter+=1
        if(movecounter < 500) avoidall else seen match {
            case ('B', pos: Int) => seenbear(pos)
            case ('S', pos: Int) => seenstone(pos)
            case ('L', pos: Int) => seenlion(pos)
            case ('W', pos: Int) => seenwolf(pos)
            case (' ', _) => myDirection
        }
    }

    def myDirection = myId % 4 match {
        case 0 => if(surroundings(0)(1)==' ') Animal.Move.LEFT else randommove
        case 1 => if(surroundings(1)(0)==' ') Animal.Move.DOWN else randommove
        case 2 => if(surroundings(1)(2)==' ') Animal.Move.RIGHT else randommove
        case 3 => if(surroundings(2)(1)==' ') Animal.Move.UP else randommove
    }

    def randommove = Random.shuffle(List(Animal.Move.UP, Animal.Move.LEFT, Animal.Move.RIGHT, Animal.Move.DOWN)).head

    def seen = {
        surroundings(1)(1)=' '
        val surroundingsflat=surroundings.flatten.mkString
        val seenbeasts = for {
            beast <- "BSLW" if surroundingsflat contains beast
        } yield (beast, surroundingsflat.indexOf(beast))
        seenbeasts.headOption.getOrElse((' ', 0))
    }

    def seenbear(pos: Int) = chase(pos)

    def seenstone(pos: Int) = pos match {
        case 1 => Animal.Move.LEFT
        case 3 => Animal.Move.UP
        case _ => myDirection
    }

    def seenlion(pos: Int) = pos match {
        case 1 => Animal.Move.LEFT
        case 3 => Animal.Move.UP
        case 5 => Animal.Move.HOLD
        case 7 => Animal.Move.HOLD
        case 0 => Animal.Move.UP
        case 2 => Animal.Move.HOLD
        case 6 => Animal.Move.HOLD
        case 8 => Animal.Move.HOLD
    }

    def seenwolf(pos: Int) = chase(pos)

    def chase(pos: Int) = pos match {
        case 1 => Animal.Move.UP
        case 3 => Animal.Move.LEFT
        case 5 => Animal.Move.RIGHT
        case 7 => Animal.Move.DOWN
        case 0 => Animal.Move.UP
        case 2 => Animal.Move.UP
        case 6 => Animal.Move.DOWN
        case 8 => Animal.Move.DOWN
    }

    def avoidall = {
        val safemoves = for {
            move <- List(
                            (0, 1, Animal.Move.UP), 
                            (1, 0, Animal.Move.LEFT), 
                            (1, 2, Animal.Move.RIGHT), 
                            (2, 1, Animal.Move.DOWN)
                        ) if(surroundings(move._1)(move._2)==' ')
        } yield move
        if(safemoves.length < 4) Random.shuffle(safemoves).head._3 else Animal.Move.HOLD
    }

}

object PassiveAgressiveWolf {
    private var id=0
    private def nextId = {id+=1; id}

    private var lastopponents=Array.fill[Char](100)(' ');
}

ජේවීඑම් පදනම් කරගත් භාෂාවක් ලෙස, ස්කලා සාපේක්ෂව පහසුවෙන් ඒකාබද්ධ කළ හැකිය.

ඔබ විසින්ම වැඩසටහන සම්පාදනය කරන්නේ නම්, පරිමාණ ගොනුව ජාවා .classගොනු සමඟ (ගොනු නොවේ .java) දමා භාවිතා කරන්න

scalac PassiveAggressiveWolf.scala

එය සම්පාදනය කිරීමට. ඔබට ජාවා පංති සමඟ මෙන් PassiveAggressiveWolf.classප්‍රධාන Wild.javaපන්තියේ භාවිතා කළ හැකිය . ඔබට scala-library.jarඔබේ පංති පථයටද එකතු කිරීමට අවශ්‍ය වනු ඇත (මම විධාන රේඛා විකල්පය භාවිතා කර ඇත -cp /path/to/scala-library.jar).

විකල්පයක් ලෙස, මම ජනනය කරන ලද පන්ති ලිපිගොනු සහ scala-library.jarස්කලා 2.10.3 සඳහා භාජනයක් උඩුගත කර ඇති අතර එමඟින් ඔබට ඒවා බාගත කළ හැකිය.

PassiveAggressiveWolf.jar
scala-library.jar


බාගත කිරීම පහසු කිරීම සඳහා ඔබට ගොනු 10 තනි සිප් ගොනුවකට ඇසුරුම් කළ හැකිය.
johnchen902

@ johnchen902 මගේ පන්ති අඩංගු කිරීම සඳහා භාජනයක් නිර්මාණය කරන ලෙස මට චැට් වලදී යෝජනා විය. මම අද සවස වැඩ කිරීමෙන් පසු ඒ ගැන සොයා බලමි. එය බාගත කිරීම් 2 ක් දක්වා අඩු කරනු ඇති අතර එය ඇතුළත් කිරීම සමඟ රුෂර්ට ඇති ගැටළු විසඳනු ඇත.
ගරෙත්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.