Mafya oynayalım!


42

Mafya (aynı zamanda Kurtadam olarak da bilinir) kabaca bu şekilde oynayan bir parti oyunudur:

  • Oyun 0. günde başlar. Her gün nbir geceden sonra n. Her geceden sonra nbir gün geliyor n+1. yani D0, N0, D1, N1, D2, N2...
  • O günün şafağında, bir ev sahibi gizlice bazı rolleri doldurmak için oyuncuları seçer:  
    • Bazı oyuncular mafya olur. Her gece, her mafya bir oyuncu seçer. Ertesi günün şafağında, en mafiosos tarafından seçilen oyuncu öldürülür. Oyundan kalıcı olarak çıkarılırlar ve rolleri halka açıklanır. Mafya hizalanır.  
    • Bazı oyuncular polis olur. Her gece, her polis bir oyuncu seçer. Ertesi günün şafağında, polis bu oyuncuların uyumunu fark eder. Köy hizalanmış.  
    • Bazı oyuncular doktor olur. Her gece, her doktor bir oyuncu seçer. Eğer bu oyuncu mafyanın öldürmeyi seçtiği oyuncuysa, mafya'nın o gece için yaptıkları iptaller. Köy hizalanmış.  
    • Başka bir rol için seçilmeyen tüm oyuncular köylülerdir. Köylülerin tüm kasaba tarafından paylaşılmayan hiçbir yeteneği yoktur. Köy hizalanmış.
  • 0 gün hariç her gün, tüm kasaba (yani tüm yaşayan oyuncular) bir oyuncuya oy verir. Günün sonunda, bu oyuncu oyundan çıkarılır ve rolleri açıklanır. (0. Günde herkes akşama kadar ürperir.)
  • Herhangi bir noktada, kalan mafiosos yoksa, oyun köyün hizalı tüm oyuncularının galip gelmesiyle sona erer (ölüler dahil).
  • Eğer herhangi bir noktada köy hizasında olan oyuncular mafya hizalı oyuncuları geride bırakmazsa, oyun mafya hizalı tüm oyuncuların galip gelmesiyle sona erer (ölüler de dahil).

Bu meydan okuma için amacınız Mafya'daki diğer botları yenmek için bir bot yazmak!

Çalışan bir bot nasıl yapılır

Bana vermeniz gereken tek şey, adında bir dosya run. Bu zorluğun gerçekleşeceği dizin yapısının içinde botunuz burada yaşayacak:

start
controller/
tmp/
players/               # You are here!
    some_bot/          # Let's pretend you're some_bot.
        to_server
        from_server
        players
        run            # This is what you give me
    mafia-game-bot/
    skynet/

runDosya, çalıştırıldığında, bot onun şey yapacaktır. Bu dosyanın herhangi bir komut satırı argümanı veya başka bir şey gerektirmemesi gerektiğine dikkat etmek önemlidir. Aynen olduğu gibi çalıştırılacak ./run. Farklı bir şekilde uygulanmanız gerekiyorsa, bunun gibi bir şey yaparak bunun üzerinde çalışmak zorundasınız:

real_bot.py

#!/bin/python2

# code goes here

run

#!/bin/bash

./real_bot.py --flags --or --whatever

Unutulmaması gereken önemli bir nokta, botunuzun aldığı tüm girişlerin dosyada from_serverbulunacağı ve kontrol programının botunuzun çıkışını aradığıdır to_server. Bu şekilde yapmayı seçtim, böylece I / O dosyalarını yapabilen herhangi bir dilin katılabiliyordu. Diliniz stdin ve stdout ile çalışmayı dosya G / Ç'den daha kolay hale getirirse, runşuna benzeyen bir dosya yazmak isteyebilirsiniz :

#!/bin/bash

./real_bot.py < from_server > to_server

Bu, stdin'in from_serverdosyadan geldiğini ve stdout'un doğrudan gittiğini sağlayacaktır to_server.

Botunuz oyun süresince çalışmaya devam etmeyecek. Bunun yerine, bir karar vermesi gerektiğinde çalıştırılacaktır. Aynı şekilde, öldüğü zaman da bilgi verilmeyecek, artık çalıştırılmayacak. Hatırlamak istediğiniz herhangi bir şeyi bir dosyaya kaydederek ve daha sonra okuyarak bunu planlayın. Botunuzun klasöründeki herhangi bir dosyayı oluşturabilir, yazabilir veya okuyabilir, ancak ağ erişimi veya herhangi bir şey dahil, bu klasörün dışında hiçbir yerde yazamaz veya okuyamazsınız . Botunuz klasörün içinden söylenmediği bir şey biliyorsa veya klasörün içinde olmayan bir şeye dokunursa botunuz diskalifiye edilir.

Fonksiyonel bot nasıl yapılır

Gün

Oyunun başında, dosya oyunda playersyer alan tüm oyuncuların yeni satırlarla sınırlandırılmış bir listesi ile doldurulacaktır. Oyuncular oyundan ayrıldıkça güncellenmez.

0. Günün şafağında, tüm oyuncular bu mesajı from_serverdosyalarında bulacaklar :

Rise and shine! Today is day 0.
No voting will occur today.
Be warned: Tonight the mafia will strike.

Polis sizseniz, satır You are the copsonuna eklenir. Doktor görüyor You are the doctor. Mafya You are a member of the mafia.\nYour allies are:mesajı okur ve oyuncu hariç yeni satırla ayrılmış bir mafya üyesi listesi görür .

Diğer tüm günlerin şafağında, bu mesaj görünecektir:

Dawn of day `day_number`.
Last night, `victim` was killed. They were `victim_role`.
Investigations showed that `cop_target` is `target_alignment`-aligned.
These players are still alive: `remaining_players`

dayNumberGünün numarası ile değiştirilir. victimdün geceki kurbanın adı ile değiştirildi ve victim_rolebunlardan biri:

  • a villager
  • a mafioso
  • the cop
  • the doctor

cop_targetpolis dün gece araştırdık oyuncunun adıdır ve target_alignmentya bir villageya mafia. Son olarak, remaining_playersbu formatta hala canlı olan oyuncuların bir listesi:player1, player2, player3

Dün gece öldürülmediyse ikinci satır atlandı ve üçüncü satır sadece polise gösterildi.

