दोनों: हर कोई टोकन प्यार करता है


24

इस खेल में दो खिलाड़ी टोकन के लायक सबसे अधिक अंक खाने के लिए प्रतिस्पर्धा करते हैं, लेकिन एक मोड़ है! एक ही रंग की एक पंक्ति में कई टोकन खाने से एक कभी-बढ़ने वाला बोनस मिलता है, लेकिन बाहर देखो, या आपका प्रतिद्वंद्वी आपके द्वारा इच्छित टोकन खाने से पहले आपकी योजनाओं को विफल कर देगा!

नियम:

  • 1 बनाम 1
  • एन बोर्ड द्वारा (यादृच्छिक आकार 5x5 और 15x15 के बीच)
  • आप और आपका प्रतिद्वंद्वी एक ही यादृच्छिक सेल में स्पॉन करेंगे
  • बोर्ड में 1-3 से मूल्य वाले कुछ कोशिकाओं में यादृच्छिक रूप से उत्पन्न संख्या होगी
  • 2 * (बोर्ड की चौड़ाई) टोकन उत्पन्न होंगे, लेकिन ओवरराइड हो सकते हैं, इसलिए संयोग से कम हो सकता है।
  • प्रत्येक संख्या 3 रंगों में से एक होगी: लाल, हरा, या नीला, हेक्स आरजीबी प्रारूप में
  • प्रत्येक राउंड, खिलाड़ी 1 चलता है और बोर्ड अपडेट होता है, फिर खिलाड़ी 2 चलता है, और बोर्ड अपडेट किया जाता है। इसलिए प्रत्येक खिलाड़ी प्रभावी रूप से बता सकता है कि बोर्ड राज्य में परिवर्तन के आधार पर पिछले खिलाड़ी को क्या स्थानांतरित करना है। यह खेल समाप्त होने तक जारी रहता है, जैसा कि बाद में बताया गया है।
  • आपके पास एक मोड़ के लिए 6 संभावित क्रियाएं हैं: UP, RIGHT, DOWN, LEFT, EAT, और PASS
  • 4 चाल कमांड स्व-व्याख्यात्मक हैं, और आप अपनी बारी पारित कर सकते हैं। यदि आप एक निरर्थक कदम वापस करते हैं, तो हम मान लेंगे कि आप पास हैं। यदि आप बोर्ड के किनारे से हटने की कोशिश करते हैं, तो आप नहीं हटेंगे। किनारों लपेट नहीं है।
  • ईएटी उस संख्या का उपभोग करता है जो आप वर्तमान में उसी स्थान पर हैं
  • आप जितने अंक लेते हैं उतने अंक आप हासिल करते हैं
  • यदि आप एक ही रंग की पंक्ति में 2 नंबर खाते हैं, तो आपको +1 मिलता है
  • यदि आप एक ही रंग की एक पंक्ति में 3 नंबर खाते हैं, तो आपको +2 मिलता है
  • यदि आप एक ही रंग की एक पंक्ति में m नंबर खाते हैं, तो आपको + (m-1) मिलता है
  • इन बोनसों को संचयी रूप से जोड़ा जाता है, इसलिए एक पंक्ति में m नंबर प्राप्त करने से m * (m-1) / 2 कुल बोनस में होता है जब तक आप एक अलग रंग खाते हैं।
  • खेल समाप्ति की स्थिति:
    • सभी नंबरों की खपत होती है
    • 4 * (बोर्ड की चौड़ाई) बिना किसी प्रभावी खाने के साथ चली गई है (केवल ईएटी "बिना टोकन के साथ जहां आप गिनती नहीं करते हैं) या तो खिलाड़ी द्वारा घटित होता है (कोई भी टोकन 2 * (चौड़ाई) में उपलब्ध है चाल, इसलिए यह बाउंड केवल तभी पार किया जाएगा जब दोनों खिलाड़ियों के मन में एक भी लक्ष्य टोकन न हो)
  • आपके एआई को एक कदम बनाने में एक सेकंड से भी कम समय लगना चाहिए, अन्यथा पास को आपकी पसंद माना जाएगा।

टूर्नामेंट राउंड रॉबिन होगा जिसमें 100 या 1000 की एक बड़ी संख्या होगी। एक यादृच्छिक बोर्ड उत्पन्न होता है, और प्रत्येक क्रमबद्ध जोड़ीदार खिलाड़ी उस बोर्ड पर चलते हैं। टूर्नामेंट पूरा होने के बाद हम लोगों को उनके कुल स्कोर से रैंक देंगे। तो भले ही आप एक गेम के लिए खिलाड़ी 2 हैं, आपका लक्ष्य अभी भी अधिक से अधिक अंक प्राप्त करना है।

ऐ सबमिशन: मेरे नियंत्रक का समर्थन करने वाली भाषा जावास्क्रिप्ट है। एकाधिक प्रस्तुतियाँ की अनुमति है। हर कोई एक निर्माता को इस तरह से वस्तु के लिए प्रस्तुत करता है:

function (player1) {
    this.yourMove = function (b) {
        return "MOVE";
    }
}

इनपुट player1एक बूलियन कह रहा है कि आप खिलाड़ी 1 हैं या नहीं। आपके निर्माता के पास yourMoveफ़ंक्शन होना चाहिए , लेकिन इसमें किसी भी अतिरिक्त फ़ंक्शन या मान भी हो सकते हैं। किसी भी वैश्विक चर को परिभाषित न करें, बस उन्हें अपनी वस्तु पर चर के रूप में रखें। प्रत्येक मैच की शुरुआत में आपकी ऑब्जेक्ट का एक नया संस्करण बनाया जाएगा, और yourMoveउस पर कॉल किया जाएगा, वर्तमान बोर्ड के साथ इनपुट के रूप में, आपके प्रत्येक मोड़ पर, और एक वैध कदम वापस करना चाहिए।

b, इनपुट करने के लिए yourMove, वर्तमान बोर्ड की एक प्रति है, यहां निर्माणकर्ता हैं, इनपुट उदाहरणों के साथ, हालांकि आप उन्हें खुद नहीं कह सकते हैं:

function token(color, points) {
    this.color = color; //"#FF0000"
    this.points = points; //5
}

function player(pos, score, colorBonus, lastColor) {
    this.pos = pos; //[5, 5]
    this.score = score; //9
    this.colorBonus = colorBonus; //i.e. 2 if you just ate 3 blue tokens in a row
                                  //0 if you just ate two different colors.
    this.lastColor = lastColor; //"#00FF00", is "#000000" at start
}

function board(player1, player2, tokens) {
    this.player1 = player1; //new player([5, 5], 9, 2, "#00FF00")
    this.player2 = player2; //new player([5, 5], 9, 2, "#00FF00")
    this.tokens = tokens; //[[new token("#0000FF", 5), false],
                      // [new token("#0000FF", 5), false]]
}

टोकन सरणी में किसी भी खाली वर्ग के लिए "गलत" है, और टोकन [a] [b] x = a, y = b पर टोकन है, जिसे ऊपरी-बाएं कोने से शुरू किया गया है।

नियंत्रक: यहाँ GitHub में कंट्रोलर का लिंक दिया गया है। यह एक html फाइल है जिसे आप यह देखने के लिए चला सकते हैं कि गेम और राउंड-रॉबिन कैसे काम करता है, और यह दो AI के साथ आता है, एक यादृच्छिक एक जो एक यादृच्छिक दिशा में हर मोड़ पर चलता है लेकिन अपनी स्थिति पर टोकन खाता है, और एक भोली एल्गोरिथ्म है निकटतम टोकन के लिए जाता है जो सबसे अधिक अंक देता है। जैसे ही इसे सबमिट किया जाएगा, मैं प्रत्येक AI में जोड़ दूंगा।

नीचे एक स्निपेट है जो आपको डिफ़ॉल्ट AI पर नियंत्रक को चलाने की अनुमति देता है। वर्तमान एआई:

  • KindaRandomAI
  • NaiveAI
  • MirrorBot
  • HungryBot


12
हाँ, एक कोथ! यह पिछले एक के बाद से हमेशा के लिए है।
TheNumberOne

2
सहमत, मैं एक अच्छा कोठ से प्यार करता हूं और यह एक शानदार आधार है। मैं js के लिए थोड़ा हरा हूँ, अगर हम खिलाड़ी ऑब्जेक्ट के भीतर परिणाम नहीं बचा सकते हैं, तो एक चाल के बीच खेल की स्थिति कैसे बनी रहती है?
डॉक्टरहेकले

क्या बोर्ड की चौड़ाई समारोह में कहीं भी पारित की गई है?
TheNumberOne

@BentNeeHumor हां, player1बूलियन में होने वाला yourMoveफ़ंक्शन आपके AI के लिए कंस्ट्रक्टर है, जिसमें एक फ़ंक्शन होगा जो वर्तमान बोर्ड को इनपुट के रूप में लेता है, जैसा कि b
फ्रिकटिव मेलन

1
@DylanSp कभी-कभी उन्हें मिलीभगत की संभावनाओं के कारण अनुमति नहीं दी जाती है, लेकिन इस मामले में, मिलीभगत के न्यूनतम लाभ होंगे, इसलिए मैं कई प्रस्तुतियाँ की अनुमति दूंगा।
फ्रिकटिव मेलन

जवाबों:


4

HungryBot

प्रत्येक टोकन का पीछा करने के मूल्य में वजन जोड़ने के लिए एक बिंदु प्रणाली का उपयोग करता है। अपने विचार में विभिन्न प्रकार के विभिन्न कारकों का उपयोग करता है, और सर्वोत्तम रणनीति का पालन करने के लिए उन्हें पुन: निर्धारित करता है।

function hungryBot(first) {
  // Set up "self"
  var self = this;

  // Determine player order
  this.player = -(first - 2);
  this.enemy = first + 1;

  // Action associative array
  this.actions = ['EAT', 'LEFT', 'RIGHT', 'UP', 'DOWN'];

  //Logic handler
  this.yourMove = function(board) {
    // Determine player object
    var player = board['player' + self.player];
    var enemy = board['player' + self.enemy];

    // Point value action grid
    var actions = [0, 0, 0, 0, 0]; // Associative with "this.actions"

    // Board dimensions
    var size = board.tokens.length;
    var maxDist = size * 2;

    // Colors remaining
    var colors = {
      '#FF0000': 0,
      '#00FF00': 0,
      '#0000FF': 0
    };

    // Averaged value weight
    var average = [0, 0];

    // Total points
    var points = 0;

    // Token holder
    var tokens = [];

    // Token parser
    for (var i = 0, x = 0, y = 0; i < size * size; i += 1, x = i % size, y = i / size | 0) {
      if (!board.tokens[x][y]) {
        continue;
      } else {
        var token = {};
        token.points = board.tokens[x][y].points;
        token.color = board.tokens[x][y].color;
        token.x = x - player.pos[0];
        token.y = y - player.pos[1];
        token.distX = Math.abs(token.x);
        token.distY = Math.abs(token.y);
        token.dist = token.distX + token.distY;
        token.distE = Math.abs(x - enemy.pos[0]) + Math.abs(y - enemy.pos[1]);
        token.value = -token.points - (player.colorBonus + 1) * (token.color == player.lastColor) * ((token.dist == 0) + 1) * 1.618 - (enemy.colorBonus + 1) * (token.color == enemy.lastColor);
        tokens.push(token);
        colors[token.color] += 1;
        points += token.points;
        average[0] += x * token.points;
        average[1] += y * token.points;
      }
    }

    // Determine actual average
    average[0] = average[0] / points | 0;
    average[1] = average[1] / points | 0;

    // Pick best token
    var best = 0;

    // Calculate point values of tokens
    for (i = 0; i < tokens.length; i++) {
      var token = tokens[i];
      // Add remaining numbers of tokens of color as factor
      token.value -= (colors[token.color] / tokens.length) * 1.618;
      // Subtract distance as a factor
      token.value += token.dist;
      // Add distance to average to value
      token.value += (Math.abs(average[0] - (token.x + player.pos[0])) + Math.abs(average[1] - (token.y + player.pos[1]))) / Math.sqrt(2);
      // Consider them higher value if we are closer, and lower if they are
      token.value += ((token.dist - token.distE) / (token.dist + token.distE + 0.001)) * token.dist;
      // Don't go for it if enemy is already there
      token.value += (token.distE == 0 && token.dist > 0) * 100;

      if (tokens[best].value > tokens[i].value || (tokens[best].value === tokens[i].value && Math.round(Math.random()))) {
        best = i;
      }
    }

    // Set token to best token
    var token = tokens[best];

    // What to respond with
    var response = 'PASS';

    // Find best action to get token
    if (token.dist == 0) {
      response = 'EAT'; // We're on the token
    } else if (token.distX >= token.distY) { // Token is more horizontal
      if (token.x < 0) { // Token is left
        response = 'LEFT';
      } else if (token.x > 0) { // Token is right
        response = 'RIGHT';
      }
    } else if (token.distX < token.distY) { // Token is more vertical
      if (token.y < 0) { // Token is above
        response = 'UP';
      } else if (token.y > 0) { // Token is below
        response = 'DOWN';
      }
    }

    // Return response
    return response;
  }
};

क्या आप पायथन प्रोग्रामर हैं?
कैलक्यूलेटरफैलिन

@CatsAreFluffy सच में नहीं ...?
म्हारे 247

बस सोचा था कि आप self:) क्योंकि
कैलक्यूलेटरफ़लाइन

