পাশা খেলা, কিন্তু 6 নম্বর এড়ানো [বন্ধ]


58

টুর্নামেন্ট শেষ!

টুর্নামেন্ট এখন শেষ! চূড়ান্ত সিমুলেশনটি রাতে চালানো হয়েছিল, মোট গেমস। বিজয়ী হলেন তার বট অপ্টফোর্ড 2 এক্স সহ খ্রিস্টান সিভারস । ক্রিশ্চিয়ান সিভারসও বিদ্রোহীর সাথে দ্বিতীয় স্থানটি সুরক্ষিত করতে সক্ষম হয়েছিল । অভিনন্দন! নীচে আপনি টুর্নামেন্টের জন্য সরকারী উচ্চ স্কোরের তালিকা দেখতে পাবেন।3108

আপনি যদি এখনও গেমটি খেলতে চান তবে নীচে পোস্ট করা নিয়ামকটি ব্যবহার করার জন্য এবং নিজের গেমটি তৈরি করতে এতে কোডটি ব্যবহার করার চেয়ে আপনাকে স্বাগত জানাতে হবে।

ছক্কা

আমাকে পাশা খেলা খেলতে আমন্ত্রণ জানানো হয়েছিল যা আমি কখনও শুনিনি। নিয়মগুলি সহজ ছিল, তবুও আমি মনে করি এটি কোনও কোট চ্যালেঞ্জের জন্য উপযুক্ত।

নিয়ম

খেলা শুরু

ডাইটি টেবিলের চারপাশে যায় এবং প্রতিবার এটি আপনার পালা, আপনি যতবার চান ডাইটিকে নিক্ষেপ করতে পারেন। তবে আপনাকে এটি একবারে ফেলে দিতে হবে। আপনি আপনার রাউন্ডের জন্য সমস্ত ছোঁড়ার যোগফলের উপর নজর রাখছেন। যদি আপনি থামতে চান, তবে রাউন্ডের জন্য স্কোরটি আপনার মোট স্কোরতে যুক্ত হবে।

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

বিজয়ী কে?

যখন টেবিলের চারপাশে প্রথম প্লেয়ার 40 পয়েন্ট বা তার বেশি পৌঁছায়, শেষ রাউন্ডটি শুরু হয়। একবার শেষ রাউন্ডটি শুরু হয়ে গেলে, শেষ রাউন্ডটি শুরু করা ব্যক্তি ব্যতীত প্রত্যেকেই আরও একবার ফিরে আসে।

শেষ রাউন্ডের নিয়মগুলি অন্য কোনও রাউন্ডের মতোই। আপনি নিক্ষেপ করা বা বন্ধ করতে পছন্দ করেন। যাইহোক, আপনি জানেন যে আপনি যদি শেষ রাউন্ডে থাকা আগের চেয়ে উচ্চতর স্কোর না পান তবে আপনার জয়ের কোনও সম্ভাবনা নেই। তবে আপনি যদি খুব বেশি দূরে যেতে থাকেন তবে আপনি 6 পেতে পারেন।

তবে, বিবেচনার জন্য আরও একটি নিয়ম রয়েছে। যদি আপনার বর্তমান মোট স্কোর (আপনার পূর্ববর্তী স্কোর + রাউন্ডের জন্য আপনার বর্তমান স্কোর) 40 বা ততোধিক হয়, এবং আপনি একটি 6 টি হিট করেন তবে আপনার মোট স্কোর 0 এ সেট করা আছে তার মানে আপনাকে পুরোটা শুরু করতে হবে। আপনার বর্তমান মোট স্কোর 40 বা তত বেশি হলে আপনি যদি 6 টি মারেন তবে খেলাটি এখন স্বাভাবিক হিসাবে চালিয়ে যায়, আপনি এখন শেষ স্থানে রয়েছেন। আপনার মোট স্কোরটি পুনরায় সেট করা হলে শেষ রাউন্ডটি ট্রিগার করা হয় না। আপনি এখনও রাউন্ডটি জিততে পারেন, তবে এটি আরও চ্যালেঞ্জিং হয়ে ওঠে।

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

একটি অতিরিক্ত নিয়ম হ'ল গেমটি সর্বোচ্চ 200 রাউন্ডের জন্য অব্যাহত থাকে। এটি হ'ল কেসগুলি প্রতিরোধ করার জন্য যেখানে একাধিক বটগুলি মূলত তাদের বর্তমান স্কোরটিতে থাকতে 6 টি আঘাত না করা পর্যন্ত ছোঁড়া চালিয়ে যায়। ১৯৯ তম রাউন্ডটি শেষ হয়ে গেলে, last_roundসত্যে সেট হয়ে যায় এবং আরও একটি রাউন্ড খেলা হয়। যদি গেমটি 200 টি রাউন্ডে যায়, তবে সর্বোচ্চ স্কোর সহ বট (বা বটস) বিজয়ী হয়, তাদের 40 পয়েন্ট বা তার বেশি না থাকলেও।

সংক্ষিপ্তবৃত্তি

  • যতক্ষণ না আপনি থামতে চান বা আপনি একটি 6 পান না হওয়া পর্যন্ত প্রতিটি রাউন্ডে আপনি ডাই ছুঁড়তে থাকেন
  • আপনাকে অবশ্যই একবার মরতে হবে (যদি আপনার প্রথম ছোঁড়া is হয়, আপনার রাউন্ডটি অবিলম্বে শেষ হয়ে যাবে)
  • যদি আপনি 6 পেয়ে থাকেন তবে আপনার বর্তমান স্কোর 0 তে সেট করা হয়েছে (আপনার মোট স্কোর নয়)
  • আপনি প্রতিটি রাউন্ড পরে আপনার মোট স্কোর আপনার বর্তমান স্কোর যোগ করুন
  • যখন কোনও বট তাদের পালা শেষ করে যার ফলাফল সর্বনিম্ন কমপক্ষে 40 এর স্কোর, অন্য প্রত্যেকে শেষ বারে
  • যদি আপনার বর্তমান মোট স্কোর এবং আপনি 6 পেয়ে থাকেন তবে আপনার মোট স্কোর 0 তে সেট করা আছে এবং আপনার রাউন্ডটি শেষ হয়েছে40
  • যখন উপরেরটি ঘটে তখন শেষ রাউন্ডটি ট্রিগার করা হয় না
  • শেষ রাউন্ডের পরে সর্বোচ্চ স্কোর প্রাপ্ত ব্যক্তিটিই বিজয়ী
  • যদি একাধিক বিজয়ী থাকে তবে সমস্তগুলি বিজয়ী হিসাবে গণ্য হবে
  • গেমটি সর্বোচ্চ 200 রাউন্ডের জন্য স্থায়ী হয়

স্কোর স্পষ্টকরণ

  • মোট স্কোর: আপনি আগের রাউন্ডগুলি থেকে সংরক্ষণ করেছেন এমন স্কোর
  • বর্তমান স্কোর: বর্তমান রাউন্ডের জন্য স্কোর
  • বর্তমান মোট স্কোর: উপরের দুটি স্কোরের যোগফল

আপনি কিভাবে অংশগ্রহণ করবেন

এই কোটএইচ চ্যালেঞ্জে অংশ নিতে আপনার উত্তরাধিকার সূত্রে পাইথন ক্লাস লিখতে হবে Bot। আপনি ফাংশন বাস্তবায়ন করা উচিত: make_throw(self, scores, last_round)। আপনার পালা হয়ে গেলে সেই ফাংশনটি ডাকা হবে এবং আপনার প্রথম নিক্ষেপ 6 নয় throw নিক্ষেপ চালিয়ে যাওয়ার জন্য আপনার উচিত yield True। নিক্ষেপ বন্ধ করার জন্য, আপনার উচিত yield False। প্রতিটি নিক্ষেপ করার পরে, প্যারেন্ট ফাংশন update_stateবলা হয়। এইভাবে, চলকটি ব্যবহার করে আপনার বর্তমান রাউন্ডের জন্য আপনার ছোঁড়ার প্রবেশাধিকার রয়েছে self.current_throws। ব্যবহার করে আপনার নিজস্ব সূচীতে অ্যাক্সেসও রয়েছে self.index। সুতরাং, আপনার নিজের মোট স্কোরটি ব্যবহার করতে হবে scores[self.index]। আপনি end_scoreব্যবহার করে গেমের জন্যও অ্যাক্সেস self.end_scoreকরতে পারেন তবে আপনি নিরাপদে ধরে নিতে পারেন যে এই চ্যালেঞ্জটির জন্য এটি 40 হবে।

আপনি আপনার শ্রেণীর ভিতরে সহায়ক ফাংশন তৈরি করার অনুমতি দেওয়া হয়। আপনি Botপ্যারেন্ট ক্লাসে বিদ্যমান ফাংশনগুলি ওভাররাইড করতে পারেন , উদাহরণস্বরূপ যদি আপনি আরও শ্রেণীর বৈশিষ্ট্য যুক্ত করতে চান। ফলনযোগ্য Trueবা বাদ দিয়ে কোনওভাবেই আপনাকে গেমের অবস্থা পরিবর্তন করার অনুমতি নেই False

আপনি এই পোস্ট থেকে অনুপ্রেরণা পেতে এবং আমি এখানে অন্তর্ভুক্ত দুটি বট যে কোনও অনুলিপি করতে পারেন। তবে আমি আশঙ্কা করছি যে তারা বিশেষ কার্যকর নয় ...

অন্যান্য ভাষাগুলির অনুমতি দেওয়ার ক্ষেত্রে

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

আপনার যে কোনও প্রশ্নের জন্য, আপনি এই চ্যালেঞ্জের জন্য চ্যাট রুমে লিখতে পারেন । দেখা হবে!

বিধি

  • সাবোটেজ অনুমোদিত, এবং উত্সাহিত। অর্থাৎ অন্যান্য খেলোয়াড়দের বিরুদ্ধে নাশকতা
  • নিয়ামক, রান-টাইম বা অন্যান্য সাবমিশনগুলির সাথে টিঙ্কার করার যে কোনও প্রয়াস অযোগ্য ঘোষণা করা হবে। সমস্ত সাবমিশনগুলি কেবলমাত্র প্রদত্ত ইনপুট এবং স্টোরেজগুলির সাথে কাজ করা উচিত।
  • যে কোনও বট তার সিদ্ধান্ত নিতে 500 এমবি মেমরির বেশি ব্যবহার করে তাকে অযোগ্য ঘোষণা করা হবে (আপনার যদি এত বেশি মেমরির প্রয়োজন হয় তবে আপনার পছন্দগুলি নিয়ে পুনর্বিবেচনা করা উচিত)
  • একটি বট ইচ্ছাকৃতভাবে বা দুর্ঘটনাক্রমে কোনও বিদ্যমান কৌশল হিসাবে ঠিক একই কৌশলটি প্রয়োগ করতে পারে না।
  • চ্যালেঞ্জের সময় আপনাকে আপনার বট আপডেট করার অনুমতি দেওয়া হয়। তবে আপনার দৃষ্টিভঙ্গি আলাদা হলে আপনি অন্য একটি বটও পোস্ট করতে পারেন।

উদাহরণ

class GoToTenBot(Bot):
    def make_throw(self, scores, last_round):
        while sum(self.current_throws) < 10:
            yield True
        yield False

রাউন্ডের জন্য কমপক্ষে 10 স্কোর না হওয়া পর্যন্ত এই বটটি চলতে থাকবে, বা এটি 6 নিক্ষেপ করবে Note. নোট করুন যে ছোঁড়াটি পরিচালনা করার জন্য আপনার কোনও যুক্তির প্রয়োজন নেই Also. এছাড়াও মনে রাখবেন যে আপনার প্রথম থ্রোটি যদি 6 make_throwহয় তবে এটি হয় কখনই ডাকা হয় নি, যেহেতু আপনার বৃত্তান্ত অবিলম্বে শেষ হয়ে গেছে।

যারা পাইথনে নতুন (এবং ধারণাটিতে নতুন yield), কিন্তু এটিকে একবার দেখতে চান, মূল yieldশব্দটি কিছু উপায়ে ফেরতের অনুরূপ, তবে অন্য উপায়ে আলাদা। আপনি ধারণা সম্পর্কে এখানে পড়তে পারেন । মূলত, একবার আপনি yield, আপনার ফাংশন বন্ধ হয়ে যাবে, এবং আপনি যে মানটি yieldসম্পাদনা করেছেন তা নিয়ামকের কাছে ফিরে পাঠানো হবে। আপনার বটকে অন্য কোনও সিদ্ধান্ত নেওয়ার সময় না আসা পর্যন্ত নিয়ামক তার যুক্তিটি পরিচালনা করে। তারপরে কন্ট্রোলার আপনাকে ডাইস থ্রো প্রেরণ করে এবং আপনার make_throwফাংশনটি ঠিক পূর্ববর্তী yieldবক্তব্যের পরে লাইনে থাকলে আগে থামানো থাকলে চালানো চালিয়ে যাবে ।

এইভাবে, গেম নিয়ামক প্রতিটি ডাইস নিক্ষেপের জন্য আলাদা বট ফাংশন কলের প্রয়োজন ছাড়াই রাষ্ট্র আপডেট করতে পারে।

সবিস্তার বিবরণী

আপনি যে কোনও পাইথন লাইব্রেরি উপলভ্য ব্যবহার করতে পারেন pip। আমি একটি ভাল গড় অর্জন করতে সক্ষম হবো তা নিশ্চিত করতে আপনার কাছে প্রতি রাউন্ডে 100 মিলিসেকেন্ড সময়সীমা রয়েছে। আপনার স্ক্রিপ্টটি যদি এর চেয়ে দ্রুততর হয় তবে আমি সত্যিই খুশি হব, যাতে আমি আরও চক্র চালাতে পারি।

মূল্যায়ন

বিজয়ী সন্ধানের জন্য, আমি সমস্ত বট নেব এবং এগুলিকে 8 এর এলোমেলো গ্রুপে চালাব, যদি এখানে 8 টিরও কম শ্রেণি জমা দেওয়া হয় তবে আমি প্রতিটি রাউন্ডে সবসময় সব বট না এড়াতে তাদের 4 টি এলোমেলো গ্রুপে চালাব। আমি প্রায় 8 ঘন্টা সিমুলেশন চালাব, এবং বিজয়ী সর্বোচ্চ জয় শতাংশ সহ বট হবে ot আমি 2019 এর শুরুতে চূড়ান্ত সিমুলেশনগুলি শুরু করব, যা আপনাকে সমস্ত ক্রিসমাস আপনার বটগুলিতে কোড করে দেয়! প্রাথমিক চূড়ান্ত তারিখটি 4 জানুয়ারী, তবে যদি খুব অল্প সময় হয় তবে আমি এটিকে পরবর্তী তারিখে পরিবর্তন করতে পারি।

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

নিজেই পরীক্ষা করে দেখুন

আপনি যদি নিজের সিমুলেশনগুলি চালাতে চান, তবে দুটি উদাহরণ বট সহ, সিমুলেশন চালানো নিয়ন্ত্রকের পুরো কোডটি এখানে।

নিয়ামক

এই চ্যালেঞ্জের জন্য আপডেট করা নিয়ামক এখানে। এটি এএনএসআই আউটপুট, মাল্টি-থ্রেডিং সমর্থন করে এবং একে্রেলের জন্য অতিরিক্ত পরিসংখ্যান সংগ্রহ করার জন্য সংগ্রহ করে ! আমি যখন নিয়ামকটিতে পরিবর্তন করি, ডকুমেন্টেশন সম্পূর্ণ হয়ে গেলে আমি পোস্টটি আপডেট করব।

