คิงปากกา! (จุดและกล่อง)


23

นี่คือราชาแห่งความท้าทายของ Dots and Boxes (aka Pen the Pig) เกมนี้เล่นง่ายเมื่อถึงคราวคุณแค่ลากเส้นบนรั้วที่ว่างเปล่า ทุกครั้งที่คุณทำตารางให้เสร็จ นอกจากนี้เนื่องจากเรากำลังเล่นตามกฎการแข่งขันชิงแชมป์หากคุณทำอย่างน้อยหนึ่งตารางในตาคุณคุณจะได้รับเทิร์นเพิ่มเติม นี่คือทัวร์นาเมนต์ Round robin ที่แต่ละ bot เล่น bot อื่น ๆสองครั้ง 12 ครั้งในตาราง 9x9 ตรวจสอบการแข่งขันนี้ระหว่างยักษ์ใหญ่สองรุ่นที่ ChainCollector สร้างเนื้อสับเพื่อครองแชมป์ Asdf: ป้อนคำอธิบายรูปภาพที่นี่

กฎระเบียบ

  1. 0.5 วินาทีเวลา จำกัด ต่อการเคลื่อนไหว
  2. ไม่มีการรบกวนบอทอื่น ๆ
  3. ใช้ PigPen.random () และ PigPen.random (int) เพื่อการสุ่ม
  4. ไม่มีการเขียนลงไฟล์
  5. บอทและข้อมูลถาวรทั้งหมดจะถูกรีเซ็ตทุกครั้งที่มีการเปลี่ยนแปลงคู่ต่อสู้ (ทุก 12 รอบ)

บอท

บอททุกอันขยาย Player.java:

package pigpen;

public abstract class Player {

public abstract int[] pick(Board board, int id, int round); 

}

Boardเป็นกระดานเกมซึ่งส่วนใหญ่ทำหน้าที่ให้คุณเข้าถึงPenชั้นเรียนและidเป็น playerID ของคุณ (บอกคุณว่าคุณเป็นคนแรกหรือคนที่สอง)roundบอกคุณว่าคุณเล่นรอบไหนกับคู่ต่อสู้คนเดียวกัน (1 หรือ 2) ค่าส่งคืนคือint[]ที่ซึ่งองค์ประกอบแรกคือ penID (1 ดัชนี) และองค์ประกอบที่สองคือ fenceID (ดัชนี 0) ดูPen.pick(int)วิธีง่ายๆในการสร้างมูลค่าส่งคืนนี้ ดูหน้าGithubสำหรับผู้เล่นตัวอย่างและ JavaDoc เนื่องจากเราใช้ตารางสี่เหลี่ยมเท่านั้นจึงไม่สนใจฟังก์ชันและฟิลด์ใด ๆ ที่เกี่ยวข้องกับรูปหกเหลี่ยม