क्यों उपयोग करें self? thisपर्याप्त नहीं है ?
कॉनर ओ'ब्रायन

2

पाथ बॉट

एक्रोनिम का अर्थ Pathfinding And Tree Heuristics Bot है

EDIT: अभी तक, यहां एआई के लिए अंक के साथ रैंकिंग हैं

  1. HungryBot (6422)
  2. पथ बॉट (4591)
  3. नैवेय (3811)
  4. KindaRandomAI (618)
  5. मिररबॉट (193)
  6. LazyBot (25)

गिटहब पर पूर्ण नियंत्रक के लिए लिंक

विवरण: NaiveAI की तरह, यह बॉट निकटतम टोकन पाता है जो इसे सबसे अधिक अंक देगा। हालाँकि, यह अपने प्रत्येक चाल के परिणामों को 6 बार तक अनुकरण भी करता है।

Rationale: क्योंकि NaiveAI पहले से ही बहुत अच्छा है, हालांकि मैं इसे बेहतर बनाऊंगा। पहले कोड को देखे बिना (बड़ी गलती)।

बीट्स: हंग्रीबोट लूज को छोड़कर सभी: हंग्रीबोट
को छोड़कर कोई नहीं

समस्या का:

  • बढ़ी हुई लकीर का अनुकरण नहीं कर सकते
  • सर्वश्रेष्ठ टोकन की गणना करते समय लटका हुआ
  • टेलीपोर्ट कर सकते हैं