বিএমওকে ধন্যবাদ , নিয়ন্ত্রণকারী এখন -dপতাকাটি ব্যবহার করে এই পোস্ট থেকে সমস্ত বট ডাউনলোড করতে সক্ষম । অন্যান্য কার্যকারিতা এই সংস্করণে অপরিবর্তিত। এটি নিশ্চিত হওয়া উচিত যে আপনার সর্বশেষ পরিবর্তনগুলি যত তাড়াতাড়ি সম্ভব সিমুলেটেড!

#!/usr/bin/env python3
import re
import json
import math
import random
import requests
import sys
import time
from numpy import cumsum

from collections import defaultdict
from html import unescape
from lxml import html
from multiprocessing import Pool
from os import path, rename, remove
from sys import stderr
from time import strftime

# If you want to see what each bot decides, set this to true
# Should only be used with one thread and one game
DEBUG = False
# If your terminal supports ANSI, try setting this to true
ANSI = False
# File to keep base class and own bots
OWN_FILE = 'forty_game_bots.py'
# File where to store the downloaded bots
AUTO_FILE = 'auto_bots.py'
# If you want to use up all your quota & re-download all bots
DOWNLOAD = False
# If you want to ignore a specific user's bots (eg. your own bots): add to list
IGNORE = []
# The API-request to get all the bots
URL = "https://api.stackexchange.com/2.2/questions/177765/answers?page=%s&pagesize=100&order=desc&sort=creation&site=codegolf&filter=!bLf7Wx_BfZlJ7X"


def print_str(x, y, string):
    print("\033["+str(y)+";"+str(x)+"H"+string, end = "", flush = True)

