The Rock, Paper, Gunting, Lizard, Spock Tournament of Epicness


98

Papan Skor Terbaru @ 2014-08-02 12:00

| Pos # | Author               | Name                    | Language   | Score | Win   | Draw  | Loss  | Avg. Dec. Time |
+-------+----------------------+-------------------------+------------+-------+-------+-------+-------+----------------+
| 1st   | Emil                 | Pony                    | Python2    | 064   | 064   | 000   | 005   | 0026.87 ms     |
| 2nd   | Roy van Rijn         | Gazzr                   | Java       | 062   | 062   | 001   | 006   | 0067.30 ms     |
| 2nd   | Emil                 | Dienstag                | Python2    | 062   | 062   | 001   | 006   | 0022.19 ms     |
| 4th   | ovenror              | TobiasFuenke            | Python2    | 061   | 061   | 001   | 007   | 0026.89 ms     |
| 5th   | PhiNotPi             | BayesianBot             | Perl       | 060   | 060   | 000   | 009   | 0009.27 ms     |
| 6th   | Claudiu              | SuperMarkov             | Python2    | 058   | 058   | 001   | 010   | 0026.77 ms     |
| 7th   | histocrat            | Alternator              | Ruby       | 057   | 057   | 001   | 011   | 0038.53 ms     |
| 8th   | histocrat            | LeonardShelby           | Ruby       | 053   | 053   | 000   | 016   | 0038.55 ms     |
| 9th   | Stretch Maniac       | SmarterBot              | Java       | 051   | 051   | 002   | 016   | 0070.02 ms     |
| 9th   | Martin Büttner       | Markov                  | Ruby       | 051   | 051   | 003   | 015   | 0038.45 ms     |
| 11th  | histocrat            | BartBot                 | Ruby       | 049   | 049   | 001   | 019   | 0038.54 ms     |
| 11th  | kaine                | ExcitingishBot          | Java       | 049   | 049   | 001   | 019   | 0065.87 ms     |
| 13th  | Thaylon              | UniformBot              | Ruby       | 047   | 047   | 001   | 021   | 0038.61 ms     |
| 14th  | Carlos Martinez      | EasyGame                | Java       | 046   | 046   | 002   | 021   | 0066.44 ms     |
| 15th  | Stretch Maniac       | SmartBot                | Java       | 045   | 045   | 001   | 023   | 0068.65 ms     |
| 16th  | Docopoper            | RoboticOboeBotOboeTuner | Python2    | 044   | 044   | 000   | 025   | 0156.55 ms     |
| 17th  | Qwix                 | Analyst                 | Java       | 043   | 043   | 001   | 025   | 0069.06 ms     |
| 18th  | histocrat            | Analogizer              | Ruby       | 042   | 042   | 000   | 027   | 0038.58 ms     |
| 18th  | Thaylon              | Naan                    | Ruby       | 042   | 042   | 004   | 023   | 0038.48 ms     |
| 20th  | Thaylon              | NitPicker               | Ruby       | 041   | 041   | 000   | 028   | 0046.21 ms     |
| 20th  | bitpwner             | AlgorithmBot            | Python2    | 041   | 041   | 001   | 027   | 0025.34 ms     |
| 22nd  | histocrat            | WereVulcan              | Ruby       | 040   | 040   | 003   | 026   | 0038.41 ms     |
| 22nd  | Ourous               | QQ                      | Cobra      | 040   | 040   | 003   | 026   | 0089.33 ms     |
| 24th  | Stranjyr             | RelaxedBot              | Python2    | 039   | 039   | 001   | 029   | 0025.40 ms     |
| 25th  | JoshDM               | SelfLoathingBot         | Java       | 038   | 038   | 001   | 030   | 0068.75 ms     |
| 25th  | Ourous               | Q                       | Cobra      | 038   | 038   | 001   | 030   | 0094.04 ms     |
| 25th  | Ourous               | DejaQ                   | Cobra      | 038   | 038   | 001   | 030   | 0078.31 ms     |
| 28th  | Luis Mars            | Botzinga                | Java       | 037   | 037   | 002   | 030   | 0066.36 ms     |
| 29th  | kaine                | BoringBot               | Java       | 035   | 035   | 000   | 034   | 0066.16 ms     |
| 29th  | Docopoper            | OboeBeater              | Python2    | 035   | 035   | 002   | 032   | 0021.92 ms     |
| 29th  | Thaylon              | NaanViolence            | Ruby       | 035   | 035   | 003   | 031   | 0038.46 ms     |
| 32nd  | Martin Büttner       | SlowLizard              | Ruby       | 034   | 034   | 004   | 031   | 0038.32 ms     |
| 33rd  | Kyle Kanos           | ViolentBot              | Python3    | 033   | 033   | 001   | 035   | 0032.42 ms     |
| 34th  | HuddleWolf           | HuddleWolfTheConqueror  | .NET       | 032   | 032   | 001   | 036   | 0029.86 ms     |
| 34th  | Milo                 | DogeBotv2               | Java       | 032   | 032   | 000   | 037   | 0066.74 ms     |
| 34th  | Timmy                | DynamicBot              | Python3    | 032   | 032   | 001   | 036   | 0036.81 ms     |
| 34th  | mccannf              | YAARBot                 | JS         | 032   | 032   | 002   | 035   | 0100.12 ms     |
| 38th  | Stranjyr             | ToddlerProof            | Java       | 031   | 031   | 010   | 028   | 0066.10 ms     |
| 38th  | NonFunctional User2..| IHaveNoIdeaWhatImDoing  | Lisp       | 031   | 031   | 002   | 036   | 0036.26 ms     |
| 38th  | john smith           | RAMBOBot                | PHP        | 031   | 031   | 002   | 036   | 0014.53 ms     |
| 41st  | EoinC                | SimpleRandomBot         | .NET       | 030   | 030   | 005   | 034   | 0015.68 ms     |
| 41st  | Martin Büttner       | FairBot                 | Ruby       | 030   | 030   | 006   | 033   | 0038.23 ms     |
| 41st  | Docopoper            | OboeOboeBeater          | Python2    | 030   | 030   | 006   | 033   | 0021.93 ms     |
| 44th  | undergroundmonorail  | TheGamblersBrother      | Python2    | 029   | 029   | 000   | 040   | 0025.55 ms     |
| 45th  | DrJPepper            | MonadBot                | Haskel     | 028   | 028   | 002   | 039   | 0008.23 ms     |
| 46th  | Josef E.             | OneBehind               | Java       | 027   | 027   | 007   | 035   | 0065.87 ms     |
| 47th  | Ourous               | GitGudBot               | Cobra      | 025   | 025   | 001   | 043   | 0053.35 ms     |
| 48th  | ProgramFOX           | Echo                    | .NET       | 024   | 024   | 004   | 041   | 0014.81 ms     |
| 48th  | JoshDM               | SelfHatingBot           | Java       | 024   | 024   | 005   | 040   | 0068.88 ms     |
| 48th  | Trimsty              | Herpetologist           | Python3    | 024   | 024   | 002   | 043   | 0036.93 ms     |
| 51st  | Milo                 | DogeBot                 | Java       | 022   | 022   | 001   | 046   | 0067.86 ms     |
| 51st  | William Barbosa      | StarWarsFan             | Ruby       | 022   | 022   | 002   | 045   | 0038.48 ms     |
| 51st  | Martin Büttner       | ConservativeBot         | Ruby       | 022   | 022   | 001   | 046   | 0038.25 ms     |
| 51st  | killmous             | MAWBRBot                | Perl       | 022   | 022   | 000   | 047   | 0016.30 ms     |
| 55th  | Mikey Mouse          | LizardsRule             | .NET       | 020   | 020   | 007   | 042   | 0015.10 ms     |
| 55th  | ja72                 | BlindForesight          | .NET       | 020   | 020   | 001   | 048   | 0024.05 ms     |
| 57th  | robotik              | Evolver                 | Lua        | 019   | 019   | 001   | 049   | 0008.19 ms     |
| 58th  | Kyle Kanos           | LexicographicBot        | Python3    | 018   | 018   | 003   | 048   | 0036.93 ms     |
| 58th  | William Barbosa      | BarneyStinson           | Lua        | 018   | 018   | 005   | 046   | 0005.11 ms     |
| 60th  | Dr R Dizzle          | BartSimpson             | Ruby       | 017   | 017   | 001   | 051   | 0038.22 ms     |
| 60th  | jmite                | IocainePowder           | Ruby       | 017   | 017   | 003   | 049   | 0038.50 ms     |
| 60th  | ArcticanAudio        | SpockOrRock             | PHP        | 017   | 017   | 001   | 051   | 0014.19 ms     |
| 60th  | Dr R Dizzle          | BetterLisaSimpson       | Ruby       | 017   | 017   | 000   | 052   | 0038.23 ms     |
| 64th  | Dr R Dizzle          | LisaSimpson             | Ruby       | 016   | 016   | 002   | 051   | 0038.29 ms     |
| 65th  | Martin Büttner       | Vulcan                  | Ruby       | 015   | 015   | 001   | 053   | 0038.26 ms     |
| 65th  | Dr R Dizzle          | Khaleesi                | Ruby       | 015   | 015   | 005   | 049   | 0038.29 ms     |
| 67th  | Dr R Dizzle          | EdwardScissorHands      | Ruby       | 014   | 014   | 002   | 053   | 0038.21 ms     |
| 67th  | undergroundmonorail  | TheGambler              | Python2    | 014   | 014   | 002   | 053   | 0025.47 ms     |
| 69th  | cipher               | LemmingBot              | Python2    | 011   | 011   | 002   | 056   | 0025.29 ms     |
| 70th  | Docopoper            | ConcessionBot           | Python2    | 007   | 007   | 000   | 062   | 0141.31 ms     |
+-------+----------------------+-------------------------+------------+-------+-------+-------+-------+----------------+
Total Players: 70
Total Matches Completed: 2415
Total Tourney Time: 06:00:51.6877573