मुझे अभी भी पता नहीं है कि यह टेलीपोर्टिंग क्यों था, लेकिन मैंने इसे ठीक कर दिया। यहां पुराना वीडियो: https://youtu.be/BIhSKycF9iA

पूर्ण कोड:

pathBot = function (player1)
{
    this.pathNode = function(pos,ppt,parents,par)
    {
        this.pos = pos;this.ppt = ppt;this.parents = parents;this.par=par;
        this.childs=[];
    }
    this.addChildren = function (pn,children)
    {
        pn.childs=[];
        for(var i=0; i<children.length; i=i+1)
        {
            if(pn.parents.indexOf(children[i].pos)==-1&&pn.pos!=children[i].pos)
                pn.childs.push(
                    new this.pathNode(
                        children[i].pos,
                        children[i].ppt*pn.ppt,
                        pn.parents.concat([pn.pos]),
                        pn
                    )
                );
        }
    }
    this.orderTokensByPPT = function(b,pos){
        var tokens = [];
        for(var y=0; y<b.tokens.length; y=y+1)
        {
            for(var x=0; x<b.tokens[y].length; x=x+1)
            {
                var tok = b.tokens[y][x];
                if(tok)
                {
                    tokens.push(
                        new this.pathNode(
                            [y,x],
                            (tok.points+(tok.color==this.color ? this.streak : 0)) / this.lenOfMovesTo(pos,[y,x]),
                            [],
                            undefined
                        )
                    );
                }
            }
        }
        tokens.sort(function(a,b){
            return b.ppt - a.ppt;
        });
        return tokens;
    }
    this.lenOfMovesTo = function(cur,pos)
    {
        return Math.abs(cur[0]-pos[0])+Math.abs(cur[1]-pos[1])+1;
    }
    this.startAndGoalToCommand = function (start, goal) {
        var diff = [goal[0] - start[0], goal[1] - start[1]];
        if (diff[0] > 0) { return "RIGHT"; }
        else if (diff[1] > 0) { return "DOWN"; }
        else if (diff[1] < 0) { return "UP"; }
        else if (diff[0] < 0) { return "LEFT"; }
        else { return "EAT"; }
    }
    this.color = 0;
    this.streak = 0;
    this.eatTok = function(b)
    {
        if(b.tokens[this.me.pos[0]][this.me.pos[1]].color==this.color)
        {
            this.streak++;
        }
        else{
            this.streak = 0;
            this.color = b.tokens[this.me.pos[0]][this.me.pos[1]].color;
        }
        this.bestToken = false;
        return "EAT";
    }

    this.recurLen = 6;
    this.include = 4;
    this.recurDown = function(b,pn,level)
    {
        if(level==0) return pn;
        this.addChildren(pn,this.orderTokensByPPT(b,pn.pos));
        var newChilds = [];
        for(var i=0; i<pn.childs.length&&i<this.include; i=i+1)
        {
            newChilds.push(this.recurDown(b,pn.childs[i],level-1));
        }
        pn.childs = newChilds;
        return pn;
    }
    this.findMax = function(pn)
    {
        if(pn.childs)
        {
            var maxList = [];
            for(var i=0; i<pn.childs.length; i=i+1)
                maxList.push(this.findMax(pn.childs[i]));
            maxList.sort(
                function(a,b)
                {
                    return b.ppt-a.ppt;
                }
            );
            return maxList[0];
        }
        return pn;
    }
    this.findMaxList = function(pnList)
    {
        for(var i=0; i<pnList.lenght; i=i+1)
        {
            pnList[i] = this.findMax(pnList[i]);
        }
        pnList.sort(function(a,b){return b.ppt-a.ppt;});
        return pnList[0];
    }
    this.bestToken=false;
    this.yourMove = function(b){
        this.op = player1 ? b.player2 : b.player1;
        this.me = player1 ? b.player1 : b.player2;
        if(this.bestToken)
        {
            if(b.tokens[this.bestToken.pos[0]][this.bestToken.pos[1]]==undefined)
                this.bestToken = false;
        }
        if(!this.bestToken)
        {
            var paths = this.orderTokensByPPT(b,this.me.pos);
            for(var i=0; i<paths.length; i++)
            {
                paths[i] = this.recurDown(b,paths[i],this.recurLen);
            }
            var max = this.findMaxList(paths);
            while(max.par)
            {
                max = max.par;
            }
            this.bestToken = max;
        }
        var move = this.startAndGoalToCommand(this.me.pos,this.bestToken.pos);
        if(move=="EAT") return this.eatTok(b);
        else return move;
    }
}

