การล่าไข่อีสเตอร์บนเนินเขา


17

การล่าไข่อิสเตอร์

บอทหาไข่ก่อนที่กระต่ายจะเจอไข่ บอทมีความสุข

ภาพรวม

นี่เป็นความท้าทายที่สำหรับเทศกาลอีสเตอร์และประเพณีการล่าไข่อีสเตอร์!

บอทของคุณมีวิสัยทัศน์สองช่องว่างในทุกทิศทางรวมทั้งแนวทแยงมุมสร้างสี่เหลี่ยมขนาด 5x5 รอบ ๆ ตัวคุณที่คุณเห็น มันกำลังมองหาไข่และใครก็ตามที่พบว่าไข่ส่วนใหญ่ชนะ!

คณะกรรมการ

กระดานจะประกอบด้วยos ซึ่งคือไข่อีสเตอร์#s ซึ่งเป็นผนัง*s ซึ่งเป็นผู้เล่นคนอื่นและs ซึ่งเป็นพื้นที่ว่าง

  • (number of entries) * 3มันจะเป็นตารางที่มีความยาวขอบ
  • มันจะถูกล้อมรอบด้วยกำแพง
  • ด้านในของผนังจะมีการจัดวางแบบสุ่มผนังแนวตรงของ#ซึ่งจะมีความยาวแบบสุ่มระหว่าง 2 ถึง 10 จะมี(number of entries) * 3ของพวกเขา
  • ไข่จะถูกวางแบบสุ่ม จะมี(number of entries) * 4ของพวกเขาและพวกเขาจะถูกสร้างขึ้นในช่องว่าง ( )
  • ต้องมีอย่างน้อย 7 รายการสำหรับกระบวนการสร้างบอร์ดเพื่อให้ทำงานได้อย่างถูกต้อง