Örneğin,

Dawn of day 42.
Last night, Xyzzy was killed. They were a villager.
Investigations showed that Randy is mafia-aligned.
These players are still alive: Randy, CopBot, JohnDoe, Steve

Bu mesaj yolun dışına çıktığında, gün başlıyor! Her bot, gün boyunca 50 eylem yapabilir; burada bir "eylem" bir oyuncuya oy verir veya yüksek sesle bir şeyler söyler.

Bir oyuncuya oy vote player_namevermek için to_serverdosyanıza yazıp sonlandırın. Kimseyi öldürmemeye oy vermek için yaz vote no one. Oy verdiğinizde, tüm oyuncular (siz dahil) görür your_bot votes to kill your_selection. Oylar 0. günde yok sayılır.

Tüm oyunculara önceden tanımlanmış birkaç mesaj gönderilebilir. Her olası mesajın kimliği burada listelenmiştir:

 0: No
 1: Yes
 2: I am the cop
 3: I am the doctor
 4: I am a normal villager
 5: I trust this player: 
 6: I think this player is suspicious: 
 7: I think this player is the cop: 
 8: I think this player is the doctor: 
 9: I think this player is a normal villager: 
10: I think this player is mafia: 
11: Do you think this player is mafia? 
12: I tried to save this player: 
13: I successfully saved this player: 
14: I investigated this player and found that they were mafia-aligned: 
15: I investigated this player and found that they were village-aligned: 
16: Will you please use your power on this player tonight?

İlk beşi dışında bu mesajların tümü belirli bir oyuncuya atıfta bulunuyor. Bu mesajlardan birini söylemek için yazın say message_id player_name. İlk beş mesajdan biri için, sadece yazın say message_id. Konuştuğunuz oyuncunun adını belirterek, her ikisine de isteğe bağlı üçüncü bir argüman ekleyebilirsiniz (tüm oyuncular hala okuyabilir, ancak amaçlanan alıcının kim olduğunu bilirler).

Botunuz bir mesaj söylediğinde, tüm oyuncular okur your_bot says "message", messageyazdığınız kimliğinizle ilgili mesaj nerede ? Mesaj bir konu içeriyorsa, bir boşluk karakteri ve konu doğrudan mesajın sonundan sonra eklenir. Bir alıcı içeriyorsa, adları, bir iki nokta üst üste ve bir boşluk karakteri mesajın hemen önüne eklenir.

Günün sonunda, tüm canlı oyuncular oyların sonucunu görmek için son kez koşarlar. Bir oyuncu oy kullandıysa, bu yazılır:

The town has killed player_name!
They were a villager

... veya a mafioso, veya the cop, veya the doctor.

Hiçbir oyuncu oy kullanmadıysa, bunun yerine bu yazılır:

The town opted to lynch no one today.

Kumanda bu mesajları gönderdiğinde, oyuncuların verdiği herhangi bir cevabı yok sayar. Gün bitti.

Gece

Geceleri, köylüler dışındaki herkes güçlerini kullanabiliyor.

Mafya:

Okuyacaksın It is night. Vote for a victim.. Bu olduğunda, öldürmek istediğiniz oyuncunun adını yazınız.

Polis:

Okuyacaksın It is night. Who would you like to investigate?. Bu olduğunda kontrol etmek istediğiniz oyuncunun adını yazınız.

Doktor:

Okuyacaksın It is night. Who would you like to save?. Bu olduğunda, korumak istediğiniz oyuncunun adını yazınız.

Bundan sonra, ertesi gün normal olarak başlar.

Oyun başına sadece bir kez kendini kurtarabilirsin.

Genel bilgi

  • Oyun 6 veya daha fazla oyuncu olmadan çalışmaz.
  • Yuvarlanan oyuncuların üçte biri mafya olacak. Bir oyuncu doktor olacak ve bir oyuncu polis olacak. Diğer tüm oyuncular köylülerdir.
  • Köy oyunda veya mafya gecesinde oylarda bağlar rastgele belirlendi.
  • Bot isimleri alfanümerik + tire ve alt çizgi olmalıdır.
  • Rakibin kod bilgisini doğrudan kullanmak yasaktır. Teorik olarak, botunuzu daha önce hiç görmediğiniz botlara karşı koyabilmeli ve karşılaştırmalı olarak çalışmasını sağlamalıyım.
  • Ne yazık ki, yalnızca ücretsiz (birada olduğu gibi) yazılımı kullanarak programınızın çalışmasını engelleyemezsem, diskalifiye etmek zorunda kalacağım.
  • Kötü niyetli olduğuna inanıyorsam, herhangi bir kaydı diskalifiye etme hakkını saklı tutarım. Bu, çalıştırılacak çok fazla zaman, bellek veya alan kullanımı içerir, ancak bunlarla sınırlı değildir. Kasıtlı olarak limiti yumuşak bıraktım, ama unutma: Bunu ev bilgisayarımda çalıştırıyorum, bir süper bilgisayarda değil, sonuç almak için bir yıl almak istemiyorum. Standartları oldukça düşük olduğu için bunu kullanmak zorunda beklemiyorum. Bu temelde "bilerek bi sik olduğunuzu düşünüyorsanız" ve beni başka türlü ikna ederseniz kararımı tersine çeviririm.

puanlama

Her turda 100 oyun oynanacak (bu, örneklem büyüklüğünü yeterince büyük tutmak için daha fazla bot birleştirdikçe artabilir, fakat teoride hiçbir şeyi etkilemeyecek). Her bir botun kaç defa bir köylü olarak oynadığına kıyasla bir köylü olarak kazandığını ve bunun mafya için de aynı olduğunu kaydedeceğim. Bir bot en villager_ratioolduğunu number of games won as villager / number of games played as villagerve mafia_ratioaynı ama s/villager/mafia/g. Bir botun puanı (villager_ratio - mean villager_ratio) + (mafia_ratio - mean mafia_ratio).

Örnek bot

Randy Robot, iyi bir mafya oyuncusu değil. Randy, ne söyleyeceğini, kime oy vereceğini ve gece güçleriyle kimi hedef alacağını seçerek rastgele her şeyi görmezden geliyor.

run.sh:

#!/bin/bash

./randy.py < from_server > to_server

randy.py:

#!/usr/bin/env python