Catatan Tourney

Bot yang Dikecualikan

  • BashRocksBot - masih tidak senang dengan .net mengeksekusi skrip cygwin bash
  • CounterPreferenceBot - menunggu perbaikan bug
  • RandomlyWeighted - menunggu perbaikan bug
  • CasinoShakespeare - dikecualikan karena memerlukan koneksi internet aktif

Pertanyaan Asli yang Diposting

Anda telah berayun ke rumah teman Anda untuk Pertempuran pertarungan epik yang paling epik dari Rock, Paper, Scissors, Lizard, Spock. Dengan gaya nerd-tastic BigBang sejati, tidak ada pemain yang bermain sendiri tetapi telah membuat bot konsol untuk bermain atas nama mereka. Anda mencabut kunci USB Anda dan menyerahkannya ke Sheldor the Conqueror untuk dimasukkan dalam showdown. Penny pingsan. Atau mungkin Howard pingsan. Kami tidak menilai di sini di apartemen Leonard.

Aturan

Berlaku standar Rock, Kertas, Gunting, Kadal, Spock.

  • Gunting memotong kertas
  • Kertas mencakup Batu
  • Rock menghancurkan Lizard
  • Kadal meracuni Spock
  • Spock menghancurkan Gunting
  • Gunting memenggal Kadal
  • Kadal makan Kertas
  • Kertas membuktikan Spock
  • Spock menguapkan Batu
  • Batu menghancurkan Gunting

Aturan RPSLV

Bot masing-masing pemain akan memainkan satu Pertandingan melawan satu sama bot lainnya di turnamen.

Setiap Pertandingan akan terdiri dari 100 iterasi game RPSLV.

Setelah setiap pertandingan, pemenangnya adalah pemain yang telah memenangkan paling banyak game / hand out dari 100.

Jika Anda memenangkan pertandingan, Anda akan diberikan 1 poin di tabel liga. Dalam hasil pertandingan seri, tidak ada pemain yang mendapat poin.

Persyaratan Bot

Bot Anda harus dapat dijalankan dari baris perintah.

Kotak * nix Sheldor telah mati, jadi kami menjalankannya dari Windows 8 Gaming Laptop, jadi pastikan solusi yang Anda berikan dapat berjalan di windows. Sheldor telah dengan ramah menawarkan untuk menginstal runtimes yang diperlukan (layaknya) untuk dapat menjalankan solusi Anda. (.NET, Java, Php, Python, Ruby, Powershell ...)

Input

Di game pertama setiap pertandingan, tidak ada argumen yang diberikan ke bot Anda. Dalam setiap pertandingan berikutnya dari setiap pertandingan: - Arg1 akan berisi sejarah tangan / keputusan bot Anda dalam pertandingan ini. - Arg2 akan berisi sejarah tangan / keputusan lawan Anda dalam pertandingan ini.

Sejarah akan diwakili oleh urutan huruf kapital tunggal yang mewakili tangan yang mungkin Anda bisa mainkan.

 | R | Rock     |
 | P | Paper    |
 | S | Scissors |
 | L | Lizard   |
 | V | Spock    |

Misalnya

  • Game 1: MyBot.exe
  • Game 2: MyBot.exe SV
  • Game 3: MyBot.exe SS VL
  • Game 4: MyBot.exe SSR VLS

Keluaran

Bot Anda harus menulis respons karakter tunggal yang mewakili "tangannya" untuk setiap game. Hasilnya harus ditulis ke STDOUT dan bot kemudian harus keluar. Huruf kapital tunggal yang valid adalah di bawah ini.

 | R | Rock     |
 | P | Paper    |
 | S | Scissors |
 | L | Lizard   |
 | V | Spock    |

Jika bot Anda tidak mengembalikan kartu yang valid (yaitu 1 dari 5 huruf kapital tunggal di atas, maka Anda secara otomatis kehilangan kartu itu dan pertandingan berlanjut.

Jika kedua bot tidak mengembalikan kartu yang valid, maka permainan dianggap seri dan pertandingan berlanjut.

Format Kecocokan

Setiap bot yang dikirimkan akan memainkan satu pertandingan melawan satu sama bot lainnya di turnamen.

Setiap pertandingan akan berlangsung tepat 100 game.

Pertandingan akan dimainkan secara anonim, Anda tidak akan memiliki pengetahuan lanjutan tentang bot spesifik yang Anda lawan, namun Anda dapat menggunakan informasi apa pun dan semua yang Anda dapat kumpulkan dari pengambilan keputusannya selama sejarah pertandingan saat ini untuk mengubah strategi Anda melawan Anda lawan. Anda juga dapat melacak sejarah gim sebelumnya untuk membangun pola / heuristik dll ... (Lihat peraturan di bawah)

Selama satu gim, mesin orkestrasi akan menjalankan bot Anda dan lawan Anda memisahkan 100 milidetik dan kemudian membandingkan hasilnya untuk menghindari tabrakan PRNG dalam bahasa / runtime yang sama. (ini benar-benar terjadi pada saya selama pengujian).

Penilaian & Kendala

Dr. Sheldon Cooper dengan kedok Sheldor Sang Penakluk dengan baik hati menawarkan untuk mengawasi jalannya turnamen. Sheldor Sang Penakluk adalah pengawas yang adil dan adil (kebanyakan). Semua keputusan oleh Sheldor bersifat final.

Permainan akan dilakukan dengan cara yang adil dan benar:

  • Skrip / program bot Anda akan disimpan di mesin orkestrasi di bawah subfolder Players\[YourBotName]\
  • Anda dapat menggunakan subfolder Players\[YourBotName]\datauntuk mencatat data atau riwayat permainan apa pun dari turnamen saat ini. Direktori data akan dibersihkan pada awal setiap turnamen dijalankan.
  • Anda tidak dapat mengakses direktori Pemain dari pemain lain di turnamen
  • Bot Anda tidak dapat memiliki kode spesifik yang menargetkan perilaku bot tertentu
  • Setiap pemain dapat mengirimkan lebih dari satu bot untuk dimainkan selama mereka tidak berinteraksi atau saling membantu.

Edit - Kendala Tambahan

  • Mengenai kehilangan, mereka tidak akan didukung. Bot Anda harus memainkan salah satu dari 5 tangan yang valid. Saya akan menguji setiap bot di luar turnamen dengan beberapa data acak untuk memastikan bahwa mereka berperilaku. Setiap bot yang melempar kesalahan (mis. Kesalahan kehilangan) akan dikeluarkan dari turnamen sampai bug diperbaiki.
  • Bot mungkin turunan selama mereka secara ringkas berbeda dalam perilaku mereka. Bot (termasuk dalam bahasa lain) yang melakukan perilaku yang sama persis dengan bot yang ada akan didiskualifikasi
  • Sudah ada bot spam untuk yang berikut jadi tolong jangan kirim ulang
    • Rock - BartSimpson
    • Kertas - LisaSimpson
    • Scissor - EdwardScissorhands
    • Spock - Vulcan
    • Kadal - Khaleesi
    • Pseudo Random - SimpleRandomBot & FairBot
    • Psuedo Random RPS - ConservativeBot
    • Psuedo Random LV - Barney Stinson
  • Bot tidak boleh memanggil layanan pihak ketiga atau sumber daya web (atau apa pun yang secara signifikan memperlambat kecepatan / waktu pengambilan keputusan pertandingan). CasinoShakespeareadalah satu-satunya pengecualian karena bot itu dikirimkan sebelum batasan ini ditambahkan.

Sheldor akan memperbarui pertanyaan ini sesering mungkin dengan hasil Turnamen, karena lebih banyak bot yang dikirimkan.

Program Orkestrasi / Kontrol

Program orkestrasi, bersama dengan kode sumber untuk setiap bot tersedia di github.

https://github.com/eoincampbell/big-bang-game

Rincian Pengiriman

Kiriman Anda harus mencakup

  • Nama Bot Anda
  • Kode Anda
  • Perintah untuk
    • jalankan bot Anda dari shell mis
    • ruby myBot.rb
    • python3 myBot.py
    • ATAU
    • kompilasi pertama Anda berdua dan kemudian jalankan. misalnya
    • csc.exe MyBot.cs
    • MyBot.exe

Pengiriman Sampel

BotName: SimpleRandomBot
Compile: "C:\Program Files (x86)\MSBuild\12.0\Bin\csc.exe" SimpleRandomBot.cs
Run:     SimpleRandomBot [Arg1] [Arg2]

Kode:

using System;
public class SimpleRandomBot
{
    public static void Main(string[] args)
    {
        var s = new[] { "R", "P", "S", "L", "V" };
        if (args.Length == 0)
        {
            Console.WriteLine("V"); //always start with spock
            return;
        }
        char[] myPreviousPlays = args[0].ToCharArray();
        char[] oppPreviousPlays = args[1].ToCharArray();
        Random r = new Random();
        int next = r.Next(0, 5);
        Console.WriteLine(s[next]);
    }
}

Klarifikasi

Ada pertanyaan, tanyakan di komentar di bawah.


7
Seperti apa sejarahnya ketika seorang pemain kehilangan satu tangan?
histokrat

1
Saya akan habis-habisan dengan pendekatan analitik, tetapi sebagian besar bot di sini cukup bodoh untuk mengalahkan AI pintar.
lembut

1
Hanya karena aku tidak pernah berada di memimpin untuk setiap tantangan Koth saya berkompetisi di, saya telah mengambil screenshot sebagai kenang-kenangan.
Kyle Kanos

3
Saya akan menjalankan pertandingan lain malam ini dan memposting hasil pertandingan penuh pada pastebin ... batch berikutnya akan memiliki sekitar 450 pertandingan tetapi harus sedikit lebih cepat untuk dijalankan karena saya telah menerapkan beberapa hal paralelisasi dalam prog kontrol
Eoin Campbell

3
Jika saya tidak salah, sepertinya ada bug serius dalam skrip orkestrasi: Sejarah pemain 1 dan 2 selalu diteruskan ke bot masing-masing sebagai argumen pertama dan kedua, sementara menurut aturan, bot harus selalu mendapatkan sejarah sendiri dulu. Sekarang pemain 2 secara efektif mencoba untuk mengalahkan dirinya sendiri. (Saya agak curiga karena bot saya memenangkan setiap pertandingan di mana itu adalah pemain 1 saat kalah setengah dari pertandingan lainnya.)
Emil

Jawaban:


26

Pony (Python 2)

Ini didasarkan pada bot batu-kertas-gunting yang saya tulis beberapa waktu lalu untuk tantangan pemrograman di akhir kelas online Udacity . Saya mengubahnya untuk memasukkan Spock dan kadal dan membuat beberapa perbaikan.

Program ini memiliki 11 strategi sederhana yang berbeda, masing-masing dengan 5 varian. Ini memilih dari antara ini berdasarkan seberapa baik mereka akan melakukan selama putaran terakhir.

Saya menghapus strategi mundur yang hanya dimainkan secara acak melawan lawan yang lebih kuat. Saya kira ini lebih menyenangkan seperti ini.

import sys

# just play Spock for the first two rounds
if len(sys.argv)<2 or len(sys.argv[1])<2: print 'V'; sys.exit()

# initialize and translate moves to numbers for better handling:
my_moves, opp_moves = sys.argv[1], sys.argv[2]
moves = ('R', 'P', 'S', 'V', 'L')   
history = zip([moves.index(i) for i in my_moves],
              [moves.index(i) for i in opp_moves])

# predict possible next moves based on history
def prediction(hist):
    N = len(hist)    

    # find longest match of the preceding moves in the earlier history
    cand_m = cand_o = cand_b = range(N-1)
    for l in xrange(1,min(N, 20)):
        ref = hist[N-l]
        cand_m = ([c for c in cand_m if c>=l and hist[c-l+1][0]==ref[0]]
                  or cand_m[-1:])
        cand_o = ([c for c in cand_o if c>=l and hist[c-l+1][1]==ref[1]]
                  or cand_o[-1:])
        cand_b = ([c for c in cand_b if c>=l and hist[c-l+1]==ref]
                  or cand_b[-1:])

    # analyze which moves were used how often
    freq_m, freq_o = [0]*5, [0]*5
    for m in hist:
        freq_m[m[0]] += 1
        freq_o[m[1]] += 1

    # return predictions
    return ([hist[-i][p] for i in 1,2 for p in 0,1]+   # repeat last moves
            [hist[cand_m[-1]+1][0],     # history matching of my own moves
             hist[cand_o[-1]+1][1],     # history matching of opponent's moves
             hist[cand_b[-1]+1][0],     # history matching of both
             hist[cand_b[-1]+1][1],
             freq_m.index(max(freq_m)), # my most frequent move
             freq_o.index(max(freq_o)), # opponent's most frequent move
             0])                        # good old rock (and friends)


# what would have been predicted in the last rounds?
pred_hist = [prediction(history[:i]) for i in xrange(2,len(history)+1)]

# how would the different predictions have scored?
n_pred = len(pred_hist[0])
scores = [[0]*5 for i in xrange(n_pred)]
for pred, real in zip(pred_hist[:-1], history[2:]):
    for i in xrange(n_pred):
        scores[i][(real[1]-pred[i]+1)%5] += 1
        scores[i][(real[1]-pred[i]+3)%5] += 1
        scores[i][(real[1]-pred[i]+2)%5] -= 1
        scores[i][(real[1]-pred[i]+4)%5] -= 1

# return best counter move
best_scores = [list(max(enumerate(s), key=lambda x: x[1])) for s in scores]
best_scores[-1][1] *= 1.001   # bias towards the simplest strategy    
if best_scores[-1][1]<0.4*len(history): best_scores[-1][1] *= 1.4
strat, (shift, score) = max(enumerate(best_scores), key=lambda x: x[1][1])
print moves[(pred_hist[-1][strat]+shift)%5]

Jalankan sebagai:

python Pony.py

Sunting : Saya membuat perubahan kecil dengan menempatkan bias terhadap strategi paling sederhana (yaitu selalu memainkan langkah yang sama) dalam kasus yang tidak pasti. Ini sedikit membantu untuk tidak mencoba menemukan pola yang terlalu rumit di mana tidak ada, misalnya dalam bot seperti ConservativeBot.

Catatan : Saya mencoba menjelaskan strategi dasar pencocokan riwayat yang digunakan bot ini dalam pos untuk bot Dienstag saya yang lain .


3
Rasio kemenangan 96 persen luar biasa.
AndoDaan

Sangat bagus. Anda mungkin menyukai Iocaine Powder , jika Anda belum melihatnya.
wchargin

@WChargin, tentu saja. :) Ketika saya menulis kode asli saya, saya telah membaca tentang Iocaine Powder beberapa tahun sebelumnya dan samar-samar mengingat ide umum. Jadi, Pony memang terinspirasi olehnya, jika tidak secara langsung. Ternyata, mereka sangat mirip. Saya pikir tambang saya memiliki repertoar strategi yang lebih luas sementara Iocaine Powder memiliki tingkat pemikiran meta-meta yang cerdas yang tidak saya sertakan.
Emil