วิธีการวิ่ง

  1. แหล่งดาวน์โหลดจาก Github
  2. เขียนบอควบคุมของคุณ (ตรวจสอบให้แน่ใจว่าจะรวม package pigpen.players ) และใส่ไว้ในsrc/โฟลเดอร์
  3. javac -cp src/* -d . src/*.javaคอมไพล์ด้วย ทำงานด้วยjava pigpen.Tournament 4 9 9 false (สามารถเปลี่ยนตัวเลขสองตัวสุดท้ายเพื่อปรับขนาดกริดตัวแปรสุดท้ายควรถูกตั้งค่าเป็นtrueหากคุณต้องการใช้ซอฟต์แวร์ pp_record เท่านั้น)

คะแนน

  1. ChainCollector: 72
  2. Asdf: 57
  3. Lazybones: 51
  4. Finisher: 36
  5. = LinearPlayer: 18
  6. = BackwardPlayer: 18
  7. RandomPlayer: 0

ดูสิ่งนี้ด้วย:

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

ขอบคุณ Nathan Merrill และ Darrel Hoffman ที่ให้คำปรึกษาเกี่ยวกับความท้าทายนี้!

อัปเดต :

  • เพิ่มmoves(int player)วิธีในคลาสบอร์ดเพื่อรับรายการการเคลื่อนไหวที่ผู้เล่นทำ

ค่าหัวไม่ จำกัด (100 Rep) :

คนแรกที่โพสต์ทางออกที่ชนะทุกรอบและใช้กลยุทธ์ (ปรับการเล่นโดยดูจากการสังเกตของฝ่ายตรงข้ามที่เล่น)


2
ความดี หมัดเด็ดคือ waaayyyy OP! : P
El'endia Starman

@ El'endiaStarman Lol สิ่งที่เขาทำก็คือการจบปากกาที่มีรั้วเดียวหรือจะเลือกปากกาที่มีรั้วเหลืออยู่มากที่สุด RandomPlayer เป็นเพียงการสุ่ม
geokavel

2
ใช่ฉันรู้. มันเป็นแค่ที่คะแนนสุดท้ายเป็น 79-2 และ RandomPlayer มีเพียงผู้ที่สองกล่องที่ผ่านมาเพราะมันมีการ : P
El'endia Starman

สวัสดี! ฉันต้องการสร้างบอทของฉันเอง แต่ฉันมีคำถาม Pen.BOTTOM ที่แถว 0 col 0 จะส่งกลับค่าเดียวกับ Pen.TOP ที่แถว 1 col 0 หรือไม่
tuskiomi

@tusk ใช่มันเป็นเช่นนั้น
geokavel

คำตอบ:


6

คนขี้เกียจ

บอทนี้ขี้เกียจ เขาเลือกจุดและทิศทางแบบสุ่มและยังคงสร้างในทิศทางนั้นโดยไม่เคลื่อนที่มากเกินไป มีเพียง 2 กรณีที่เขาทำสิ่งที่แตกต่าง:

  • "ทำเงิน" โดยการปิดหมุดด้วยรั้วที่เหลือเพียง 1 อัน
  • เลือกจุดและทิศทางใหม่หากไม่สามารถวางรั้วได้หรืออนุญาตให้บอทอื่น ๆ "สร้างรายได้"
package pigpen.players;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import pigpen.Board;
import pigpen.Pen;
import pigpen.PigPen;
import pigpen.Player;

public class Lazybones extends Player {
    private static class Fence {
        private static boolean isOk(Board board, boolean vertical, int row, int col) {
            if (vertical) {
                Pen left = board.getPenAt(row, col - 1);
                Pen right = board.getPenAt(row, col);
                if (left.id() < 0 && right.id() < 0 ||
                        left.fences()[Pen.RIGHT] > 0 ||
                        right.fences()[Pen.LEFT] > 0 ||
                        left.remaining() == 2 ||
                        right.remaining() == 2) {
                    return false;
                }
            } else {
                Pen top = board.getPenAt(row - 1, col);
                Pen bottom = board.getPenAt(row, col);
                if (top.id() < 0 && bottom.id() < 0 ||
                        top.fences()[Pen.BOTTOM] > 0 ||
                        bottom.fences()[Pen.TOP] > 0 ||
                        top.remaining() == 2 ||
                        bottom.remaining() == 2) {
                    return false;
                }
            }
            return true;
        }

        private static Fence pickRandom(Board board) {
            List<Fence> ok = new ArrayList<>();
            List<Fence> notOk = new ArrayList<>();
            for (int row = 0; row < board.rows; row ++) {
                for (int col = 0; col < board.cols; col ++) {
                    (isOk(board, false, row, col) ? ok : notOk)
                            .add(new Fence(false, row, col));
                    (isOk(board, true, row, col) ? ok : notOk)
                            .add(new Fence(true, row, col));
                }
                (isOk(board, true, row, board.cols) ? ok : notOk)
                        .add(new Fence(true, row, board.cols));
            }
            for (int col = 0; col < board.cols; col ++) {
                (isOk(board, false, board.rows, col) ? ok : notOk)
                        .add(new Fence(false, board.rows, col));
            }
            if (ok.isEmpty()) {
                return notOk.get(PigPen.random(notOk.size()));
            } else {
                return ok.get(PigPen.random(ok.size()));
            }
        }

        private final boolean vertical;
        private final int row;
        private final int col;

        public Fence(boolean vertical, int row, int col) {
            super();
            this.vertical = vertical;
            this.row = row;
            this.col = col;
        }

        private Fence next(Board board, boolean negative) {
            int newRow = vertical ? (negative ? row - 1 : row + 1) : row;
            int newCol = vertical ? col : (negative ? col - 1 : col + 1);
            if (isOk(board, vertical, newRow, newCol)) {
                return new Fence(vertical, newRow, newCol);
            } else {
                return null;
            }
        }

        private int[] getResult(Board board) {
            if (vertical) {
                if (col < board.cols) {
                    return board.getPenAt(row, col).pick(Pen.LEFT);
                } else {
                    return board.getPenAt(row, col - 1).pick(Pen.RIGHT);
                }
            } else {
                if (row < board.rows) {
                    return board.getPenAt(row, col).pick(Pen.TOP);
                } else {
                    return board.getPenAt(row - 1, col).pick(Pen.BOTTOM);
                }
            }
        }
    }

    private Fence lastFence = null;
    private boolean negative = false;

    @Override
    public int[] pick(Board board, int id, int round) {
        List<Pen> money = board.getList().stream()
                .filter(p -> p.remaining() == 1).collect(Collectors.toList());
        if (!money.isEmpty()) {
            return money.get(PigPen.random(money.size())).pick(Pen.TOP);
        }
        if (lastFence != null) {
            lastFence = lastFence.next(board, negative);
        }
        if (lastFence == null) {
            lastFence = Fence.pickRandom(board);
            negative = PigPen.random(2) == 0;
        }
        return lastFence.getResult(board);
    }
}

ว้าวเยี่ยมมาก! LazyBones เป็นเจ้าของหมัดเด็ด (ดูภาพเคลื่อนไหวใหม่)
geokavel

โดยวิธีการเพื่อให้ทุกคนรู้วิธีที่จะได้รับปากกาทางด้านซ้ายของปากกาที่กำหนดคือpen.n(Pen.LEFT)(ฟังก์ชั่นเพื่อนบ้าน)
geokavel

นอกจากนี้ฉันคิดว่ามันไม่จำเป็นเมื่อคุณตรวจสอบรั้วด้านล่างของปากกาและรั้วด้านบนของรั้วด้านล่างพวกเขารับประกันว่าจะมีค่าเดียวกัน!
geokavel

pick()วิธีการตอนนี้มีint roundพารามิเตอร์ที่สิ้นสุดดังนั้นถ้าคุณจะกรุณาเพิ่มว่า
geokavel

ฉันต้องตรวจสอบทั้งสองรั้วเพราะวัตถุปากกาใด ๆ สามารถอยู่นอกบอร์ด (id == -1) ด้วยเหตุผลเดียวกันฉันไม่สามารถใช้ฟังก์ชั่นเพื่อนบ้านได้
Sleafar

6

ChainCollector

บอทนี้ชอบโซ่1 1เขาต้องการมากที่สุด บางครั้งเขาก็เสียสละส่วนเล็ก ๆ ของโซ่เพื่อชนะส่วนที่ใหญ่กว่า

[1] โซ่ประกอบด้วยปากกาที่เชื่อมต่อกันด้วยรั้วเปิดซึ่งปากกาแต่ละด้ามมีรั้วเปิด 1 หรือ 2 เส้น หากปากกาเดียวที่อยู่ในห่วงโซ่สามารถเสร็จสิ้นได้เนื่องจากกฎการแข่งขันชิงแชมป์โซ่ทั้งหมดก็สามารถทำได้เช่นกัน

package pigpen.players;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeMap;

import pigpen.Board;
import pigpen.Pen;
import pigpen.Player;

public class ChainCollector extends Player {
    private enum Direction {
        TOP, RIGHT, BOTTOM, LEFT;

        public Direction opposite() {
            return values()[(ordinal() + 2) % 4];
        }
    }

    private enum ChainEndType {
        OPEN, CLOSED, LOOP
    }

    private static class PenEx {
        private final int id;
        private final List<Fence> openFences = new ArrayList<>();
        private boolean used = false;

        public PenEx(int id) {
            super();
            this.id = id;
        }

        public void addOpenFence(Direction direction, PenEx child) {
            openFences.add(new Fence(this, direction, child));
            if (child != null) {
                child.openFences.add(new Fence(child, direction.opposite(), this));
            }
        }
    }

    private static class Fence {
        public final PenEx parent;
        public final Direction direction;
        public final PenEx child;

        public Fence(PenEx parent, Direction direction, PenEx child) {
            super();
            this.parent = parent;
            this.direction = direction;
            this.child = child;
        }

        public int[] getMove() {
            if (parent == null) {
                return new int[] { child.id, direction.opposite().ordinal() };
            } else {
                return new int[] { parent.id, direction.ordinal() };
            }
        }
    }

    private static class Moves {
        private final TreeMap<Integer, List<Fence>> map = new TreeMap<>();

        public void add(int score, Fence move) {
            List<Fence> list = map.get(score);
            if (list == null) {
                list = new ArrayList<>();
                map.put(score, list);
            }
            list.add(move);
        }

        public boolean isEmpty() {
            return map.isEmpty();
        }

        public boolean hasExactlyOne() {
            return map.size() == 1 && map.firstEntry().getValue().size() == 1;
        }

        public int getLowestScore() {
            return map.firstKey();
        }

        public int[] getLowMove() {
            return map.firstEntry().getValue().get(0).getMove();
        }

        public int[] getHighMove() {
            return map.lastEntry().getValue().get(0).getMove();
        }
    }

    private static class BoardEx {
        private final List<PenEx> pens = new ArrayList<>();
        private final Moves neutralMoves = new Moves();
        private final Moves finisherMoves = new Moves();
        private final Moves safeFinisherMoves = new Moves();
        private final Moves sacrificeMoves = new Moves();
        private final Moves badMoves = new Moves();

        public BoardEx(Board board) {
            super();
            PenEx[][] tmp = new PenEx[board.rows][board.cols];
            for (int row = 0; row < board.rows; ++row) {
                for (int col = 0; col < board.cols; ++col) {
                    Pen pen = board.getPenAt(row, col);
                    int[] fences = pen.fences();
                    PenEx penEx = new PenEx(pen.id());
                    tmp[row][col] = penEx;
                    pens.add(penEx);
                    if (fences[Pen.TOP] == 0) {
                        penEx.addOpenFence(Direction.TOP, row == 0 ? null : tmp[row - 1][col]);
                    }
                    if (row == board.rows - 1 && fences[Pen.BOTTOM] == 0) {
                        penEx.addOpenFence(Direction.BOTTOM, null);
                    }
                    if (fences[Pen.LEFT] == 0) {
                        penEx.addOpenFence(Direction.LEFT, col == 0 ? null : tmp[row][col - 1]);
                    }
                    if (col == board.cols - 1 && fences[Pen.RIGHT] == 0) {
                        penEx.addOpenFence(Direction.RIGHT, null);
                    }
                }
            }
        }

        private ChainEndType followChain(Fence begin, List<Fence> result) {
            Fence current = begin;
            for (;;) {
                current.parent.used = true;
                result.add(current);
                if (current.child == null) {
                    return ChainEndType.OPEN;
                }
                List<Fence> childFences = current.child.openFences;
                switch (childFences.size()) {
                    case 1:
                        current.child.used = true;
                        return ChainEndType.CLOSED;
                    case 2:
                        if (current.child == begin.parent) {
                            return ChainEndType.LOOP;
                        } else {
                            current = current.direction.opposite() == childFences.get(0).direction ?
                                    childFences.get(1) : childFences.get(0);
                        }
                        break;
                    case 3:
                    case 4:
                        return ChainEndType.OPEN;
                    default:
                        throw new IllegalStateException();
                }
            }
        }

        public void findChains() {
            for (PenEx pen : pens) {
                if (!pen.used && pen.openFences.size() > 0) {
                    if (pen.openFences.size() < 3) {
                        List<Fence> fences = new ArrayList<>();
                        ChainEndType type1 = pen.openFences.size() == 1 ?
                                ChainEndType.CLOSED : followChain(pen.openFences.get(1), fences);
                        if (type1 == ChainEndType.LOOP) {
                            badMoves.add(fences.size(), fences.get(0));
                        } else {
                            Collections.reverse(fences);
                            ChainEndType type2 = followChain(pen.openFences.get(0), fences);
                            if (type1 == ChainEndType.OPEN && type2 == ChainEndType.CLOSED) {
                                type1 = ChainEndType.CLOSED;
                                type2 = ChainEndType.OPEN;
                                Collections.reverse(fences);
                            }
                            if (type1 == ChainEndType.OPEN) {
                                badMoves.add(fences.size() - 1, fences.get(fences.size() / 2));
                            } else if (type2 == ChainEndType.CLOSED) {
                                finisherMoves.add(fences.size() + 1, fences.get(0));
                                if (fences.size() == 3) {
                                    sacrificeMoves.add(fences.size() + 1, fences.get(1));
                                } else {
                                    safeFinisherMoves.add(fences.size() + 1, fences.get(0));
                                }

                            } else {
                                finisherMoves.add(fences.size(), fences.get(0));
                                if (fences.size() == 2) {
                                    sacrificeMoves.add(fences.size(), fences.get(1));
                                } else {
                                    safeFinisherMoves.add(fences.size(), fences.get(0));
                                }
                            }
                        }
                    } else {
                        pen.used = true;
                        for (Fence fence : pen.openFences) {
                            if (fence.child == null || fence.child.openFences.size() > 2) {
                                neutralMoves.add(fence.child == null ? 0 : fence.child.openFences.size(), fence);
                            }
                        }
                    }
                }
            }
        }

        public int[] bestMove() {
            if (!neutralMoves.isEmpty()) {
                if (!finisherMoves.isEmpty()) {
                    return finisherMoves.getHighMove();
                }
                return neutralMoves.getHighMove();
            }
            if (!safeFinisherMoves.isEmpty()) {
                return safeFinisherMoves.getHighMove();
            }
            if (badMoves.isEmpty() && !finisherMoves.isEmpty()) {
                return finisherMoves.getHighMove();
            }
            if (!sacrificeMoves.isEmpty()) {
                if (sacrificeMoves.hasExactlyOne()) {
                    if (badMoves.getLowestScore() - sacrificeMoves.getLowestScore() >= 2) {
                        return sacrificeMoves.getLowMove();
                    } else {
                        return finisherMoves.getHighMove();
                    }
                } else {
                    return finisherMoves.getHighMove();
                }
            }
            if (!badMoves.isEmpty()) {
                return badMoves.getLowMove();
            }
            return null;
        }
    }

    @Override
    public int[] pick(Board board, int id, int round) {
        BoardEx boardEx = new BoardEx(board);
        boardEx.findChains();
        return boardEx.bestMove();
    }
}

ว้าวขอบคุณสำหรับผลงานของคุณ ฉันถ่อมตนว่ามีคนใส่เวลามากในโครงการที่ฉันสร้างขึ้น ฉันคิดว่าการเปิดตัวบ็อตนี้ส่งผลกระทบต่อการสร้างตัวเลขสุ่มเช่นนั้น Asdf ตอนนี้เต้น Lazybones ทั้งสองครั้งด้วยระยะขอบเล็กน้อย
geokavel

ความคิดของบอทดูค่อนข้างง่ายก่อนที่จะเริ่มจากนั้นฉันก็อยากจะทำมันให้เสร็จ ;) ด้วยความเกี่ยวข้องกับการสุ่มคุณควรปล่อยให้บอทเล่นมากกว่า 2 เกมเพื่อให้ได้ผลลัพธ์ที่แม่นยำยิ่งขึ้น
Sleafar

ความคิดที่ดี ฉันเพิ่มมันเป็น 12 รอบต่อการจับคู่และตอนนี้อย่างที่คุณเห็น Asdf มีขอบเล็กน้อย แม้ในรอบ 100 เกมจะมีเกมมากกว่า Lazybones 13 เกมเท่านั้น
geokavel

3

หมัดเด็ด

package pigpen.players;

import pigpen.*;

import java.util.*;

/**
 * Picks a Pen with only one fence remaining. 
 * Otherwise picks one with the most fences remaining
 */