SLaNTbot टर्न गति को धीमा कर रहा है, और मेरे CPU का 15% खा रहा है ... D: EDIT: और कुछ भी नहीं खा रहा है?
M24247

@ Mwr247 स्पीड, हाँ, यह मॉडल ~ 2500 संभावनाएं हर टिक। लेकिन खाने की चीज़ के लिए, मुझे नहीं पता कि क्यों। जैसा कि मैंने सवाल में कहा था, यह सिर्फ टेलीकास्ट करता है (उर्फ 1 बारी में कई जगह घूमता है), और वहाँ कुछ भी नहीं करता है। मैंने वापसी से ठीक पहले एक चेतावनी दी और यह हर बार सही निर्देश देता हुआ प्रतीत होता है।
ब्लू

शायद यह: "आपके एआई को एक कदम बनाने में एक सेकंड से भी कम समय लगना चाहिए, अन्यथा पास को आपकी पसंद माना जाएगा।" मैंने नियंत्रक को नहीं पढ़ा है, लेकिन अगर यह एक सेकंड से अधिक हो रहा है, तो क्या यह PASS मान रहा है?
22:24 पर Mwr247

@ Mwr247 मैं उस पर गौर करूंगा, लेकिन ऐसा लगता है कि यह संभावना नहीं है कि यह मेरी मशीन पर <1 सेकंड (या इसलिए मैं) ले रहा था। फिर भी, देखने के लिए कभी दर्द नहीं होता। धन्यवाद!
ब्लू