นี่คือ JSFiddle ที่จะสร้างบอร์ดแบบสุ่มให้คุณทดสอบด้วย นี่คือตัวอย่างด้วย(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#
#                   #
#####################

หลังจากสร้างบอร์ดแล้วผู้เล่นแต่ละคนจะถูกวางลงบนพื้นที่สุ่ม(พื้นที่ว่าง)

อินพุต

คุณจะต้องป้อนข้อมูลหกบรรทัด ห้าบรรทัดแรกคือฟิลด์การมองเห็นของคุณ (เว้นวรรคนอกกระดานจะถูกแทนด้วยXและคุณจะมีช่องว่างตรงกลาง*) และบรรทัดที่หกจะว่างเปล่า (ตอนแรก)

เอาท์พุต

คุณจะออกสามบรรทัด ก่อนอื่นทิศทางที่คุณต้องการย้าย:

1  2  3
8 YOU 4
7  6  5

(9 เป็นแบบไม่มี op ถ้าคุณไม่ต้องการย้าย) วินาทีหนึ่งในAttack, Counter หรือNothing (ซึ่งจะอธิบายในเชิงลึกในไม่ช้า) และบรรทัด thrid จะเป็นสตริงที่มีความยาวสูงสุด 1024 นี่จะเป็นความทรงจำของบอทของคุณ คุณสามารถใช้มันเพื่อสิ่งที่คุณต้องการหรือคุณอาจปล่อยให้มันว่างเปล่า หน่วยความจำนี้จะเป็นบรรทัดที่หกของอินพุตไปยังโปรแกรมของคุณในการรันครั้งถัดไป

บรรทัดเอาต์พุตเพิ่มเติมทั้งหมดจะถูกละเว้นและหากมีเพียงหนึ่งบรรทัดบรรทัดที่สองจะถือว่าว่างเปล่า

การย้าย

กระบวนการต่อไปนี้ใช้เพื่อกำหนดตำแหน่งที่คุณย้าย:

  • หากเมื่อคุณย้ายคุณจะสิ้นสุดในพื้นที่ว่างเปล่า ( ) เครื่องเล่นของคุณจะถูกวางลงในพื้นที่นั้น
  • หากคุณสิ้นสุดในกำแพง ( #) การเคลื่อนไหวของคุณจะถูกละเว้นและคุณสูญเสียตาคุณ
  • หากคุณลงเอยด้วยไข่ ( o) หรือเครื่องเล่น ( *) ข้อมูลนี้จะถูกเก็บไว้และจะถูกใช้หลังจากที่ทุกคนย้ายไปแล้ว

หลังจากที่ทุกคนเคลื่อนย้ายความคลุมเครือจะได้รับการแก้ไข

หากมีผู้เล่นสองคนที่ลงจอดในพื้นที่เดียวกันการต่อสู้จะเกิดขึ้น! นี่คือที่A/ C/ เข้าNมาเพื่อเล่น Attack beats Nothing (การโจมตีปกติ), Nothing beats Counter (คุณไม่สามารถโต้กลับได้) และCounter beats Attack (โต้กลับ) ผู้เล่นที่ชนะการต่อสู้ครั้งนี้จะอยู่ในจตุรัสของพวกเขาและผู้เล่นที่แพ้จะกลับไปที่จตุรัสเดิมที่พวกเขาเริ่ม ในกรณีที่เสมอกันผู้เล่นทั้งสองกลับไปที่เดิม

หากผู้เล่นที่สูญเสียหรือถูกผูกมัดกลับไปยังที่ที่พวกเขาอยู่และมีผู้เล่นอื่นอยู่ที่นั่นไม่มีการต่อสู้และผู้เล่นคนอื่นจะกลับไปสู่พื้นที่เดิม หากพื้นที่นี้มีผู้เล่นอื่นผู้เล่นรายนั้นจะกลับไปและจะดำเนินการต่อไปจนกว่าผู้เล่นทั้งหมดจะอยู่ในพื้นที่ที่แตกต่างกัน

หากมีผู้เล่นสามคนขึ้นไปในหนึ่งช่องว่างผู้เล่นทุกคนจะกลับสู่ตำแหน่งเดิม

หากผู้เล่นคนใดยังคงยืนอยู่บนไข่ ...

  • หากผู้เล่นเลือกAไข่จะถูกทำลาย
  • หากผู้เล่นเลือกจะCไม่มีอะไรเกิดขึ้นและผู้เล่นกลับไปยังพื้นที่ดั้งเดิม
  • หากผู้เล่นเลือกผู้เล่นจะNหยิบไข่ขึ้นมา! คะแนนของผู้เล่นจะเพิ่มขึ้นหนึ่งและไข่จะถูกลบออก

ภาษา

คุณสามารถใช้ภาษาใดก็ได้ที่มีให้ใช้งานได้ฟรีบน Windows, OSX และ Linux เพื่อรับรองความเป็นธรรมในการแข่งขันแต่ละครั้ง หากรหัสไม่สามารถรันได้อย่างอิสระ แต่สามารถรวบรวมหรือบรรจุเป็นรูปแบบที่เป็นได้โปรดรวมรูปแบบนี้ไว้ในคำตอบของคุณด้วย หากคุณสามารถรวบรวมรหัสของคุณเป็นภาษาที่ใช้กันทั่วไปมากขึ้น (เช่น CoffeeScript -> JavaScript) โปรดทำเช่นนั้น

เกณฑ์การให้คะแนน

คะแนนของคุณจะเป็นจำนวนไข่เฉลี่ยที่คุณได้รับจากการวิ่งสิบครั้ง การวิ่งสิ้นสุดลงเมื่อเก็บไข่ทั้งหมดหรือเมื่อ(number of entries * 25)ครบรอบแล้ว ฉันจะตรวจสอบด้วยตนเองว่าเป็นไปได้ที่จะเข้าถึงไข่ทั้งหมดสำหรับแต่ละแผนที่ (โดยการสร้างแผนที่อย่างต่อเนื่องจนกว่าไข่ทั้งหมดจะสามารถเข้าถึงได้)

ป้ายบอกคะแนน

กระดานคะแนนจะถูกเพิ่มเมื่อตรงตามเงื่อนไขต่อไปนี้ทั้งหมด:

  • มีการส่งรายการที่ถูกต้องอย่างน้อยเจ็ดรายการที่มีคะแนนเป็นบวกหรือเป็นศูนย์ (ไม่ใช่ downvote)
  • ผ่านไปอย่างน้อย 48 ชั่วโมงนับตั้งแต่การสร้างความท้าทายนี้ (UTC 14:23)

กฎจะไม่เปลี่ยนแปลงในช่วงระยะเวลาก่อนการแข่งขันยกเว้นเพื่อเพิ่มความกระจ่างในกรณีที่กฎไม่ชัดเจน เมื่อติดป้ายบอกคะแนนแล้วโปรแกรมทดสอบจะถูกโพสต์ที่นี่เพื่อให้คุณสามารถทดสอบรายการของคุณได้ รหัสการทดสอบสำหรับสิ่งนี้ยังคงอยู่ระหว่างดำเนินการ แต่สามารถเล่นได้และใช้งานได้ นี่คือ repo ของ GitHub


4
เราจะได้รับโปรแกรมทดสอบก่อนโพสต์ 7 รายการหรือไม่ ฉันชอบที่จะทดสอบก่อนโพสต์แม้ว่ามันจะต่อต้านบอททดสอบ "โง่" ดูเหมือนว่านี่จะเป็นข้อได้เปรียบที่สำคัญเมื่อไม่โพสต์จนกว่าคนอื่น ๆ จะมี
Geobits

1
เกี่ยวกับผู้เล่นจะกลับมา ดังนั้นฉันจึงอาจโชคไม่ดีและชนะกับคู่ต่อสู้ แต่เขาก้าวกลับเข้าสู่ผู้เล่นคนอื่นและเริ่มต้นการวนรอบที่ย้อนกลับไปยังเว็บไซต์ของการต่อสู้ของเรา (ถ้าที่ไม่ชัดเจนผมจะโพสต์กระทู้ GitHub กับตัวอย่าง)
มาร์ตินเอนเดอร์

1
โปรแกรมควบคุมตัวอย่างจะมีประโยชน์มากที่นี่
starbeamrainbowlabs

3
ฉันชอบแนวคิดของหน่วยความจำ
Einacio

2
นอกจากนี้คุณยังตระหนักถึงความหมายของกฎของคุณด้วย: หากผู้เล่น (A) เลือก9เขาจะไม่ถูกโจมตีอย่างมีความหมาย หากผู้เล่นอื่น (B) ก้าวเข้าสู่ผู้เล่นสี่เหลี่ยมจัตุรัสและชนะ A จะถูกย้ายกลับไปที่จตุรัสเดิม (ซึ่งเหมือนกัน) แต่ตอนนี้มีการปะทะกันเพราะทั้ง A และ B อยู่ที่นั่นดังนั้น B จึงต้องกลับไปที่จัตุรัสของเขาเอง ดังนั้นผลลัพธ์จึงเป็นอิสระจากการต่อสู้ที่แท้จริง B จะย้ายกลับไปที่จตุรัสเริ่มต้นและ A จะยังคงอยู่ ที่จะให้ฉันเขียนทั้งสองที่สามารถช่วยให้การส่งอื่นโดยการปิดกั้นเส้นทางสำหรับคนอื่น
Martin Ender

คำตอบ:


3

Cart'o'Gophers

นี่คือการส่งอื่น - และอันนี้จริงๆแล้วหมายถึงการแข่งขัน อีกครั้งมันอยู่ในทับทิม ruby cartogophers.rbดังนั้นเรียกมันด้วย ใช้เวลานานกว่าที่คาดไว้มาก ...

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

บอทนี้จดจำสิ่งที่เคยเห็นมาก่อนและพยายามสร้างแผนที่ขนาดใหญ่ในแต่ละเทิร์น จากนั้นใช้การค้นหาความกว้างแรกเพื่อหาไข่ที่ใกล้ที่สุดและมุ่งหน้าไปทางนั้น หากไม่มีไข่ที่สามารถเข้าถึงได้บนแผนที่ปัจจุบันบอทจะมุ่งไปยังขอบเปิดที่ใกล้ที่สุดของแผนที่ (เพื่อขยายแผนที่อย่างรวดเร็วในทิศทางที่มันยังคงเคลื่อนที่อยู่)

บอทนี้ยังไม่มีแนวคิดของบอทอื่น ๆ และยังไม่มีกลยุทธ์การต่อสู้เช่นกัน เนื่องจากฉันไม่พบวิธีที่เชื่อถือได้เพื่อตรวจสอบว่าการย้ายของฉันประสบความสำเร็จหรือไม่นี่อาจทำให้เกิดปัญหาบางอย่าง ฉันคิดเสมอว่าการย้ายนั้นประสบความสำเร็จ - ดังนั้นหากไม่ใช่แพทช์ใหม่จะถูกโหลดลงในแผนที่ในตำแหน่งที่ไม่ถูกต้องซึ่งอาจเป็นอันตรายต่อการค้นพบ

บอทใช้หน่วยความจำในการจัดเก็บแผนที่และตำแหน่งใหม่บนแผนที่ (สมมติว่าการย้ายจะสำเร็จ) แผนที่จะถูกจัดเก็บโดยไม่มีตัวแบ่งบรรทัดซิปและการเข้ารหัส base64 (พร้อมกับจำนวนแถวของแผนที่เพื่อให้สามารถแทรกตัวแบ่งบรรทัดใหม่ได้) การบีบอัดนี้ทำให้ขนาดลดลงเหลือประมาณหนึ่งในสามของแผนที่ที่ไม่มีการบีบอัดดังนั้นจึงมีเฉดสีมากกว่า 1,000 ไบต์ฉันสามารถเก็บแผนที่ประมาณ 3000 เซลล์ซึ่งสอดคล้องกับการสำรวจแผนที่อย่างเต็มที่ด้วย 18 บอต ตราบใดที่ยังไม่มีการส่งผลงานมากมายฉันไม่คิดว่าฉันจะใส่ใจกับการแก้ไขในกรณีนั้น

หลังจากการทดสอบสองสามครั้งวิ่งไปถึง 5 dumbbotวินาทีและ 1naivebot (การส่งอื่น ๆ ของฉัน) การทดสอบนั้นทำได้ไม่ดีจริง ๆ (เช่น 1 หรือ 2 ฟอง) หรือทำได้ดีกว่าคนอื่น ๆ ด้วยอัตรากำไรขั้นต้น (7 ถึง 9 ฟอง) ฉันอาจคิดถึงกลยุทธ์การต่อสู้ที่ดีกว่าและฉันจะทราบได้อย่างไรว่าฉันเคลื่อนไหวจริงหรือไม่ ทั้งสองอาจปรับปรุงคะแนนได้บ้าง

โอ้และถ้าคุณสงสัยเกี่ยวกับชื่อบอทคุณควรอ่าน The Order of The Stick ( แผงสุดท้ายในหนังสือการ์ตูนนี้ )

แก้ไข:มีข้อผิดพลาดเล็กน้อยกับการตรวจจับขอบของแผนที่ที่ค้นพบ ตอนนี้ที่ผมได้แก้ไขพวกเขาบอตนี้มักจะได้รับคะแนนของเกี่ยว20กับ 5 dumbbotและ naivebot1 มันเป็นมากกว่านี้! ถ้าคุณเพิ่ม$stderr.puts mapในบอทของฉันตอนนี้คุณจะเห็นว่าเขาเปิดแผนที่อย่างเป็นระบบและเก็บไข่ทั้งหมดในเวลาเดียวกันได้อย่างไร ฉันก็ตัดสินใจเลือกเช่นกันAแทนNทุกครั้งที่ไม่ได้เหยียบไข่เพื่อลดความน่าจะเป็นที่จะย้ายกลับไปที่เซลล์ดั้งเดิมของบอท

(มันทำงานได้ค่อนข้างไม่ดีเท่ากับ 6 naivebotวินาทีโดยเฉพาะอย่างยิ่งเนื่องจากมีความเป็นไปได้ที่จะจบลงด้วย "การหยุดชะงัก" กับบอทอื่นเมื่อทั้งคู่ต้องการคว้าไข่และเลือกNซ้ำ ๆ ฉันต้องคิดเกี่ยวกับเรื่องนี้ ... )


3

Java Bunny

กระต่ายตัวนี้ยังไม่โตเต็มที่ (ฉันยังวางแผนที่จะเปลี่ยนแปลง) แต่มันเป็นจุดเริ่มต้นของตอนนี้ เขามองหาไข่ที่อยู่ใกล้ที่สุดและไปหามัน ยังไม่มีการตรวจจับบนผนังหรือการตรวจจับนอกขอบเขต (ยัง) เขาจะไปรับไข่ที่เขาตกลงมา แต่ไม่เช่นนั้นเขาจะพยายามผลักเขาไปรอบ ๆ แล้วโจมตีอย่างอื่น หากไม่มีไข่ใกล้เคียงเขาจะเริ่มติดตามกระต่ายที่ใกล้ที่สุด พวกเขาอาจรู้บางสิ่งที่เขาทำ มิฉะนั้นเขาจะเลือกทิศทางแบบสุ่มเพื่อเดิน และเขาก็ค่อนข้างลืม (ไม่ใช้ตัวแปรหน่วยความจำ)

แผนการเดินหน้า:

  • ตัดสินใจบนพื้นฐานของกำแพง / นอกขอบเขต
  • เลือกเส้นทางที่มีจุดประสงค์มากกว่าจะเป็นการสุ่ม
  • ใช้หน่วยความจำเพื่อกำหนดทิศทางที่ฉันไปก่อน

อัปเดต 1 กระต่ายของฉันจะติดตามกระต่ายอื่น ๆ หากเขาไม่เห็นไข่ ปรับโครงสร้างรหัส "ค้นหาไข่ที่ใกล้ที่สุด" ด้วยวิธีของตัวเอง

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

    }

}