public class Finisher extends Player implements Comparator<Pen> {


  public int[] pick(Board board, int id) {
     return Collections.max(board.getList(),this).pick(Pen.TOP);

  }

  @Override
  public int compare(Pen p1, Pen p2) {
    //1 remaining is best, all remaining is second.
    int r1 = p1.remaining();
    int r2 = p2.remaining();
    if(r1 == 1) r1 = 7;
    if(r2 == 1) r2 = 7;
    return Integer.compare(r1,r2);
 }


}

ใช้ Comparator เพื่อเลือกปากกาที่มีรั้วที่มีอยู่มากที่สุด แต่ให้ความสำคัญกับปากกาที่มีเพียงรั้วเดียวเท่านั้น (7 ใช้มากกว่า 5 เพื่อให้รหัสนี้ทำงานในโหมดรูปหกเหลี่ยมได้เช่นกัน)


3

asdf

กำหนดคะแนนให้กับแต่ละรั้วแล้วเลือกสิ่งที่ดีที่สุดออกมา ตัวอย่างเช่น: ปากกาที่มีรั้วเปิดหนึ่งอันมีคะแนน 10 ขณะที่ปากกาที่มีรั้วเปิด 2 อันมีคะแนน -8

ดูเหมือนว่าLazybonesจะใช้กลยุทธ์ที่คล้ายกันเพราะมันเชื่อมโยงกับบอทนี้