20

Markov, Ruby

Melihat dua gerakan terakhir lawan dan menentukan tindak lanjut yang mungkin (dan kemungkinan besar). Jika kombinasi belum dipilih sebelumnya, ia hanya menggunakan semua gerakan lawan (sejauh ini). Kemudian ia mengumpulkan semua respons yang mungkin untuk ini dan mengambil yang acak.

responses = {
  'R' => ['P', 'V'],
  'P' => ['S', 'L'],
  'S' => ['R', 'V'],
  'L' => ['S', 'R'],
  'V' => ['P', 'L']
}

if ARGV.length == 0 || (history = ARGV[1]).length < 3
    choices = ['R','P','S','L','V']
else
    markov = Hash.new []
    history.chars.each_cons(3) { |chars| markov[chars[0..1].join] += [chars[2]] }

    choices = []
    likely_moves = markov.key?(history[-2,2]) ? markov[history[-2,2]] : history.chars
    likely_moves.each { |move| choices += responses[move] }
end

puts choices.sample

Jalankan seperti

markov.rb

Dan kemudian saya menggunakan program ini untuk menentukan langkah yang paling mungkin yang akan saya lakukan selanjutnya kemudian mencari tahu apa yang akan Anda lakukan dan akhirnya menemukan cara untuk mengalahkan apa yang akan Anda lakukan dan mengulangi semuanya secara berulang, berulang-ulang.
Jamie

@Jamie Maksudmu seperti orang ini? codegolf.stackexchange.com/a/35295/8478
Martin Ender

Anda menebaknya. (komentar itu tidak cukup panjang untuk diposting)
Jamie

19

ConservativeBot, Ruby

Hal-hal baru adalah hal-hal buruk.

puts ['R','P','S'].sample

Jalankan seperti

ruby conservative.rb

Versi OG adalah versi terbaik.
maxywb

13

Kipas Star Wars - Ruby

Persetan denganmu, Spock

puts ['R','P','L','S'].sample

Jalankan seperti:

ruby starwarsfan.rb

Ditambahkan ke Controller
Eoin Campbell

Anda dapat mengembalikan dengan mengedit jawaban - Saya hanya akan berkomentar di sini ketika saya telah menambahkannya.
Eoin Campbell

Kenapa R dan S? : P
cjfaure

@ardard Ini adalah penggemar Star Wars karena tidak menggunakan Spock.
William Barbosa

ah, kamu benar (tentu saja). Saya membacanya terlalu cepat, kesalahan saya (tapi tanpa konsekuensi untungnya)
mardavi

13

Barney Stinson - Lua

Saya hanya punya satu aturan: Baru selalu lebih baik. Persetan Jo Ken Po tua atau apa pun namanya.

math.randomseed(os.time())
print(math.random() > 0.5 and "V" or "L")

Jalankan seperti:

lua legenwaitforitdary.lua

8

Boring Bot (Jawa)

Dia menganggap semua orang selalu memainkan hal yang sama dan merencanakannya. Dia biasanya memetik batu dalam ikatan, karena begitu juga orang lain?

public class BoringBot
{
    public static void main(String[] args)
    {
        int Rock=0;
        int Paper=0;
        int Scissors=0;
        int Lizard=0;
        int Spock=0;

        if (args.length == 0)
        {
            System.out.print("P");
            return;
        }

        char[] oppPreviousPlays = args[1].toCharArray();

        for (int j=0; j<oppPreviousPlays.length; j++) {
            switch(oppPreviousPlays[j]){
                case 'R': Rock++; break;
                case 'P': Paper++; break;
                case 'S': Scissors++; break;
                case 'L': Lizard++; break;
                case 'V': Spock++;
            }
        }

        int Best = Math.max(Math.max(Lizard+Scissors-Spock-Paper,
                                     Rock+Spock-Lizard-Scissors),
                            Math.max(Math.max(Paper+Lizard-Spock-Rock,
                                              Paper+Spock-Rock-Scissors),
                                     Rock+Scissors-Paper-Lizard));

        if (Best== Lizard+Scissors-Spock-Paper){
            System.out.print("R"); return;
        } else if (Best== Rock+Spock-Lizard-Scissors){
            System.out.print("P"); return;
        } else if (Best== Paper+Lizard-Spock-Rock){
            System.out.print("S"); return;
        } else if(Best== Paper+Spock-Rock-Scissors){
            System.out.print("L"); return;
        } else {
            System.out.print("V"); return;
        }
    }
}

Perhatikan bahwa jika ini adalah strategi yang sudah digunakan orang lain, beri tahu saya dan saya akan hapus. Rasanya seperti yang sudah saya lihat.
kaine