class bcolors:
    WHITE = '\033[0m'
    GREEN = '\033[92m'
    BLUE = '\033[94m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    ENDC = '\033[0m'

# Class for handling the game logic and relaying information to the bots
class Controller:

    def __init__(self, bots_per_game, games, bots, thread_id):
        """Initiates all fields relevant to the simulation

        Keyword arguments:
        bots_per_game -- the number of bots that should be included in a game
        games -- the number of games that should be simulated
        bots -- a list of all available bot classes
        """
        self.bots_per_game = bots_per_game
        self.games = games
        self.bots = bots
        self.number_of_bots = len(self.bots)
        self.wins = defaultdict(int)
        self.played_games = defaultdict(int)
        self.bot_timings = defaultdict(float)
        # self.wins = {bot.__name__: 0 for bot in self.bots}
        # self.played_games = {bot.__name__: 0 for bot in self.bots}
        self.end_score = 40
        self.thread_id = thread_id
        self.max_rounds = 200
        self.timed_out_games = 0
        self.tied_games = 0
        self.total_rounds = 0
        self.highest_round = 0
        #max, avg, avg_win, throws, success, rounds
        self.highscore = defaultdict(lambda:[0, 0, 0, 0, 0, 0])
        self.winning_scores = defaultdict(int)
        # self.highscore = {bot.__name__: [0, 0, 0] for bot in self.bots}

    # Returns a fair dice throw
    def throw_die(self):
        return random.randint(1,6)
    # Print the current game number without newline
    def print_progress(self, progress):
        length = 50
        filled = int(progress*length)
        fill = "="*filled
        space = " "*(length-filled)
        perc = int(100*progress)
        if ANSI:
            col = [
                bcolors.RED, 
                bcolors.YELLOW, 
                bcolors.WHITE, 
                bcolors.BLUE, 
                bcolors.GREEN
            ][int(progress*4)]

            end = bcolors.ENDC
            print_str(5, 8 + self.thread_id, 
                "\t%s[%s%s] %3d%%%s" % (col, fill, space, perc, end)
            )
        else:
            print(
                "\r\t[%s%s] %3d%%" % (fill, space, perc),
                flush = True, 
                end = ""
            )

    # Handles selecting bots for each game, and counting how many times
    # each bot has participated in a game
    def simulate_games(self):
        for game in range(self.games):
            if self.games > 100:
                if game % (self.games // 100) == 0 and not DEBUG:
                    if self.thread_id == 0 or ANSI:
                        progress = (game+1) / self.games
                        self.print_progress(progress)
            game_bot_indices = random.sample(
                range(self.number_of_bots), 
                self.bots_per_game
            )

            game_bots = [None for _ in range(self.bots_per_game)]
            for i, bot_index in enumerate(game_bot_indices):
                self.played_games[self.bots[bot_index].__name__] += 1
                game_bots[i] = self.bots[bot_index](i, self.end_score)

            self.play(game_bots)
        if not DEBUG and (ANSI or self.thread_id == 0):
            self.print_progress(1)

        self.collect_results()

    def play(self, game_bots):
        """Simulates a single game between the bots present in game_bots

        Keyword arguments:
        game_bots -- A list of instantiated bot objects for the game
        """
        last_round = False
        last_round_initiator = -1
        round_number = 0
        game_scores = [0 for _ in range(self.bots_per_game)]


        # continue until one bot has reached end_score points
        while not last_round:
            for index, bot in enumerate(game_bots):
                t0 = time.clock()
                self.single_bot(index, bot, game_scores, last_round)
                t1 = time.clock()
                self.bot_timings[bot.__class__.__name__] += t1-t0

                if game_scores[index] >= self.end_score and not last_round:
                    last_round = True
                    last_round_initiator = index
            round_number += 1

            # maximum of 200 rounds per game
            if round_number > self.max_rounds - 1:
                last_round = True
                self.timed_out_games += 1
                # this ensures that everyone gets their last turn
                last_round_initiator = self.bots_per_game

        # make sure that all bots get their last round
        for index, bot in enumerate(game_bots[:last_round_initiator]):
            t0 = time.clock()
            self.single_bot(index, bot, game_scores, last_round)
            t1 = time.clock()
            self.bot_timings[bot.__class__.__name__] += t1-t0

        # calculate which bots have the highest score
        max_score = max(game_scores)
        nr_of_winners = 0
        for i in range(self.bots_per_game):
            bot_name = game_bots[i].__class__.__name__
            # average score per bot
            self.highscore[bot_name][1] += game_scores[i]
            if self.highscore[bot_name][0] < game_scores[i]:
                # maximum score per bot
                self.highscore[bot_name][0] = game_scores[i]
            if game_scores[i] == max_score:
                # average winning score per bot
                self.highscore[bot_name][2] += game_scores[i]
                nr_of_winners += 1
                self.wins[bot_name] += 1
        if nr_of_winners > 1:
            self.tied_games += 1
        self.total_rounds += round_number
        self.highest_round = max(self.highest_round, round_number)
        self.winning_scores[max_score] += 1

    def single_bot(self, index, bot, game_scores, last_round):
        """Simulates a single round for one bot

        Keyword arguments:
        index -- The player index of the bot (e.g. 0 if the bot goes first)
        bot -- The bot object about to be simulated
        game_scores -- A list of ints containing the scores of all players
        last_round -- Boolean describing whether it is currently the last round
        """

        current_throws = [self.throw_die()]
        if current_throws[-1] != 6:

            bot.update_state(current_throws[:])
            for throw in bot.make_throw(game_scores[:], last_round):
                # send the last die cast to the bot
                if not throw:
                    break
                current_throws.append(self.throw_die())
                if current_throws[-1] == 6:
                    break
                bot.update_state(current_throws[:])

        if current_throws[-1] == 6:
            # reset total score if running total is above end_score
            if game_scores[index] + sum(current_throws) - 6 >= self.end_score:
                game_scores[index] = 0
        else:
            # add to total score if no 6 is cast
            game_scores[index] += sum(current_throws)

        if DEBUG:
            desc = "%d: Bot %24s plays %40s with " + \
            "scores %30s and last round == %5s"
            print(desc % (index, bot.__class__.__name__, 
                current_throws, game_scores, last_round))

        bot_name = bot.__class__.__name__
        # average throws per round
        self.highscore[bot_name][3] += len(current_throws)
        # average success rate per round
        self.highscore[bot_name][4] += int(current_throws[-1] != 6)
        # total number of rounds
        self.highscore[bot_name][5] += 1


    # Collects all stats for the thread, so they can be summed up later
    def collect_results(self):
        self.bot_stats = {
            bot.__name__: [
                self.wins[bot.__name__],
                self.played_games[bot.__name__],
                self.highscore[bot.__name__]
            ]
        for bot in self.bots}


# 
def print_results(total_bot_stats, total_game_stats, elapsed_time):
    """Print the high score after the simulation

    Keyword arguments:
    total_bot_stats -- A list containing the winning stats for each thread
    total_game_stats -- A list containing controller stats for each thread
    elapsed_time -- The number of seconds that it took to run the simulation
    """

    # Find the name of each bot, the number of wins, the number
    # of played games, and the win percentage
    wins = defaultdict(int)
    played_games = defaultdict(int)
    highscores = defaultdict(lambda: [0, 0, 0, 0, 0, 0])
    bots = set()
    timed_out_games = sum(s[0] for s in total_game_stats)
    tied_games = sum(s[1] for s in total_game_stats)
    total_games = sum(s[2] for s in total_game_stats)
    total_rounds = sum(s[4] for s in total_game_stats)
    highest_round = max(s[5] for s in total_game_stats)
    average_rounds = total_rounds / total_games
    winning_scores = defaultdict(int)
    bot_timings = defaultdict(float)

    for stats in total_game_stats:
        for score, count in stats[6].items():
            winning_scores[score] += count
    percentiles = calculate_percentiles(winning_scores, total_games)


    for thread in total_bot_stats:
        for bot, stats in thread.items():
            wins[bot] += stats[0]
            played_games[bot] += stats[1]

            highscores[bot][0] = max(highscores[bot][0], stats[2][0])       
            for i in range(1, 6):
                highscores[bot][i] += stats[2][i]
            bots.add(bot)

    for bot in bots:
        bot_timings[bot] += sum(s[3][bot] for s in total_game_stats)

    bot_stats = [[bot, wins[bot], played_games[bot], 0] for bot in bots]

    for i, bot in enumerate(bot_stats):
        bot[3] = 100 * bot[1] / bot[2] if bot[2] > 0 else 0
        bot_stats[i] = tuple(bot)

    # Sort the bots by their winning percentage
    sorted_scores = sorted(bot_stats, key=lambda x: x[3], reverse=True)
    # Find the longest class name for any bot
    max_len = max([len(b[0]) for b in bot_stats])

    # Print the highscore list
    if ANSI:
        print_str(0, 9 + threads, "")
    else:
        print("\n")


    sim_msg = "\tSimulation or %d games between %d bots " + \
        "completed in %.1f seconds"
    print(sim_msg % (total_games, len(bots), elapsed_time))
    print("\tEach game lasted for an average of %.2f rounds" % average_rounds)
    print("\t%d games were tied between two or more bots" % tied_games)
    print("\t%d games ran until the round limit, highest round was %d\n"
        % (timed_out_games, highest_round))

    print_bot_stats(sorted_scores, max_len, highscores)
    print_score_percentiles(percentiles)
    print_time_stats(bot_timings, max_len)

def calculate_percentiles(winning_scores, total_games):
    percentile_bins = 10000
    percentiles = [0 for _ in range(percentile_bins)]
    sorted_keys = list(sorted(winning_scores.keys()))
    sorted_values = [winning_scores[key] for key in sorted_keys]
    cumsum_values = list(cumsum(sorted_values))
    i = 0

    for perc in range(percentile_bins):
        while cumsum_values[i] < total_games * (perc+1) / percentile_bins:
            i += 1
        percentiles[perc] = sorted_keys[i] 
    return percentiles

def print_score_percentiles(percentiles):
    n = len(percentiles)
    show = [.5, .75, .9, .95, .99, .999, .9999]
    print("\t+----------+-----+")
    print("\t|Percentile|Score|")
    print("\t+----------+-----+")
    for p in show:
        print("\t|%10.2f|%5d|" % (100*p, percentiles[int(p*n)]))
    print("\t+----------+-----+")
    print()


def print_bot_stats(sorted_scores, max_len, highscores):
    """Print the stats for the bots

    Keyword arguments:
    sorted_scores -- A list containing the bots in sorted order
    max_len -- The maximum name length for all bots
    highscores -- A dict with additional stats for each bot
    """
    delimiter_format = "\t+%s%s+%s+%s+%s+%s+%s+%s+%s+%s+"
    delimiter_args = ("-"*(max_len), "", "-"*4, "-"*8, 
        "-"*8, "-"*6, "-"*6, "-"*7, "-"*6, "-"*8)
    delimiter_str = delimiter_format % delimiter_args
    print(delimiter_str)
    print("\t|%s%s|%4s|%8s|%8s|%6s|%6s|%7s|%6s|%8s|" 
        % ("Bot", " "*(max_len-3), "Win%", "Wins", 
            "Played", "Max", "Avg", "Avg win", "Throws", "Success%"))
    print(delimiter_str)

    for bot, wins, played, score in sorted_scores:
        highscore = highscores[bot]
        bot_max_score = highscore[0]
        bot_avg_score = highscore[1] / played
        bot_avg_win_score = highscore[2] / max(1, wins)
        bot_avg_throws = highscore[3] / highscore[5]
        bot_success_rate = 100 * highscore[4] / highscore[5]

        space_fill = " "*(max_len-len(bot))
        format_str = "\t|%s%s|%4.1f|%8d|%8d|%6d|%6.2f|%7.2f|%6.2f|%8.2f|"
        format_arguments = (bot, space_fill, score, wins, 
            played, bot_max_score, bot_avg_score,
            bot_avg_win_score, bot_avg_throws, bot_success_rate)
        print(format_str % format_arguments)

    print(delimiter_str)
    print()

def print_time_stats(bot_timings, max_len):
    """Print the execution time for all bots

    Keyword arguments:
    bot_timings -- A dict containing information about timings for each bot
    max_len -- The maximum name length for all bots
    """
    total_time = sum(bot_timings.values())
    sorted_times = sorted(bot_timings.items(), 
        key=lambda x: x[1], reverse = True)

    delimiter_format = "\t+%s+%s+%s+"
    delimiter_args = ("-"*(max_len), "-"*7, "-"*5)
    delimiter_str = delimiter_format % delimiter_args
    print(delimiter_str)

    print("\t|%s%s|%7s|%5s|" % ("Bot", " "*(max_len-3), "Time", "Time%"))
    print(delimiter_str)
    for bot, bot_time in sorted_times:
        space_fill = " "*(max_len-len(bot))
        perc = 100 * bot_time / total_time
        print("\t|%s%s|%7.2f|%5.1f|" % (bot, space_fill, bot_time, perc))
    print(delimiter_str)
    print() 


def run_simulation(thread_id, bots_per_game, games_per_thread, bots):
    """Used by multithreading to run the simulation in parallel

    Keyword arguments:
    thread_id -- A unique identifier for each thread, starting at 0
    bots_per_game -- How many bots should participate in each game
    games_per_thread -- The number of games to be simulated
    bots -- A list of all bot classes available
    """
    try:
        controller = Controller(bots_per_game, 
            games_per_thread, bots, thread_id)
        controller.simulate_games()
        controller_stats = (
            controller.timed_out_games,
            controller.tied_games,
            controller.games,
            controller.bot_timings,
            controller.total_rounds,
            controller.highest_round,
            controller.winning_scores
        )
        return (controller.bot_stats, controller_stats)
    except KeyboardInterrupt:
        return {}


# Prints the help for the script
def print_help():
    print("\nThis is the controller for the PPCG KotH challenge " + \
        "'A game of dice, but avoid number 6'")
    print("For any question, send a message to maxb\n")
    print("Usage: python %s [OPTIONS]" % sys.argv[0])
    print("\n  -n\t\tthe number of games to simluate")
    print("  -b\t\tthe number of bots per round")
    print("  -t\t\tthe number of threads")
    print("  -d\t--download\tdownload all bots from codegolf.SE")
    print("  -A\t--ansi\trun in ANSI mode, with prettier printing")
    print("  -D\t--debug\trun in debug mode. Sets to 1 thread, 1 game")
    print("  -h\t--help\tshow this help\n")

# Make a stack-API request for the n-th page
def req(n):
    req = requests.get(URL % n)
    req.raise_for_status()
    return req.json()

# Pull all the answers via the stack-API
def get_answers():
    n = 1
    api_ans = req(n)
    answers = api_ans['items']
    while api_ans['has_more']:
        n += 1
        if api_ans['quota_remaining']:
            api_ans = req(n)
            answers += api_ans['items']
        else:
            break

    m, r = api_ans['quota_max'], api_ans['quota_remaining']
    if 0.1 * m > r:
        print(" > [WARN]: only %s/%s API-requests remaining!" % (r,m), file=stderr)

    return answers


def download_players():
    players = {}

    for ans in get_answers():
        name = unescape(ans['owner']['display_name'])
        bots = []

        root = html.fromstring('<body>%s</body>' % ans['body'])
        for el in root.findall('.//code'):
            code = el.text
            if re.search(r'^class \w+\(\w*Bot\):.*$', code, flags=re.MULTILINE):
                bots.append(code)

        if not bots:
            print(" > [WARN] user '%s': couldn't locate any bots" % name, file=stderr)
        elif name in players:
            players[name] += bots
        else:
            players[name] = bots

    return players


# Download all bots from codegolf.stackexchange.com
def download_bots():
    print('pulling bots from the interwebs..', file=stderr)
    try:
        players = download_players()
    except Exception as ex:
        print('FAILED: (%s)' % ex, file=stderr)
        exit(1)

    if path.isfile(AUTO_FILE):
        print(' > move: %s -> %s.old' % (AUTO_FILE,AUTO_FILE), file=stderr)
        if path.exists('%s.old' % AUTO_FILE):
            remove('%s.old' % AUTO_FILE)
        rename(AUTO_FILE, '%s.old' % AUTO_FILE)

    print(' > writing players to %s' % AUTO_FILE, file=stderr)
    f = open(AUTO_FILE, 'w+', encoding='utf8')
    f.write('# -*- coding: utf-8 -*- \n')
    f.write('# Bots downloaded from https://codegolf.stackexchange.com/questions/177765 @ %s\n\n' % strftime('%F %H:%M:%S'))
    with open(OWN_FILE, 'r') as bfile:
        f.write(bfile.read()+'\n\n\n# Auto-pulled bots:\n\n')
    for usr in players:
        if usr not in IGNORE:
            for bot in players[usr]:
                f.write('# User: %s\n' % usr)
                f.write(bot+'\n\n')
    f.close()

    print('OK: pulled %s bots' % sum(len(bs) for bs in players.values()))


if __name__ == "__main__":

    games = 10000
    bots_per_game = 8
    threads = 4

    for i, arg in enumerate(sys.argv):
        if arg == "-n" and len(sys.argv) > i+1 and sys.argv[i+1].isdigit():
            games = int(sys.argv[i+1])
        if arg == "-b" and len(sys.argv) > i+1 and sys.argv[i+1].isdigit():
            bots_per_game = int(sys.argv[i+1])
        if arg == "-t" and len(sys.argv) > i+1 and sys.argv[i+1].isdigit():
            threads = int(sys.argv[i+1])
        if arg == "-d" or arg == "--download":
            DOWNLOAD = True
        if arg == "-A" or arg == "--ansi":
            ANSI = True
        if arg == "-D" or arg == "--debug":
            DEBUG = True
        if arg == "-h" or arg == "--help":
            print_help()
            quit()
    if ANSI:
        print(chr(27) + "[2J", flush =  True)
        print_str(1,3,"")
    else:
        print()

    if DOWNLOAD:
        download_bots()
        exit() # Before running other's code, you might want to inspect it..

    if path.isfile(AUTO_FILE):
        exec('from %s import *' % AUTO_FILE[:-3])
    else:
        exec('from %s import *' % OWN_FILE[:-3])

    bots = get_all_bots()

    if bots_per_game > len(bots):
        bots_per_game = len(bots)
    if bots_per_game < 2:
        print("\tAt least 2 bots per game is needed")
        bots_per_game = 2
    if games <= 0:
        print("\tAt least 1 game is needed")
        games = 1
    if threads <= 0:
        print("\tAt least 1 thread is needed")
        threads = 1
    if DEBUG:
        print("\tRunning in debug mode, with 1 thread and 1 game")
        threads = 1
        games = 1

    games_per_thread = math.ceil(games / threads)

    print("\tStarting simulation with %d bots" % len(bots))
    sim_str = "\tSimulating %d games with %d bots per game"
    print(sim_str % (games, bots_per_game))
    print("\tRunning simulation on %d threads" % threads)
    if len(sys.argv) == 1:
        print("\tFor help running the script, use the -h flag")
    print()

    with Pool(threads) as pool:
        t0 = time.time()
        results = pool.starmap(
            run_simulation, 
            [(i, bots_per_game, games_per_thread, bots) for i in range(threads)]
        )
        t1 = time.time()
        if not DEBUG:
            total_bot_stats = [r[0] for r in results]
            total_game_stats = [r[1] for r in results]
            print_results(total_bot_stats, total_game_stats, t1-t0)

আপনি যদি এই চ্যালেঞ্জটির জন্য মূল নিয়ামকের অ্যাক্সেস চান তবে এটি সম্পাদনা ইতিহাসে উপলব্ধ। নতুন কন্ট্রোলারের গেমটি চালানোর জন্য ঠিক একই যুক্তি রয়েছে, পার্থক্য কেবল পারফরম্যান্স, স্ট্যাট কালেকশন এবং সুন্দর প্রিন্টিং।

বট

আমার মেশিনে, বটগুলি ফাইলটিতে রাখা হয় forty_game_bots.py। আপনি যদি ফাইলটির জন্য অন্য কোনও নাম ব্যবহার করেন তবে আপনাকে অবশ্যই importনিয়ামকের শীর্ষে বিবৃতিটি আপডেট করতে হবে ।

import sys, inspect
import random
import numpy as np

# Returns a list of all bot classes which inherit from the Bot class
def get_all_bots():
    return Bot.__subclasses__()

# The parent class for all bots
class Bot:

    def __init__(self, index, end_score):
        self.index = index
        self.end_score = end_score

    def update_state(self, current_throws):
        self.current_throws = current_throws

    def make_throw(self, scores, last_round):
        yield False


class ThrowTwiceBot(Bot):

    def make_throw(self, scores, last_round):
        yield True
        yield False

class GoToTenBot(Bot):

    def make_throw(self, scores, last_round):
        while sum(self.current_throws) < 10:
            yield True
        yield False

সিমুলেশন চলছে

একটি সিমুলেশন চালাতে, দুটি পৃথক ফাইলের উপরে পোস্ট করা উভয় কোড স্নিপেট সংরক্ষণ করুন। আমি তাদের হিসাবে সংরক্ষিত আছে forty_game_controller.pyএবং forty_game_bots.py। তারপরে আপনি কেবল ব্যবহার করতে python forty_game_controller.pyবা python3 forty_game_controller.pyআপনার পাইথন কনফিগারেশনের উপর নির্ভর করে। আপনি যদি নিজের সিমুলেশনটি আরও কনফিগার করতে চান তবে সেখান থেকে নির্দেশাবলী অনুসরণ করুন বা আপনি চাইলে কোডটির সাথে টিঙ্কারিং চেষ্টা করুন।

গেমের পরিসংখ্যান

যদি আপনি এমন বট তৈরি করেন যা অন্য বটগুলি বিবেচনায় না নিয়ে নির্দিষ্ট স্কোর অর্জনের লক্ষ্যে থাকে তবে এগুলি হ'ল বিজয়ী স্কোর পারসেন্টাইল:

+----------+-----+
|Percentile|Score|
+----------+-----+
|     50.00|   44|
|     75.00|   48|
|     90.00|   51|
|     95.00|   54|
|     99.00|   58|
|     99.90|   67|
|     99.99|  126|
+----------+-----+

উচ্চ ফল

আরও উত্তর পোস্ট হওয়ার সাথে সাথে আমি এই তালিকাটি আপডেট রাখার চেষ্টা করব। তালিকার বিষয়বস্তু সর্বদা সর্বশেষতম সিমুলেশন থেকে থাকবে। উপরের কোড থেকে বটগুলি হ'ল ThrowTwiceBotএবং GoToTenBotউল্লেখ হিসাবে ব্যবহৃত হয়। আমি 10 ^ 8 গেমের সাথে একটি সিমুলেশন করেছি, যা প্রায় 1 ঘন্টা সময় নেয়। তখন আমি দেখেছি যে 10 ^ 7 গেমের সাথে আমার রানগুলির তুলনায় গেমটি স্থিতিশীলতায় পৌঁছেছে। তবে, লোকেরা এখনও বট পোস্ট দিচ্ছে, প্রতিক্রিয়াগুলির ফ্রিকোয়েন্সি হ্রাস না হওয়া পর্যন্ত আমি আর সিমুলেশনগুলি করব না।

আমি সমস্ত নতুন বট যোগ করার চেষ্টা করেছি এবং বিদ্যমান বটগুলিতে আপনি যে কোনও পরিবর্তন করেছেন। যদি মনে হয় যে আমি আপনার বট বা আপনার কোনও নতুন পরিবর্তন মিস করেছি, তবে আড্ডায় লিখুন এবং আমি পরবর্তী সিমুলেশনে আপনার খুব সাম্প্রতিক সংস্করণটি নিশ্চিত করব।

একরোয়েলের প্রতি প্রতিটি বটকে ধন্যবাদ দেওয়ার জন্য এখন আমাদের আরও পরিসংখ্যান রয়েছে ! তিনটি নতুন কলামে সমস্ত গেমের সর্বোচ্চ স্কোর, প্রতি গেমের গড় স্কোর এবং প্রতিটি বোটের জন্য জয়ের সময় গড় স্কোর থাকে।

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

Simulation or 300000000 games between 49 bots completed in 35628.7 seconds
Each game lasted for an average of 3.73 rounds
29127662 games were tied between two or more bots
0 games ran until the round limit, highest round was 22

+-----------------------+----+--------+--------+------+------+-------+------+--------+
|Bot                    |Win%|    Wins|  Played|   Max|   Avg|Avg win|Throws|Success%|
+-----------------------+----+--------+--------+------+------+-------+------+--------+
|OptFor2X               |21.6|10583693|48967616|    99| 20.49|  44.37|  4.02|   33.09|
|Rebel                  |20.7|10151261|48977862|   104| 21.36|  44.25|  3.90|   35.05|
|Hesitate               |20.3| 9940220|48970815|   105| 21.42|  44.23|  3.89|   35.11|
|EnsureLead             |20.3| 9929074|48992362|   101| 20.43|  44.16|  4.50|   25.05|
|StepBot                |20.2| 9901186|48978938|    96| 20.42|  43.47|  4.56|   24.06|
|BinaryBot              |20.1| 9840684|48981088|   115| 21.01|  44.48|  3.85|   35.92|
|Roll6Timesv2           |20.1| 9831713|48982301|   101| 20.83|  43.53|  4.37|   27.15|
|AggressiveStalker      |19.9| 9767637|48979790|   110| 20.46|  44.86|  3.90|   35.04|
|FooBot                 |19.9| 9740900|48980477|   100| 22.03|  43.79|  3.91|   34.79|
|QuotaBot               |19.9| 9726944|48980023|   101| 19.96|  44.95|  4.50|   25.03|
|BePrepared             |19.8| 9715461|48978569|   112| 18.68|  47.58|  4.30|   28.31|
|AdaptiveRoller         |19.7| 9659023|48982819|   107| 20.70|  43.27|  4.51|   24.81|
|GoTo20Bot              |19.6| 9597515|48973425|   108| 21.15|  43.24|  4.44|   25.98|
|Gladiolen              |19.5| 9550368|48970506|   107| 20.16|  45.31|  3.91|   34.81|
|LastRound              |19.4| 9509645|48988860|   100| 20.45|  43.50|  4.20|   29.98|
|BrainBot               |19.4| 9500957|48985984|   105| 19.26|  45.56|  4.46|   25.71|
|GoTo20orBestBot        |19.4| 9487725|48975944|   104| 20.98|  44.09|  4.46|   25.73|
|Stalker                |19.4| 9485631|48969437|   103| 20.20|  45.34|  3.80|   36.62|
|ClunkyChicken          |19.1| 9354294|48972986|   112| 21.14|  45.44|  3.57|   40.48|
|FortyTeen              |18.8| 9185135|48980498|   107| 20.90|  46.77|  3.88|   35.32|
|Crush                  |18.6| 9115418|48985778|    96| 14.82|  43.08|  5.15|   14.15|
|Chaser                 |18.6| 9109636|48986188|   107| 19.52|  45.62|  4.06|   32.39|
|MatchLeaderBot         |16.6| 8122985|48979024|   104| 18.61|  45.00|  3.20|   46.70|
|Ro                     |16.5| 8063156|48972140|   108| 13.74|  48.24|  5.07|   15.44|
|TakeFive               |16.1| 7906552|48994992|   100| 19.38|  44.68|  3.36|   43.96|
|RollForLuckBot         |16.1| 7901601|48983545|   109| 17.30|  50.54|  4.72|   21.30|
|Alpha                  |15.5| 7584770|48985795|   104| 17.45|  46.64|  4.04|   32.67|
|GoHomeBot              |15.1| 7418649|48974928|    44| 13.23|  41.41|  5.49|    8.52|
|LeadBy5Bot             |15.0| 7354458|48987017|   110| 17.15|  46.95|  4.13|   31.16|
|NotTooFarBehindBot     |15.0| 7338828|48965720|   115| 17.75|  45.03|  2.99|   50.23|
|GoToSeventeenRollTenBot|14.1| 6900832|48976440|   104| 10.26|  49.25|  5.68|    5.42|
|LizduadacBot           |14.0| 6833125|48978161|    96|  9.67|  51.35|  5.72|    4.68|
|TleilaxuBot            |13.5| 6603853|48985292|   137| 15.25|  45.05|  4.27|   28.80|
|BringMyOwn_dice        |12.0| 5870328|48974969|    44| 21.27|  41.47|  4.24|   29.30|
|SafetyNet              |11.4| 5600688|48987015|    98| 15.81|  45.03|  2.41|   59.84|
|WhereFourArtThouChicken|10.5| 5157324|48976428|    64| 22.38|  47.39|  3.59|   40.19|
|ExpectationsBot        | 9.0| 4416154|48976485|    44| 24.40|  41.55|  3.58|   40.41|
|OneStepAheadBot        | 8.4| 4132031|48975605|    50| 18.24|  46.02|  3.20|   46.59|
|GoBigEarly             | 6.6| 3218181|48991348|    49| 20.77|  42.95|  3.90|   35.05|
|OneInFiveBot           | 5.8| 2826326|48974364|   155| 17.26|  49.72|  3.00|   50.00|
|ThrowThriceBot         | 4.1| 1994569|48984367|    54| 21.70|  44.55|  2.53|   57.88|
|FutureBot              | 4.0| 1978660|48985814|    50| 17.93|  45.17|  2.36|   60.70|
|GamblersFallacy        | 1.3|  621945|48986528|    44| 22.52|  41.46|  2.82|   53.07|
|FlipCoinRollDice       | 0.7|  345385|48972339|    87| 15.29|  44.55|  1.61|   73.17|
|BlessRNG               | 0.2|   73506|48974185|    49| 14.54|  42.72|  1.42|   76.39|
|StopBot                | 0.0|    1353|48984828|    44| 10.92|  41.57|  1.00|   83.33|
|CooperativeSwarmBot    | 0.0|     991|48970284|    44| 10.13|  41.51|  1.36|   77.30|
|PointsAreForNerdsBot   | 0.0|       0|48986508|     0|  0.00|   0.00|  6.00|    0.00|
|SlowStart              | 0.0|       0|48973613|    35|  5.22|   0.00|  3.16|   47.39|
+-----------------------+----+--------+--------+------+------+-------+------+--------+

নিম্নলিখিত বটগুলি (বাদে Rebel) নিয়মগুলি বাঁকতে তৈরি করা হয়েছে, এবং নির্মাতারা সরকারী টুর্নামেন্টে অংশ না নেওয়ার বিষয়ে সম্মত হয়েছেন। তবে আমি এখনও তাদের ধারণাগুলি সৃজনশীল বলে মনে করি এবং সেগুলি একটি সম্মানজনক উল্লেখের প্রাপ্য। বিদ্রোহীও এই তালিকায় রয়েছে কারণ এটি নাশকতা এড়ানোর জন্য একটি চতুর কৌশল ব্যবহার করে এবং প্রকৃতপক্ষে নাশকতার বোটের সাথে আরও ভাল অভিনয় করে।

বটগুলি NeoBotএবং KwisatzHaderachনিয়মগুলি অনুসরণ করে তবে এলোমেলো জেনারেটরের পূর্বাভাস দিয়ে একটি লুফোল ব্যবহার করে। যেহেতু এই বটগুলি অনুকরণে প্রচুর সংস্থান লাগে, তাই আমি এর পরিসংখ্যানগুলি কম গেমের সাথে একটি সিমুলেশন থেকে যুক্ত করেছি। বট HarkonnenBotঅন্যান্য সমস্ত বট অক্ষম করে বিজয় অর্জন করে, যা নিয়মের বিরুদ্ধে কঠোর।

    Simulation or 300000 games between 52 bots completed in 66.2 seconds
    Each game lasted for an average of 4.82 rounds
    20709 games were tied between two or more bots
    0 games ran until the round limit, highest round was 31

    +-----------------------+----+--------+--------+------+------+-------+------+--------+
    |Bot                    |Win%|    Wins|  Played|   Max|   Avg|Avg win|Throws|Success%|
    +-----------------------+----+--------+--------+------+------+-------+------+--------+
    |KwisatzHaderach        |80.4|   36986|   46015|   214| 58.19|  64.89| 11.90|   42.09|
    |HarkonnenBot           |76.0|   35152|   46264|    44| 34.04|  41.34|  1.00|   83.20|
    |NeoBot                 |39.0|   17980|   46143|   214| 37.82|  59.55|  5.44|   50.21|
    |Rebel                  |26.8|   12410|   46306|    92| 20.82|  43.39|  3.80|   35.84|
    +-----------------------+----+--------+--------+------+------+-------+------+--------+

    +----------+-----+
    |Percentile|Score|
    +----------+-----+
    |     50.00|   45|
    |     75.00|   50|
    |     90.00|   59|
    |     95.00|   70|
    |     99.00|   97|
    |     99.90|  138|
    |     99.99|  214|
    +----------+-----+

2
সুতরাং সম্ভবত নিয়মগুলি কিছুটা স্পষ্ট হবে যদি তারা বলেছিল "যখন কোনও খেলোয়াড় কমপক্ষে 40 এর স্কোর দিয়ে তাদের পালা শেষ করে, তখন প্রত্যেকেই শেষ বারে"। এটি 40-এ পৌঁছায় না এমন ইঙ্গিত দিয়ে আপাত দ্বন্দ্ব এড়ানো যায় যা সত্যই শেষ রাউন্ডটিকে ট্রিগার করে, এটি কমপক্ষে 40 দিয়ে থামছে
অ্যাসিপলারের

1
@ এস্পেল্পার এটি একটি ভাল সূত্র, আমি আমার কম্পিউটারে থাকাকালীন পোস্টটি সম্পাদনা করব
ম্যাক্সবি

2
@ ম্যাক্সবি আমি আমার বিকাশের প্রক্রিয়ার সাথে প্রাসঙ্গিক আরও পরিসংখ্যান যুক্ত করতে নিয়ামককে প্রসারিত করেছি: সর্বোচ্চ স্কোর পৌঁছেছে, গড় স্কোর পৌঁছেছে এবং গড় জয়ের স্কোর gist.github.com/AwK/91446718a46f3e001c19533298b5756c
এক্রোয়েল

2
এই Farkled নামক একটি খুব মজা পাশা খেলা অনুরূপ শোনাচ্ছে en.wikipedia.org/wiki/Farkle
কালেব জে

5
আমি এই প্রশ্নটি বন্ধ করার পক্ষে ভোট দিচ্ছি কারণ এটি ইতিমধ্যে ডি-ফ্যাক্টো নতুন জবাব বন্ধ করেছে ("টুর্নামেন্টটি এখন শেষ! রাতের বেলা চূড়ান্ত সিমুলেশনটি চালানো হয়েছিল, মোট 3 ∗ 108 গেমস")
পিপ্পি

উত্তর:


6

OptFor2X

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

class OptFor2X(Bot):

    _r = []
    _p = []

    def _u(self,l):
        res = []
        for x in l:
            if isinstance(x,int):
                if x>0:
                    a=b=x
                else:
                    a,b=-2,-x
            else:
                if len(x)==1:
                    a = x[0]
                    if a<0:
                        a,b=-3,-a
                    else:
                        b=a+2
                else:
                    a,b=x
            if a<0:
                res.extend((b for _ in range(-a)))
            else:
                res.extend(range(a,b+1))
        res.extend((res[-1] for _ in range(40-len(res))))
        return res


    def __init__(self,*args):
        super().__init__(*args)
        if self._r:
            return
        self._r.append(self._u([[-8, 14], -15, [-6, 17], [18, 21], [21],
                                 -23, -24, 25, [-3, 21], [22, 29]]))
        self._r.extend((None for _ in range(13)))
        self._r.extend((self._u(x) for x in
                   ([[-19, 13], [-4, 12], -13, [-14], [-5, 15], [-4, 16],
                     -17, 18],
                    [[-6, 12], [-11, 13], [-4, 12], -11, -12, [-13], [-14],
                     [-5, 15], -16, 17],
                    [11, 11, [-10, 12], -13, [-24], 13, 12, [-6, 11], -12,
                     [-13], [-6, 14], -15, 16],
                    [[-8, 11], -12, 13, [-9, 23], 11, [-10], [-11], [-12],
                     [-5, 13], -14, [14]],
                    [[-4, 10], [-11], 12, [-14, 22], 10, 9, -10, [-4, 11],
                     [-5, 12], -13, -14, 15],
                    [[-4, 10], 11, [-18, 21], [-9], [-10], [-5, 11], [-12],
                     -13, 14],
                    [[-24, 20], [-5, 9], [-4, 10], [-4, 11], -12, 13],
                    [[-25, 19], [-8], [-4, 9], [-4, 10], -11, 12],
                    [[-26, 18], [-5, 8], [-5, 9], 10, [10]],
                    [[-27, 17], [-4, 7], [-5, 8], 9, [9]],
                    [[-28, 16], -6, [-5, 7], -8, -9, 10],
                    [[-29, 15], [-5, 6], [-7], -8, 9],
                    [[-29, 14], [-4, 5], [-4, 6], [7]],
                    [[-30, 13], -4, [-4, 5], 6, [6]], 
                    [[-31, 12], [-5, 4], 5, [5]],
                    [[-31, 11], [-4, 3], [3], 5, 6],
                    [[-31, 10], 11, [-2], 3, [3]],
                    [[-31, 9], 10, 2, -1, 2, [2]],
                    [[-31, 8], 9, [-4, 1], [1]],
                    [[-30, 7], [7], [-5, 1], 2],
                    [[-30, 6], [6], 1],
                    [[-31, 5], [6], 1],
                    [[-31, 4], [5, 8], 1],
                    [[-31, 3], [4, 7], 1],
                    [[-31, 2], [3, 6], 1],
                    [[-31, 1], [2, 10]] ) ))
        l=[0.0,0.0,0.0,0.0,1.0]
        for i in range(300):
            l.append(sum([a/6 for a in l[i:]]))
        m=[i/6 for i in range(1,5)]
        self._p.extend((1-sum([a*b for a,b in zip(m,l[i:])])
                                           for i in range(300)))

    def update_state(self,*args):
        super().update_state(*args)
        self.current_sum = sum(self.current_throws)

    def expect(self,mts,ops):
        p = 1.0
        for s in ops:
            p *= self._p[mts-s]
        return p

    def throw_again(self,mts,ops):
        ps = self.expect(mts,ops)
        pr = sum((self.expect(mts+d,ops) for d in range(1,6)))/6
        return pr>ps

    def make_throw(self,scores,last_round):
        myscore=scores[self.index]
        if last_round:
            target=max(scores)-myscore
            if max(scores)<40:
                opscores = scores[self.index+1:]
            else:
                opscores = []
                i = (self.index + 1) % len(scores)
                while scores[i] < 40:
                    opscores.append(scores[i])
                    i = (i+1) % len(scores)
        else:
            opscores = [s for i,s in enumerate(scores) if i!=self.index]
            bestop = max(opscores)
            target = min(self._r[myscore][bestop],40-myscore)
            # (could change the table instead of using min)
        while self.current_sum < target:
            yield True
        lr = last_round or myscore+self.current_sum >= 40
        while lr and self.throw_again(myscore+self.current_sum,opscores):
            yield True
        yield False

আমি যত তাড়াতাড়ি পারবো বাস্তবায়নটি দেখব। বড়দিন উদযাপনের সাথে, এটি 25 তম
ম্যাক্সব

আপনার বট নেতৃত্বে হয়! এছাড়াও, এটি দ্রুত চালিত করার কোনও প্রয়োজন নেই, সিদ্ধান্ত গ্রহণে এটি অন্যান্য সমস্ত বটের মতোই প্রায় দ্রুত।
ম্যাক্সবি

আমি এটিকে দ্রুত করতে চাইনি। আমি যা করতে চাইছিলাম তা ইতিমধ্যে করেছি - একবার মাত্র আরম্ভ করলাম - তবে এটি করার জন্য আরও সুন্দর উপায় খুঁজছিলাম, বিশেষত শ্রেণীর বাইরে ফাংশনগুলি সংজ্ঞায়িত না করে। আমি মনে করি এটি এখন আরও ভাল।
খ্রিস্টান সিভর্স

এটি এখন অনেক ভাল দেখাচ্ছে, ভাল কাজ!
সর্বোচ্চ

প্রথম এবং দ্বিতীয় স্থান অর্জনের জন্য অভিনন্দন!
সর্বোচ্চ

20

NeoBot

পরিবর্তে, কেবল সত্য উপলব্ধি করার চেষ্টা করুন - কোনও চামচ নেই

নিওবট ম্যাট্রিক্সে উঁকি দিয়েছে (ওরফে এলোমেলো) এবং ভবিষ্যদ্বাণী করে যে পরবর্তী রোলটি 6 হবে বা না - এটি শুরু করার জন্য একটি 6 হস্তান্তর সম্পর্কে কিছুই করতে পারে না তবে একটি স্ট্রাইক এন্ডারে ডজ খুশি হওয়ার চেয়ে বেশি আনন্দিত।

নিওবোট আসলে নিয়ামক বা রানটাইম সংশোধন করে না, কেবল বিনয়ের সাথে লাইব্রেরিকে আরও তথ্যের জন্য জিজ্ঞাসা করে।

class NeoBot(Bot):
    def __init__(self, index, end_score):
        self.random = None
        self.last_scores = None
        self.last_state = None
        super().__init__(index,end_score)

    def make_throw(self, scores, last_round):
        while True:
            if self.random is None:
                self.random = inspect.stack()[1][0].f_globals['random']
            tscores = scores[:self.index] + scores[self.index+1:]
            if self.last_scores != tscores:
                self.last_state = None
                self.last_scores = tscores
            future = self.predictnext_randint(self.random)
            if future == 6:
                yield False
            else:
                yield True

    def genrand_int32(self,base):
        base ^= (base >> 11)
        base ^= (base << 7) & 0x9d2c5680
        base ^= (base << 15) & 0xefc60000
        return base ^ (base >> 18)

    def predictnext_randint(self,cls):
        if self.last_state is None:
            self.last_state = list(cls.getstate()[1])
        ind = self.last_state[-1]
        width = 6
        res = width + 1
        while res >= width:
            y = self.last_state[ind]
            r = self.genrand_int32(y)
            res = r >> 29
            ind += 1
            self.last_state[-1] = (self.last_state[-1] + 1) % (len(self.last_state))
        return 1 + res

1
পিপিসিজিতে আপনাকে স্বাগতম! এটি একটি সত্যই চিত্তাকর্ষক উত্তর। আমি যখন প্রথম এটি চালিয়েছি, তখন আমি বিরক্ত হয়েছিলাম যে এটি অন্যান্য সমস্ত বটগুলিকে সংযুক্ত করার মতো রানটাইম হিসাবে একই পরিমাণ ব্যবহার করেছিল। তারপরে আমি জয়ের শতাংশের দিকে তাকালাম। নিয়ম skirting সত্যিই চতুর উপায়। আমি আপনার বটকে টুর্নামেন্টে অংশ নেওয়ার অনুমতি দেব, তবে আমি আশা করি যে অন্যরা এটির মতো কৌশল ব্যবহার করা থেকে বিরত থাকবে, কারণ এটি গেমের চেতনা লঙ্ঘন করে।
সর্বোচ্চ

2
যেহেতু এই বট এবং দ্বিতীয় স্থানের মধ্যে এত বিশাল ব্যবধান রয়েছে, আপনার বটকে প্রচুর পরিমাণে কম্পিউটিং দরকার এই সত্যের সাথে মিলিত, আপনি কি স্বীকার করবেন যে আমি আপনার জয়ের হার খুঁজে পেতে কম পুনরাবৃত্তির সাথে একটি সিমুলেশন চালাচ্ছি, এবং তারপরে অফিসিয়ালটি চালনা করব আপনার বট ছাড়া সিমুলেশন?
সর্বোচ্চ

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

2
ধন্যবাদ! আমি মনে করি না যে অন্য কোনও বট আপনার স্কোরের কাছে চলে আসবে। এবং এই কৌশলটি বাস্তবায়নের বিষয়ে অন্য যে কেউ ভাবছেন, তা করবেন না। এখন থেকে এই কৌশলটি বিধিবিরোধী, এবং টুর্নামেন্টটি সুষ্ঠু রাখার স্বার্থে কেবল নিওবটই এটির ব্যবহারের অনুমতিপ্রাপ্ত।
ম্যাক্সবি

1
ঠিক আছে, মাইবট প্রত্যেককে মারধর করে, তবে এটি আরও অনেক ভাল - আমি যদিও আমি যদি এইভাবে বট পোস্ট করি তবে আমি সেরা স্কোর নয় -100 পাব।
জানু ইভান

15

সমবায় জলা

কৌশল

আমি মনে করি না যে অন্য কেউ এই নিয়মের তাত্পর্য এখনও লক্ষ্য করেছেন:

যদি গেমটি 200 টি রাউন্ডে যায়, তবে সর্বোচ্চ স্কোর সহ বট (বা বটস) বিজয়ী, তাদের 40 পয়েন্ট বা তার বেশি না থাকলেও।

যদি প্রতিটি বট সর্বদা ঘেউ ঘেউ ঘেউ ঘায়ে না ফেলা হয়, তবে প্রত্যেকের 200 এর রাউন্ড শেষে শূন্যের স্কোর হবে এবং প্রত্যেকেই জিতবে! সুতরাং, সমবায় গোষ্ঠীর কৌশলটি যতক্ষণ না সমস্ত খেলোয়াড়ের স্কোর শূন্য থাকে ততক্ষণ সহযোগিতা করা, তবে কেউ যদি কোনও পয়েন্ট দেয় তবে সাধারণত খেলতে হয়।

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

কোড

class CooperativeSwarmBot(Bot):
    def defection_strategy(self, scores, last_round):
        yield False

    def make_throw(self, scores, last_round):
        cooperate = max(scores) == 0
        if (cooperate):
            while True:
                yield True
        else:
            yield from self.defection_strategy(scores, last_round)

class CooperativeThrowTwice(CooperativeSwarmBot):
    def defection_strategy(self, scores, last_round):
        yield True
        yield False

বিশ্লেষণ

টেকসইতা

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

100130991299812897127961269512594124931230.115

আরও সাধারণভাবে, কো-অপারেটিভ বট এবং নন- কো- অপারেটিং বটগুলির একটি পুল থেকে কো-অপারেটিভ বটগুলি বেছে নেওয়ার প্রতিক্রিয়াগুলি হ'ল:icn

c!÷(ci)!(c+n)!÷(c+ni)!

এই সমীকরণটি থেকে আমরা সহজেই দেখাতে পারি যে আমাদের 50% গেমের সমবায় শেষ হতে প্রায় 430 সমবায় বটগুলির প্রয়োজন হবে, বা 90% এর জন্য প্রায় 2900 বট ( নিয়ম অনুসারে ব্যবহার করা হবে , এবং )।i=8n=38

কেস স্টাডি

বিভিন্ন কারণে (পাদটীকা 1 এবং 2 দেখুন), একটি উপযুক্ত সমবায় ঝাঁক কখনই সরকারী গেমগুলিতে প্রতিযোগিতা করবে না। এর মতো, আমি এই বিভাগে আমার নিজস্ব সিমুলেশনগুলির ফলাফল সংক্ষিপ্ত করে বলছি।

এই সিমুলেশনটি এখানে শেষবার যখন আমি পরীক্ষা করেছিলাম এমন 38 টি বট এবং 2900 বট যা তাদের অভিভাবক শ্রেণি হিসাবে কো-অপারেটিভসওয়ার্মবট ছিল তা ব্যবহার করে 10000 গেমস দৌড়েছিল। নিয়ন্ত্রক রিপোর্ট করেছেন যে 10000 গেমগুলির 9051 (90.51%) 200 রাউন্ডে শেষ হয়েছে, যা 90% গেমস সহযোগিতামূলক হবে বলে পূর্বাভাসের একেবারেই কাছাকাছি। এই বটগুলির প্রয়োগটি ছিল তুচ্ছ; কোঅপারেটিভসওয়ার্মবট ব্যতীত তারা সকলেই এই ফর্মটি নিয়েছিল:

class CooperativeSwarm_1234(CooperativeSwarmBot):
    pass

বটসের 3% এরও কম একটি জয়ের শতাংশ ছিল যা 80% এর নীচে ছিল , এবং বটগুলির 11% এরও বেশি তারা প্রতিটি খেলায় জিতেছে। জলাবদ্ধতার 2900 বটের মধ্যম জয়ের শতাংশ প্রায় 86%, যা আশ্চর্যের সাথে ভাল। তুলনার জন্য, বর্তমান অফিশিয়াল লিডারবোর্ডে শীর্ষস্থানীয় পারফর্মাররা তাদের গেমগুলির 22% এরও কম জিতেছে। উত্তরের সর্বাধিক অনুমোদিত দৈর্ঘ্যের মধ্যে আমি সমবায় ছাঁয়ের পুরো তালিকা মাপসই করতে পারছি না, তাই আপনি যদি দেখতে চান যে পরিবর্তে আপনাকে এখানে যেতে হবে: https://pastebin.com/3Zc8m1Ex

যেহেতু প্রতিটি বট গড়ে প্রায় 27 টি গেম খেলেছে, পৃথক বটের ফলাফলগুলি যখন দেখেন তখন ভাগ্য একটি তুলনামূলকভাবে বড় রোল খেল। যেহেতু আমি এখনও অসহযোগিতামূলক গেমগুলির জন্য একটি উন্নত কৌশল বাস্তবায়িত করি নি, বেশিরভাগ অন্যান্য বটগুলি সমবায় জলাভূমির বিরুদ্ধে খেলে প্রচুর উপকার পেয়েছিল, এমনকি সমবায় ছত্রাকের মধ্যম জয়ের হারটি 86% সম্পাদন করে।

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

+---------------------+----+--------+--------+------+------+-------+------+--------+
|Bot                  |Win%|    Wins|  Played|   Max|   Avg|Avg win|Throws|Success%|
+---------------------+----+--------+--------+------+------+-------+------+--------+
|AggressiveStalker    |100.0|      21|      21|    42| 40.71|  40.71|  3.48|   46.32|
|PointsAreForNerdsBot |100.0|      31|      31|     0|  0.00|   0.00|  6.02|    0.00|
|TakeFive             |100.0|      18|      18|    44| 41.94|  41.94|  2.61|   50.93|
|Hesitate             |100.0|      26|      26|    44| 41.27|  41.27|  3.32|   41.89|
|Crush                |100.0|      34|      34|    44| 41.15|  41.15|  5.38|    6.73|
|StepBot              |97.0|      32|      33|    46| 41.15|  42.44|  4.51|   24.54|
|LastRound            |96.8|      30|      31|    44| 40.32|  41.17|  3.54|   45.05|
|Chaser               |96.8|      30|      31|    47| 42.90|  44.33|  3.04|   52.16|
|GoHomeBot            |96.8|      30|      31|    44| 40.32|  41.67|  5.60|    9.71|
|Stalker              |96.4|      27|      28|    44| 41.18|  41.44|  2.88|   57.53|
|ClunkyChicken        |96.2|      25|      26|    44| 40.96|  41.88|  2.32|   61.23|
|AdaptiveRoller       |96.0|      24|      25|    44| 39.32|  40.96|  4.49|   27.43|
|GoTo20Bot            |95.5|      21|      22|    44| 40.36|  41.33|  4.60|   30.50|
|FortyTeen            |95.0|      19|      20|    48| 44.15|  45.68|  3.71|   43.97|
|BinaryBot            |94.3|      33|      35|    44| 41.29|  41.42|  2.87|   53.07|
|EnsureLead           |93.8|      15|      16|    55| 42.56|  42.60|  4.04|   26.61|
|Roll6Timesv2         |92.9|      26|      28|    45| 40.71|  42.27|  4.07|   29.63|
|BringMyOwn_dice      |92.1|      35|      38|    44| 40.32|  41.17|  4.09|   28.40|
|LizduadacBot         |92.0|      23|      25|    54| 47.32|  51.43|  5.70|    5.18|
|FooBot               |91.7|      22|      24|    44| 39.67|  41.45|  3.68|   51.80|
|Alpha                |91.7|      33|      36|    48| 38.89|  42.42|  2.16|   65.34|
|QuotaBot             |90.5|      19|      21|    53| 38.38|  42.42|  3.88|   24.65|
|GoBigEarly           |88.5|      23|      26|    47| 41.35|  42.87|  3.33|   46.38|
|ExpectationsBot      |88.0|      22|      25|    44| 39.08|  41.55|  3.57|   45.34|
|LeadBy5Bot           |87.5|      21|      24|    50| 37.46|  42.81|  2.20|   63.88|
|GamblersFallacy      |86.4|      19|      22|    44| 41.32|  41.58|  2.05|   63.11|
|BePrepared           |86.4|      19|      22|    59| 39.59|  44.79|  3.81|   35.96|
|RollForLuckBot       |85.7|      18|      21|    54| 41.95|  47.67|  4.68|   25.29|
|OneStepAheadBot      |84.6|      22|      26|    50| 41.35|  46.00|  3.34|   42.97|
|FlipCoinRollDice     |78.3|      18|      23|    51| 37.61|  44.72|  1.67|   75.42|
|BlessRNG             |77.8|      28|      36|    47| 40.69|  41.89|  1.43|   83.66|
|FutureBot            |77.4|      24|      31|    49| 40.16|  44.38|  2.41|   63.99|
|SlowStart            |68.4|      26|      38|    57| 38.53|  45.31|  1.99|   66.15|
|NotTooFarBehindBot   |66.7|      20|      30|    50| 37.27|  42.00|  1.29|   77.61|
|ThrowThriceBot       |63.0|      17|      27|    51| 39.63|  44.76|  2.50|   55.67|
|OneInFiveBot         |58.3|      14|      24|    54| 33.54|  44.86|  2.91|   50.19|
|MatchLeaderBot       |48.1|      13|      27|    49| 40.15|  44.15|  1.22|   82.26|
|StopBot              | 0.0|       0|      27|    43| 30.26|   0.00|  1.00|   82.77|
+---------------------+----+--------+--------+------+------+-------+------+--------+

সংক্রান্ত ত্রুটিগুলি

এই সমবায় পদ্ধতির বেশ কয়েকটি ত্রুটি রয়েছে। প্রথমত, অসহযোগকারী বটসের বিরুদ্ধে খেললে কো-অপারেটিভ বটগুলি কখনই প্রথম-টার্নের সুবিধা পায় না কারণ তারা যখন প্রথম খেলবে, তারা এখনও জানে না যে তাদের বিরোধীরা সহযোগিতা করতে ইচ্ছুক এবং না, এবং সুতরাং এটি পাওয়ার ব্যতীত আর কোনও উপায় নেই have শূন্য স্কোর। একইভাবে, এই সমবায় কৌশলটি দূষিত বট দ্বারা শোষণের জন্য চরম ঝুঁকিপূর্ণ; উদাহরণস্বরূপ, সমবায় খেলার সময় যে বট শেষ রাউন্ডে খেলে তারা অন্য সবাইকে হারাতে অবিলম্বে রোলিং বন্ধ করতে বেছে নিতে পারে (ধরে নিই, তাদের প্রথম রোলটি ছয়টি নয়)।

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

পাদটিকা

[১]: আমি কেবল দুটি পরিবর্তে কয়েক হাজার বট জমা দিতে চাই না এমন প্রাথমিক কারণগুলি হ'ল এটি করা 1000 এর ক্রম অনুসারে একটি ফ্যাক্টর দ্বারা সিমুলেশনটি ধীর করে দেবে [2], এবং এটি করার ফলে তাড়াতাড়ি নষ্ট হবে শতাংশ জিতে যেমন অন্যান্য বট প্রায় একচেটিয়াভাবে একে অপরের চেয়ে ঝাঁকের বিরুদ্ধে খেলতে হবে। তবে আরও গুরুত্বপূর্ণ বিষয়টি হ'ল আমি চাইলেও নিয়মের চেতনা ভঙ্গ না করে যুক্তিসঙ্গত সময়সীমার মধ্যে অনেকগুলি বট তৈরি করতে সক্ষম হব না যে "বটকে অবশ্যই ঠিক একই কৌশল বাস্তবায়ন করতে হবে না বিদ্যমান একটি, ইচ্ছাকৃতভাবে বা দুর্ঘটনাক্রমে "।

[২]: আমি মনে করি যে দুটি মূল কারণ আছে যে কোনও সমবায় জলাবদ্ধতা চালানোর সময় সিমুলেশনটি ধীর হয়ে যায়। প্রথমত, আরও বটস আরও বেশি গেম মানে যদি আপনি প্রতিটি বট একই সংখ্যক গেম খেলতে চান (কেস স্টাডিতে, গেমের সংখ্যা প্রায় 77 77 এর ফ্যাক্টর দ্বারা পৃথক হতে পারে)। দ্বিতীয়ত, সমবায় গেমগুলি আরও বেশি সময় নেয় কারণ এগুলি পুরো 200 রাউন্ডের জন্য স্থায়ী হয় এবং একটি রাউন্ড প্লেয়ারের মধ্যেই অনির্দিষ্টকালের জন্য ঘূর্ণায়মান থাকতে হয়। আমার সেটআপের জন্য, গেমস অনুকরণে প্রায় 40 গুণ বেশি সময় লেগেছিল: কেস স্টাডিতে 10000 গেমস চালাতে তিন মিনিটের বেশি সময় লেগেছে, তবে সমবায় জলা অপসারণের পরে এটি 10000 গেমগুলি মাত্র 4.5 সেকেন্ডের মধ্যে শেষ করবে। এই দুটি কারণে, আমি অনুমান করি যে বটগুলির পারফরম্যান্স সঠিকভাবে পরিমাপ করতে প্রায় 3100 গুণ বেশি সময় লাগবে যখন যখন সেখানে নেই যখন তুলনায় একটি ঝাঁক প্রতিযোগিতা রয়েছে।


4
কি দারুন. এবং পিপিসিজিতে আপনাকে স্বাগতম। এটি বেশ প্রথম উত্তর। আমি আসলে এমন পরিস্থিতি নিয়ে পরিকল্পনা করছিলাম না। আপনি অবশ্যই নিয়মের একটি ফাঁক খুঁজে পেয়েছেন। আমি কীভাবে এটি স্কোর করব তা আমি সত্যিই নিশ্চিত নই, কারণ আপনার উত্তরটি একক বটের পরিবর্তে বটের সংগ্রহ। তবে, এখনই কেবলমাত্র আমি যা বলব তা হ'ল এটি অনুপযুক্ত অনুভব করে যে একজন অংশগ্রহণকারী সমস্ত বটগুলির 98.7% নিয়ন্ত্রণ করবে।
ম্যাক্সব

2
আমি চাই না সদৃশ বটগুলি সরকারী প্রতিযোগিতায় আসুক; এ কারণেই আমি হাজার হাজার খুব অভিন্ন বট জমা দেওয়ার পরিবর্তে নিজেই সিমুলেশনটি চালিয়েছি। আমি আরও জমা দেওয়ার জন্য আমার জমাটি সংশোধন করব।
আইএনহেন্ডার

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

1
আমি মনে করি আপনার পোস্টটি আরও ভাল করে পড়ার পরে এটি পরিষ্কার।
ম্যাক্সবি

তাদের বেশিরভাগের লিডারবোর্ড বসানোতে নেট লাভ দেখার জন্য এই সহযোগিতার কাঠামোর মধ্যে কতগুলি বিদ্যমান বটকে তাদের কোডটি মোড়ানো দরকার? আমার নিষ্পাপ অনুমান 50%
স্পার

10

GoTo20Bot

class GoTo20Bot(Bot):

    def make_throw(self, scores, last_round):
        target = min(20, 40 - scores[self.index])
        if last_round:
            target = max(scores) - scores[self.index] + 1
        while sum(self.current_throws) < target:
            yield True
        yield False

সকলের সাথে একবার চেষ্টা করুন GoToNBot, এবং 20, 22, 24 নাটকগুলি সেরা খেলুন। কেন জানি না।


আপডেট: 40 বা ততোধিক স্কোর পেলে সর্বদা থ্রোক বন্ধ করুন।


আমি এই ধরণের বটগুলির সাথেও পরীক্ষা-নিরীক্ষা করেছি। বটটি 16 এ যাওয়ার সময় প্রতি রাউন্ডে সর্বোচ্চ গড় স্কোর পাওয়া যায় তবে আমি ধরে নিচ্ছি যে "শেষ খেলা" 20-বটকে আরও বেশি বার জিতিয়ে তোলে।
সর্বোচ্চ

@ ম্যাক্সব না তাই, আমার পরীক্ষায় "শেষ খেলা" ছাড়াই ২০ জন এখনও সেরা হন। হতে পারে আপনি এটি নিয়ামকের পুরানো সংস্করণে পরীক্ষা করেছেন।
tsh

আমি এই চ্যালেঞ্জটি ডিজাইনের আগে একটি পৃথক পরীক্ষা চালিয়েছি, যেখানে আমি আমার পোস্টে দুটি কৌশল ("থ্রো এক্স টাইম" এবং "এক্স স্কোর অবধি থ্রো") জন্য রাউন্ডে গড়ে গড় স্কোর গণনা করেছি এবং সর্বাধিক আমি পেয়েছি 15-15 । যদিও আমার নমুনার আকার খুব ছোট হতে পারে, আমি অস্থিরতা লক্ষ্য করেছি।
ম্যাক্সব

2
আমি এটি দিয়ে কিছু পরীক্ষা করেছি এবং আমার উপসংহারটি হ'ল 20 টি ভাল কাজ করে কারণ এটি 40/2। যদিও আমি পুরোপুরি নিশ্চিত নই। আমি যখন end_score4000 এ সেট করলাম (এবং এটি targetগণনায় এটি ব্যবহারের জন্য আপনার বটটি পরিবর্তন করেছি ), 15-16 বটগুলি আরও অনেক ভাল ছিল। তবে গেমটি যদি আপনার স্কোর বাড়ানোর বিষয়ে হয় তবে এটি তুচ্ছ।
সর্বোচ্চ

1
@ ম্যাক্সবিবি end_score4000 হলে 200 টার্নের আগে 4000 পাওয়া প্রায় অসম্ভব। এবং গেমটি কেবলমাত্র 200 টার্নে সর্বোচ্চ স্কোর পেয়েছে। এবং 15 এ থামানো কাজ করা উচিত যেহেতু এবার এক পালা সর্বোচ্চ স্কোর করার কৌশলটি 200 টার্নে সর্বোচ্চ স্কোরের সমান।
tsh

10

অভিযোজক রোলার

আরও আক্রমণাত্মক শুরু হয় এবং রাউন্ডের শেষের দিকে শান্ত হয়।
যদি এটি বিশ্বাস করে যে এটি জিতেছে, তবে সুরক্ষার জন্য অতিরিক্ত সময় রোল করুন।

class AdaptiveRoller(Bot):

    def make_throw(self, scores, last_round):
        lim = min(self.end_score - scores[self.index], 22)
        while sum(self.current_throws) < lim:
            yield True
        if max(scores) == scores[self.index] and max(scores) >= self.end_score:
            yield True
        while last_round and scores[self.index] + sum(self.current_throws) <= max(scores):
            yield True
        yield False

দুর্দান্ত প্রথম জমা! আমি এটি পরীক্ষার জন্য লিখেছি আমার বটগুলির বিরুদ্ধে চালাব, তবে আরও বট পোস্ট করা হলে আমি হাইস্কোরটি আপডেট করব।
সর্বোচ্চ

আপনার বটটিতে সামান্য পরিবর্তন নিয়ে আমি কিছু পরীক্ষা চালিয়েছি। lim = max(min(self.end_score - scores[self.index], 24), 6)সর্বোচ্চ ২৪-এ উন্নীত করা এবং সর্বনিম্ন of জন যোগ করা উভয়ই তাদের নিজস্ব হিসাবে বিজয়ী শতাংশ বৃদ্ধি করে এবং আরও বেশি সংযুক্ত করে।
এক্রোয়েল

@ ক্রোকেল: দুর্দান্ত! শেষ পর্যন্ত কয়েকবার এটি রোল হয়ে যায় তা নিশ্চিত করার জন্য আমি অনুরূপ কিছু করার ইচ্ছা নিয়েছিলাম, তবে আমি এখনও এটি করার জন্য সময় নিইনি। যদিও আশ্চর্যজনকভাবে, আমি যখন 100k রান করি তখন এই মানগুলির সাথে আরও খারাপ পারফর্ম করা মনে হয়। যদিও আমি কেবল 18 বট দিয়ে পরীক্ষা করেছি। সমস্ত বট দিয়ে আমার কিছু পরীক্ষা করা উচিত।
এমিগানা

5

আরম্ভ

class Alpha(Bot):
    def make_throw(self, scores, last_round):
        # Throw until we're the best.
        while scores[self.index] + sum(self.current_throws) <= max(scores):
            yield True

        # Throw once more to assert dominance.
        yield True
        yield False

আলফা কারও চেয়ে দ্বিতীয় হতে অস্বীকৃতি জানায়। যতক্ষণ না উচ্চতর স্কোর সহ একটি বট থাকবে, তা ঘোরানো থাকবে।


কীভাবে yieldকাজ করে, যদি এটি ঘূর্ণায়মান শুরু হয় তবে তা কখনই থামবে না। আপনি my_scoreলুপ আপডেট করতে চাইবেন ।
স্পাইটমাস্টার

@স্পিটিমাস্টার স্থির, ধন্যবাদ
মনমোনিক

5

NotTooFarBehindBot

class NotTooFarBehindBot(Bot):
    def make_throw(self, scores, last_round):
        while True:
            current_score = scores[self.index] + sum(self.current_throws)
            number_of_bots_ahead = sum(1 for x in scores if x > current_score)
            if number_of_bots_ahead > 1:
                yield True
                continue
            if number_of_bots_ahead != 0 and last_round:
                yield True
                continue
            break
        yield False

ধারণাটি হ'ল অন্যান্য বট পয়েন্টগুলি হারাতে পারে, সুতরাং ২ য় স্থানে থাকা খারাপ নয় - তবে আপনি যদি খুব পিছনে থাকেন তবে আপনি সম্ভবত বিরতিতে যেতে পারেন।


1
পিপিসিজিতে আপনাকে স্বাগতম! আমি আপনার জমা দেওয়ার বিষয়ে নজর রাখছি এবং মনে হচ্ছে যে খেলাগুলি যত বেশি খেলোয়াড়ের মধ্যে রয়েছে, আপনার বটের জন্য জয়ের পরিমাণ কম। আমি সরাসরি বলতে পারি না কেন। 1vs1 এর সাথে বট মিলছে আপনি একটি 10% উইনরেট পান rate ধারণাটি প্রতিশ্রুতিবদ্ধ শোনায়, এবং কোডটি সঠিক দেখাচ্ছে বলে আপনার উইনরেট কেন বেশি নয় তা আমি সত্যিই বলতে পারছি না।
ম্যাক্সব

6
আমি আচরণ মধ্যে লাগছিল, আর এই লাইন আমাকে বিভ্রান্ত করেছেন: 6: Bot NotTooFarBehindBot plays [4, 2, 4, 2, 3, 3, 5, 5, 1, 4, 1, 4, 2, 4, 3, 6] with scores [0, 9, 0, 20, 0, 0, 0] and last round == False। যদিও আপনার বটটি 7 টি ছোঁড়ার পরে লিডে রয়েছে, এটি 6 টি হিট হওয়া অবধি অব্যাহত থাকে I'm আমি এটি টাইপ করার সাথে সাথে আমি বিষয়টি আবিষ্কার করেছি! scoresশুধুমাত্র মোট স্কোর, না বর্তমান রাউন্ডের জন্য ডাই ক্ষেত্রে ধারণ করে। আপনি হতে এটি পরিবর্তন করা উচিত নয় current_score = scores[self.index] + sum(self.current_throws)
ম্যাক্সব

ধন্যবাদ - যে পরিবর্তন করতে হবে!
স্টুয়ার্ট মুর

5

GoHomeBot

class GoHomeBot(Bot):
    def make_throw(self, scores, last_round):
        while scores[self.index] + sum(self.current_throws) < 40:
            yield True
        yield False

আমরা বড় হতে চাই বা বাড়ি যেতে চাই, তাই না? GoHomeBot বেশিরভাগ ক্ষেত্রে কেবল ঘরে যায়। (তবে আশ্চর্যজনকভাবে কি ভাল!)


যেহেতু এই বটটি সর্বদা 40 পয়েন্টে যায় তাই scoresতালিকার কোনও পয়েন্ট কখনই থাকবে না । এর আগে (GoToEnd বট) এর মতো বট ছিল, তবে ডেভিড তাদের উত্তর মুছে ফেলে। আমি এই বটটি আপনার দ্বারা প্রতিস্থাপন করব।
ম্যাক্সবি

1
এই বটগুলির বিস্তৃত পরিসংখ্যানগুলি দেখে এটি বেশ মজাদার: পয়েন্টএয়ারফোর্ডস এবং স্টপবট ব্যতীত এই বটটিতে সর্বনিম্ন গড় পয়েন্ট রয়েছে এবং এটিতে খুব সুন্দর জয় অনুপাত রয়েছে
বেলহেনিক্স

5

EnsureLead

class EnsureLead(Bot):

    def make_throw(self, scores, last_round):
        otherScores = scores[self.index+1:] + scores[:self.index]
        maxOtherScore = max(otherScores)
        maxOthersToCome = 0
        for i in otherScores:
            if (i >= 40): break
            else: maxOthersToCome = max(maxOthersToCome, i)
        while True:
            currentScore = sum(self.current_throws)
            totalScore = scores[self.index] + currentScore
            if not last_round:
                if totalScore >= 40:
                    if totalScore < maxOtherScore + 10:
                        yield True
                    else:
                        yield False
                elif currentScore < 20:
                    yield True
                else:
                    yield False
            else:
                if totalScore < maxOtherScore + 1:
                    yield True
                elif totalScore < maxOthersToCome + 10:
                    yield True
                else:
                    yield False

এনএসওরলিড GoTo20Bot থেকে ধারনা ধার করে। এটি এমন ধারণাটি যুক্ত করে যা এটি সর্বদা বিবেচনা করে (যখন সর্বশেষে বা 40 এ পৌঁছায়) এমন আরও কিছু রয়েছে যা কমপক্ষে আরও একটি রোল রাখবে। সুতরাং, বট তাদের থেকে কিছুটা এগিয়ে যাওয়ার চেষ্টা করে, যাতে তাদের ধরতে হয়।


4

Roll6TimesV2

বর্তমানের সেরাটিকে পরাজিত করে না, তবে আমি মনে করি এটি আরও বট খেললে আরও ভাল হবে।

class Roll6Timesv2(Bot):
    def make_throw(self, scores, last_round):

        if not last_round:
            i = 0
            maximum=6
            while ((i<maximum) and sum(self.current_throws)+scores[self.index]<=40 ):
                yield True
                i=i+1

        if last_round:
            while scores[self.index] + sum(self.current_throws) < max(scores):
                yield True
        yield False

উপায় দ্বারা সত্যিই দুর্দান্ত খেলা।


পিপিসিজিতে আপনাকে স্বাগতম! আপনার প্রথম কোট চ্যালেঞ্জই নয়, আপনার প্রথম জবাবের জন্য খুব চিত্তাকর্ষক। আপনি খেলা পছন্দ করেছেন যে খুশি! সন্ধ্যা হওয়ার পরে যখন আমি এটি খেলি তখন খেলার সেরা কৌশল সম্পর্কে আমার প্রচুর আলোচনা হয়েছিল, সুতরাং এটি কোনও চ্যালেঞ্জের জন্য নিখুঁত বলে মনে হয়েছিল। আপনি বর্তমানে 18 এর মধ্যে তৃতীয় স্থানে রয়েছেন
সর্বোচ্চ

4

StopBot

class StopBot(Bot):
    def make_throw(self, scores, last_round):
        yield False

আক্ষরিক মাত্র একটি নিক্ষেপ।

এটি বেস Botশ্রেণীর সমান ।


1
আফসোস করবেন না! আপনি সমস্ত নিয়ম অনুসরণ করছেন, যদিও আমি আশঙ্কা করছি যে আপনার বটটি প্রতি রাউন্ডে গড়ে 2.5 পয়েন্টের সাথে ভয়ঙ্করভাবে কার্যকর হয় না।
ম্যাক্সব

1
আমি জানি, কারও কারও কাছে যদিও এই বট পোস্ট করতে হয়েছিল। ক্ষতির জন্য বটগুলি হ্রাস করুন।
জাকারি

5
আমি বলব যে আমি আপনার বটটি শেষ সিমুলেশনে এক জয়ের সুরক্ষায় মুগ্ধ হয়েছি, তা প্রমাণ করে যে এটি সম্পূর্ণ অকেজো নয়।
সর্বোচ্চ

2
এটি খেলা খেলেনি ?! অবাক করা বিষয়।
জাকারি

3

MakeMyOwn_dice (BMO_d)

এই বটটি পাশা পছন্দ করে, এটি নিজস্ব নিজস্ব ডাইস এনেছে 2 (সেরাটি সম্পাদন করে বলে মনে হচ্ছে)। একটি রাউন্ডে পাশা নিক্ষেপের আগে, এটি নিজস্ব 2 পাশা ছুঁড়ে দেয় এবং তাদের যোগফলগুলি গণনা করে, এটি এটি সম্পাদন করতে চলেছে এমন সংখ্যা, এটি ইতিমধ্যে 40 পয়েন্ট না থাকলে কেবল এটি ছোঁড়ে।

class BringMyOwn_dice(Bot):

    def __init__(self, *args):
        import random as rnd
        self.die = lambda: rnd.randint(1,6)
        super().__init__(*args)

    def make_throw(self, scores, last_round):

        nfaces = self.die() + self.die()

        s = scores[self.index]
        max_scores = max(scores)

        for _ in range(nfaces):
            if s + sum(self.current_throws) > 39:
                break
            yield True

        yield False

2
আমি একটি কয়েন ফ্লিপ ব্যবহার করে একটি এলোমেলো বট সম্পর্কে ভাবছিলাম, তবে এটি চ্যালেঞ্জের সাথে আত্মার চেয়ে আরও বেশি কিছু! আমি মনে করি যে দুটি ডাইস সেরা সঞ্চালন করে, যেহেতু আপনি যখন প্রতি ডাইস ing-। বার মরাবেন তখন আপনি প্রতি রাউন্ডে সর্বাধিক পয়েন্ট পান, যখন দুটি পাশা castালাইয়ের সময় গড় স্কোরের কাছাকাছি থাকে।
ম্যাক্সব

3

FooBot

class FooBot(Bot):
    def make_throw(self, scores, last_round):
        max_score = max(scores)

        while True:
            round_score = sum(self.current_throws)
            my_score = scores[self.index] + round_score

            if last_round:
                if my_score >= max_score:
                    break
            else:
                if my_score >= self.end_score or round_score >= 16:
                    break

            yield True

        yield False

# Must throw at least onceঅনিবদ্ধ - এটি আপনার বটকে কল করার আগে একবার ছুড়ে দেয়। আপনার বট সর্বদা সর্বনিম্ন দুবার নিক্ষেপ করবে।
স্পাইটমাস্টার

ধন্যবাদ। পদ্ধতিটির নাম দিয়ে আমি বিভ্রান্ত হয়েছিলাম।
পিটার টেলর

@ পিটারটেলর আপনার জমা দেওয়ার জন্য ধন্যবাদ! আমি make_throwপ্রথমদিকেই এই নামটির নামকরণ করেছি , যখন আমি চেয়েছিলাম খেলোয়াড়রা তাদের পালাটি এড়াতে সক্ষম হয়। আমি অনুমান করি যে আরও উপযুক্ত নাম হবে keep_throwing। স্যান্ডবক্সে প্রতিক্রিয়া জানানোর জন্য ধন্যবাদ, এটি এটিকে যথাযথ চ্যালেঞ্জ করতে সত্যই সহায়তা করেছে!
ম্যাক্সবি

3

বিগ আর্লি তাড়াতাড়ি যান

class GoBigEarly(Bot):
    def make_throw(self, scores, last_round):
        yield True  # always do a 2nd roll
        while scores[self.index] + sum(self.current_throws) < 25:
            yield True
        yield False

ধারণা: প্রারম্ভিক রোল (25 এ পেয়ে) এ বড় জয়ের চেষ্টা করুন তারপরে সেখান থেকে একবারে 2 টি রোল নিন।


3

BinaryBot

শেষ স্কোরের কাছাকাছি যাওয়ার চেষ্টা করে, যাতে অন্য কেউ শেষ রাউন্ডটি ট্রিগার করার সাথে সাথে এটি জয়ের জন্য তাদের স্কোরকে হারাতে পারে। লক্ষ্য সর্বদা বর্তমান স্কোর এবং শেষ স্কোরের মাঝামাঝি।

class BinaryBot(Bot):

    def make_throw(self, scores, last_round):
        target = (self.end_score + scores[self.index]) / 2
        if last_round:
            target = max(scores)

        while scores[self.index] + sum(self.current_throws) < target:
            yield True

        yield False

আকর্ষণীয়, Hesitateএছাড়াও প্রথম লাইন অতিক্রম করতে অস্বীকার। আপনার classস্টাফ দিয়ে আপনার ফাংশনটি ঘিরে রাখা দরকার ।
খ্রিস্টান সিভর্স

3

PointsAreForNerdsBot

class PointsAreForNerdsBot(Bot):
    def make_throw(self, scores, last_round):
        while True:
            yield True

এটির কোনও ব্যাখ্যা দরকার নেই।

OneInFiveBot

class OneInFiveBot(Bot):
    def make_throw(self, scores, last_round):
        while random.randint(1,5) < 5:
            yield True
        yield False

এটি নিজের 5-পার্শ্বযুক্ত ডাইতে পাঁচটিতে রোল না হওয়া পর্যন্ত ঘূর্ণায়মান রাখে। পাঁচটি ছয়টির চেয়ে কম, সুতরাং এটি জিততে হবে!


2
পিপিসিজিতে আপনাকে স্বাগতম! আমি নিশ্চিত আপনি সচেতন, কিন্তু আপনার প্রথম বট আক্ষরিক অর্থে এই প্রতিযোগিতার সবচেয়ে খারাপ বট! OneInFiveBotএকটি ঝরঝরে ধারণা, কিন্তু আমি এটা আরো উন্নত বট কিছু তুলনায় শেষ গেমে ভুগছেন মনে করি। তবুও দুর্দান্ত জমা!
সর্বোচ্চ

2
OneInFiveBotউপায় যে তিনি ধারাবাহিকভাবে সর্বোচ্চ সামগ্রিক স্কোর পৌঁছেছে বেশ আকর্ষণীয়।
এক্রোয়েল

1
StopBotএকটি ঘুষি ব্যাগ দেওয়ার জন্য ধন্যবাদ : পি। ওয়ানআইএনফাইভবট আসলে বেশ ঝরঝরে সুন্দর কাজ!
জ্যাকারি

@ ম্যাক্সব ইয়েপ, সেখানেই আমি নামটি পেয়েছি। আমি সততার সাথে পরীক্ষা করিনি OneInFiveBotএবং এটি আমার প্রত্যাশার চেয়ে অনেক ভাল করছে
The_obi


3

LizduadacBot

1 ধাপে জয়ের চেষ্টা করে। শেষ শর্তটি কিছুটা আধ্যাত্মিক।

এটিও আমার প্রথম পোস্ট (এবং আমি পাইথনে নতুন), সুতরাং যদি আমি "পয়েন্টসআরফোরইনার্ডসবট" কে পরাজিত করি তবে আমি খুশি হব!

class LizduadacBot(Bot):

    def make_throw(self, scores, last_round):
        while scores[self.index] + sum(self.current_throws) < 50 or scores[self.index] + sum(self.current_throws) < max(scores):
            yield True
        yield False

পিপিসিজিতে আপনাকে স্বাগতম (এবং পাইথনে স্বাগতম)! PointsAreForNerdsBotআপনার বিপক্ষে হারাতে আপনার খুব কষ্ট হয়েছে, তবে আপনার বটটি আসলে বেশ ভাল ভাড়া নেয়। আমি আজ রাত্রে বা কালকে স্কোর আপডেট করব, তবে আপনার উইনরেট প্রায় 15%, যা গড় 12.5% ​​এর চেয়ে বেশি।
ম্যাক্সবি

"কঠিন সময়" দ্বারা, তাদের অর্থ এটি অসম্ভব (যদি আমি খুব বেশি ভুল বুঝি না)
জ্যাকারি

@ ম্যাক্সবি আমি আসলে ভাবি নি যে জয়ের হার এত বেশি হবে! (আমি স্থানীয়ভাবে এটি পরীক্ষা করে দেখিনি)। আমি ভাবছি 50 টি পরিবর্তন করা যদি কিছুটা বেশি / কম হয় তবে জয়ের হার বাড়বে।
লিজডুডাক

3

SlowStart

এই বট টিসিপি স্লো স্টার্ট অ্যালগরিদম প্রয়োগ করে। এটি তার আগের রোল অনুসারে এর রোলগুলির সংখ্যা ( না ) সামঞ্জস্য করে : যদি এটি পূর্ববর্তী ঘুরে 6 টি রোল না করে, তবে এই পালাটির জন্য বা বৃদ্ধি করে না ; যদিও এটি হ্রাস করে না যদি তা করে।

class SlowStart(Bot):
    def __init__(self, *args):
        super().__init__(*args)
        self.completeLastRound = False
        self.nor = 1
        self.threshold = 8

    def updateValues(self):
        if self.completeLastRound:
            if self.nor < self.threshold:
                self.nor *= 2
            else:
                self.nor += 1
        else:
            self.threshold = self.nor // 2
            self.nor = 1


    def make_throw(self, scores, last_round):

        self.updateValues()
        self.completeLastRound = False

        i = 1
        while i < self.nor:
            yield True

        self.completeLastRound = True        
        yield False

পিপিসিজিতে আপনাকে স্বাগতম! আকর্ষণীয় পদ্ধতির, আমি জানি না যে এটি এলোমেলো ওঠানামার জন্য কতটা সংবেদনশীল। এই রানটি চালানোর জন্য দুটি জিনিস দরকার: def updateValues():হওয়া উচিত def updateValues(self):(বা def update_values(self):আপনি পিইপি 8 অনুসরণ করতে চান)। দ্বিতীয়ত, কলটি updateValues()পরিবর্তে self.updateValues()(বা self.update_vales()) হওয়া উচিত ।
সর্বোচ্চ

2
এছাড়াও, আমি মনে করি আপনার iযখন আপনার লভ সময়টি পরিবর্তনশীল আপডেট করতে হবে । এই মুহূর্তে আপনার বটটি হয় পুরোপুরি লুপটি পাস করবে বা 6 টি না হওয়া পর্যন্ত
লুপটিতে

বর্তমান হাইস্কোরে, আমি এই পরিবর্তনগুলি বাস্তবায়নের স্বাধীনতা গ্রহণ করেছি। আমি মনে করি আপনি self.norএটির জন্য প্রাথমিক মানটি পরীক্ষা করতে পারবেন এবং দেখুন এটি কীভাবে আপনার বটের কার্য সম্পাদনকে প্রভাবিত করে।
সর্বোচ্চ 25

3

KwisatzHaderach

import itertools
class KwisatzHaderach(Bot):
    """
    The Kwisatz Haderach foresees the time until the coming
    of Shai-Hulud, and yields True until it is immanent.
    """
    def __init__(self, *args):
        super().__init__(*args)
        self.roller = random.Random()
        self.roll = lambda: self.roller.randint(1, 6)
        self.ShaiHulud = 6

    def wormsign(self):
        self.roller.setstate(random.getstate())
        for i in itertools.count(0):
            if self.roll() == self.ShaiHulud:
                return i

    def make_throw(self, scores, last_round):
        target = max(scores) if last_round else self.end_score
        while True:
            for _ in range(self.wormsign()):
                yield True
            if sum(self.current_throws) > target + random.randint(1, 6):
                yield False                                               

বিবেক সাধারণত জয়ী হয় - তবে নিয়ত সর্বদা এড়ানো যায় না।
শাই-হুলুদের উপায় দুর্দান্ত এবং রহস্যময়!


এই চ্যালেঞ্জের প্রথম দিনগুলিতে (যেমন NeoBotপোস্ট হওয়ার আগে ) আমি প্রায় তুচ্ছ Oracleবোট লিখেছিলাম :

    class Oracle(Bot):
        def make_throw(self, scores, last_round):
        randơm = random.Random()
        randơm.setstate(random.getstate())
        while True:
            yield randơm.randint(1, 6) != 6

তবে এটি যথেষ্ট আকর্ষণীয় মনে হয়নি বলে এটি পোস্ট করে নি;) তবে একবার NeoBotনেতৃত্বের দিকে চলে গেলে আমি ভবিষ্যতের ভবিষ্যদ্বাণী করার নির্ভুল দক্ষতাকে কীভাবে পরাজিত করব তা নিয়ে ভাবতে শুরু করি। সুতরাং এখানে একটি uneিবির উদ্ধৃতি; পল অ্যাট্রেইডস, কুইসাত্জ হাদের্যাচ একটি নেক্সাসে এসে দাঁড়িয়েছিলেন যা থেকে বিভিন্ন ফিউচারের একটি অনন্তকে তালিকাভুক্ত করতে পারে:

তিনি অনুধাবন করেছিলেন, প্রজ্ঞাটি এমন একটি আলোকসজ্জা ছিল যা এটি প্রকাশ করেছিল তার সীমাবদ্ধতাকে একত্রিত করেছিল - একবারে নির্ভুলতা এবং অর্থবোধক ত্রুটির উত্স। এক ধরণের হাইজেনবার্গের অনির্দিষ্টতা হস্তক্ষেপ করেছিল: শক্তির ব্যয় যা সে যা দেখেছিল তা প্রকাশ করেছিল, যা দেখেছিল তা বদলেছে…… সবচেয়ে মিনিটের ক্রিয়া- চোখের পলক, একটি অযত্নের শব্দ, বালির এক অপরিশোধিত দানা- এক বিশাল লিভারকে সরিয়ে নিয়েছে পরিচিত মহাবিশ্ব। তিনি পরিণামের সাথে সহিংসতা দেখতে পেয়েছিলেন এতগুলি পরিবর্তনশীল যে তার সামান্যতম আন্দোলন নিদর্শনগুলিতে বিশাল স্থান পরিবর্তন করেছিল created

এই দৃষ্টিভঙ্গি তাকে অচলতার মধ্যে স্থির রাখতে চেয়েছিল, কিন্তু এটিও এর পরিণতিগুলির সাথে কাজ করেছিল।

সুতরাং এখানে উত্তর ছিল: ভবিষ্যতের ভবিষ্যদ্বাণী করা এটি পরিবর্তন করা; এবং যদি আপনি খুব সাবধান হন তবে বেছে বেছে পদক্ষেপ বা নিষ্ক্রিয়তার মাধ্যমে আপনি এটিকে একটি সুবিধাজনক উপায়ে পরিবর্তন করতে পারেন - কমপক্ষে বেশিরভাগ সময়। এমনকি KwisatzHaderach100% জয়ের হারও পেতে পারে না!


দেখে মনে হচ্ছে এই বটটি এলোমেলো নম্বর জেনারেটরের অবস্থার পরিবর্তন করে যাতে এটি 6 রোলিং এড়াতে পারে বা কমপক্ষে এটি প্রত্যাশা করে তা নিশ্চিত করে। একই হারকোনেনবোটের জন্য যায়। তবে আমি নোট করছি যে এই বটগুলির জয়ের হার নব্যবটের তুলনায় অনেক বেশি। আপনি এলোমেলো নম্বর জেনারেটরটি 6 রোলিং থেকে রোধ করার জন্য সক্রিয়ভাবে পরিচালনা করছেন?
13

ওহ, আমার প্রথম পড়াতে আমি লক্ষ্য করিনি যে এটি কেবল সুন্দর NeoBotনয়, আরও ভাল! আমি এও পছন্দ করি যে আপনি এখানে র্যান্ডমনেস (বিশেষত নিয়ন্ত্রক) ব্যবহার করে যা করা উচিত তার একটি উদাহরণ দিন: নিজের random.Randomউদাহরণটি ব্যবহার করুন । পছন্দ NeoBotকরুন, এটি নিয়ামকের অনির্ধারিত প্রয়োগের বিশদ পরিবর্তনের ক্ষেত্রে কিছুটা সংবেদনশীল বলে মনে হচ্ছে।
খ্রিস্টান সিভর্স

@ ম্যাক্সবি: আরএনজি HarkonnenBotস্পর্শ করে না; এটি এলোমেলো সংখ্যা সম্পর্কে মোটেই পরোয়া করে না। এটি কেবলমাত্র সমস্ত অন্যান্য বটকেই বিষাক্ত করে তোলে, তারপরে যত তাড়াতাড়ি আস্তে আস্তে ফিনিস লাইনে উঠে যায়। অনেক রন্ধনসম্পর্কিত খাবার হিসাবে, প্রতিশোধ হ'ল একটি থালা, দীর্ঘ এবং সূক্ষ্ম প্রস্তুতির পরে আস্তে আস্তে সঞ্চিত।
দানি ও

@ খ্রিস্টিয়ানসিভারস: (এবং ) এর বিপরীতে , বাস্তবায়নের কেবলমাত্র একটি বিশদের উপর নির্ভর করে; বিশেষত এটি র্যান্ডম.রেন্ডম () কীভাবে প্রয়োগ করা হয় তা কেবল জানতে হবে না, কেবল নিয়ামক এটি ব্যবহার করেন; ডিNeoBotHarkonnenBotKwisatzHaderach
দানি ও

1
আমি আপনার সমস্ত বট দেখেছি আমি চিকিত্সা করার সিদ্ধান্ত নিয়েছি KwisatzHaderachএবং HarkonnenBotএকইভাবে NeoBot। তারা কম গেমগুলির সাথে একটি সিমুলেশন থেকে তাদের স্কোরগুলি গ্রহণ করবে এবং সরকারী অনুকরণে থাকবে না। যাইহোক, তারা অনেকটা পছন্দ মতো হাইস্কোর তালিকায় শেষ হবে NeoBot। তাদের সরকারী সিমুলেশন না থাকার মূল কারণ হ'ল তারা অন্যান্য বট কৌশলগুলিকে গণ্ডগোল করে দেবে। যাহোক. WisdomOfCrowdsঅংশগ্রহণের জন্য ভালভাবে উপযোগী হওয়া উচিত এবং আপনি যে নতুন পরিবর্তন করেছেন তা সম্পর্কে আমি আগ্রহী!
সর্বোচ্চ

2
class ThrowThriceBot(Bot):

    def make_throw(self, scores, last_round):
        yield True
        yield True
        yield False 

ঠিক আছে, এটি একটি সুস্পষ্ট


আমি বর্গের সেই শ্রেণীর সাথে কিছু পরীক্ষা-নিরীক্ষা করেছি (প্রথমবারের মতো গেমটি খেলতে গিয়ে আমি এটি কৌশলটি ব্যবহার করেছি)। আমি তখন 4 টি ছোঁড়া দিয়েছিলাম, যদিও রাউন্ডে 5-6 এর উচ্চতর গড় স্কোর থাকে।
সর্বোচ্চ

এছাড়াও, আপনার প্রথম KotH জবাবের জন্য অভিনন্দন!
ম্যাক্সব

2
class LastRound(Bot):
    def make_throw(self, scores, last_round):
        while sum(self.current_throws) < 15 and not last_round and scores[self.index] + sum(self.current_throws) < 40:
            yield True
        while max(scores) > scores[self.index] + sum(self.current_throws):
            yield True
        yield False

লাস্ট রাউন্ড এটি সর্বদা সর্বশেষ রাউন্ডের মতো কাজ করে এবং এটি শেষ বট: এটি শীর্ষে না হওয়া পর্যন্ত এটি ঘূর্ণায়মান থাকে। এটি 15 টিরও কম পয়েন্টে স্থির থাকতে চায় না যদি না এটি আসলে শেষ রাউন্ড না হয় বা এটি 40 পয়েন্টে পৌঁছায়।


আকর্ষণীয় পদ্ধতির। আমি মনে করি আপনার বটটি যদি পিছনে পড়তে শুরু করে তবে তা ভোগেন। যেহেতু একক রাউন্ডে> 30 পয়েন্ট পাওয়ার অসুবিধা কম তাই আপনার বটটি বর্তমান স্কোরে থাকার সম্ভাবনা বেশি।
ম্যাক্সব

1
আমি সন্দেহ করি যে এটি আমার একই ভুল দ্বারা হয়েছে (নোটটোফারহাইন্ডবট মন্তব্য দেখুন) - শেষ রাউন্ডের মতো আপনি যদি জিত না হন তবে আপনি 6 টি না পাওয়া অবধি ছোঁড়াতে থাকবেন (স্কোর [স্ব। ইন্ডেক্স] কখনই আপডেট হয় না) আসলে - আপনার কি সেই অসমতা ভুল পথে আছে? সর্বাধিক (স্কোর) সর্বদা> = স্কোর [self.index] হবে
স্টুয়ার্ট মুর

@ স্টার্টমুর হা হা, হ্যাঁ, আমি মনে করি আপনি ঠিক বলেছেন। ধন্যবাদ!
স্পাইটমাস্টার

আমি সন্দেহ করি যে আপনি 2 ও "শেষ এবং শেষ" চান যা করতে চান - অন্যথায় 2 য় সময় ব্যবহার করা হবে যদিও শেষ_আমিটি সত্য কিনা
স্টুয়ার্ট মুর

3
এটা ইচ্ছাকৃত। এটি সর্বদা তার পালা শেষ করার সময় নেতৃত্বে হওয়ার চেষ্টা করে।
স্পাইটমাস্টার

2

QuotaBot

আমি প্রয়োগ করি এমন একটি নিখুঁত "কোটা" সিস্টেম, যা বাস্তবে মোটামুটিভাবে মোটামুটিভাবে স্কোর করে।

class QuotaBot(Bot):
    def __init__(self, *args):
        super().__init__(*args)
        self.quota = 20
        self.minquota = 15
        self.maxquota = 35

    def make_throw(self, scores, last_round):
        # Reduce quota if ahead, increase if behind
        mean = sum(scores) / len(scores)
        own_score = scores[self.index]

        if own_score < mean - 5:
            self.quota += 1.5
        if own_score > mean + 5:
            self.quota -= 1.5

        self.quota = max(min(self.quota, self.maxquota), self.minquota)

        if last_round:
            self.quota = max(scores) - own_score + 1

        while sum(self.current_throws) < self.quota:
            yield True

        yield False


if own_score mean + 5:আমার জন্য একটি ত্রুটি দেয়। এছাড়াওwhile sum(self.current_throws)
স্পাইটমাস্টার

@ শিপমাস্টার স্ট্যাক এক্সচেঞ্জে আটকানো একটি ত্রুটি ছিল, এখনই কাজ করা উচিত।
ফ্লিপট্যাক

@ সুপারমাস্টার কারণ এটি ছিল যে আমি যে ট্যাগগুলি ব্যবহার <><pre>
করছিলাম সেগুলিতে

2

ExpectationsBot

কেবল এটি সরাসরি খেলায়, পাশা নিক্ষেপের প্রত্যাশিত মান গণনা করে এবং এটি ইতিবাচক হলেই তা তৈরি করে।

class ExpectationsBot(Bot):

    def make_throw(self, scores, last_round):
        #Positive average gain is 2.5, is the chance of loss greater than that?
        costOf6 = sum(self.current_throws) if scores[self.index] + sum(self.current_throws) < 40  else scores[self.index] + sum(self.current_throws)
        while 2.5 > (costOf6 / 6.0):
            yield True
            costOf6 = sum(self.current_throws) if scores[self.index] + sum(self.current_throws) < 40  else scores[self.index] + sum(self.current_throws)
        yield False

কন্ট্রোলারটি চালাতে আমার সমস্যা হচ্ছে, একটি "নেমেরর: নাম 'বটস_পার_গ্যাম" সংজ্ঞায়িত নয় "মাল্টিথ্রেডেড জনের উপর, সুতরাং কীভাবে এটি সম্পাদন করে তা বাস্তবে কোনও ধারণা নেই।


1
আমি মনে করি এটি "16 এ যান" বটের সমতুল্য হয়ে যায়, তবে এখনও আমাদের মধ্যে একটি নেই
স্টুয়ার্ট মুর

1
@ স্টুয়ার্টমুর এটি ... খুব সত্য পয়েন্ট, হ্যাঁ
কেইন

আমি যখন এটি আমার উইন্ডোজ মেশিনে চালিত করতাম তখন আমি নিয়ন্ত্রকের সাথে আপনার সমস্যাগুলিতে চলে যাই। একরকম এটি আমার লিনাক্স মেশিনে দৌড়ে গেছে। আমি নিয়ামকটি আপডেট করছি, এবং পোস্টটি শেষ হয়ে গেলে এটি আপডেট করা হবে।
ম্যাক্সব

@ ম্যাক্সবি ধন্যবাদ, সম্ভবত বিভিন্ন প্রক্রিয়াতে ভেরিয়েবল উপলব্ধ probably এফওয়াইআই এটিও আপডেট করেছে, ফলন পাওয়ার আশেপাশে আমি নির্লিপ্ত ত্রুটি করেছি: /
কেইন

2

BlessRNG

class BlessRNG(Bot):
    def make_throw(self, scores, last_round):
        if random.randint(1,2) == 1 :
            yield True
        yield False

BlessRNG ফ্র্যাঙ্কারজেড গাবেন BlessRNG


2

FortyTeen

class FortyTeen(Bot):
    def make_throw(self, scores, last_round):
        if last_round:
            max_projected_score = max([score+14 if score<self.end_score else score for score in scores])
            target = max_projected_score - scores[self.index]
        else:
            target = 14

        while sum(self.current_throws) < target:
            yield True
        yield False

শেষ রাউন্ড পর্যন্ত 14 পয়েন্টের জন্য চেষ্টা করুন, তারপরে ধরে নিন অন্য সবাই 14 পয়েন্টের জন্য চেষ্টা করে যাচ্ছে এবং সেই স্কোরটি টাই করার চেষ্টা করবে।


আমি TypeError: unsupported operand type(s) for -: 'list' and 'int'আপনার বট সঙ্গে পেয়েছিলাম ।
tsh

আমি ধরে নিচ্ছি যে max_projected_scoreপুরো তালিকার চেয়ে আপনার তালিকাটি সর্বোচ্চ হওয়া উচিত, আমি কি সঠিক? অন্যথায় আমি tsh হিসাবে একই সমস্যা পেতে।
সর্বোচ্চ

ওফস, ঠিক করার জন্য সম্পাদিত।
হিস্টোক্র্যাট

2

দ্বিধা করা

দুটি পরিমিত পদক্ষেপ করে, তারপরে অন্য কেউ লাইনটি অতিক্রম করার জন্য অপেক্ষা করে। আপডেট করা সংস্করণ আর হাইস্কোরকে পরাজিত করার চেষ্টা করে না, কেবল এটি পৌঁছাতে চায় - উত্স কোডের দুটি বাইট মুছে ফেলে কর্মক্ষমতা উন্নত করে!

class Hesitate(Bot):
    def make_throw(self, scores, last_round):
        myscore = scores[self.index]
        if last_round:
            target = max(scores)
        elif myscore==0:
            target = 17
        else:
            target = 35
        while myscore+sum(self.current_throws) < target:
            yield True
        yield False

2

বিদ্রোহী

এই বটটি Hesitate উন্নত সর্বশেষ রাউন্ডের কৌশলটির সহজ কৌশলটির সাথে একত্রিত করে BotFor2X, এটি কে তা মনে করার চেষ্টা করে এবং বুনো হয়ে যায় যখন এটি খুঁজে পায় কোনও মায়ায় পড়ে।

class Rebel(Bot):

    p = []

    def __init__(self,*args):
        super().__init__(*args)
        self.hide_from_harkonnen=self.make_throw
        if self.p:
            return
        l = [0]*5+[1]
        for i in range(300):
            l.append(sum(l[i:])/6)
        m=[i/6 for i in range(1,5)]
        self.p.extend((1-sum([a*b for a,b in zip(m,l[i:])])
                                          for i in range(300) ))

    def update_state(self,*args):
        super().update_state(*args)
        self.current_sum = sum(self.current_throws)
        # remember who we are:
        self.make_throw=self.hide_from_harkonnen

    def expect(self,mts,ops):
        p = 1
        for s in ops:
            p *= self.p[mts-s]
        return p

    def throw_again(self,mts,ops):
        ps = self.expect(mts,ops)
        pr = sum((self.expect(mts+d,ops) for d in range(1,6)))/6
        return pr>ps

    def make_throw(self, scores, last_round):
        myscore = scores[self.index]
        if len(self.current_throws)>1:
            # hello Tleilaxu!
            target = 666
        elif last_round:
            target = max(scores)
        elif myscore==0:
            target = 17
        else:
            target = 35
        while myscore+self.current_sum < target:
            yield True
        if myscore+self.current_sum < 40:
            yield False
        opscores = scores[self.index+1:] + scores[:self.index]
        for i in range(len(opscores)):
            if opscores[i]>=40:
                opscores = opscores[:i]
                break
        while True:
            yield self.throw_again(myscore+self.current_sum,opscores)

ভাল এটি বেশ মার্জিত :) এছাড়াও, মূল প্রতিযোগিতায় প্রথম এবং দ্বিতীয় স্থান উভয়ই পাওয়ার জন্য অভিনন্দন!
দানি হে