ฉันยังได้เรียนรู้ว่า Java enums นั้นเต็มไปด้วยชั้นเรียนค่อนข้างมากและฉันชอบ. NET enums มากขึ้น
Brian J

0

NaiveBot (ใน Ruby)

นี่คือบอง่าย ๆ ที่จะได้รับการกลิ้งไข่ (เราต้องการที่จะตี 7 ส่งอย่างรวดเร็วใช่มั้ย) Ruby ของฉันไม่ได้เป็นสำนวนผิดเพี้ยนดังนั้นรหัสนี้อาจทำให้นักบวช rubyists รู้สึกเจ็บปวด อ่านความเสี่ยงของคุณเอง

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

ruby naivebot.rbทำงานด้วย

ฉันแค่ฮาร์ดโค้ดสักสองสามกรณีที่มองเห็นไข่และไม่ถูกบดบังด้วยกำแพง มันไม่ได้ไปหาไข่ที่ใกล้ที่สุด แต่เลือกท่าแรกที่เหมาะสม หากไม่พบไข่ดังกล่าวบอทจะเคลื่อนที่แบบสุ่ม มันไม่สนใจผู้เล่นคนอื่นและไม่เคยโจมตีหรือนับ


0

WallFolower

(การพิจารณาโดยเจตนา) ใน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)))