apakah ini C #. Anda. properti panjang salah. dan tidak ada metodemax
Eoin Campbell

@EoinCampbell Ini adalah java, saya telah bermain dengan keduanya dan tampaknya lupa perintah mana yang menjadi miliknya.
kaine

ah keren tinggalkan dengan saya dan saya akan memasukkannya.
Eoin Campbell

masih rusak. running jre8 - java BoringBot.java - Kesalahan: Tidak dapat menemukan atau memuat kelas utama D: \ Perangkat Lunak Saya \ big-bang-game \ BigBang.Orchestrator \ bin \ Debug \ Pemain \ BoringBot \ BoringBot.java -
Eoin Campbell

8

IocainePowder, Ruby

masukkan deskripsi gambar di sini

Didasarkan dari (tanpa malu dicuri dari) strategi RPS di sini . Bot terlihat memilih tebakan yang identik dengan bot Markov, tetapi kemudian mengasumsikan lawan telah menebak apa yang akan dipilih, dan memilih langkah untuk mengalahkan yang sesuai.

Perhatikan bahwa saya baru saja mengadaptasi ide dasar strategi tertaut, tidak mengikutinya secara rinci.

responses = {
  'R' => ['P', 'V'],
  'P' => ['S', 'L'],
  'S' => ['R', 'V'],
  'L' => ['S', 'R'],
  'V' => ['P', 'L']
}

if ARGV.length == 0 || (history = ARGV[1]).length < 3
    choices = ['R','P','S','L','V']
else
    markov = Hash.new []
    history.chars.each_cons(3) { |chars| markov[chars[0..1].join] += [chars[2]] }

    choices = []
    likely_moves = markov.key?(history[-2,2]) ? markov[history[-2,2]] : history.chars
    likely_moves.each { |move| choices += responses[move] }
end

myChoice = choices.sample 
theirChoice = responses[myChoice].sample
actualChoice = responses[theirChoice].sample
puts actualChoice

Jalankan seperti

iocaine.rb

5
Anda tetap menggunakan kata itu. Saya tidak berpikir itu berarti apa yang Anda pikirkan artinya.
JoshDM

2
Kekuatan sebenarnya dari Iocaine Powder adalah beralih antara menggunakan markov dan beating-markov. Ini dimulai sebagai markov pintar, tetapi begitu ia merasakan (mulai kehilangan) itu melompat ke mode pemukulan-markov. Harus mudah ditambahkan.
Roy van Rijn

Ahh, pintar! Tidak akan berbohong, saya hanya mendengar Iocaine menjelaskan kepada saya, tidak benar-benar melihatnya secara detail. Jangan ragu untuk memodifikasi kode saya jika Anda ingin atau mengirimkan kode Anda dan dapatkan kredit!
jmite

8

HuddleWolfTheConqueror - C #

HuddleWolf kembali dan lebih baik dari sebelumnya. Dia akan mengalahkan Sheldor Sang Penakluk di pertandingan konyolnya sendiri. HuddleWolf cukup pintar untuk mengidentifikasi dan melawan spammer. Untuk lawan yang lebih cerdas, HuddleWolf menggunakan pengetahuannya tentang statistik dasar kelas 5 dan menggunakan roll dadu berbobot berdasarkan sejarah permainan lawan.

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

public class HuddleWolfTheConqueror
{

    public static readonly char[] s = new[] { 'R', 'P', 'S', 'L', 'V' };

    public static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Console.WriteLine(pickRandom());
            return;
        }

        char[] myPlays = args[0].ToCharArray();
        char[] oppPlays = args[1].ToCharArray();

        char tryPredict = canPredictCounter(oppPlays);
        if (tryPredict != '^')
        {
            Console.WriteLine(tryPredict);
        }
        else
        {
            Console.WriteLine(pickRandom());
        }
        return;
    }


    public static char canPredictCounter(char[] history)
    {
        // don't predict if insufficient data
        if (history.Length < 5)
        {
            return '^';
        }

        // calculate probability of win for each choice
        Dictionary<char, double> dic = getBestProabability(history);

        // get item with highest probability of win
        List<char> maxVals = new List<char>();
        char maxVal = '^';
        double mostFreq = 0;
        foreach (var kvp in dic)
        {
            if (kvp.Value > mostFreq)
            {
                mostFreq = kvp.Value;
            }
        }
        foreach (var kvp in dic)
        {
            if (kvp.Value == mostFreq)
            {
                maxVals.Add(kvp.Key);
            }
        }

        // return error
        if (maxVals.Count == 0)
        {
            return maxVal;
        }

        // if distribution is not uniform, play best play
        if (maxVals.Count <= 3)
        {
            Random r = new Random(Environment.TickCount);
            return maxVals[r.Next(0, maxVals.Count)];
        }

        // if probability is close to uniform, use weighted dice roll
        if (maxVals.Count == 4)
        {
            return weightedRandom(dic);
        }

        // if probability is uniform, use random dice roll
        if (maxVals.Count >= 5)
        {
            return pickRandom();
        }

        // return error
        return '^';
    }

    public static Dictionary<char, double> getBestProabability(char[] history)
    {
        Dictionary<char, double> dic = new Dictionary<char, double>();
        foreach (char c in s)
        {
            dic.Add(c, 0);
        }
        foreach (char c in history)
        {
            if (dic.ContainsKey(c))
            {
                switch(c)
                {
                    case 'R' : 
                        dic['P'] += (1.0/(double)history.Length);
                        dic['V'] += (1.0/(double)history.Length);
                        break;
                    case 'P' : 
                        dic['S'] += (1.0/(double)history.Length);
                        dic['L'] += (1.0/(double)history.Length);
                        break;
                    case 'S' : 
                        dic['V'] += (1.0/(double)history.Length);
                        dic['R'] += (1.0/(double)history.Length);
                        break;
                    case 'L' : 
                        dic['R'] += (1.0/(double)history.Length);
                        dic['S'] += (1.0/(double)history.Length);
                        break;
                    case 'V' : 
                        dic['L'] += (1.0/(double)history.Length);
                        dic['P'] += (1.0/(double)history.Length);
                        break;
                    default : 
                        break;

                }
            }
        }
        return dic;
    }

    public static char weightedRandom(Dictionary<char, double> dic)
    {
        Random r = new Random(Environment.TickCount);
        int next = r.Next(0, 100);
        int curVal = 0;
        foreach (var kvp in dic)
        {
            curVal += (int)(kvp.Value*100);
            if (curVal > next)
            {
                return kvp.Key;
            }
        }
        return '^';
    }

    public static char pickRandom()
    {
        Random r = new Random(Environment.TickCount);
        int next = r.Next(0, 5);
        return s[next];
    }
}

8

Bukti Balita

Bot yang cukup bodoh ini mengasumsikan sedang bermain balita yang akan "mengejar" gerakannya, selalu berusaha untuk mengalahkan apa pun yang terakhir kali dilemparkan. Jika bot dikalahkan beberapa kali berturut-turut, bot akan melompat ke titik baru dalam pola. Ini didasarkan pada strategi saya untuk selalu mengalahkan adik saya yang jauh lebih muda. :)

SUNTING:: Mengubah panjang garis kerugian yang diperlukan untuk melompat ke lemparan acak Juga memperbaiki bug utama dengan lompatan acak.

Simpan sebagai ToddlerProof.java, kompilasi, lalu jalankan denganjava ToddlerProof [me] [them]

import java.util.HashMap;
public class ToddlerProof
{
    char[] moves = new char[]{'R', 'P', 'S', 'L', 'V'};
    public static void main(String[] args)
    {
        if(args.length<1) //first Round
        {
            System.out.print('V');//Spock is best
            return;
        }
        else
        {
            String them = args[1];
            String me = args[0];
            int streak = 0;

            HashMap<Character, Character> nextMove = new HashMap<Character, Character>();
            //Next move beats things that beat my last move
            nextMove.put('L', 'V');
            nextMove.put('V', 'S');
            nextMove.put('S', 'P');
            nextMove.put('P', 'R');
            nextMove.put('R', 'L');
            //Check if last round was a tie or the opponent beat me
            int lastResult = winner(me.charAt(me.length()-1), them.charAt(them.length()-1));
            if(lastResult == 0)
            {
                //tie, so they will chase my last throw
                System.out.print(nextMove.get(me.charAt(me.length()-1)));

                return;
            }
            else if(lastResult == 1)
            {
                //I won, so they will chase my last throw
                System.out.print(nextMove.get(me.charAt(me.length()-1)));


                return;
            }

            else{
                //I lost
                //find streak
                for(int i = 0; i<me.length(); i++)
                {
                    int a = winner(me.charAt(i), them.charAt(i));
                    if(a >= 0) streak = 0;
                    else streak++;
                }
                //check lossStreak
                //If the streak is 2, then a rotation will make it even.
                //if it is >2, something bad has happened and I need to adjust.
                if(streak>2)
                {
                    //if they are on to me, do something random-ish
                    int r = (((them.length()+me.length()-1)*13)/7)%4;
                    System.out.print(move[r]);
                    return;
                }
                //otherwise, go on with the plan
                System.out.print(nextMove.get(me.charAt(me.length()-1)));
                return;
            }
        }
    }
    public static int winner(char me, char them)
    {
        //check for tie
        if(me == them) return 0;
        //check if they won
        if(me=='V' && (them == 'L' || them == 'P')) return -1;
        if(me=='S' && (them == 'V' || them == 'R')) return -1;
        if(me=='P' && (them == 'S' || them == 'L')) return -1;
        if(me=='R' && (them == 'P' || them == 'V')) return -1;
        if(me=='L' && (them == 'R' || them == 'S')) return -1;
        //otherwise, I won
        return 1;
    }
}

1
Haruskah kita menggunakan print atau println? ... Saya tidak yakin.
kaine