স্বভাবতই আমি টুইট করেছি HarkonnenBotযাতে এটি Rebelআর নিজেকে চালিত করতে পারে না;) এবং আমি এমন টুইটও করেছি TleilaxuBotযাতে এটি Rebelআর সনাক্ত না করে!
দানি ও

1

পাঁচটি নাও

class TakeFive(Bot):
    def make_throw(self, scores, last_round):
        # Throw until we hit a 5.
        while self.current_throws[-1] != 5:
            # Don't get greedy.
            if scores[self.index] + sum(self.current_throws) >= self.end_score:
                break
            yield True

        # Go for the win on the last round.
        if last_round:
            while scores[self.index] + sum(self.current_throws) <= max(scores):
                yield True

        yield False

অর্ধেক সময়, আমরা a এর আগে একটি 5 রোল করব যখন আমরা করি তখন নগদ আউট।


পরিবর্তে আমরা যদি 1 এ থামি তবে এটি ধীর গতিতে অগ্রগতি করে, তবে এটি একক সীমানায় 40 এ যাওয়ার সম্ভাবনা বেশি।
স্মৃতিবিদ্যার

আমার পরীক্ষায়, টেকওন রাউন্ডে টেকফাইভের 24.262 পয়েন্টের তুলনায় রাউন্ডে 20.868 পয়েন্ট পেয়েছে (এবং 0.21 থেকে 0.259 পর্যন্ত উইনরেট নিয়ে এসেছে)। সুতরাং আমি এটি মূল্যবান বলে মনে করি না।
স্পাইটমাস্টার