ย้ายไปที่ไข่หากมีไข่อยู่ในสายตา แต่จะอยู่ใกล้กับไข่นั้นมากกว่าหุ่นยนต์ตัวอื่น หากมีการผูกในระยะทางมันไปเพื่อมันต่อไป ไม่เช่นนั้น LH จะติดตามได้

ยังคงต้องการทำงานบนกำแพงตาม แต่ฉันจะโพสต์ที่นี่ต่อไป


1
เมื่อฉันเรียกใช้ bot ของคุณด้วย tester.py ฉันได้รับข้อผิดพลาดนี้ในคอนโซล: pastebin.com/cT5xGdSW
starbeamrainbowlabs

กันที่นี่ คุณลองมองดูว่า ฉันต้องการทดสอบบอตใหม่ของฉันกับสิ่งนี้
Martin Ender

@ m.buettner จะเกิดอะไรขึ้นถ้าคุณเปลี่ยนsys.exit(0)ไปexit(0)? นอกจากนี้ฉันต้องทำงานนี้ (ตอนนี้ถือว่าตัวเองเป็น ``) แต่ฉันไม่มีเวลาจริงๆ เมื่อฉันมีเวลาฉันจะมาแก้ไขสิ่งนี้
Justin

@Quincunx โชคไม่ดีที่ไม่ได้เปลี่ยนแปลงอะไรเลย
Martin Ender
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.