Hmmm. Saya akan membayangkan keduanya akan bekerja, tetapi saya bisa melihat println kacau jika program kontrol mengambil baris baru, bukan karakter. Terima kasih telah menunjukkan itu, saya akan mengedit kode saya untuk berjaga
Stranjyr

@Stranjyr ada beberapa bug dalam menjalankan terakhir Anda. Itu tidak mengebom program kontrol tetapi jika Anda mencari sejarah untuk "ToddlerProof plays n" sepertinya bot Anda mengembalikan nol untuk tangan tertentu dan kemudian mengololkannya secara otomatis. Contoh game adalah "Echo & ToddlerProof" di mana Echo memainkan "LVSPRLV" sebelum bot Anda mulai keluar.
Eoin Campbell

@ Eion Campbell Terima kasih telah menyebutkannya. Saya melihat itu sebelumnya ketika Anda memposting log dari pertandingan gagal, dan saya pikir saya sudah memperbaikinya. Itu mengalami kesalahan di mana jika kehilangan lebih dari 5 lurus, alih-alih melompat ke permainan acak itu hanya melemparkan nilai yang tidak valid. Dan kemudian, karena itu membuatnya kalah, itu melemparkan nilai yang tidak valid lain . Sebuah lingkaran setan.
Stranjyr

Keren. Telah diperbarui di prog kontrol sekarang.
Eoin Campbell

8

Bart Simpson

"Batu tua yang bagus! Tidak ada yang mengalahkan batu!"

puts 'R'

Jalankan sebagai

ruby DoTheBartman.rb

Lisa Simpson

"Kas miskin, bisa ditebak. Selalu memilih rock."

puts 'P'

Jalankan sebagai

ruby LisaSimpson.rb

Lisa Simpson yang lebih baik

Aku merasa tidak enak membuat Lisa sangat bodoh, jadi aku membiarkannya memilih secara acak antara salah satu tangan yang akan mengalahkan rock. Masih bodoh, tapi bagaimanapun juga dia seorang Simpson. Mungkin krayon tersangkut di otaknya?

puts ['P','V'].sample

Jalankan sebagai

ruby BetterLisaSimpson.rb

2
Bentrokan nama kecil . Tetap memberi +1.
Martin Ender

@ MartinBüttner Damn, tidak memperhatikan itu. Program-programnya tampaknya masih melakukan hal-hal yang berbeda - dan setidaknya Lisa di sini dapat merasa lebih unggul dengan mengalahkan dua versi berbeda dari kakaknya.
Dr R Dizzle

1
Sheldor setuju ... akan ada BartBot dan BartSimpson :)
Eoin Campbell

3
Kami hanya memiliki BortBot.
JoshDM

1
Ini akan dibantai oleh markov :)
Cruncher

7

Gema

Ditulis dalam C #. Kompilasi dengan csc Echo.cs. Jalankan sepertiEcho.exe ARG1 ARG2 .

Jalankan pertama, Echo mengambil opsi acak. Setiap menjalankan setelah yang pertama, Echo hanya mengulangi tindakan terbaru lawan.

using System;

namespace Echo
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Random r = new Random();
                string[] options = new string[] { "R", "P", "S", "L", "V" };
                Console.WriteLine(options[r.Next(0, options.Length)]);
            }
            else if (args.Length == 2)
            {
                string opponentHistory = args[1];
                Console.WriteLine(opponentHistory[opponentHistory.Length - 1]);
            }
        }
    }
}

7

Vulcan, Ruby

Jari-jariku direkatkan.

puts 'V'

Jalankan seperti

ruby vulcan.rb

(Saya pikir ini adalah satu-satunya strategi karakter untuk pengaturan latar belakang Anda.)


Perlu melihat kembali episode untuk melihat apakah ada orang yang lahir dengan lidah bercabang. LizardMan FTW !!!
Eoin Campbell

3
Tapi bukankah ini bagaimana semua orang di big bang bermain?
kaine

2
@anotherguest Itulah yang saya maksud dengan "ini adalah satu-satunya strategi dalam karakter".
Martin Ender

6

Tyrannosaurus, Godzilla, Barney ... Aturan Kadal. Kadang-kadang mereka mendapat masalah dan perlu memanggil Spock atau melempar Rocks

using System;
public class LizardsRule
{
    public static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Console.WriteLine("L");
            return;
        }
        char[] oppPreviousPlays = args[1].ToCharArray();
        var oppLen = oppPreviousPlays.Length;
        if (oppPreviousPlays.Length > 2
            && oppPreviousPlays[oppLen - 1] == 'R'
            && oppPreviousPlays[oppLen - 2] == 'R'
            && oppPreviousPlays[oppLen - 3] == 'R')
        {
            //It's an avalance, someone call Spock
            Console.WriteLine("V");
            return;
        }

        if (oppPreviousPlays.Length > 2
                && oppPreviousPlays[oppLen - 1] == 'S'
                && oppPreviousPlays[oppLen - 2] == 'S'
                && oppPreviousPlays[oppLen - 3] == 'S')
        {
            //Scissors, Drop your tail and pick up a rock
            Console.WriteLine("R");
            return;
        }

        //Unleash the Fury Godzilla
        Console.WriteLine("L");     
    }
}

6

BayesianBot, Perl (sekarang v2!)

Di atas segalanya, ini adalah program yang unik. Di dalamnya, Anda akan melihat perpaduan cemerlang antara statistik dan bentuk pemrograman yang mengerikan. Juga, bot ini mungkin melanggar banyak aturan statistik Bayesian, tetapi namanya terdengar lebih keren.

Esensi inti dari bot ini adalah pembuatan 250 model prediksi yang berbeda. Setiap model mengambil bentuk "Mengingat saya bermain giliran terakhir rock dan lawan saya bermain gunting dua putaran lalu, ini adalah distribusi probabilitas untuk langkah selanjutnya lawan saya." Setiap distribusi probabilitas mengambil bentuk distribusi Dirichlet multi-dimensi.

Setiap belokan, prediksi semua model yang berlaku (biasanya 10) dikalikan bersama untuk membentuk prediksi keseluruhan, yang kemudian digunakan untuk menentukan gerakan mana yang memiliki hasil tertinggi yang diharapkan.

Sunting 1: Dalam versi ini, saya mengubah distribusi sebelumnya dan membuat bot lebih acak ketika kehilangan.

Ada beberapa hal yang mungkin mengalami peningkatan, seperti jumlah model (250 hanya angka 3 digit), pilihan distribusi sebelumnya (saat ini Dir (3,3,3,3,3)), dan metode prediksi sekering. Juga, saya tidak pernah repot-repot menormalkan salah satu distribusi probabilitas, yang oke untuk saat ini karena saya mengalikannya.

Saya tidak memiliki harapan yang sangat tinggi, tetapi saya berharap bot ini akan dapat melakukannya dengan baik.

my ($phist, $ohist) = @ARGV;

my %text2num = ('R',0,'V',1,'P',2,'L',3,'S',4);  #the RVPLS ordering is superior
my @num2text = ('R','V','P','L','S');