1

শিকারী

class Chaser(Bot):
    def make_throw(self, scores, last_round):
        while max(scores) > (scores[self.index] + sum(self.current_throws)):
            yield True
        while last_round and (scores[self.index] + sum(self.current_throws)) < 44:
            yield True
        while self.not_thrown_firce() and sum(self.current_throws, scores[self.index]) < 44:
            yield True
        yield False

    def not_thrown_firce(self):
        return len(self.current_throws) < 4

চেসার একটি অবস্থানে পৌঁছানোর চেষ্টা করে যদি এটি শেষ রাউন্ড হয় তবে তিনি মারাত্মকভাবে কমপক্ষে 50 পয়েন্টে পৌঁছানোর চেষ্টা করেছেন ভাল পরিমাপের জন্য তিনি কমপক্ষে চার বার নিক্ষেপ করুন যাই হোক না কেন

[সম্পাদনা 1: শেষ রাউন্ডে স্বর্ণের কৌশলযুক্ত যোগ করা]

[সম্পাদনা 2: আপডেট যুক্তি কারণ আমি ভুল করে ভেবেছিলাম যে একটি বট কেবল সর্বোচ্চ বট স্কোরিংয়ের চেয়ে 40 এ স্কোর করবে]

[3 সম্পাদনা করুন: শেষ খেলায় চেজারটিকে আরও কিছুটা প্রতিরক্ষামূলক করা]