@ Mwr247 कुछ और परीक्षण के बाद, यह नहीं है। यह लगभग तेजी से (कम से कम मेरे लिए) नावी के रूप में निर्णय ले रहा है। इसके अलावा, आप बड़े मानचित्रों पर टेलीपोर्टेशन का अनुभव करने की अधिक संभावना रखते हैं
ब्लू

1

NaiveAI

से शुरू करें r=0, टेक्सी के साथ सभी टोकन rको अपनी स्थिति से दूर देखें। यदि कोई हो, तो उसे उठाएं जो आपको सबसे अधिक स्कोर देगा यदि आपने इसे अभी प्राप्त किया है। अन्यथा, r1 से बढ़ाएं और फिर से प्रयास करें।

naiveAI = function(player1) {
  this.player1 = player1;
  this.yourMove = function(b) {
    var me;
    if (this.player1) {
      me = b.player1;
    } else {
      me = b.player2;
    }
    var d = 0;
    var tokenP;
    while (tokenP == undefined) {
      var arr = this.findTokensAtDistance(me.pos, d)
      tokenP = this.findBestToken(arr, b.tokens, me);
      d += 1;
    }
    return this.startAndGoalToCommand(me.pos, tokenP);
  }
  this.findTokensAtDistance = function(p, d) {
    if (d == 0) {
      return [
        [p[0], p[1]]
      ];
    }
    var myArr = [];
    for (i = 0; i <= d; i++) {
      myArr[i] = [i, d - i];
    }
    var mySecArr = [];
    for (i = 0; i <= d; i++) {
      mySecArr[i] = [myArr[i][0] + p[0], myArr[i][1] + p[1]];
    }
    mySecArr[mySecArr.length] = [myArr[0][0] + p[0], -myArr[0][1] + p[1]];
    for (i = 1; i < myArr.length - 1; i++) {
      mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], myArr[i][1] + p[1]]
      mySecArr[mySecArr.length] = [myArr[i][0] + p[0], -myArr[i][1] + p[1]]
      mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], -myArr[i][1] + p[1]]
    }
    mySecArr[mySecArr.length] = [-myArr[myArr.length - 1][0] + p[0], myArr[myArr.length - 1][1] + p[1]];
    return mySecArr;
  }
  this.findBestToken = function(arr, t, player) {
    var tokenPos;
    for (i = 0; i < arr.length; i++) {
      if (arr[i][0] >= 0 && arr[i][0] < t.length && arr[i][1] >= 0 && arr[i][1] < t.length) {
        if (t[arr[i][0]][arr[i][1]] != false && ((tokenPos == undefined) || (this.tokenScore(player, t[arr[i][0]][arr[i][1]]) > this.tokenScore(player, t[tokenPos[0]][tokenPos[1]])))) {
          tokenPos = [arr[i][0],
            [arr[i][1]]
          ];
        }
      }
    }
    return tokenPos;
  }
  this.tokenScore = function(player, token) {
    if (player.lastColor == token.color) {
      return player.colorBonus + 1 + token.points;
    } else {
      return token.points;
    }
  }
  this.startAndGoalToCommand = function(start, goal) {
    var diff = [goal[0] - start[0], goal[1] - start[1]];
    if (diff[0] > 0) {
      return "RIGHT";
    } else if (diff[1] > 0) {
      return "DOWN";
    } else if (diff[1] < 0) {
      return "UP";
    } else if (diff[0] < 0) {
      return "LEFT";
    } else {
      return "EAT";
    }
  }
}