@phist = map($text2num{$_},split(//,$phist));
@ohist = map($text2num{$_},split(//,$ohist));

$lowerlimit = 0;
for($lowerlimit..~~@phist-3){$curloc=$_;
 $result = $ohist[$curloc+2];
 @moveset = ($ohist[$curloc],$ohist[$curloc+1],$phist[$curloc],$phist[$curloc+1]);
 for(0..3){$a=$_;
  for(0..$a){$b=$_;
   $predict[$a][$b][$moveset[$a]][$moveset[$b]][$result]++;
  }
 }
}

@recentmoves = ($ohist[-2],$ohist[-1],$phist[-2],$phist[-1]);

@curpred = (1,1,1,1,1);

for(0..3){$a=$_;
 for(0..$a){$b=$_;
  for(0..4){$move=$_;
   $curpred[$move] *= $predict[$a][$b][$recentmoves[$a]][$recentmoves[$b]][$move]/3+1;
  }
 }
}

@bestmove = (0,0,0,0,0);
for(0..4){
 $bestmove[$_] = $curpred[$_]/2+$curpred[$_-1]+$curpred[$_-2];
}

$max = 0;
for(0..4){
 if($bestmove[$_]>$max){
  $max = $bestmove[$_];
 }
}
@options=();
$offset=0;
if(($ohist[-1] - $phist[-1])%5 < 2 && ($ohist[-2] - $phist[-2])%5 < 2 && ($ohist[-3] - $phist[-3])%5 < 2){  #frequentist alert!
 $offset=int(rand(3));
}
for(0..4){
 if($bestmove[$_] == $max){
  push(@options,$num2text[($_+$offset)%5]);
 }
}
$outputb = $options[int(rand(~~@options))];

print "$outputb";

Saya sudah menjalankan program ini seperti ini:

perl BayesianBot.plx

5

DynamicBot

Bot dinamis hampir selalu berubah. Itu benar-benar benci terulang

import sys, random
choices = ['L','V','S','P','R'] * 20
if len(sys.argv) > 1:
    my_history = sys.argv[1]
    [choices.remove(my_history[-1]) for i in range(15)]
print(choices[random.randrange(len(choices))])

Bahasa: Python 3.4.1

Perintah: python dynamicbot.py <history>atau python3 dynamicbot.py <history>tergantung pada sistem Anda


Ya, pikirkan tentang itu.
seequ

5

SmartBot - Java

Entri pertama saya untuk apa pun di situs ini!

Meskipun bukan nama yang sangat kreatif ...

SmartBot menemukan urutan gerakan di mana lawan dan / atau gerakan itu sendiri mirip dengan gerakan yang terakhir dibuat dan rencana yang sesuai.

name = SmartBot

Saya pikir untuk menjalankannya, koreksi saya jika saya salah.

java -jar SmartBot.jar

import java.util.ArrayList;
public class SmartBot {
    public static void main(String[] args) {
        if(args.length ==0){
            System.out.print("L");
            return;
        }
        if(args[0].length()<3){
            String[] randLetter = new String[]{"R","P","S","L","V"};
            System.out.print(randLetter[(int) Math.floor(Math.random()*5)]);
            return;
        }
        String myHistory = args[0];
        String otherHistory = args[1];

        double rScore,pScore,sScore,lScore,vScore;//score - highest = highest probability of next opponent move
        rScore = pScore = sScore = lScore = vScore = 0;
        lScore = .001;
        ArrayList<ArrayList<Integer>> moveHits = new ArrayList<ArrayList<Integer>>();
        for(int g = 0;g<2;g++){
            for(int i=1;i<(myHistory.length() / 2) + 1;i++){
                if(g==0){
                    moveHits.add(findAll(myHistory.substring(myHistory.length() - i),myHistory));
                }
                else{
                    moveHits.add(findAll(otherHistory.substring(otherHistory.length() - i),otherHistory));
                }
            }
            for(int i = 0; i < moveHits.size();i++){
                int matchingMoves = i+1;
                ArrayList<Integer> moveIndexes = moveHits.get(i);
                for(Integer index:moveIndexes){
                    if(index+matchingMoves +1<= otherHistory.length()){
                        char nextMove = otherHistory.charAt(index + matchingMoves-1);
                        if(nextMove=='R'){rScore = rScore + matchingMoves;}
                        if(nextMove=='P'){pScore = pScore + matchingMoves;}
                        if(nextMove=='S'){sScore = sScore + matchingMoves;}
                        if(nextMove=='L'){lScore = lScore + matchingMoves;}
                        if(nextMove=='V'){vScore = vScore + matchingMoves;}
                    }
                }
            }
        }
        if(rScore >= pScore && rScore >= sScore && rScore >= lScore && rScore >= vScore){
            System.out.print("V");
            return;
        }
        if(pScore >= rScore && pScore >= sScore && pScore >= lScore && pScore >= vScore){
            System.out.print("L");
            return;
        }
        if(sScore >= pScore && sScore >= rScore && sScore >= lScore && sScore >= vScore){
            System.out.print("R");
            return;
        }
        if(vScore >= pScore && vScore >= sScore && vScore >= lScore && vScore >= rScore){
            System.out.print("L");
            return;
        }
        if(lScore >= pScore && lScore >= sScore && lScore >= rScore && lScore >= vScore){
            System.out.print("S");
        }
        return;
    }
    public static ArrayList<Integer> findAll(String substring,String realString){
        ArrayList<Integer> ocurrences = new ArrayList<Integer>();
        Integer index = realString.indexOf(substring);
        if(index==-1){return ocurrences;}
        ocurrences.add(index+1);
        while(index!=-1){
            index = realString.indexOf(substring,index + 1);
            if(index!=-1){
                ocurrences.add(index+1);
            }
        }
        return ocurrences;
    }
}

Ini memberikan skor untuk setiap kemungkinan langkah selanjutnya dengan berapa kali pola yang sama terjadi.

Itu sedikit lebih menyukai kadal.


Saya percaya itu adalah bagaimana Anda menjalankannya jika Anda toples dulu. Jika Anda hanya mengompilasinya terlebih dahulu, maka itu java ABotharus bekerja (ingat untuk memberi nama file yang sama dengan kelas publik)
Justin

Terima kasih! Sebagai seorang programmer yang relatif baru, saya tidak mengetahui hal ini.
Stretch Maniac

5

SpockOrRock - PHP

SpockOrRock

Ketika dimainkan di dunia nyata, kebanyakan orang secara naluriah memilih gunting. Bot ini memilih Spock atau Rock untuk mengalahkan pemain rata-rata. Ini tidak terganggu dengan putaran sebelumnya.

jalankan bersama php spockorrock.php

<?php

//Pick either Spock or Rock
if (rand(0,1) == 0)     echo("R\n");
else                    echo("V\n");


?>

4

SlowLizard, Ruby

Setelah memulai dengan Lizard, ia selalu memilih gerakan acak yang mengalahkan gerakan lawan sebelumnya.

responses = {
  'R' => ['P', 'V'],
  'P' => ['S', 'L'],
  'S' => ['R', 'V'],
  'L' => ['S', 'R'],
  'V' => ['P', 'L']
}

if ARGV.length == 0
  puts 'L'
else
  puts responses[ARGV[1][-1]].sample
end

Jalankan seperti

ruby slowlizard.rb

4

LexicographicBot

Bot ini suka memesan surat-suratnya, jadi dia akan memilih respons yang 1 lebih tinggi dari yang diberikan lawannya di babak sebelumnya - kecuali jika lawan memilih Vulcan, maka dia akan secara acak memilih respons.

import sys
import random

choices = ["L", "P", "R", "S", "V"]

total = len(sys.argv)
if total==1:
    print("L")
    sys.exit()

opponent = sys.argv[2]
opponent_last = opponent[-1]

if opponent_last == choices[-1]:
    print(random.choice(choices))
else:
    next = choices.index(opponent_last)+1
    print(choices[next])

Ini mengharapkan lawan untuk dibagikan kedua:

                           me
                            v
python LexicographicBot.py SR RV
                              ^
                            opponent

@ MartinBüttner: Perintah ditambahkan! Saya sudah cukup sibuk di tempat kerja mencoba untuk menerbitkan sesuatu, karenanya menghilang.
Kyle Kanos

istirahat pada jalankan pertama tanpa args. Traceback (panggilan terakhir terakhir): File "LexicographicBot \ LexicographicBot.py", baris 10, di <module> lawan = sys.argv [2] IndexError: daftar indeks di luar jangkauan
Eoin Campbell

@EoinCampbell: Saya lupa klausa keluar saat pertama kali dijalankan, sudah ditambahkan & seharusnya berfungsi dengan baik sekarang.
Kyle Kanos

4

Werevulcan - Ruby

Jalankan sebagai ruby werevulcan.rb

@rules = {

  'L' => %w[V P],
  'P' => %w[V R],
  'R' => %w[L S],
  'S' => %w[P L],
  'V' => %w[R S]
}

@moves = @rules.keys

def defeats?(move1, move2)
  @rules[move1].include?(move2)
end

def score(move1, move2)
  if move1 == move2
    0
  elsif defeats?(move1, move2)
    1
  else
    -1
  end
end

def move
  player, opponent = ARGV

  # For the first 30 rounds, pick a random move that isn't Spock
  if player.to_s.size < 30
    %w[L P R S].sample
  elsif opponent.chars.to_a.uniq.size < 5
    exploit(opponent)
  else
    # Pick a random move that's biased toward Spock and against lizards
    %w[L P P R R S S V V V].sample
  end

end

def exploit(opponent)
  @moves.shuffle.max_by{ |m| opponent.chars.map{|o| score(m,o) }.reduce(:+) }
end

puts move

Para vulcan terlihat normal pada siang hari, tetapi ketika bulan naik, telinganya tumbuh runcing, dan gerakannya tumbuh lebih logis.


4

Analogizer - Ruby

Jalankan dengan ruby analogizer.rb. Saya telah membuat perbaikan logika ke kode, tetapi tidak tahu mengapa ada kesalahan dengan ini.

@rules = {

  'L' => %w[V P],
  'P' => %w[V R],
  'R' => %w[L S],
  'S' => %w[P L],
  'V' => %w[R S]
}

@moves = @rules.keys

def defeats?(move1, move2)
  @rules[move1].include?(move2)
end

def score(move1, move2)
  if move1 == move2
    0
  elsif defeats?(move1, move2)
    1
  else
    -1
  end
end

def move
  player, opponent = ARGV

  case player.to_s.size
  # Throw six lizards in the beginning to confuse opponent
  when 0..5
    'L'
  when 6
    'V'
  when 7
    'S'
  when 8
    'P'
  when 9
    'R'
  else
    analyze_history(player.chars.to_a, opponent.chars.to_a)
  end

end

def analyze_history(player, opponent)
  my_last_move = player.last
  predicted_moves = Hash.new {0}
  opponent_reactions = player.zip(opponent.drop(1))

  # Check whether opponent tended to make a move that would've beaten, lost, or tied my last move
  opponent_reactions.each do |my_move, reaction|
    score = score(reaction, my_move)
    analogous_moves = @moves.select { |move| score == score(move, my_last_move) }
    analogous_moves.each { |move| predicted_moves[move] += 1 }
  end

  # Assume if an opponent has never made a certain move, it never will
  @moves.each { |m| predicted_moves[m] = 0 unless opponent.include?(m) }

  # Pick the move with the best score against opponent's possible moves, weighted by their likelihood, picking randomly for ties
  @moves.shuffle.max_by{ |m| predicted_moves.map { |predicted, freq| score(m, predicted) * freq }.reduce(0,:+) }

end

puts move

Anggap bot lawan selalu bereaksi terhadap gerakan saya sebelumnya, dan entah memilih sesuatu yang akan mengalahkannya, sesuatu yang akan kalah darinya, atau gerakan yang sama, mungkin dari serangkaian gerakan yang mungkin terbatas. Itu kemudian mengambil langkah terbaik mengingat asumsi itu.

Kecuali bahwa sepuluh langkah pertama adalah hardcode: pertama saya berpura-pura saya hanya tahu kadal, maka saya menganggap lawan saya selalu melempar sesuatu untuk mengalahkan hal terakhir yang saya lemparkan sampai saya memiliki cukup data untuk analisis yang tepat.


4

Java - SelfLoathingBot

BotName: SelfLoathingBot
Compile: Save as 'SelfLoathingBot.java'; compile.
Run:     java SelfLoathingBot [me] [them]

Bot dimulai secara acak, kemudian ~ 33% untuk menjadi acak, atau ~ 33% untuk memainkan taktik kemenangan melawan salah satu dari bermain segera sebelumnya, dengan 50% pilihan taktik kemenangan.

import java.util.Random;

public class SelfLoathingBot {

    static final Random RANDOM = new Random();

    private static char randomPlay() {

        switch (RANDOM.nextInt(5)) {

            case 0 : return 'R';

            case 1 : return 'P';

            case 2 : return 'S';

            case 3 : return 'L';

            default : return 'V';
        }
    }

    private static char antiPlay(String priorPlayString) {

        char[] priorPlays = priorPlayString.toCharArray();

        int choice = RANDOM.nextInt(2);

        switch (priorPlays[priorPlays.length - 1]) {

            case 'R' : return choice == 0 ? 'P' : 'V'; 

            case 'P' : return choice == 0 ? 'S' : 'L';

            case 'S' : return choice == 0 ? 'V' : 'R';

            case 'L' : return choice == 0 ? 'R' : 'S';

            default : return choice == 0 ? 'L' : 'P'; // V        
        }
    }

    public static void main(String[] args) {

        int choice = args.length == 0 ? 0 : RANDOM.nextInt(3);

        char play;

        switch (choice) {

            case 1 :

                // 33.3% chance Play myself
                play = antiPlay(args[0]);
                break;

            case 2 :

                // 33.3% chance Play opponent just in case opponent is screwy like that
                play = antiPlay(args[1]);
                break;

            default :

                // 33.3% chance 100% Random
                play = randomPlay();
        }

        System.out.print(play);
        return;
    }
}

4

Analis

Analis menganalisis beberapa hal dan melakukan beberapa hal untuk mencoba mengalahkan Anda.

kompilasi dengan javac Analyst.javadan jalankan sebagaijava Analyst

import java.util.Random;

public class Analyst{
    public static void main(String[] args){
        char action = 'S';

        try{
            char[] enemyMoves = null, myMoves = null;

            //first move is random
            if(args.length == 0){
                System.out.print(randomMove());
                System.exit(0);
            //moves 2-3 will beat their last move
            }else if(args[0].length() < 8){
                System.out.print(counterFor(args[1].charAt(args[1].length()-1)));
                System.exit(0);
            //following moves will execute some analyzation stuff
            }else{
                //get previous moves
                myMoves = args[0].toCharArray();
                enemyMoves = args[1].toCharArray();
            }

            //test if they're trying to beat our last move
            if(beats(enemyMoves[enemyMoves.length-1], myMoves[myMoves.length-2])){
                action = counterFor(counterFor(myMoves[myMoves.length-1]));
            }
            //test if they're copying our last move
            else if(enemyMoves[enemyMoves.length-1] == myMoves[myMoves.length-2]){
                action = counterFor(myMoves[myMoves.length-1]);
            }
            //else beat whatever they've done the most of
            else{
                action = counterFor(countMost(enemyMoves));
            }

            //if they've beaten us for the first 40 moves, do the opposite of what ive been doing
            if(theyreSmarter(myMoves, enemyMoves)){
                action = counterFor(action);
            }

        //if you break my program do something random
        }catch (Exception e){
            action = randomMove();
        }

        System.out.print(action);
    }

    private static char randomMove(){
        Random rand = new Random(System.currentTimeMillis());
        int randomMove = rand.nextInt(5);

        switch (randomMove){
            case 0: return 'R';
            case 1: return 'P';
            case 2: return 'S';
            case 3: return 'L';
            default: return 'V';
        }
    }

    private static char counterFor(char move){
        Random rand = new Random(System.currentTimeMillis());
        int moveSet = rand.nextInt(2);

        if(moveSet == 0){
            switch (move){
                case 'R': return 'P'; 
                case 'P': return 'S'; 
                case 'S': return 'R'; 
                case 'L': return 'R'; 
                default: return 'P';
            }
        }else{
            switch (move){
                case 'R': return 'V'; 
                case 'P': return 'L'; 
                case 'S': return 'V'; 
                case 'L': return 'S'; 
                default: return 'L';
            }
        }
    }

    private static boolean beats(char move1, char move2){
        if(move1 == 'R'){
            if((move2 == 'S') || (move2 == 'L')){
                return true;
            }else{
                return false;
            }
        }else if(move1 == 'P'){
            if((move2 == 'R') || (move2 == 'V')){
                return true;
            }else{
                return false;
            }
        }else if(move1 == 'S'){
            if((move2 == 'L') || (move2 == 'P')){
                return true;
            }else{
                return false;
            }
        }else if(move1 == 'L'){
            if((move2 == 'P') || (move2 == 'V')){
                return true;
            }else{
                return false;
            }
        }else{
            if((move2 == 'R') || (move2 == 'S')){
                return true;
            }else{
                return false;
            }
        }
    }

    private static char countMost(char[] moves){
        int[] enemyMoveList = {0,0,0,0,0};

        for(int i=0; i<moves.length; i++){
            if(moves[i] == 'R'){
                enemyMoveList[0]++;
            }else if(moves[i] == 'P'){
                enemyMoveList[1]++;
            }else if(moves[i] == 'S'){
                enemyMoveList[2]++;
            }else if(moves[i] == 'L'){
                enemyMoveList[3]++;
            }else if(moves[i] == 'V'){
                enemyMoveList[4]++;
            }
        }

        int max = 0, maxIndex = 0;
        for(int i=0; i<5; i++){
            if(enemyMoveList[i] > max){
                max = enemyMoveList[i];
                maxIndex = i;
            }
        }

        switch (maxIndex){
            case 0: return 'R';
            case 1: return 'P';
            case 2: return 'S';
            case 3: return 'L';
            default: return 'V';
        }
    }

    private static boolean theyreSmarter(char[] myMoves, char[] enemyMoves){
        int loseCounter = 0;

        if(enemyMoves.length >= 40){
            for(int i=0; i<40; i++){
                if(beats(enemyMoves[i],myMoves[i])){
                    loseCounter++;
                }
            }
        }else{
            return false;
        }

        if(loseCounter > 20){
            return true;
        }else{
            return false;
        }
    }
}

4

The Gambler - Python 2

import sys
import random

MODE = 1

moves = 'RSLPV'

def element_sums(a, b):
    return [a[i] + b[i] for i in xrange(len(a))]

def move_scores(p):
    def calc(to_beat):
        return ['LDW'.find('DLLWW'[moves.find(m)-moves.find(to_beat)]) for m in moves]

    return dict(zip(moves, element_sums(calc(p[0]), calc(p[1]))))

def move_chooser(my_history, opponent_history):
    predict = sorted(moves, key=opponent_history.count, reverse=MODE)[-2:]
    scores = move_scores(predict)
    return max(scores, key=lambda k:scores[k])

if __name__ == '__main__':
    if len(sys.argv) == 3:
        print move_chooser(*sys.argv[1:])
    elif len(sys.argv) == 1:
        print random.choice(moves)

Berlawanan dengan namanya, satu-satunya waktu keacakan digunakan dalam program ini adalah pada putaran pertama, ketika tidak ada informasi. Sebaliknya, itu dinamai untuk kesalahan penjudi, keyakinan bahwa jika kejadian acak lebih jarang terjadi di masa lalu, itu lebih mungkin terjadi di masa depan. Misalnya, jika Anda melempar koin yang adil sebanyak 20 kali, dan 15 yang pertama adalah kepala, kesalahan penjudi menyatakan bahwa peluang sisa flip menjadi ekor meningkat. Tentu saja, ini tidak benar; terlepas dari membalik sebelumnya, peluang koin yang adil untuk selalu muncul selalu 50%.

Program ini menganalisis sejarah lawan, menemukan 2 gerakan yang telah digunakan sejauh ini, dan mengasumsikan bahwa gerakan lawan kali ini akan menjadi salah satu dari keduanya. Menetapkan 2 untuk menang, 1 untuk imbang dan 0 sampai kalah, ia menemukan gerakan dengan skor maksimum terhadap dua gerakan yang diprediksi ini dan melemparkannya.

The Gambler's Brother - Python 2

import sys
import random

MODE = 0

moves = 'RSLPV'

def element_sums(a, b):
    return [a[i] + b[i] for i in xrange(len(a))]

def move_scores(p):
    def calc(to_beat):
        return ['LDW'.find('DLLWW'[moves.find(m)-moves.find(to_beat)]) for m in moves]

    return dict(zip(moves, element_sums(calc(p[0]), calc(p[1]))))

def move_chooser(my_history, opponent_history):
    predict = sorted(moves, key=opponent_history.count, reverse=MODE)[-2:]
    scores = move_scores(predict)
    return max(scores, key=lambda k:scores[k])

if __name__ == '__main__':
    if len(sys.argv) == 3:
        print move_chooser(*sys.argv[1:])
    elif len(sys.argv) == 1:
        print random.choice(moves)

Dengan mengganti MODE variabel ke 0, program ini akan beroperasi berdasarkan kekeliruan terkait, juga kadang-kadang disebut sebagai kekeliruan penjudi. Ini menyatakan bahwa jika peristiwa acak telah terjadi lebih sering di masa lalu, itu lebih mungkin terjadi di masa depan. Misalnya, jika Anda melempar koin 20 kali dan 15 yang pertama adalah kepala, fallacy ini menyatakan bahwa flip yang tersisa lebih cenderung menjadi kepala, karena saat ini ada goresan. Dalam mode 0, program ini beroperasi dengan cara yang sama, kecuali mengasumsikan bahwa lawan akan melempar salah satu dari dua gerakan yang dilemparnya paling sering sejauh ini.

Jadi ya, kedua program ini hanya terpisah satu karakter. :)


Pada kondisi apa TheGambler mengubah MODE?
Dr R Dizzle

@DrRDizzle Tidak, sepertinya ini adalah pengiriman dua bot dalam satu.
Paŭlo Ebermann

2
Apakah program ini tidak akan lebih efektif jika MODE beralih jika Anda kehilangan lebih dari beberapa kali berturut-turut?
Dr R Dizzle

4

Dienstag (Python 2)

Entri pertama saya, Pony, tampaknya cukup baik dengan semua tebakan keduanya (tebakan tripple, ...) dan meta reasoning. Tetapi apakah itu bahkan perlu?

Jadi, inilah Dienstag, teman kecil Pony, dengan hanya satu dari 55 strategi: Prediksikan langkah lawan berikutnya dan kalahkan.

Pada akhirnya Dienstag menang atau mengikat dengan setiap Bot di sepuluh teratas papan peringkat saat ini. Kecuali untuk Pony.

import sys
if len(sys.argv)<2 or len(sys.argv[1])<2: print 'L'; sys.exit()
hist = [map('RPSVL'.index, p) for p in zip(sys.argv[1], sys.argv[2])]
N = len(hist)
cand = range(N-1)
for l in xrange(1,N):
    cand = ([c for c in cand if c>=l and hist[c-l+1]==hist[-l]] or cand[-1:])
print 'RPSVL'[(hist[cand[-1]+1][1]+(1,3)[N%2==0])%5]

Jalankan sebagai:

python Dienstag.py

Saya akui bahwa kodenya agak dikaburkan. Jika ada yang mau tahu lebih banyak tentang itu, saya dapat menambahkan penjelasan.

Sunting: Berikut adalah contoh singkat langkah-langkah untuk menjelaskan gagasan:

  • Program mendapatkan sejarahnya sendiri dan gerakan lawan:

    sys.arg[1] = 'LLVLLVL', sys.arg[2] = 'RPSPSSP'

  • Sejarah digabungkan ke dalam daftar pasangan dan gerakan diterjemahkan ke angka (R = 0, ...):

    hist = [[4, 0], [4, 1], [3, 2], [4, 1], [4, 2], [3, 2], [4, 1]]

  • Jumlah putaran yang dimainkan sejauh ini ditentukan:

    N = 7

  • Ide dasarnya sekarang adalah mencari rantai tak terputus terpanjang dari gerakan terakhir dalam sejarah sebelumnya. Program ini melacak di mana rantai tersebut berakhir dalam daftar cand(untuk 'kandidat'). Pada awalnya, tanpa memeriksa, setiap posisi dalam sejarah kecuali yang terakhir dianggap:

    cand = [0, 1, 2, 3, 4, 5]

  • Sekarang panjang rantai yang mungkin bertambah langkah demi langkah. Untuk panjang rantai l = 1terlihat kejadian sebelumnya dari pasangan langkah terakhir [4, 1]. Ini dapat ditemukan di posisi riwayat 1dan 3. Hanya ini yang disimpan dalam canddaftar:

    cand = [1, 3]

  • Selanjutnya, untuk l = 2itu periksa kandidat mana yang mungkin didahului oleh pasangan langkah kedua hingga terakhir [3, 2]. Ini hanya berlaku untuk posisi 3:

    cand = [3]

  • Sebab l = 3dan banyak lagi tidak ada rantai sebelumnya yang panjangnya dan candakan kosong. Dalam hal ini elemen terakhir canddisimpan:

    cand = [3]

  • Bot sekarang mengasumsikan bahwa sejarah akan berulang. Terakhir kali kain itu [3, 2], [4, 1]terjadi, itu diikuti oleh [4, 2]. Jadi, lawan bermain 2(gunting) yang bisa dikalahkan oleh (2+1)%5 = 3(Spock) atau (2+3)%5 = 0(batu). Bot menjawab, dengan alternatif pertama atau kedua tergantung pada apakah Naneh atau bahkan hanya untuk memperkenalkan beberapa variasi.

  • Di sini langkah 3dipilih yang kemudian diterjemahkan kembali:

    print 'V'

Catatan: Dienstag memiliki kompleksitas waktu O ( N 2 ) untuk mengembalikan langkah berikutnya setelah putaran N. Pony memiliki kompleksitas waktu O ( N 3 ). Jadi dalam aspek ini mereka mungkin jauh lebih buruk daripada kebanyakan entri lainnya.


silakan lakukan. ini adalah pengalaman belajar yang luar biasa bagi saya. Saya biasanya tinggal di tanah C # / Java sehingga semua lua, ruby, python, haskell madness sangat menarik bagi saya.
Eoin Campbell

Saya juga tergoda untuk menambahkan contoh tambahan dari Pony ke dalam game. Ini akan seperti harus bertarung dengan dirimu sendiri di level 3 hingga terakhir level Combat Mortal ;-)
Eoin Campbell

@EoinCampbell :-) Setidaknya pertandingan langsung Pony vs. Pony akan menjadi hasil imbang yang sempurna. Tidak ada unsur keacakan di kedua bot saya.
Emil

3

Bash Rocks

Apakah cygwin terlalu banyak bertanya sebagai runtime?

bashrocks.sh:

#!/bin/bash
HAND=(R P S L V)
RAND=`od -A n -t d -N 1 /dev/urandom | xargs`
echo ${HAND[ $RAND  % 5 ]}

dan jalankan seperti ini:

sh bashrocks.sh

5
Setelah membaca judulnya, saya sedikit kecewa bahwa Anda tidak melakukan apa-apa selain itu R. ;)
Martin Ender

