Perburuan Telur Paskah di Bukit

17

Perburuan Telur Paskah

Bot menemukan telur sebelum kelinci menemukan telur. Bot senang.

Gambaran

Ini adalah tantangan untuk menghormati Paskah dan tradisi berburu telur Paskah!

Bot Anda memiliki visi dua ruang di setiap arah, termasuk diagonal, menciptakan kotak 5x5 di sekitar Anda yang dapat Anda lihat. Ia mencari telur, dan siapa pun yang menemukan telur terbanyak akan menang!

Papan

Papan akan terdiri dari os, yang merupakan telur Paskah, #s, yang merupakan dinding, *s, yang merupakan pemain lain, dan s, yang merupakan ruang kosong.

  • Itu akan menjadi persegi dengan panjang tepi (number of entries) * 3.
  • Itu akan dikelilingi oleh dinding.
  • Di dalam dinding akan ada bermacam-macam dinding garis lurus yang ditempatkan secara acak #, yang akan memiliki panjang acak antara 2 dan 10 inklusif. Akan ada (number of entries) * 3dari mereka.
  • Telur-telur itu kemudian akan ditempatkan secara acak. Akan ada (number of entries) * 4dari mereka, dan mereka hanya akan dihasilkan pada kotak kosong ( ).
  • Harus ada setidaknya 7 entires agar proses pembuatan papan berfungsi dengan benar.

Berikut ini adalah JSFiddle yang akan menghasilkan papan acak untuk Anda uji. Ini sebuah contoh, dengan (number of entries) = 7:

#####################
#        o         ##
#    #    o        ##
#    #o    ######  ##
######     #       ##
## o #     #       ##
##  o#   #o#    o o##
##   #o  # # o  #   #
##   # o # #    #   #
##  ##   # #  o #   #
##  #    #  o   # # #
##  # o  #   ## # # #
##  #           # # #
# o #          ## # #
# o oo         ##o  #
#o  ####### oo ##   #
#        #      #   #
#   o o o#          #
#   o ####   o     o#
#                   #
#####################

Setelah papan dibuat, setiap pemain ditempatkan pada kotak acak (ruang kosong).

Memasukkan

Anda akan mengambil enam baris input. Lima baris pertama adalah bidang penglihatan Anda (ruang di luar batas papan akan diwakili oleh X, dan ruang tengah akan selalu *, Anda), dan baris keenam akan kosong (pada awalnya).

Keluaran

Anda akan menghasilkan tiga baris. Pertama, arah yang Anda inginkan:

1  2  3
8 YOU 4
7  6  5

(9 adalah no-op jika Anda tidak ingin pindah), kedua, salah satu taktik A, Counter, atau Nothing (ini akan dijelaskan secara mendalam segera), dan baris ketiga akan menjadi string dengan panjang hingga 1024 Ini akan menjadi memori bot Anda. Anda dapat menggunakannya untuk apa pun yang Anda inginkan, atau Anda dapat membiarkannya kosong. Memori ini kemudian akan menjadi baris input keenam untuk program Anda pada proses selanjutnya.

Semua jalur keluaran selanjutnya diabaikan, dan jika hanya ada satu jalur, yang kedua diasumsikan kosong.

Bergerak