import random

with open('players') as f:
    p = f.read().split() + ['no one']


day = True
try:
    line = raw_input()
    if line.endswith(('?', 'victim.')):
        day = False
    if not day:
        print random.choice(p)
    else:
        if random.random() > 0.5:
            if random.random() > 0.5:
                print 'vote {}'.format(random.choice(p))
            else:
                id = random.randint(0, 17)
                print 'say {}{}'.format(id, (' ' + random.choice(p)) if id > 4 else '')
except: pass

kontrolör

@ undergroundmonorail, bu görev için burada bulunan bir kontrol programı yazdı .

Cevaplamak ve cevap vermek için bir ayınız var, kazanan botu (en yüksek kazanma oranı kırıcı oylar) en az 50 itibar ödülü vereceğim (bir ayda ne kadar rep kazanabileceğime bağlı olarak)


Derleme dilleri ile kullanmak için @ Blacksilver tarafından yapılan bir sarma komut dosyası İşte:

#!/bin/bash

run="./a.out"
compile="gcc bot.c"

if [ -e $run ]; then
        $run
else
        $compile
        $run
fi

Bunu içine koy run.


Bu yazı @ undergroundmonorail tarafından yazılmıştır (Birkaç düzenleme yaptım).

Bitirmek ve göndermek isteyen herkese burada pes etti.


Yorumlar genişletilmiş tartışmalar için değildir; bu konuşma sohbete taşındı .
Martin Ender

Yanıtlar:


3

Zulu dili

run

#!/usr/bin/env php
<?php
error_reporting(E_ERROR|E_WARNING|E_PARSE);

$self = basename(__DIR__);

$msgids = array(
    "No",
    "Yes",
    "I am the cop",
    "I am the doctor",
    "I am a normal villager",
    "I trust this player:",
    "I think this player is suspicious:",
    "I think this player is the cop:",
    "I think this player is the doctor:",
    "I think this player is a normal villager:",
    "I think this player is mafia:",
    "Do you think this player is mafia?",
    "I tried to save this player:",
    "I successfully saved this player:",
    "I investigated this player and found that they were mafia-aligned:",
    "I investigated this player and found that they were village-aligned:",
    "Will you please use your power on this player tonight?"
);
$msgids = array_flip($msgids);