@ mccannf. mengalami beberapa masalah dengan yang ini ... Saya telah menginstal cygwin dan memodifikasi skrip Anda dengan jalur yang sepenuhnya memenuhi syarat untuk C: \ Cygwin \ bin untuk od.exe, xargs.exe & echo.exe. masih mendapatkan kesalahan berikut. C: / Cygwin / bin / xargs: echo: Tidak ada file atau direktori seperti itu% 5 ") kesalahan sintaks: operan diharapkan (token errornya adalah"
Eoin Campbell

@EoinCampbell - saat Anda membuat file di windows, dapatkah Anda menjalankannya dos2unixdi cygwin sebelum menjalankannya?
mccannf

Tentu. Saya akan mencobanya.
Eoin Campbell

Saya pikir masalahnya mungkin dengan pernyataan / dev / urandom
Eoin Campbell

3

Algoritma

Algoritma demi memiliki satu.

Karena selalu terasa lebih aman melakukan sesuatu, semakin rumit semakin baik.

Belum melakukan beberapa Matematika serius, jadi algoritma ini mungkin tidak efektif.

import random, sys

if __name__ == '__main__':

    # Graph in adjacency matrix here
    graph = {"S":"PL", "P":"VR", "R":"LS", "L":"VP", "V":"SR"}
    try:
        myHistory = sys.argv[1]
        opHistory = sys.argv[2]
        choices = ""

        # Insert some graph stuff here. Newer versions may include advanced Math.
        for v in graph:
            if opHistory[-1] == v:
                for u in graph:
                    if u in graph[v]:
                        choices += graph[u]

        print random.choice(choices + opHistory[-1])

    except:
        print random.choice("RPSLV")