Proses berikut digunakan untuk menentukan ke mana Anda pindah:

  • Jika, ketika Anda bergerak, Anda berakhir di ruang kosong ( ), pemain Anda ditempatkan di ruang itu.
  • Jika Anda berakhir di dinding ( #), gerakan Anda diabaikan dan Anda kehilangan giliran.
  • Jika Anda berakhir dengan telur ( o) atau pemain ( *), informasi ini disimpan dan akan digunakan setelah semua orang pindah.

Setelah semua orang pindah, ambiguitas teratasi.

Jika ada dua pemain yang mendarat di ruang yang sama, perkelahian terjadi! Di sinilah A/ C/ Nmasuk untuk bermain. Serangan Aketukan Nothing (serangan normal), Nothing ketukan Counter (Anda tidak dapat melawan apa-apa), dan Counter mengalahkan detak A(serangan balik). Pemain yang memenangkan pertarungan ini tetap berada di kotak mereka, dan pemain yang kalah akan kembali ke kotak awal yang mereka mulai. Jika terjadi seri, kedua pemain kembali ke posisi semula.

Jika pemain yang kalah atau terikat kembali ke tempat mereka berada dan ada pemain lain di sana, tidak ada pertarungan dan pemain lain juga akan kembali ke ruang asalnya. Jika ini ruang memiliki pemain lain, bahwa pemain kembali, dan ini terus sampai semua pemain berada dalam ruang yang berbeda.

Jika ada tiga atau lebih pemain dalam satu ruang, mereka semua kembali ke posisi semula.

Jika ada pemain yang masih berdiri di atas telur ...

  • Jika pemain memilih A, telur dihancurkan.
  • Jika pemain memilih C, tidak ada yang terjadi dan pemain kembali ke ruang aslinya.
  • Jika pemain memilih N, pemain mengambil telur! Skor pemain bertambah satu dan telur dikeluarkan.

Bahasa

Anda dapat menggunakan bahasa apa pun yang tersedia secara bebas di Windows, OSX, dan Linux, untuk memastikan keadilan di antara setiap kontestan. Jika kode ini tidak dapat dijalankan secara bebas tetapi dapat dikompilasi atau dikemas ke dalam format yang ada, harap sertakan juga format ini dalam jawaban Anda. Idealnya, jika Anda dapat mengkompilasi kode Anda ke bahasa yang lebih umum (mis. CoffeeScript -> JavaScript), silakan lakukan.

Mencetak gol

Skor Anda akan menjadi jumlah rata-rata telur yang Anda kumpulkan dari sepuluh run. Berlari berakhir ketika semua telur dikumpulkan atau ketika (number of entries * 25)belokan telah lewat. Saya akan secara manual memastikan bahwa mungkin untuk mencapai semua telur untuk setiap peta (dengan terus menghasilkan peta sampai semua telur dapat dijangkau).

Papan angka

Papan skor akan ditambahkan ketika semua kondisi berikut dipenuhi:

  • Setidaknya tujuh entri yang valid dengan skor positif atau nol (tidak diturunkan) telah dikirimkan
  • Setidaknya 48 jam telah berlalu sejak penciptaan tantangan ini (UTC 14:23)

Aturan tidak akan berubah selama periode pra-kontes ini, kecuali untuk menambahkan klarifikasi di mana aturan tidak jelas. Setelah papan skor dipasang, program pengujian juga akan diposting di sini sehingga Anda dapat menguji entri Anda. Kode pengujian untuk ini masih dalam proses, tetapi dapat dimainkan dan berfungsi. Ini repo GitHub.

Gagang pintu
sumber
4
Bisakah kita mendapatkan program pengujian sebelum 7 entri diposting? Saya suka menguji sebelum memposting, meskipun itu bertentangan dengan "test-bots" bodoh. Tampaknya ini memberikan keuntungan yang signifikan untuk tidak memposting sampai beberapa yang lain memilikinya.
Geobits
1
Mengenai pemain yang akan kembali. Jadi saya bisa berpotensi tidak beruntung dan menang melawan lawan tetapi dia melangkah kembali ke pemain lain dan memulai kaskade yang berputar kembali ke situs pertarungan kita, sehingga pemain yang mulai di sana mengirim saya mundur selangkah juga? (jika itu tidak jelas, saya akan memposting inti github dengan sebuah contoh)
Martin Ender
1
Program kontrol sampel akan sangat berguna di sini.
starbeamrainbowlabs
3
Saya suka ide jalur memori
Einacio
2
Juga apakah Anda menyadari implikasi peraturan Anda: jika seorang pemain (A) memilih 9, ia tidak akan pernah bisa diserang secara berarti. Jika pemain lain (B) melangkah ke kotak pemain itu dan menang, A akan dipindahkan kembali ke kotak aslinya (yang sama). Tapi sekarang ada bentrokan karena A dan B ada di sana, jadi B harus kembali ke alun-alun sendiri. Jadi hasilnya tidak tergantung pada pertarungan yang sebenarnya, B selalu bergerak kembali ke awal kuadrat dan A selalu bertahan. Itu akan memungkinkan saya untuk menulis keduanya yang dapat membantu pengiriman lain dengan memblokir jalan bagi orang lain.
Martin Ender

Jawaban:

3

Cart'o'Gophers

Ini adalah pengajuan lain - dan ini sebenarnya dimaksudkan untuk menjadi kompetitif. Sekali lagi, ada di Ruby. Jadi jalankan dengan ruby cartogophers.rb. Ini memakan waktu lebih lama dari yang diharapkan ...

require 'zlib'
require 'base64'

def encode map, coords
    zipped = Zlib::Deflate.deflate map.join
    encoded = Base64.encode64(zipped).gsub("\n",'')
    "#{coords[:x]}|#{coords[:y]}|#{map.length}|#{encoded}"
end

def decode memory
    memory =~ /^(\d+)[|](\d+)[|](\d+)[|](.*)$/
    coords = {x: $1.to_i, y: $2.to_i}
    n_rows = $3.to_i
    encoded = $4
    decoded = Base64.decode64 encoded
    unzipped = Zlib::Inflate.inflate decoded
    n_cols = unzipped.length / n_rows;
    return unzipped.scan(/.{#{n_cols}}/), coords
end

def update map, fov, coords
    if coords[:x] < 2
        map.map! { |row| '?' << row }
        coords[:x] += 1
    elsif coords[:x] >= map[0].length - 2
        map.map! { |row| row << '?' }
    end

    if coords[:y] < 2
        map.unshift '?' * map[0].length
        coords[:y] += 1
    elsif coords[:y] >= map.length - 2
        map.push '?' * map[0].length
    end

    fov.each_index do |i|
        map[coords[:y]-2+i][coords[:x]-2, 5] = fov[i]
    end

    return map, coords
end

def clean_up map
    map.each do |row|
        row.gsub!('*', ' ')
    end
end

DIRECTIONS = [
    [],
    [-1,-1],
    [ 0,-1],
    [ 1,-1],
    [ 1, 0],
    [ 1, 1],
    [ 0, 1],
    [-1, 1],
    [-1, 0],
    [ 0, 0]
]

def move_to dir, coords
    {
        x: coords[:x] + DIRECTIONS[dir][0],
        y: coords[:y] + DIRECTIONS[dir][1]
    }
end

def get map, coords
    if coords[:x] < 0 || coords[:x] >= map[0].length ||
       coords[:y] < 0 || coords[:y] >= map.length
        return '?'
    end
    map[coords[:y]][coords[:x]]
end

def set map, coords, value
    unless coords[:x] < 0 || coords[:x] >= map[0].length ||
       coords[:y] < 0 || coords[:y] >= map.length
        map[coords[:y]][coords[:x]] = value
    end
    map[coords[:y]][coords[:x]]
end

def scan_surroundings map, coords
    not_checked = [coords]
    checked = []
    cost = { coords => 0 }
    direction = { coords => 9 }
    edges = {}

    while not_checked.length > 0
        current = not_checked.pop

        checked.push current
        (-1..1).each do |i|
            (-1..1).each do |j|
                c = { x: current[:x]+i, y: current[:y]+j }
                unless not_checked.include?(c) || checked.include?(c)
                    if get(map, c) == '#'
                        checked.push c
                    elsif get(map, c) == '?'
                        checked.push c
                        edges[current] = { cost: cost[current], move: direction[current] }
                    else
                        not_checked.unshift c

                        cost[c] = cost[current] + 1
                        if direction[current] == 9 # assign initial direction
                            direction[c] = DIRECTIONS.find_index([i,j])
                        else
                            direction[c] = direction[current]
                        end

                        if get(map, c) == 'o'
                            return direction[c], if cost[c] == 1 then 'N' else 'A' end
                        end

                        edges[c] = { cost: cost[c], move: direction[c] } if c[:x] == 0 || c[:x] == map[0].length - 1 ||
                                                                            c[:y] == 0 || c[:y] == map.length - 1
                    end
                end
            end
        end
    end

    # If no egg has been found return the move to the closest edge
    nearest_edge = edges.keys.sort_by { |c| edges[c][:cost] }.first
    if edges.length > 0
        return edges[nearest_edge][:move], 'A'
    else
        # The entire map has been scanned and no more eggs are left.
        # Wait for the game to end.
        return 9, 'N'
    end
end

input = $<.read.split "\n"
fov = input[0..4]
memory = input[5]

if memory
    map, coords = decode memory
    map, coords = update(map, fov, coords)
else
    map = fov
    coords = {x: 2, y: 2}
end
clean_up map

move, attack = scan_surroundings(map, coords)

memory = encode map, move_to(move, coords)

puts "#{move}
#{attack}
#{memory}"

Bot ini mengingat apa yang dilihatnya sebelumnya dan mencoba membuat peta yang lebih besar di setiap belokan. Kemudian menggunakan pencarian luas pertama untuk telur terdekat dan kepala seperti itu. Jika tidak ada telur yang bisa dijangkau di peta saat ini, bot mengarah ke tepi terbuka terdekat dari peta (sehingga untuk memperluas peta dengan cepat ke arah itu masih bisa bergerak).

Bot ini belum memiliki konsep bot lain dan juga tidak memiliki strategi bertarung. Karena saya belum menemukan cara yang dapat diandalkan untuk menentukan apakah langkah saya berhasil, ini dapat menyebabkan beberapa masalah. Saya hanya selalu berasumsi bahwa langkah itu berhasil - jadi jika bukan tambalan baru akan dimuat ke peta di tempat yang salah, yang mungkin atau mungkin tidak berbahaya untuk merintis jalan.

Bot menggunakan memori untuk menyimpan peta dan posisi barunya di peta (dengan asumsi langkah akan berhasil). Peta disimpan tanpa jeda baris, zip dan base64 disandikan (bersama dengan jumlah baris peta, sehingga jeda baris dapat dimasukkan kembali). Kompresi ini membawa ukurannya menjadi sekitar sepertiga dari peta yang tidak terkompresi, sehingga memiliki keteduhan lebih dari 1000 byte, saya bisa menyimpan peta sekitar 3000 sel, yang kira-kira sama dengan menjelajahi sepenuhnya peta dengan 18 bot. Selama ada banyak pengajuan yang dekat, saya tidak berpikir saya bisa repot-repot mencari tahu untuk memperbaiki kasus itu.

Setelah beberapa tes berjalan terhadap 5 dumbbotdan 1 naivebot(pengajuan saya yang lain), itu dilakukan dengan sangat buruk (seperti 1 atau 2 telur) atau mengungguli yang lain dengan selisih yang cukup besar (7 hingga 9 telur). Saya mungkin berpikir tentang strategi pertempuran yang lebih baik dan bagaimana saya bisa menentukan apakah saya benar-benar bergerak atau tidak. Keduanya mungkin dapat sedikit meningkatkan skor.

Oh dan jika Anda bertanya-tanya tentang nama bot, Anda harus membaca The Order of The Stick ( panel terakhir pada komik ini ).

EDIT: Ada beberapa bug dengan mendeteksi tepi peta yang ditemukan. Sekarang saya sudah memperbaikinya bot ini selalu mendapat skor sekitar 205 dumbbots dan 1 naivebot. Itu lebih seperti itu! Jika Anda menambahkan $stderr.puts mapke bot saya sekarang, Anda benar-benar dapat melihat bagaimana dia secara sistematis membuka peta dan mengumpulkan semua telur untuk sementara waktu. Saya juga memutuskan untuk memilih Adaripada Nsetiap kali tidak melangkah ke telur, untuk mengurangi kemungkinan pindah kembali ke sel asli bot (yang sebagian mengacaukan peta).

(Ini tidak berkinerja baik melawan 6 naivebots, terutama karena sangat mungkin berakhir di "jalan buntu" dengan bot lain ketika mereka berdua berulang kali ingin mengambil telur dan memilih N. Saya perlu memikirkan itu ... )

Martin Ender
sumber
3

Kelinci Jawa

Kelinci ini belum selesai tumbuh (saya masih berencana untuk melakukan perubahan), tetapi ini adalah titik awal untuk saat ini. Dia mencari telur terdekat dan menuju ke sana. Belum ada deteksi dinding atau deteksi di luar batas. Dia akan pergi untuk mengambil telur yang dia tuju, tetapi jika tidak dia akan mencoba mendorongnya dan menyerang yang lain. Jika tidak ada telur di dekatnya, ia akan mulai mengikuti kelinci terdekat. Mereka mungkin tahu sesuatu yang tidak dia ketahui. Kalau tidak, dia hanya akan memilih arah acak untuk berjalan. Dan dia cukup pelupa (tidak menggunakan variabel memori).

Paket bergerak maju:

  • Buat keputusan berdasarkan pada tembok / di luar batas
  • Pilih jalur dengan tujuan, bukan secara acak
  • Gunakan memori untuk menentukan arah yang saya tuju sebelumnya

Perbarui 1 Kelinci saya akan mengikuti kelinci lain jika dia tidak melihat telur. Juga refactored kode "cari telur terdekat" ke dalam metode itu sendiri.

import java.util.*;

public class EasterEggHunt {

    // board chars
    public static final char EGG = 'o';
    public static final char WALL = '#';
    public static final char BUNNY = '*';
    public static final char SPACE = ' ';
    public static final char OUT_OF_BOUNDS = 'X';

    // player moves
    public static final char ATTACK = 'A';
    public static final char COUNTER = 'C';
    public static final char NOTHING = 'N';

    // directions
    public static final int UPPER_LEFT = 1;
    public static final int UP = 2;
    public static final int UPPER_RIGHT = 3;
    public static final int RIGHT = 4;
    public static final int LOWER_RIGHT = 5;
    public static final int DOWN = 6;
    public static final int LOWER_LEFT = 7;
    public static final int LEFT = 8;
    public static final int STAY = 9;


    // the size of the immediate area
    // (I'll be at the center)
    public static final int VISION_RANGE = 5;

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        char[][] immediateArea = new char[VISION_RANGE][VISION_RANGE];

        for (int i = 0; i < VISION_RANGE; ++i) {
            String line = input.nextLine();
            for (int j = 0; j < VISION_RANGE; ++j) {
                immediateArea[i][j] = line.charAt(j);
            }
        }

        String memory = input.nextLine();

        int moveDirection = decideMoveDirection(immediateArea, memory);
        System.out.println(moveDirection);

        char action = decideAction(immediateArea, memory, moveDirection);
        System.out.println(action);

        // change the memory?
        System.out.println(memory);

    }

    private static int decideMoveDirection(char[][] immediateArea, String memory) {

        // if there's a nearby egg, go towards it
        int direction = nearestBoardObject(immediateArea, EGG);

        // if we didn't find an egg, look for a bunny
        // (maybe he knows where to find eggs)
        if (direction == STAY)
            direction = nearestBoardObject(immediateArea, BUNNY);

        // otherwise, pick a random direction and go
        // we want to also have the chance to stop and catch our breath
        if (direction == STAY)
            direction = new Random().nextInt(STAY + 1);

        return direction;
    }

    private static int nearestBoardObject(char[][] immediateArea, char boardObject) {

        // start at the center and go outward (pick a closer target over a farther one)
        int spacesAway = 1;
        int meX = immediateArea.length / 2;
        int meY = immediateArea[meX].length / 2;

        while (spacesAway <= immediateArea.length / 2) {

            // I like to look right, and go clockwise
            if (immediateArea[meX][meY + spacesAway] == boardObject)
                return RIGHT;
            if (immediateArea[meX + spacesAway][meY + spacesAway] == boardObject)
                return LOWER_RIGHT;
            if (immediateArea[meX + spacesAway][meY] == boardObject)
                return DOWN;
            if (immediateArea[meX + spacesAway][meY - spacesAway] == boardObject)
                return LOWER_LEFT;
            if (immediateArea[meX][meY - spacesAway] == boardObject)
                return LEFT;
            if (immediateArea[meX - spacesAway][meY - spacesAway] == boardObject)
                return UPPER_LEFT;
            if (immediateArea[meX - spacesAway][meY] == boardObject)
                return UP;
            if (immediateArea[meX - spacesAway][meY + spacesAway] == boardObject)
                return UPPER_RIGHT;

            ++spacesAway;
        }

        // if the target object isn't in the immediate area, stay put
        return STAY;

    }

    private static char decideAction(char[][] immediateArea, String memory, int moveDirection) {

        char destinationObject = getDestinationObject(immediateArea, moveDirection);

        switch (destinationObject) {

            case EGG:
                // don't break the egg
                return NOTHING;
            default:
                // get really aggressive on everything else
                // other players, walls, doesn't matter
                return ATTACK;

        }

    }

    private static char getDestinationObject(char[][] immediateArea, int moveDirection) {

        // start at my spot (middle of the board) and figure out which direction I'm going
        int targetX = immediateArea.length / 2;
        int targetY = immediateArea[targetX].length / 2;

        switch (moveDirection) {

            case RIGHT:
                ++targetY;
                break;
            case LOWER_RIGHT:
                ++targetX;
                ++targetY;
                break;
            case DOWN:
                ++targetX;
                break;
            case LOWER_LEFT:
                ++targetX;
                --targetY;
                break;
            case LEFT:
                --targetY;
                break;
            case UPPER_LEFT:
                --targetX;
                --targetY;
                break;
            case UP:
                --targetX;
                break;
            case UPPER_RIGHT:
                --targetX;
                ++targetY;
                break;
            // otherwise we aren't moving

        }

        return immediateArea[targetX][targetY];

    }

}
Brian J
sumber
Saya juga belajar bahwa enum Java cukup penuh di kelas, dan saya suka. NET enum jauh lebih baik.
Brian J
0

NaiveBot (dalam Ruby)

Ini adalah bot yang sangat sederhana untuk mendapatkan telur bergulir (kami ingin menekan 7 kiriman cepat, kan?). Ruby saya tidak terlalu idiomatis sehingga kode ini bisa membuat rubyists merasa ngeri kesakitan. Baca dengan risiko Anda sendiri.

input = $<.read
$data = input.split("\n")

def is_egg x, y
    $data[y+2][x+2] == 'o'
end

def is_wall x, y
    $data[y+2][x+2] == '#'
end

def is_empty x, y
    $data[y+2][x+2] == ' '
end

def is_player x, y
    $data[y+2][x+2] == '*'
end

if (is_egg(-2,-2) || is_egg(-2,-1) || is_egg(-1,-2)) && !is_wall(-1,-1) || is_egg(-1,-1)
    dir = 1
elsif is_egg(0,-2) && !is_wall(0,-1) || is_egg(0,-1)
    dir = 2
elsif (is_egg(2,-2) || is_egg(2,-1) || is_egg(1,-2)) && !is_wall(1,-1) || is_egg(1,-1)
    dir = 3
elsif is_egg(2,0) && !is_wall(1,0) || is_egg(1,0)
    dir = 4
elsif (is_egg(2,2) || is_egg(2,1) || is_egg(1,2)) && !is_wall(1,1) || is_egg(1,1)
    dir = 5
elsif is_egg(0,2) && !is_wall(0,1) || is_egg(0,1)
    dir = 6
elsif (is_egg(-2,2) || is_egg(-2,1) || is_egg(-1,2)) && !is_wall(-1,1) || is_egg(-1,1)
    dir = 7
elsif is_egg(-2,0) && !is_wall(-1,0) || is_egg(-1,0)
    dir = 8
else
    dir = rand(8) + 1
end

attack = 'N'
puts "#{dir}
#{attack}
"

Jalankan dengan ruby naivebot.rb.

Saya hanya meng-hardcoding beberapa kasus, di mana telur terlihat dan tidak terhalang oleh dinding. Itu bahkan tidak berlaku untuk telur terdekat, tetapi mengambil langkah pertama yang masuk akal. Jika tidak ada telur seperti itu ditemukan, bot membuat gerakan acak. Itu mengabaikan semua pemain lain dan tidak pernah menyerang atau melawan.

Martin Ender
sumber
0

WallFolower

(permainan kata-kata yang disengaja) dalam Python 3 :

import sys
import random

#functions I will use
dist       = lambda p1,p2: max(abs(p2[1] - p1[1]), abs(p2[0] - p1[0]))
distTo     = lambda p    : dist((2,2), p)
cmp        = lambda x,y  : (x > y) - (x < y)
sgn        = lambda x    : (-1,0,1)[(x>0)+(x>=0)]
move       = lambda p    : (sgn(p[0] - 2), sgn(p[1] - 2))
unmove     = lambda p    : (p[0] * 2 + 2, p[1] * 2 + 2)
outputmove = lambda p    : (1,2,3,8,9,4,7,6,5)[(sgn(p[0] - 2) + 1) + 3*(sgn(p[1]-2) + 1)]
def noeggfinish(move):
    print(outputmove(unmove(move)))
    print('ACN'[random.randint(0, 2)])
    print("1"+move)
    sys.exit(0)

#beginning of main body
view    = [list(l) for l in map(input, ('',)*5)] #5 line input, all at once.
memory  = input() #currently used only as last direction moved in a tuple
eggs    = []
enemies = []
for y in range(5):
    for x in range(5):
        if   view[y][x] == 'o': eggs    += [(x,y)]
        elif view[y][x] == '*': enemies += [(x,y)]

eggs.sort(key = lambda p:distTo(p)) #sort by how close to me they are.

tiedeggs = []
end = 0
for egg in eggs[:]:
    if end:break
    for enemy in enemies:
        exec({
            -1: 'eggs.remove(egg)',
             0: 'tiedeggs += egg',
             1: 'end=1'
        }[cmp(dist(enemy, egg), distTo(egg))])
        if end:break
if eggs:
    print(outputmove(eggs[0]))
    print('N')              #no attack here
    print("0"+move(eggs[0]))
    sys.exit(0)
elif tiedeggs:
    print(outputmove(tiedeggs[0]))
    print('N')              #no attack here
    print("0"+move(tiedeggs[0]))
    sys.exit(0) 
#now there are no eggs worth going for
#do a LH wall follow

lastmove = eval(memory[1:]) #used to resolve ambiguity
if lastmove[0] and lastmove[1]:
    lastmove[random.randint(0,1)] = 0 #disregard diagonal moves
if eval(memory[0]):
    exec("check=view[%n][%n]"%{(0,-1):(0,0),(1,0):(4,0),(0,1):(4,4),(-1,0):(0,4)}[lastmove])
    if check == '#':
        noeggfinish(lastmove)
    else:pass
#currently unimplemented
#move randomly
noeggfinish(tuple([(x,y) for x in [-1,0,1] for y in [-1,0,1] if (x,y) != (0,0)))

Bergerak ke telur jika ada telur yang terlihat, tetapi hanya jika lebih dekat ke telur itu daripada robot lain. Jika ada ikatan di kejauhan, itu berlaku untuk itu. Jika tidak, apakah dinding LH mengikuti (saat ini tidak diimplementasikan dengan baik).

Masih perlu bekerja di dinding ikuti, tapi saya akan memposting ini di sini.

Justin
sumber
1
Ketika saya menjalankan bot Anda dengan tester.py, saya mendapatkan kesalahan ini di konsol: pastebin.com/cT5xGdSW
starbeamrainbowlabs
Sama disini. Bisakah Anda melihat itu? Saya ingin menguji bot baru saya terhadap ini.
Martin Ender
@ m.buettner Apa yang terjadi jika Anda mengubah sys.exit(0)ke exit(0)? Juga, saya perlu mengerjakan ini (sekarang, ini menganggap dirinya adalah ``), tapi saya tidak punya waktu. Ketika saya punya waktu, saya akan datang dan memperbaikinya.
Justin
@ Quincunx sayangnya, itu tidak mengubah apa pun.
Martin Ender