1

KindaRandomAI

हर मोड़, निम्नलिखित करें: यदि आपकी स्थिति में एक टोकन है, तो "ईएटी"। अन्यथा, एक यादृच्छिक व्यवहार्य दिशा में आगे बढ़ें, अर्थात यदि आप बाएं किनारे पर हैं तो "LEFT" न कहें।

kindaRandomAI = function(player1) {
    this.player1 = player1;
    this.yourMove = function(b) {
        var me;
        if (this.player1) {
            me = b.player1;
        } else {
            me = b.player2;
        }
        if (b.tokens[me.pos[0]][me.pos[1]] != false) {
            return "EAT";
        } else {
            var dirs = this.getViableDirections(b, me.pos);
            var rand = Math.floor(Math.random() * dirs.length);
            return dirs[rand];
        }
    }
    this.getViableDirections = function(b, p) {
        var dirs = [];
        if (p[0] > 0) {
            dirs.push("LEFT");
        }
        if (p[1] > 0) {
            dirs.push("UP");
        }
        if (p[1] < b.tokens.length - 1) {
            dirs.push("DOWN");
        }
        if (p[0] < b.tokens.length - 1) {
            dirs.push("RIGHT");
        }
        return dirs;
    }
}

-1 पूरी तरह से यादृच्छिक नहीं
CalculatorFeline