Program Python 2: python algorithm.py


1
Ringkasan algoritme ini: lihat apa yang dimainkan lawan terakhir, dan kemudian mainkan secara acak salah satu dari dua gerakan yang akan kalah melawan gerakan terakhir lawan jika mereka memainkannya lagi. Jadi lebih baik melawan bot yang tidak memainkan gerakan yang sama dua kali berturut-turut.
Rory O'Kane

Ha ha. Saya tidak benar-benar tahu apakah saya memang berhasil seperti itu. Jika saya tidak salah, itu sebenarnya hanya cara berbelit-belit memilih secara acak salah satu dari 5 bergerak. ;)
Vectorized

3

FairBot, Ruby

Mari kita mulai dari yang sederhana.

puts ['R','P','S','L','V'].sample

Jalankan seperti

ruby fairbot.rb

kesalahan ketik kecil pada param 'V' terakhir. telah memperbaikinya di sisi saya jika Anda ingin memperbarui untuk kelengkapan
Eoin Campbell

@EoinCampbell terima kasih, sudah diperbaiki!
Martin Ender

1
Yang menarik adalah bahwa ini memiliki peluang yang sama persis untuk menang melawan SEMUA strategi.
Cruncher

3

ViolentBot

Bot ini memilih opsi paling kejam berdasarkan lawan pilihan sebelumnya:

import sys

choice_dict = {"L" : "S", "P" : "S", "R" : "V", "S" : "V", "V" : "L"}

total = len(sys.argv)
if total==1:
    print("L")
    sys.exit()

opponent = sys.argv[2]
opponent_last = opponent[-1]

print(choice_dict[opponent_last])

Jalankan sebagai

python ViolentBot.py (me) (opp)

istirahat tanpa params. Traceback (panggilan terakhir terakhir): File "ViolentBot \ ViolentBot.py", baris 9, di <module> lawan = sys.argv [2] IndexError: daftar indeks di luar jangkauan
Eoin Campbell

istirahat dengan params. Traceback (panggilan terakhir terakhir): File "ViolentBot \ ViolentBot.py", baris 12, dalam cetakan <module> (choice_dict [lawan_last]) KeyError: 'S'
Eoin Campbell

@EoinCampbell: Saya telah menambahkan klausa keluar untuk menjalankan pertama, Anda harus dapat menjalankannya sekarang.
Kyle Kanos

3

Haskell - MonadBot

Saya tidak tahu apakah ghc dianggap "masuk akal", tetapi mari kita asumsikan saja. Strategi bot ini adalah untuk melawan gerakan lawannya yang paling populer.

Compile: ghc monadbot.hs
Run:     ./monadbot [Arg1] [Arg2]

Kode:

import System.Environment
import Data.List
import Data.Ord

main :: IO ()
main = do
  args <- getArgs
  let moves = if not (null args) then args !! 1 else ""
      fave = if not (null moves) then head $ maximumBy (comparing length) (group $ sort moves) else 'V'
  putChar $ case fave of 'R' -> 'P'
                         'P' -> 'S'
                         'S' -> 'R'
                         'L' -> 'R'
                         'V' -> 'P'
                         _   -> 'V'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.