Cuộc săn trứng Phục sinh trên đồi


17

Săn trứng Phục sinh

Bot tìm trứng trước khi thỏ tìm trứng. Bot hạnh phúc.

Tổng quat

Đây là một thử thách để tôn vinh lễ Phục sinh và truyền thống săn trứng Phục sinh!

Bot của bạn có tầm nhìn về hai không gian theo mọi hướng, bao gồm các đường chéo, tạo ra một hình vuông 5x5 xung quanh bạn mà bạn có thể nhìn thấy. Nó đang tìm trứng, và ai tìm được nhiều trứng nhất sẽ thắng!

Hội đồng quản trị

Bảng sẽ bao gồm os, đó là trứng Phục sinh, #s, là tường, *s, là những người chơi khác và s, là những khoảng trống.

  • Nó sẽ là một hình vuông với chiều dài cạnh (number of entries) * 3.
  • Nó sẽ được bao quanh bởi các bức tường.
  • Bên trong các bức tường sẽ là một loại gồm các bức tường thẳng, được đặt ngẫu nhiên #, sẽ có chiều dài ngẫu nhiên trong khoảng từ 2 đến 10. Sẽ có (number of entries) * 3họ.
  • Trứng sau đó sẽ được đặt ngẫu nhiên. Sẽ có (number of entries) * 4chúng và chúng sẽ chỉ được tạo trên các ô vuông ( ) trống .
  • Phải có ít nhất 7 nhiệm vụ để quy trình tạo bảng hoạt động đúng.