वह बेहतर है!।
कैलक्यूलेटरफैनलाइन

1

LazyBot

केवल कुछ खा लेता है अगर वह उस पर जासूसी करता है। इसके पास जीतने का कोई मौका नहीं है, लेकिन चुनौती के पास इनमें से एक भी नहीं है, इसलिए क्यों नहीं।

lazyBot = function (player1) {
    this.yourMove = function(b) {
        return "EAT";
    }
}

1
हर कोथ में एक EmoWolf है ...
ब्लू

3
@ लेकिन यह 100% भावनाएं नहीं है, यह खाने की कोशिश करता है।
बैलिंट


1

MirrorBot

कहा जाना चाहिए "तोप चारा"

विवरण: दूसरे खिलाड़ी ने जो किया उसके ठीक विपरीत चलता है

Rationale: मैं जेएस में फिर से आरामदायक प्रोग्रामिंग प्राप्त करना चाहता था। यह नहीं जीतना चाहिए

हरा देंगे: कोई नहीं

के लिए खो देंगे: हर कोई

function mirror(player1) {
    this.hasStarted=false;
    this.player1 = player1;
    this.opl=[0,0];
    this.yourMove = function(b){
        this.op = this.player1 ? b.player2.pos : b.player1.pos;
        out = "EAT";
        console.log(this.op);
        console.log(this.opl);
        if(this.hasStarted){
            if(this.opl[0] < this.op[0]) out = "RIGHT";
            if(this.opl[0] > this.op[0]) out = "LEFT";
            if(this.opl[1] < this.op[1]) out = "UP";
            if(this.opl[1] > this.op[1]) out = "DOWN";
        }
        this.opl = [this.op[0],this.op[1]];
        this.hasStarted = true;
        return out;
    }
}

आपके कोड में कुछ समस्याएं हैं। दाएं और बाएं विपरीत नहीं हैं, और आपकेMove के लिए आपकी फ़ंक्शन परिभाषा वैध सिंटैक्स नहीं है। मेरा कोड पहले भी टूटा हुआ था, इसलिए मेरे कोड में समस्या को खोजने और ठीक करने की प्रक्रिया में मैंने आपका कोड भी ठीक कर दिया। आप मेरी स्क्रिप्ट में निश्चित कोड देख सकते हैं।
फ्रिकेटिव मेलन

@FricativeMelon मैंने टूटी फंक्शन परिभाषा तय की। मुझे यह दावा करना होगा कि अधिकार विपरीत नहीं हैं।
ब्लू