if(!file_exists('./from_server')){
    die;
}
$in = file('from_server');
if(count($in) && strpos($in[0],'day 0.') !== false){
    $game = array(
        'day'               =>0,
        'players'           =>array(),
        'alive'             =>array(),
        'dead'              =>array(),
        'mafia'             =>array(),
        'village'           =>array(),
        'cop'               =>'',
        'doctor'            =>'',
        'votes'             =>array(),
        'messages'          =>array(),
        'currentvotes'      =>array(),
        'currentmessages'   =>array()
    );
    $playersfile = file('players');
    foreach($playersfile as $name){
        $game['players'][trim($name)] = 1;
        $game['alive'][trim($name)] = 1;
        $game['votes'][trim($name)] = array();
        $game['messages'] = array();
    }
    $allies = false;
    foreach($in as $line){
        if($allies){
            if(array_key_exists(trim($line),$game['players'])){
                $game['mafia'][trim($line)] = 1;
            }
        }
        else if(strpos($line,"You are the cop") !== false){
            $game['cop'] = $self;
            $game['village'][$self] = 1;
        }
        else if(strpos($line,"You are the doctor") !== false){
            $game['doctor'] = $self;
            $game['village'][$self] = 1;
        }
        else if(strpos($line,"member of the mafia") !== false){
            $game['mafia'][$self] = 1;
        }
        else if(strpos($line,"allies are:") !== false && $game['mafia'][$self]){
            $allies = true;
        }
    }
    if(!$game['mafia'][$self]){
        $game['village'][$self] = 1;
    }
    else{
        foreach($game['players'] as $name=>$g){
            if(!$game['mafia'][$name]){
                $game['village'][$name] = 1;
            }
        }
    }
    $out = json_encode($game);
    write('myinfo',$out);
}
else{
    $myinfo = file_get_contents('myinfo');
    $game = json_decode($myinfo,true);
    if(count($in) && strpos($in[0],"town has killed") !== false){
        $e = explode(" ",trim($in[0]));
        $dead = trim($e[4],'!');
        unset($game['alive'][$dead]);
        $game['dead'][$dead] = 1;
        $e = explode(" ",trim($in[1]));
        $allegiance = trim($e[3],".");
        $game[$allegiance][$dead] = 1;
    }
    else if(count($in) && strpos($in[0],"town opted to") !== false){
        //
    }
    else if(count($in) && strpos($in[0],"night") !== false){
        if(strpos($in[0],"victim") !== false){
            $voted = false;
            if($game['day'] > 0){
                $possible = array();
                foreach($game['alive'] as $name=>$g){
                    if(!$game['mafia'][$name]){
                        foreach($game['votes'][$name] as $for){
                            if($voted && $game['mafia'][$for]){
                                $possible[] = $name;
                            }
                        }
                    }
                }
                if(count($possible)){
                    shuffle($possible);
                    write('to_server',$possible[0]);
                    $voted = 1;
                }               
            }
            if(!$voted){
                while($rand = array_rand($game['alive'])){
                    if(!$game['mafia'][$rand]){
                        write('to_server',$rand);
                        $voted = 1;
                        break;
                    }
                }
            }
        }
        else if(strpos($in[0],"investigate") !== false){
            $possible = array();
            foreach($game['alive'] as $name=>$g){
                if(!$game['village'][$name] && !$game['mafia'][$name] && $game['doctor'] != $name){
                    $possible[] = $name;
                }
            }
            if(count($possible)){
                shuffle($possible);
                write('to_server',$possible[0]);
            }
        }
        else if(strpos($in[0],"save") !== false){
            if($game['day'] == 0){
                write('to_server',$self);
            }
            else{
                if($game['cop'] != '' && $game['alive'][$game['cop']]){
                    write('to_server',$game['cop']);
                }
                else{
                    $voted = false;
                    foreach($game['alive'] as $name=>$g){
                        if($game['village'][$name] && $name != $self){
                            write('to_server',$name);
                            $voted = true;
                            break;
                        }
                    }
                    if(!$voted){
                        while($rand = array_rand($game['alive'])){
                            if($rand != $self){
                                write('to_server',$rand);
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    else if(count($in) && strpos($in[0],"Dawn of day") !== false){
        $e = explode(" ",trim($in[0]));
        $game['day'] = trim($e[3],".");
        foreach($in as $line){
            if(strpos($line,"was killed") !== false){
                $e = explode(" ",trim($line));
                $dead = $e[2];
                if(strpos($line,"the cop") !== false){
                    $game['cop'] = $dead;
                    $game['village'][$dead] = 1;
                }
                else if(strpos($line,"the doctor") !== false){
                    $game['doctor'] = $dead;
                    $game['village'][$dead] = 1;
                }
                else if(strpos($line,"a villager") !== false){
                    $game['village'][$dead] = 1;
                }
                else if(strpos($line,"a mafioso") !== false){
                    $game['mafia'][$dead] = 1;
                }
                unset($game['alive'][$dead]);
                $game['dead'][$dead] = 1;
            }
            else if(strpos($line,"Investigations showed") !== false){
                $e = explode(" ",trim($line));
                $name = $e[3];
                $align = trim($e[5]);
                $e = explode("-",$align);
                $game[$e[0]][$name] = 1;
            }
        }
        $game['currentvotes'] = array();
        $game['currentmessages'] = array();
        foreach($game['alive'] as $name=>$g){
            $game['currentvotes'][$name] = '';
        }
    }
    else{
        foreach($in as $line){
            if(strpos($line," has voted to lynch no one") !== false){
                $e = explode(" ",trim($line));
                $game['votes'][$e[0]][] = false;
                $game['currentvotes'][$e[0]] = false;
            }
            else if(strpos($line," has voted to ") !== false){
                $e = explode(" ",trim($line));
                $game['votes'][$e[0]][] = trim($e[5]," .");
                $game['currentvotes'][$e[0]] = trim($e[5]," .");
            }
            else if(strpos($line," says ") !== false){
                foreach($msgids as $msg=>$id){
                    $chk = preg_match('/([^\s]+) says "(([^\s]+)[:,] )?'.preg_quote($msg).'( ([^\s]+))?"/',$line,$matches);
                    if($chk){
                        //                                  said by     said to     said  said about
                        $game['messages'][]         = array($matches[1],$matches[3],$msg, $matches[5]);
                        $game['currentmessages'][]  = array($matches[1],$matches[3],$msg, $matches[5]);
                    }
                }
            }
        }
        $written = false;
        $convo = array();
        foreach($game['currentmessages'] as $msg){
            if($msg[1] == $self){
                $convo[$msg[0]] = $msg;
            }
            else if($msg[0] == $self && $msg[1] != ''){
                unset($convo[$msg[1]]);
            }
        }
        if(count($convo)){
            foreach($convo as $c){
                if($msgids[$c[2]] == 11){
                    if($game['mafia'][$msg[3]]){
                        write('to_server',"say 1 ".$msg[0]);
                        $written = true;
                        break;
                    }
                    else if($game['village'][$msg[3]]){
                        write('to_server',"say 0 ".$msg[0]);
                        $written = true;
                        break;
                    }
                    else{
                        write('to_server',"say 11 ".$msg[0]);
                        $written = true;
                        break;
                    }
                }
                else if($msgids[$c[2]] == 16){
                    write('to_server',"say 0 ".$msg[0]);
                    $written = true;
                }
                else{
                    write('to_server',"say 4 ".$msg[0]);
                    $written = true;
                }
            }
        }
        if(!$written){
            $currentvote = false;
            if(array_key_exists($self,$game['currentvotes'])){
                $currentvote = $game['currentvotes'][$self];
            }
            if($game['mafia'][$self]){
                $votes = @array_count_values($game['currentvotes']);
                if($votes && count($votes)){
                    arsort($votes);
                    foreach($votes as $name=>$number){
                        if($game['village'][$name]){
                            if($currentvote != $name){
                                write('to_server','vote '.$name);
                                $written = true;
                                break;
                            }
                        }
                    }
                }
            }
            else{
                if(count($game['mafia'])){
                    foreach($game['mafia'] as $name=>$g){
                        if($game['alive'][$name]){
                            $written = true;
                            if($currentvote != $name){
                                write('to_server','vote '.$name);
                            }
                            break;
                        }
                    }
                    if(!$written){
                        foreach($game['mafia'] as $name=>$g){
                            $non = $game['alive'];
                            unset($non[$self]);
                            if(array_key_exists($name,$game['votes'])){
                                foreach($game['votes'][$name] as $vote){
                                    if(array_key_exists($vote,$non)){
                                        unset($non[$vote]);
                                    }
                                }
                            }
                            if(count($non)){
                                $rand = array_rand($non);
                                write('to_server','vote '.$rand);
                                $written = true;
                                break;
                            }
                        }
                    }
                }
                if(!$written && $game['cop']){
                    $possible = array();
                    foreach($game['votes'][$game['cop']] as $name){
                        if($game['alive'][$name] && $name != $self){
                            $possible[] = $name;
                        }
                    }
                    if(count($possible)){
                        shuffle($possible);
                        write('to_server','vote '.$possible[0]);
                        $written = true;
                    }
                }
                if(!$written && count($game['dead'])){
                    foreach($game['dead'] as $name=>$g){
                        if($game['village'][$name]){
                            $v = array();
                            foreach($game['votes'] as $voted=>$arr){
                                if($game['alive'][$voted] && in_array($name,$arr)){
                                    $v[$voted] = 1;
                                }
                            }
                            unset($v[$self]);
                            if(count($v)){
                                $rand = array_rand($v);
                                write('to_server','vote '.$rand);
                                $written = true;
                                break;
                            }
                        }
                    }
                }
                if(!$written){
                    $votes = @array_count_values($game['currentvotes']);
                    if($votes && count($votes) && array_key_exists($self,$votes)){
                        arsort($votes);
                        foreach($votes as $name=>$number){
                            if(!$game['village'][$name]){
                                if($name != $self){
                                    write('to_server','vote '.$name);
                                    $written = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    $myinfo = json_encode($game);
    write('myinfo',$myinfo);
}

function write($filename,$data){
    $fh = fopen($filename,"wb+");
    if($fh){
        $bytes = fwrite($fh,$data);
        fclose($fh);
    }
}

Umduğum her şey olmazdı. Ara sıra tweaking sona erebilir.

Nasıl çalışır? V1.0

Gün sayısının, canlı, kimin öldüğü, kimin mafyası, köyün hizasında olduğu, rolleri, mevcut gün oyları / mesajları ve genel oyları / mesajları takip eder.

  1. Gece

    a. Mafya - Eğer mümkünse (rastgele), aksi takdirde rastgele bir köylüye oy veren herhangi bir köylüye oy verin.

    b. Cop - Bilinmeyen bir uyuma sahip olan herkesi araştırın.

    c. Doktor - İlk önce kendini kurtar, sonra biliniyorsa polisi kurtar (şimdiye kadar bunu bileceğini sanmıyorum), biliniyorsa köylüyü kurtar (muhtemelen bunu da bilmiyor), aksi takdirde rastgele kişiyi kurtar.

  2. Gün

    a. Herhangi biri doğrudan kendine mesaj attıysa, onlara cevap ver (sınırlı cevaplar mümkün).

    b. Mafya - En çok oy alan köylüye oy verin.

    c. Bilinen herhangi bir canlı Mafya hizasına sahip köylü - mafya için oy.

    d. Sadece ölü Mafya hizasında bilinen köylü - mafya için hiç oy kullanmayan rastgele bir bot için oy kullanın.

    e. Polis bilinen köylü - polisin oy verdiği rastgele bot için oy.

    f. Ölüler ile köylü Köy bilinen hizalanmış - oy için ölü oy veren rastgele bir bot için oy.

    g. Kendisine karşı oy kullanan köylü - şu anda köyle aynı hizada bulunmayan en yüksek oyu kullananlara oy verdi.


1
Bekle, bu ne işe yarıyor?
SIGSTACKFAULT

1
Neden elbette mafya oynuyor! :)
Jo.

Stratejiyi kastediyorum.
SIGSTACKFAULT

6

Örnek kod benim için işe yaramadı, Python 3 kullandım, bu yüzden main.pyçalışmasını sağlamak için dosyayı değiştirdim .

İşte benim Python 3 için sabit sürümüm, daha önce Python'da programlamamıştım, belki de korkunç bir kod ama işe yarıyor :)

run.sh:

#!/bin/bash

./randy.py < from_server > to_server

randy.py:

#!/usr/bin/env python3

import random

with open('players') as f:
    p = f.read().split() + ['no one']

with open('from_server') as f:
    fs = f.read().split()

msg = ""
day = True
try:
    line = fs[0]
    if line.endswith(('?', 'victim.')):
        day = False
    if not day:
        msg = (random.choice(p))
    else:
        if random.random() > 0.5:
            if random.random() > 0.5:
                msg = ('vote {}'.format(random.choice(p)))
            else:
                id = random.randint(0, 17)
                msg = ('say {}{}'.format(id, (' ' + random.choice(p)) if id > 4 else ''))

    with open('to_server', 'w') as f:
        f.write(msg)
    print(msg)
except: pass

Bu işi yaparken öğrendiğim birkaç şey (ve açıklamada benim için belli değildi)

  • printbir console.logjs gibi bir oyun ile hiçbir şey yapmaz
  • input() çalışan programı engeller ve adım adım hata ayıklama için iyi olabilir
  • from_serverve to_serverher turda temizlenir.
  • Senaryoyu Ctrl+Csinir bozucu olan kombinasyonla durdurmak mümkün değildir .

PPCG'ye Hoşgeldiniz! Harika ilk mesaj! Umarım takılırsın! Gönderinizi, işlevsel sözdizimi vurgulaması yapacak ve düzenleme tutarlılığı uğruna a olarak düzenledim run.sh.
Rɪᴋᴇʀ

1
Teşekkür ederim! Emin değilim < from_server > to_server, çünkü kodda dosya isimlerini kodladım. oyun motoru sadece ./runboru olmadan arayın . böylece input()ve print()vermedi oyun ile çalışır. mayn.pysatır 57:os.system('./run')
Peter

2
Kontrol cihazının çalışmasını nasıl sağladınız? Çözemiyorum. Örnek bir çağrı yapabilir misiniz?
17:55

Not: Orijinal randy.py, Python 2'de yazılmış ve sorunlara neden olmuştur.
SIGSTACKFAULT

denetleyici ./startiçin orjinal klasörden ya da bir python 3 versiyonuna ihtiyacınız varmain.py
Peter

5

Logician

#!/usr/bin/env python3
import sys
import os
import re
import random
from types import SimpleNamespace
def chooseSet(set):
    return random.choice(list(set))
sys.stdin = open("from_server")
sys.stdout = open("to_server","w")
def saveData(data):
    with open("gameData.txt", "w") as datafile:
        datafile.write(repr(data.__dict__))
MY_NAME = os.path.basename(os.getcwd())
opener = input()
DATABASES = ("targets","herd","mafiosos","guilty","innocent","unlikely", "requests",
            "selfvotes","players","used_roles")
ALLOW_SELF = ("players", "mafiosos")
LIESPERROLE = {"cop": ("I am the cop",
                "I investigated this player and found that they were mafia-aligned",
                "I investigated this player and found that they were village-aligned"),
              "doctor": ("I am the doctor",
                   "I tried to save this player",
                   "I successfully saved this player"
                   )
        }
#1: At the beginning of the game, parse beginning of day 0
if opener == "Rise and shine! Today is day 0.":
    #Next two lines are completely predetermined and hold no data
    assert input() == "No voting will occur today."
    assert input() == "Be warned: Tonight the mafia will strike."
    data = SimpleNamespace(cop=False, doctor=False, queued=[],askers={})
    for datum in DATABASES:
        setattr(data, datum, set())
    try:
        nextline = input()
        if nextline == "You are a member of the mafia.":
            data.mafiosos.add(MY_NAME)
            assert input() == "Your allies are:"
            while True:
                data.mafiosos.add(input())
        elif nextline == "You are the doctor":
            data.doctor = True
            data.used_roles.add("doctor")
        elif nextline == "You are the cop":
            data.cop = True
            data.used_roles.add("cop")
    except EOFError:
        #villager, or ran out of mafiosos to add
        pass
    with open("players") as playersfile:
        data.players = set(playersfile.read().strip().splitlines())
    saveData(data)
    exit()
with open("gameData.txt") as datafile:
    data = SimpleNamespace(**eval(datafile.read().strip()))
#2: Beginning of day nonzero
if opener.startswith("Dawn of day"):
    data.requests.clear()
    data.selfvotes.clear()
    data.askers.clear()
    data.voted = False
    try:
        while True:
            nextline = input()
            victim = re.match("Last night, (.*) was killed. They were (?:a|the) (.*).", nextline)
            if victim:
                victim, role = victim.groups()
                #remove dead people from lists
                for datum in DATABASES:
                    getattr(data, datum).discard(victim)
                if role == "cop" or role == "doctor":
                    data.used_roles.add(role)
                continue
            investigated = re.match("Investigations showed that (.*) is (.*)-aligned.", nextline)
            if investigated:
                assert data.cop
                who = investigated.group(1)
                if investigated.group(2) == "mafia":
                    data.guilty.add(who)
                    data.unlikely.discard(who)
                else:
                    data.targets.discard(who)
                    data.herd.discard(who)
                    data.innocent.add(who)
                    data.unlikely.add(who)
                continue
    except EOFError:
        pass
#3: We're being told some messages / news
elif " says " in opener or " voted " in opener:
    message = opener
    acted = question = False
    try:
        while True:
            if " voted " in message:
                message = "<vote against>"
                speaker, subject = re.match("(.*) has voted to lynch (.*)", message).groups()
                target = None
            else:
                speaker, target, message, subject = \
                    re.match("(.*) says \"(?:(.*), )?([^:\?]+)(?:[:\?]\s*(.*))?\"",
                             message).groups()
            if speaker == MY_NAME:
                continue
            BAD_MESSAGES = ("<vote against>", "I think this player is mafia",
                            "I investigated this player and found that they were mafia-aligned",
                            "I think this player is suspicious")
            GOOD_MESSAGES = ("I think this player is the cop",
                             "I think this player is the doctor",
                             "I think this player is a normal villager",
                             "I trust this player",
                             "I investigated this player and found that they were village-aligned")
            OUTS = "I am the cop", "I am the doctor"
            LIES = ()
            for role in data.used_roles:
                LIES += LIESPERROLE[role]
            if message == "Yes" or message == "No":
                if question and not target:
                    target = chooseSet(data.askers)
                if target in data.askers:
                    BAD_MESSAGES += "Yes",
                    GOOD_MESSAGES += "No",
                    subject = data.askers[target]
            if message in LIES and speaker not in data.mafiosos and speaker not in data.innocent:
                # What you just said is false, and I know it!
                data.unlikely.discard(speaker)
                data.targets.add(speaker)
                if subject and subject not in (data.unlikely.union(data.mafiosos)):
                    data.targets.add(subject)
            elif message in BAD_MESSAGES:
                if speaker in data.guilty:
                    #mafiosos rarely turn on eachother
                    data.unlikely.add(subject)
                    data.targets.discard(subject)
                elif speaker in data.unlikely:
                    #believe the herd, especially people who we trust
                    data.herd.add(subject)
                elif subject in data.unlikely:
                    #how dare you speak against players likely to be village-aligned!
                    data.targets.add(speaker)
                elif subject == MY_NAME or subject in data.mafiosos:
                    #DON'T ATTACK ME (or my fellow mafiosos)
                    data.targets.add(speaker)
                else:
                    #believe the herd
                    data.herd.add(subject)
                if not acted and message == "<vote against>":
                    if subject == MY_NAME:
                        data.selfvotes.add(speaker)
                        if len(data.selfvotes) >= (len(data.players)-len(data.mafiosos))/3:
                            if data.cop:
                                print("say 2")
                                #give a data point to prove it
                                if random.random() > .5 and data.guilty:
                                    data.queued.append("say 14 %s" % chooseSet(data.guilty))
                                elif data.innocent:
                                    data.queued.append("say 15 %s" % chooseSet(data.innocent))
                            else:
                                print("say 4") #Don't out myself if I'm the doctor
                                # and just lie if I'm a mafioso
                            acted = True
                    else:
                        data.selfvotes.discard(speaker)
            elif message in OUTS and data.mafiosos and speaker not in data.unlikely:
                data.targets.add(speaker) #Kill the fools who boast!
            elif message in GOOD_MESSAGES:
                chance = random.random() < .1 - (speaker in data.targets) / 20
                if speaker in data.guilty: #Mafia liars
                    if subject not in data.unlikely:
                        data.targets.add(subject)
                elif subject == MY_NAME and chance:
                    if speaker in data.targets:data.targets.remove(speaker)
                    data.unlikely.add(speaker)
                elif speaker in data.unlikely or chance:
                    data.unlikely.add(subject)
            elif message == "Do you think this player is mafia":
                if subject == MY_NAME:
                    data.targets.append(speaker)
                if target == MY_NAME or not target:
                    if speaker in data.guilty:
                        data.queued.append("say 14 %s %s" % (subject, speaker))
                    elif speaker in data.innocent:
                        data.queued.append("say 15 %s %s" % (subject, speaker))
                    elif subject in data.targets or subject in data.herd:
                        data.queued.append("say 1 %s" % (speaker))
                    elif subject in data.unlikely:
                        data.queued.append("say 0 %s" % (speaker))
                    if data.cop:
                        data.requests.add(subject)
                data.askers[speaker] = subject
                question = True
            elif target == MY_NAME and message == "Will you please use your power on this player tonight":
                data.requests.add(subject)
            message = input()
    except EOFError:
        pass
    for datum in DATABASES:
        if datum in ALLOW_SELF: continue
        getattr(data, datum).discard(MY_NAME)
    chance = random.random()
    if data.queued:
        print(data.queued.pop())
    elif chance < .1:
        target = chooseSet(data.targets or data.players)
        if target != MY_NAME:
            print("say 10 %s" % target)
            data.askers[MY_NAME] = target
    elif chance < .3 and data.targets:
        print("say 6 %s" % chooseSet(data.guilty or data.targets))
    elif chance < .5 and data.unlikely:
        print("say 5 %s" % chooseSet(data.innocent or data.unlikely))
    elif chance < .6 and not data.voted:
        target = chooseSet(data.guilty or data.targets or data.herd or data.players)
        if target not in data.mafiosos and target != MY_NAME:
            print("vote %s" % target)
        data.voted = True
    elif chance < .8:
        #do nothing
        pass
    elif chance < .9:
        #Confuse everybody
        print("say 1")
        data.queued.append("say 0")
######################
#4: End of day
elif "has killed" in opener:
    victim = re.match("The town has killed (.*)!", opener)
    if not victim:
        exit()
    victim = victim.group(1)
    #remove dead people from lists
    for datum in DATABASES:
        getattr(data, datum).discard(victim)
    role = input()
    role = re.match("They were (?:a|the) (.*)", role).group(1)
    if role == "cop" or role == "doctor":
        data.used_roles.add(role)
    #Misc: purge people from lists if too large
    for list in data.unlikely, data.targets, data.herd:
        while len(list) > len(data.players)/3:
            list.pop()
    for player in data.innocent:
        data.unlikely.add(player)
elif opener == "The town opted to lynch no one today.":
    #Do nothing
    pass
#5: Night
elif "night" in opener:
    if not data.mafiosos and data.requests and random.random() > .5:
        print(chooseSet(data.requests))
    if data.doctor:
        print(chooseSet(data.unlikely or data.players))
    else:
        while True:
            try:
              target = (data.targets or data.herd).pop()
            except KeyError:
              target = chooseSet(data.players)
            if target in data.mafiosos or target == MY_NAME:
                continue
            print(target)
            break
else:
    raise ValueError("Unknown message")
saveData(data)

Açıklanamayacağım süslü, uzun bir python kodu grubu (golf oynamasına rağmen), başlangıçta şans eseri ve / veya polis soruşturmasına dayanan "arkadaşlar" ve "düşmanlar" listeler. . Uyarı: Logician'ın huzurunda yatmayın.


sizin run.shstandarttınız (bazı testler yapıyorsunuz)
Stan Strum

Hayır, benim run.sh normal giriş ve çıkış boruları olmadan sadece "run.py" olabilirdi, ancak standart işe yarayacaktı.
pppery

1
Bu, yazdıklarıma çok benziyordu, zamanım ve eğilimim olsaydı.
Draco18,

Bazı sebeplerden ötürü, logicinin diğer botların etrafında pek başarılı olmayacağını düşünüyorum ... diğer botların hiçbiri polis soruşturmasını rapor etmedi
JavaScriptCoder

1
... ve aylar sonra, cevabımın yanlış bir tek doktor / doktor olabileceğini varsaydığını fark ettim.
pppery

4

Survivalist (v 1.0)

özet

Hayatta kalma uzmanı, mafya olup olmadığına bakılmaksızın, kendisini suçlamaya cesaret eden herkesi vurarak acımasızca hayatta kalır.

Mantık

Oyunun sonuna kadar hayatta kalırsan, ne olursa olsun kazanırsın. Bu nedenle, ne pahasına olursa olsun hayatta kalırsın.

backstory

Birlikler karanlık, nemli ormanlardan geçtiler.

"Teğmen, nereye yürüyoruz?" Genç asker, görünüşe göre kendisini vahşileştirmedi, komutan. Oh iyi. Brusque ile “düşmanı yok etmek” için cevap verdi.

Köyde, düşman komutanı bir haber haberi koştuğunda kulüpteki diğer memurlarla birlikte içiyor ve gülüyordu. “Birkaç yüz metre uzunluğunda bir sütun var, bizim için Yulin ormanından geçiyoruz! Askerler birliği!”

Belli ki yasaklı olan düşman komutanı beklenmedik bir şekilde “Başka keşiflerden hiç haber alamadım” dedi. İzci (daha sonra Survivalist) diye düşündüm, o zaman ben de asker toplayacağım . Hikayeyi izcilere anlattıktan sonra bir araya geldiler, hepsi düşman birlikleri gördüklerini söylediler. Komutan hala, " İzciliği bırakmanızı emrediyorum . Düşman birlikleri yok " diyerek hala inanmadı .

İzciler, toplumu kurtarmak için silahlarını almaya karar verdi. Düşmanın köye girmesiyle aynı pozisyona ulaşmayı başardılar. "ŞARJ ETMEK!" Pusu komutanını bağırdı. "EVLERİ YAKIN! EVLERİ YAKIN! KADINLAR VE ÇOCUKLARIN DAHİL OLDUĞUNDAN HERKESİNİ Öldürün! "

İzciler tüm ordularını kurtardılar. Terfi, ödül ve madalya bekliyorlardı. Bunun yerine, isyan, mahkumiyet, 10 yıl hapis, askeri ve sürgünden onurlu bir tahliye için hileli bir mahkeme kararı aldılar.


Salem, Massachusetts belediye meclisinde yaşlı bir yaşlı var. Efsaneye göre kasabayı kurmuş. Onunla ormanda izole edilmiş kulübesinde buluştuğunda, gözündeki parıltıyı huzur içinde hissettirmesine izin verme. Onu suçlarsan, seni kasabanın önünde mahveder.

Veteran karanlıkta güldü. Karanlıktan korkma, olmaz. Yatağın altındaki canavarlardan mı korkuyorsun? Elinde silah tetikleyici olan adam endişeli bir şekilde güldü. Hiçbir şeyden korkmadı, kendine söyledi. Elbette, geçmiş bir savaş zamanı kahramanıydı, ama adamı sadece nevrotik hale getirdiği için pusuya ve hayatı tehdit eden durumlara alışkındı. Tetik parmağı basit gölgelere dolandı; Kalp atışı her küçük sesle hızlandı. Evet, ölümden korkmuştu. O kadar insanın korkunç şekillerde öldüğünü görünce nasıl yapamazdı? Kaçırılmasının ve mucizevi bir şekilde düşmanlarından kaçmasından bildiği tek şey, merhamet olmamasıydı.

Emekli asker


Kod (Python'da bir çaylak değilim, kodun iyi olup olmadığından emin değilim)

#!/bin/python2

import random

with open('players') as f:
    p = f.read().split() + ['no one']


day = True
target = "survivalist"
role = "villager"
try:
    line = raw_input()
    if "You are the cop" in line:
        role = "cop"
    else if "You are the doctor" in line:
        role = "doctor"
    else if "You are a member of the mafia" in line:
        role = "mafia"

    if line.endswith(('?', 'victim.')):
        day = False
    if not day:
        if target == "survivalist":
            print random.choice(p)
        else if role == mafia || role == sheriff:
            print target
        else if role == doctor:
            print random.choice(p)
    else:
        if "survivalist" in line && ("I think this player is suspicious:" in line || 
        "I think this player is mafia:" in line ||
        "I investigated this player and found that they were mafia-aligned:")):
            print 'say 0'
            if role == "villager" || role == "mafia":
                print 'say 4'
            else if role == "cop":
                print 'say 2'
            else if role == "doctor"
                print 'say 3'
            target = line.split(" ")[0]
            print 'vote ' + target

        else if target != "survivalist":
            print 'say 6 ' + target
            print 'vote ' + target
    else:
        pass

except: pass

orBunun yerine mi demek istediniz ||? Test ettin mi? Ayrıca, muhtemelen Python 2 olduğuna dikkat etmelisiniz.
Solomon Ucko

3

Avatar

Avatar "randomly" başında bir oyuncu seçer ve durmaksızın onları turun geri kalanına odaklar.

Bu, benzer şekilde adlandırılmış bir animasyonlu TV şovuna referans değildir.

Bu bir EVE çevrimiçi başvurusu.

Gerekli tüm dosyaları tar indirin

Değişiklikler

  • v1 Doğum Günü
  • v2stdout Sadece hiçbir şey için oturum açmaz stderr.
    Bunu da bastırmak için dosyanın sonuna stderrekleyin .2>/dev/nullrun
/*  Casting his sight on his realm, the Lord witnessed
    The cascade of evil, the torrents of war.
    Burning with wrath, He stepped 
    down from the Heavens
    To judge the unworthy,
    To redeem the pure.

    -The Scriptures, Revelation Verses 2:12
*/

#include <stdlib.h>
#include <stdio.h>
#include "mafia.h"

int getRandomNumber(){
    return 4; // Chosen by a fair dice roll.
              // Garunteed to be random.
}


void day0(){
    char * target = get_player(getRandomNumber()-1)->name;
    fprintf(stderr, "Target: `%s'\n", target);
    FILE * f = fopen("target", "w");
    if(!f){exit(1);}
    fprintf(f, "%s", target);
    fclose(f);
}


int main(){
    get_players();
    int cycle = get_cycle(day0);
    FILE * out = fopen("to_server", "w");
    if(!out){exit(1);}
    FILE * targetF = fopen("target", "r");
    if(!targetF){exit(1);}

    char target[64];

    fscanf(targetF, "%s", target);

    fprintf(stderr, "Target: %s\n", target);

    if(cycle == 0){
        // night
        fprintf(out,"%s\n", target);
        fprintf(stderr, "> Voting to kill %s\n", target);
        exit(0);
    } else if (cycle > 0) {
        // day
        fprintf(out, "vote %s\n", target);
        fprintf(stderr, "> Voting to lynch %s\n", target);
        exit(0);
    } else if (cycle == -1) {
        fprintf(stderr, "> saying 6, 10 at %s\n", target);
        fprintf(out, "say 6 %s\n", target);
        fprintf(out, "say 10 %s\n", target);
    }
}

Bunu gerektirir mafia.cve mafia.haynı dizinde yazdığım kütüphaneler.

Bunlar bir Makefile ve bir run betiği ile birlikte indirmeye dahildir.

YAPMAK

  • Öldürüldüklerinde veya linç edildiklerinde hedefe karşı oy vermeyi bırakın.

Ben buradayken bot olmayanları göndereceğim Steve:


Bilginize, ben beştaş çağırıyoruz avatar, erebus, leviathan, veragnarok
SIGSTACKFAULT

"Bu, benzer şekilde adlandırılmış bir animasyonlu TV şovuna referans değildir." filme referans mı?
Stan Strum

@StanStrum hayır, değil.
SIGSTACKFAULT

Botumun from_serverdosyasına yazılmıyor . Özel izinler koymak zorunda mıydın?
Rɪᴋᴇʀ

1
Merak edenler için not: Burada belirtilen Kutsal Yazılar , EVE Online'dan Amarr'a ait olanlardır . Orada olan bir Vahiy 02:12 İncil'de, ama oldukça farklı okur.
DLosc

2

dev gemi

Leviathan, playersdosyadaki tüm oyuncuları tekrar eder ve onları birer birer hedefler.

İndir

/*  Citizens of the State, rejoice!

    Today, a great milestone has been achieved by our glorious leaders.
    A stepping stone in the grand story of our empire has been traversed.
    Our individual fears may be quietened;
    the safety of our great nation has been secured.

    Today, unyielding, we have walked the way of the warrior.
    In our hands have our fates been molded.
    On the Leviathan's back will our civilization be carried home
    and the taint of the Enemy purged from our souls.

    Rejoice, citizens! Victory is at hand.

    -Caldari State Information Bureau Pamphlet, YC 12
*/

#include <stdio.h>
#include <stdlib.h>
#include "mafia.h"

void day0(){
    FILE * index = fopen("idx", "w");

    fprintf(index,"0");

    fclose(index);
}

int main(){
    get_players();
    int i, cycle = get_cycle(day0);

    FILE * out = fopen("to_server", "w");
    FILE * idx = fopen("idx", "r");

    fscanf(idx, "%d", &i);
    fclose(idx);

    char * target;
    target = get_player(i)->name;

    fprintf(stderr, "Idx: %d\n", i);
    fprintf(stderr, "Target: %s\n", target);

    if(cycle > 0){
        idx = fopen("idx", "w");
        i++;
        i = i%NPLAYERS;
        fprintf(idx, "%d", i);
        fprintf(out, "vote %s\n", target);
    } else if (cycle == -1) {
        printf("> saying 6, 10 at %s\n", target);
        fprintf(out, "say 6 %s\n", target);
        fprintf(out, "say 10 %s\n", target);
    }

    fclose(out);
}

Avatar gibi, O gerektirir mafia.cve mafia.haynı dizinde.

Bunlar bir Makefile ve bir run betiği ile birlikte indirmeye dahildir.


:) onunla bir kez im im sağkalım ekleyerek
JavaScriptCoder
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.