Dưới đây là một JSFiddle sẽ tạo ra một bảng ngẫu nhiên để bạn kiểm tra. Đây là một ví dụ, với (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#
#                   #
#####################

Sau khi bảng được tạo, mỗi người chơi được đặt trên một hình vuông ngẫu nhiên (không gian trống).

Đầu vào

Bạn sẽ mất sáu dòng đầu vào. Năm dòng đầu tiên là tầm nhìn của bạn (không gian ngoài giới hạn của bảng sẽ được đại diện Xvà không gian giữa sẽ luôn là *bạn) và dòng thứ sáu sẽ trống (lúc đầu).

Đầu ra

Bạn sẽ xuất ba dòng. Đầu tiên, hướng mà bạn muốn di chuyển đến:

1  2  3
8 YOU 4
7  6  5

(9 là một không-op nếu bạn không muốn di chuyển), thứ hai, một trong những Attack, Counter, hoặc Nothing (điều này sẽ được giải thích sâu sớm), và dòng thrid sẽ được bất kỳ chuỗi có độ dài lên đến 1024 Đây sẽ là bộ nhớ bot của bạn. Bạn có thể sử dụng nó cho bất cứ điều gì bạn muốn, hoặc bạn có thể để trống. Bộ nhớ này sau đó sẽ là dòng đầu vào thứ sáu cho chương trình của bạn trong lần chạy tiếp theo.

Tất cả các dòng đầu ra tiếp theo được bỏ qua và nếu chỉ có một dòng, dòng thứ hai được coi là trống.

Di chuyển

Quá trình sau đây được sử dụng để xác định nơi bạn di chuyển:

  • Nếu, khi bạn di chuyển, bạn kết thúc trong một khoảng trống ( ), trình phát của bạn được đặt vào khoảng trống đó.
  • Nếu bạn kết thúc trong một bức tường ( #), di chuyển của bạn bị bỏ qua và bạn mất lượt của mình.
  • Nếu bạn kết thúc trong một quả trứng ( o) hoặc trên một người chơi ( *), thông tin này sẽ được lưu trữ và sẽ được sử dụng sau khi mọi người đã di chuyển.

Sau khi mọi người đã di chuyển, sự mơ hồ được giải quyết.

Nếu có hai người chơi đã hạ cánh trên cùng một không gian, một cuộc chiến sẽ xảy ra! Đây là nơi A/ C/ Nđến để chơi. Attack nhịp đập nhẹ Nnhàng (tấn công bình thường), Nnhịp đập nhẹ Cnhàng (bạn không thể chống lại điều gì) và Ccuộc chạm trán nhịp đập Attack (phản công). Người chơi chiến thắng trong cuộc chiến này sẽ ở lại quảng trường của họ và người chơi thua sẽ quay lại quảng trường ban đầu mà họ bắt đầu. Trong trường hợp hòa, cả hai người chơi quay trở lại nơi họ đang ở.

Nếu một người chơi bị mất hoặc bị trói trở lại nơi họ đang ở và có một người chơi khác ở đó, không có chiến đấu và người chơi khác cũng sẽ trở lại không gian ban đầu của nó. Nếu này không gian có người chơi khác, người chơi quay ngược lại, và điều này tiếp tục cho đến khi tất cả người chơi trong không gian khác nhau.

Nếu có ba hoặc nhiều người chơi trên một không gian, tất cả họ sẽ quay trở lại vị trí ban đầu của họ.

Nếu bất kỳ người chơi nào vẫn đứng trên một quả trứng ...

  • Nếu người chơi chọn A, quả trứng sẽ bị phá hủy.
  • Nếu người chơi chọn C, không có gì xảy ra và người chơi trở lại không gian ban đầu.
  • Nếu người chơi chọn N, người chơi nhặt trứng! Điểm của người chơi được tăng lên một và trứng được loại bỏ.

Ngôn ngữ

Bạn có thể sử dụng bất kỳ ngôn ngữ nào có sẵn miễn phí trên Windows, OSX và Linux, để đảm bảo sự công bằng giữa mỗi thí sinh. Nếu mã không thể tự do chạy được nhưng có thể được biên dịch hoặc đóng gói thành định dạng, vui lòng bao gồm định dạng này trong câu trả lời của bạn. Lý tưởng nhất, nếu bạn có thể biên dịch mã của mình thành một ngôn ngữ phổ biến hơn (ví dụ CoffeeScript -> JavaScript), vui lòng làm như vậy.

Chấm điểm

Điểm của bạn sẽ là số trứng trung bình bạn thu thập được sau mười lần chạy. Một cuộc chạy kết thúc khi tất cả trứng được thu thập hoặc khi (number of entries * 25)lượt đã qua. Tôi sẽ tự đảm bảo rằng có thể tiếp cận tất cả trứng cho mỗi bản đồ (bằng cách liên tục tạo bản đồ cho đến khi tất cả trứng có thể tiếp cận được).

Bảng điểm

Một bảng điểm sẽ được thêm vào khi tất cả các điều kiện sau được đáp ứng:

  • Ít nhất bảy mục hợp lệ có điểm số dương hoặc bằng 0 (không được đánh giá thấp) đã được gửi
  • Ít nhất 48 giờ đã trôi qua kể từ khi tạo ra thử thách này (UTC 14:23)

Các quy tắc sẽ không thay đổi trong giai đoạn trước cuộc thi này, ngoại trừ để thêm làm rõ trong đó quy tắc không rõ ràng. Sau khi bảng điểm được đưa lên, chương trình kiểm tra cũng sẽ được đăng ở đây để bạn có thể kiểm tra các mục của mình. Mã thử nghiệm cho việc này vẫn đang được tiến hành, nhưng nó có thể chơi được và nó hoạt động. Đây là repo GitHub.


4
Chúng tôi có thể nhận được chương trình thử nghiệm trước khi 7 mục được đăng không? Tôi thích thử nghiệm trước khi đăng, ngay cả khi nó chống lại các bot thử nghiệm "ngu ngốc". Có vẻ như điều này mang lại một lợi thế đáng kể để không đăng cho đến khi một số người khác có.
Geobits

1
Về người chơi sẽ trở lại. Vì vậy, tôi có khả năng có thể không may mắn và giành chiến thắng trước một đối thủ nhưng anh ta lại lùi vào một người chơi khác và bắt đầu một dòng thác vòng quanh trang web của cuộc chiến của chúng tôi, sao cho người chơi bắt đầu ở đó cũng gửi lại cho tôi một bước? (nếu điều đó không rõ ràng, tôi sẽ đăng một ý chính github với một ví dụ)
Martin Ender

1
Một chương trình kiểm soát mẫu sẽ rất hữu ích ở đây.
starbeamrainbowlabs

3
Tôi thích ý tưởng về dòng bộ nhớ
Einacio

2
Ngoài ra, bạn có biết ý nghĩa của các quy tắc của bạn: nếu người chơi (A) chọn 9, anh ta không bao giờ có thể bị tấn công một cách có ý nghĩa. Nếu một người chơi khác (B) bước lên ô vuông của người chơi đó và thắng, A sẽ được chuyển về hình vuông ban đầu của nó (giống như vậy). Nhưng bây giờ có một cuộc đụng độ vì cả A và B đều ở đó, vì vậy B phải quay lại quảng trường của chính mình. Vì vậy, kết quả là độc lập với cuộc chiến thực tế, B luôn di chuyển trở lại hình vuông ban đầu và A luôn luôn đặt. Điều đó sẽ cho phép tôi viết cả hai có thể giúp trình khác bằng cách chặn đường dẫn cho những người khác.
Martin Ender

Câu trả lời:


3

Cart'o'Gophers

Đây là một đệ trình khác - và điều này thực sự có nghĩa là cạnh tranh. Một lần nữa, nó ở Ruby. Vì vậy, chạy nó với ruby cartogophers.rb. Việc này mất nhiều thời gian hơn dự kiến ​​...

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 này nhớ những gì nó đã thấy trước đó và cố gắng xây dựng một bản đồ lớn hơn ở mỗi lượt. Sau đó, nó sử dụng một tìm kiếm đầu tiên cho trứng gần nhất và đi theo hướng đó. Nếu không có quả trứng nào có thể chạm tới trên bản đồ hiện tại, bot sẽ hướng tới cạnh mở gần nhất của bản đồ (để mở rộng bản đồ nhanh chóng theo hướng nó vẫn có thể di chuyển).

Bot này chưa có khái niệm về các bot khác và cũng không có chiến lược chiến đấu. Vì tôi không tìm thấy một cách đáng tin cậy để xác định xem liệu bước đi của tôi có thành công hay không, điều này có thể gây ra một số vấn đề. Tôi chỉ đơn giản là luôn cho rằng việc di chuyển đã thành công - vì vậy nếu đó không phải là các bản vá mới sẽ được tải vào bản đồ ở những vị trí sai, điều này có thể hoặc không gây hại cho việc tìm đường.

Bot sử dụng bộ nhớ để lưu trữ bản đồ và vị trí mới của nó trên bản đồ (giả sử việc di chuyển sẽ thành công). Bản đồ được lưu trữ mà không ngắt dòng, được nén và mã hóa base64 (cùng với số lượng hàng của bản đồ, để có thể xác nhận lại các ngắt dòng). Quá trình nén này làm giảm kích thước xuống khoảng một phần ba bản đồ không nén, do đó, có độ bóng trên 1000 byte, tôi có thể lưu trữ bản đồ khoảng 3000 ô, tương đương với việc khám phá hoàn toàn bản đồ với 18 bot. Miễn là không có nơi nào có nhiều bài nộp, tôi không nghĩ mình có thể bị làm phiền để tìm ra cách khắc phục cho trường hợp đó.

Sau một vài thử nghiệm so với 5 dumbbotgiây và 1 naivebot(lần gửi khác của tôi), nó đã thực hiện rất tệ (như 1 hoặc 2 quả trứng) hoặc vượt trội so với các thử nghiệm khác với biên độ đáng kể (7 đến 9 quả trứng). Tôi có thể nghĩ về một chiến lược chiến đấu tốt hơn và làm thế nào tôi có thể xác định liệu tôi có thực sự di chuyển hay không. Cả hai có thể có thể cải thiện điểm số một chút.

Ồ và nếu bạn đang tự hỏi về tên của bot, bạn nên đọc The Order of The Stick ( bảng cuối cùng trong truyện tranh này ).

EDIT: Có một vài lỗi phát hiện các cạnh của bản đồ được phát hiện. Bây giờ tôi đã sửa chúng, bot này luôn đạt điểm khoảng 205 dumbbotgiây và 1 naivebot. Tốt hơn rồi đấy! Nếu bạn thêm $stderr.puts mapvào bot của tôi bây giờ, bạn thực sự có thể thấy cách anh ta khám phá bản đồ một cách có hệ thống và thu thập tất cả trứng trong thời gian đó. Tôi cũng đã quyết định chọn Athay vì Nbất cứ khi nào không bước lên một quả trứng, để giảm xác suất quay trở lại tế bào ban đầu của bot (phần nào làm hỏng bản đồ).

(Nó không hoạt động tốt trong 6 naivebotgiây, đặc biệt là vì rất có thể sẽ rơi vào tình trạng "bế tắc" với một bot khác khi cả hai liên tục muốn lấy một quả trứng và chọn N. Tôi cần nghĩ về điều đó ... )


3

Chú thỏ Java

Chú thỏ này chưa hoàn thành lớn lên (tôi vẫn có kế hoạch thay đổi), nhưng bây giờ nó là điểm khởi đầu. Anh ta tìm quả trứng gần nhất và đi về phía nó. Không có phát hiện tường hoặc phát hiện ngoài giới hạn (chưa). Anh ta sẽ đi nhặt quả trứng mà anh ta đáp xuống, nhưng nếu không, anh ta sẽ cố gắng đẩy anh ta ra xung quanh và tấn công bất cứ thứ gì khác. Nếu không có trứng gần đó, anh ta sẽ bắt đầu theo con thỏ gần nhất. Họ có thể biết một cái gì đó mà anh ta không. Nếu không, anh ta sẽ chỉ chọn một hướng ngẫu nhiên để đi bộ. Và anh ấy khá hay quên (không sử dụng biến bộ nhớ).

Kế hoạch di chuyển về phía trước:

  • Đưa ra quyết định dựa trên tường / ngoài giới hạn
  • Chọn đường dẫn có mục đích, thay vì ngẫu nhiên
  • Sử dụng bộ nhớ để xác định hướng tôi sẽ đi trước đó

Cập nhật 1 Chú thỏ của tôi sẽ theo dõi những chú thỏ khác nếu nó không nhìn thấy một quả trứng. Đồng thời tái cấu trúc mã "tìm trứng gần nhất" thành phương thức riêng của nó.

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];

    }

}