0,0 शीर्ष-बाएं कोने है, इसलिए सकारात्मक x सही है और नकारात्मक x बाएं है। यदि नया x-pos पुराने x-pos के मान से अधिक है, तो दूसरा खिलाड़ी दाएं चला जाता है, इसलिए आपको बाईं ओर चलना चाहिए, और इसके विपरीत। इसके अलावा, आपको इसके var out = "EAT";बजाय का उपयोग करना चाहिए out = "EAT";, क्योंकि बाद में एक वैश्विक चर को परिभाषित करता है। थोडा थोडा करने पर, तीसरी और चौथी लाइन कुछ भी नहीं करती है और इसे हटाया भी जा सकता है, और एक संपत्ति के बजाय opएक स्थानीय चर हो सकता है out
फ्रिकेटिव मेलन

@FricativeMelon आह, मुझे वही मिल रहा है जो आप कह रहे हैं। मैंने कोड अपडेट कर दिया है। धन्यवाद!
ब्लू अप

मैंने आपका नया कोड स्क्रिप्ट में डाल दिया है, और यह अब काम कर रहा है। रैंडमएआई को नहीं हराते हैं :(
फ्रिकेटिव मेलन

0

OneTarget

एक टोकन प्राप्त करता है जो कम से कम समय में सबसे अधिक अंक देगा और उस एक के लिए जाएगा। संचयी प्रभाव के कारण समान रंग के टोकन थोड़ा अधिक ऊंचा हो जाता है।

function (player1) {
    this.yourMove = function (b) {
        var me = player1? b.player1: b.player2;
        var him= player1? b.player2: b.player1;
        var x = me.pos[0];
        var y = me.pos[1];
        var maxVal = -1;
        var maxX = 0;
        var maxY = 0;
        for(var i = 0;i < b.tokens.length;i++){
            for(var j = 0;j < b.tokens.length;j++){
                if(b.tokens[i][j]){
                    var dist = Math.abs(x-i) + Math.abs(y-j);
                    var val = this.valueOf(b.tokens[i][j]);
                    val /= (dist + 1);
                    if(val > maxVal){
                        maxVal = val;
                        maxX = i;
                        maxY = j;
                    }
                }
            }
        }
        if(maxY < y)
            return "UP";
        if(maxX < x)
            return "LEFT";
        if(maxY > y)
            return "DOWN";
        if(maxX > x)
            return "RIGHT";
        return "EAT";
    }
    this.valueOf = function(t){
        //how many points would it give you?
        return t.points + (this.lastColor == t.color? 2 * this.colorBonus + 1 : 0);
    }
}

0

QuantityPlayer

सभी QuantityPlayer के बारे में परवाह करता है कि वह डॉट्स का खाका है, न कि डॉट्स का मूल्य या रंग। वह जानता है कि भले ही सभी डॉट्स अलग-अलग हों, लेकिन उन्हें एक ही माना जाना चाहिए।

QuantityBot = function(playernum) {

this.dist = function(token) {
    return (Math.abs(token[0])+Math.abs(token[1]))
}

this.yourMove = function(game_board) {

    board_size = game_board.tokens.length
    board_area = board_size * board_size
    fete = board_size = size * 2

    token_list = []
    count = curr_x = curr_y = 0
    while(count < board_area) {
        if(game_board.tokens[x][y]) {
        token_list.push([x-player.pos[0],y-player.pos[1]])
        }
        count++; x = count % board_size; y = Math.floor(count / size)
    }

    closest_token = token_list[0]
    count = 1
    while(count < token_list.length) {
        curr_token = token_list[count]
        if(dist(curr_token) < dist(closest_token)){closest_token = curr_token}

        count++
    }

    if(dist(closest_token)==0){return 'EAT'}
    else{
    if(closest_token[0] >= closest_token[1]) {if(closest_token[0]<0) {return 'LEFT'} {return 'RIGHT'}}
    else{if(closest_token[1]<0) {return 'UP'} {return 'DOWN'}}
    }

}

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.