পিপিসিজিতে আপনাকে স্বাগতম! ঝরঝরে ধারণাটি কেবল ধরার চেষ্টা করবে না, তবে প্রথম স্থানটিও পাস করবে। আমি এখনই একটি সিমুলেশন চালাচ্ছি, এবং আমি আপনাকে ভাগ্য কামনা করি!
maxb

ধন্যবাদ! প্রথমদিকে আমি পূর্ববর্তী নেতাকে একটি নির্দিষ্ট পরিমাণে (6 থেকে 20 এর মধ্যে মূল্যবান চেষ্টা করা) ছাড়িয়ে যাওয়ার চেষ্টা করেছি তবে এটি আরও দু'বার মেলা আরও ভাল করে ফেলেছে।
এক্রোয়েল


1

FutureBot

class FutureBot(Bot):
    def make_throw(self, scores, last_round):
        while (random.randint(1,6) != 6) and (random.randint(1,6) != 6):
            current_score = scores[self.index] + sum(self.current_throws)
            if current_score > (self.end_score+5):
                break
            yield True
        yield False

OneStepAheadBot

class OneStepAheadBot(Bot):
    def make_throw(self, scores, last_round):
        while random.randint(1,6) != 6:
            current_score = scores[self.index] + sum(self.current_throws)
            if current_score > (self.end_score+5):
                break
            yield True
        yield False

একজোড়া বট, তারা ডাইসের নিজস্ব সেট নিয়ে আসে এবং ভবিষ্যতের ভবিষ্যদ্বাণী করতে তাদের রোল করে। যদি একটি 6 হয় তবে তারা থামবে, ফিউচারবটটি মনে করতে পারে না যে এটির মধ্যে 2 ডাইস পরবর্তী রোলের জন্য ছিল তাই এটি ছেড়ে দেয়।

আমি আশ্চর্য যে আরও ভাল করতে হবে।

ওয়ানস্টেপএড আমার স্বাদের জন্য ওয়ানআইফাইভের সাথে সামান্য কিছুটা মিল তবে এটি কীভাবে ফিউচারবোট এবং ওয়ানআইএনফাইভের সাথে তুলনা করা যায় তাও দেখতে চাই।

সম্পাদনা করুন: এখন তারা 45 টি আঘাত করার পরে থামে


পিপিসিজিতে আপনাকে স্বাগতম! আপনার বটটি অবশ্যই গেমের স্পিরিটের সাথে খেলে! আমি এই সন্ধ্যায় পরে একটি সিমুলেশন চালাব।
maxb

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