Tôi cũng đã học được rằng các enum Java có khá nhiều trên các lớp và tôi thích .NET enums tốt hơn rất nhiều.
Brian J

0

NaiveBot (trong Ruby)

Đây là một bot rất đơn giản để có được trứng lăn (chúng tôi muốn nhanh chóng đạt được 7 bài nộp đó, phải không?). Ruby của tôi không phải là rất thành ngữ nên mã này có thể khiến những người chơi ruby ​​thích hợp co rúm lại trong đau đớn. Đọc có nguy cơ của riêng bạn.

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}
"

Chạy với ruby naivebot.rb.

Tôi chỉ đơn giản là mã hóa một vài trường hợp, trong đó một quả trứng có thể nhìn thấy và không bị cản trở bởi một bức tường. Nó thậm chí không đi tìm quả trứng gần nhất, nhưng chọn động tác đầu tiên có ý nghĩa. Nếu không tìm thấy trứng như vậy, bot sẽ di chuyển ngẫu nhiên. Nó coi thường tất cả những người chơi khác và không bao giờ tấn công hoặc phản công.


0

WallFolower

(chơi chữ có chủ ý) trong 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)))

Di chuyển đến một quả trứng nếu có một quả trứng trong tầm nhìn, nhưng chỉ khi nó ở gần quả trứng đó hơn một con robot khác. Nếu có một sự ràng buộc trong khoảng cách, nó sẽ đi cho nó dù sao đi nữa. Mặt khác, tường LH có tuân theo (hiện không được triển khai tốt).

Vẫn cần làm việc trên tường, nhưng dù sao tôi cũng sẽ đăng bài này ở đây.


1
Khi tôi chạy bot của bạn với trình kiểm tra, tôi gặp lỗi này trong bảng điều khiển: pastebin.com/cT5xGdSW
starbeamrainbowlabs

Tương tự ở đây. Bạn có thể nhìn vào đó không? Tôi muốn thử nghiệm bot mới của tôi chống lại điều này.
Martin Ender

@ m.buettner Điều gì xảy ra nếu bạn đổi sys.exit(0)sang exit(0)? Ngoài ra, tôi cần phải làm việc này (ngay bây giờ, nó tự cho rằng nó là một ``), nhưng tôi không thực sự có thời gian. Khi tôi có thời gian, tôi sẽ đến và sửa nó.
Justin

Thật không may @Quincunx, điều đó đã không thay đổi bất cứ điều gì.
Martin Ender
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.