package pigpen.players;

import java.util.*;
import pigpen.*;

public class Asdf extends Player {
    private final List<Score> scores = new ArrayList<>();

    @Override
    public int[] pick(Board board, int id, int round) {
        scores.clear();
        List<Pen> pens = board.getList();

        pens.stream().filter(x -> !x.closed()).forEach((Pen p) -> evaluate(p));
        Optional<Score> best = scores.stream().max(Comparator.comparingInt(p -> p.points));

        if (best.isPresent()) {
            Score score = best.get();
            return score.pen.pick(score.fence);
        }
        return null;
    }

    private void evaluate(Pen pen) {
        int[] fences = pen.fences();
        for (int i = 0; i < fences.length; i++) {
            if (fences[i] == 0) {
                int points = getPoints(pen);
                Pen neighbour = pen.n(i);
                if (neighbour.id() != -1) {
                    points += getPoints(neighbour);
                }
                scores.add(new Score(pen, i, points));
            }
        }
    }

    private int getPoints(Pen pen) {
        switch (pen.remaining()) {
            case 1: return 10;
            case 2: return -1;
            case 3: return 1;
        }
        return 0;
    }

    class Score {
        private Pen pen;
        private int fence;
        private int points;

        Score(Pen pen, int fence, int points) {
            this.pen = pen;
            this.fence = fence;
            this.points = points;
        }
    }
}

นี่คือคะแนน มันน่าสนใจที่ใครก็ตามที่ได้อันดับสองจะได้รับคะแนนมากเป็นสองเท่า Asdf vs. Lazybones: 27 - 54; Lazybones กับ Asdf: 27 - 54
geokavel

@geokavel ใช่แล้วเพราะบอตนั้นถูกบังคับให้ทำ "เลี้ยวไม่ดี" ดังนั้นคู่ต่อสู้สามารถปิดปากกาได้
CommonGuy

นี่เป็นอัลกอริทึมที่ดีที่สุดใช่ไหม?
justhalf

@ justhalf ไม่ใช่เพราะคนเล่นเกมนี้ด้วยการประชัน ฉันคิดว่าอัลกอริทึมเหล่านี้สามารถขยายได้อย่างแน่นอน ดูลิงก์ที่ฉันให้ไว้สำหรับข้อมูลเพิ่มเติม
geokavel

0

LinearPlayer

package pigpen.players;

import pigpen.*;

/**
 * Picks the first available fence in the first available Pen
 */ 
public class LinearPlayer extends Player {


@Override
public int[] pick(Board board, int id) {
    for(int p = 1;p<=board.size;p++) {
        Pen pen = board.get(p);
            if(!pen.closed()) {
                int[] fences = pen.fences();
                    for(int i =0;i<fences.length;i++) {
                        if(fences[i] == 0) {
                            return new int[]{pen.id(),i};
                        }
                    }
                }
        }
    return new int[]{1,0};
    } 
}

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


0

BackwardPlayer

package pigpen.players;

import pigpen.*;

/**
 * Picks the first available fence in the last available Pen
 */
 public class BackwardPlayer extends Player {

public int[] pick(Board board, int id) {
    for(int i = board.size;i>0;i--) {
        Pen p = board.get(i);
        if(!p.closed()) {
            return p.pick(Pen.TOP);
        }
    }
    return new int[] {1,0};
}
}

รหัสนี้ใช้วิธีลัดPen.pick(int)เพื่อสร้างค่าส่งคืน หากรั้วด้านบนไม่พร้อมใช้งานมันจะเลือกรั้วที่มีอยู่ใกล้เคียงที่สุดตามเข็มนาฬิกา


0

RandomPlayer

package pigpen.players;

import pigpen.*;


/** 
 * Picks the first available fence in a random Pen 
 */
public class RandomPlayer extends Player {
    public int[] pick(Board board, int id) {
        int pen = PigPen.random(board.size)+1;
        return board.get(pen).pick(Pen.TOP);
    }
}

แนวคิดเดียวกับ BackwardPlayer แต่สุ่มเลือกปากกา หมายเหตุ+1เนื่องจากปากกามีการจัดทำดัชนี 1 รายการ

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