Asimetrik KOTH: Kediyi Yakala (Kedi İpliği)


14

Asimetrik KOTH: Kediyi Yakala

GÜNCELLEME : Controller.java özel durumları yakalamadığından (yalnızca hatalar) gist dosyaları güncellenir (yeni alt bölümler dahil). Artık hataları ve istisnaları yakalar ve yazdırır.

Bu zorluk iki iplikten oluşur, bu kedi ipliğidir, yakalayıcı iplik burada bulunabilir .

Kontrolör indirilebilir burada .

Bu asimetrik bir KOTH: Her başvuru ya bir kedi ya da bir avcıdır . Her bir kedinin her çifti ve bir avcı arasında oyunlar var. Kediler ve avcıların ayrı sıralamaları vardır.

yakalayan şey

Altıgen ızgarada bir kedi var. Göreviniz onu mümkün olduğunca hızlı yakalamak. Her turda, kedinin oraya gitmesini önlemek için bir ızgara hücresine bir su kovası yerleştirebilirsiniz. Ancak kedi (belki de) o kadar aptal değildir ve bir kova yerleştirdiğinizde kedi başka bir ızgara hücresine hareket eder. Izgara altıgen olduğundan, kedi 6 farklı yöne gidebilir. Amacınız kediyi su kovalarıyla çevrelemek, ne kadar hızlı o kadar iyi.

Kedi

Yakalayıcının, etrafınıza su kovaları koyarak sizi yakalamak istediğini biliyorsunuz. Elbette kaçmaya çalışıyorsunuz, ama tembel bir kedi olduğunuzda (kediler gibi) o anda tam olarak bir adım atıyorsunuz. Bu, sizinle aynı yerde kalamayacağınız anlamına gelir, ancak çevredeki altı noktadan birine taşınmanız gerekir. Yakalayıcının yeni bir su kovası yerleştirdiğini her gördüğünüzde başka bir hücreye gidersiniz. Tabii ki mümkün olduğunca uzun süre kaçmaya çalışıyorsunuz.

Kafes

Izgara altıgen, ancak altıgen veri yapılarımız olmadığından, 11 x 11kare 2d dizisi alıyoruz ve kedinin sadece 6 yönde hareket edebileceği altıgen 'davranışı' taklit ediyoruz :

resim açıklamasını buraya girin

Topoloji toroidaldir, yani dizinin 'dışında' bir hücreye basarsanız, dizinin diğer tarafındaki ilgili hücreye aktarılırsınız.

oyun

Kedi ızgarada belirli bir pozisyonda başlar. Yakalayıcı ilk hareketi yapabilir, sonra kedi ve yakalayıcı kedi yakalanana kadar alternatif olarak hareket eder. Adım sayısı o oyunun skorudur. Kedi mümkün olduğunca büyük bir puan almaya çalışır, yakalayıcı mümkün olduğunca düşük bir puan almaya çalışır. Katıldığınız tüm oyunların ortalama toplamı, başvurunuzun puanı olacaktır. Biri kedi, diğeri yakalayıcılar için olmak üzere iki ayrı sıralama vardır.

kontrolör

Verilen denetleyici Java ile yazılmıştır. Bir yakalayıcı ya da kedi olarak, her biriniz bir Java sınıfını (zaten bazı ilkel örnekler vardır) uygulamanız ve playerspakete yerleştirmeniz (ve Controller sınıfındaki kedi / yakalayıcıların listesini güncellemeniz) gerekir, ancak ayrıca yazabilirsiniz. bu sınıf içindeki ek işlevler. Kontrolör, basit kediler / yakalayıcı sınıflarının her iki çalışma örneğiyle birlikte gelir.

Alan, hücrelerin geçerli durumlarının değerlerini depolayan bir 11 x 112D intdizisidir. Bir hücre boşsa, değeri 0vardır, bir kedi varsa değeri vardır -1ve bir kova varsa bir vardır 1.

Kullanabileceğiniz birkaç işlev vardır: isValidMove()/ isValidPosition()hamle (cat) / pozisyonunuzun (catcher) geçerli olup olmadığını kontrol etmek içindir.

Sıra size geldiğinde, fonksiyonunuz takeTurn()çağrılır. Argüman read(i,j), hücrenin okunması gibi yöntemlerin (i,j)yanı sıra isValidMove()/ isValidPosition()cevabınızın geçerliliğini kontrol eden mevcut ızgaranın bir kopyasını içerir . Bu, toroidal topolojinin sarılmasını da yönetir, yani ızgara sadece 11 x 11 olsa bile, hücreye erişebilirsiniz (-5,13).

Yöntem int, olası hareketleri temsil eden iki öğeden oluşan bir dizi döndürmelidir . Kediler için bunlar {-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}kedinin nereye gitmek istediği göreceli konumunu temsil eder ve yakalayıcılar bir kova yerleştirmek istedikleri yerin mutlak koordinatlarını döndürür {i,j}.

Metodunuz geçersiz bir hamle üretirse, gönderiminiz diskalifiye edilecektir. Hedefiniz zaten bir kova ise veya harekete izin verilmiyorsa / hedef zaten işgal edilmişse (kedi olarak) veya zaten bir kova / kedi (yakalayıcı olarak) varsa, taşıma geçersiz kabul edilir. Verilen fonksiyonlarla elden önce kontrol edebilirsiniz.

Gönderiminiz oldukça hızlı olmalıdır. Metodunuz her adım için 200 ms'den uzun sürerse, diskalifiye edilir. (Tercihen çok daha az ...)

Programların adımlar arasında bilgi depolamasına izin verilir.

gönderimler

  • İstediğiniz sayıda başvuru yapabilirsiniz.
  • Lütfen daha önce gönderdiğiniz gönderileri önemli ölçüde değiştirmeyin.
  • Lütfen her bir gönderiyi yeni bir yanıtla gönderin.
  • Her gönderinin tercihen benzersiz bir adı olmalıdır.
  • Gönderme, sınıfınızın kodunun yanı sıra gönderiminizin nasıl çalıştığını bize açıklayan bir açıklamadan oluşmalıdır.
  • <!-- language: lang-java -->Otomatik sözdizimi vurgulaması için kaynak kodunuzdaki satırı yazabilirsiniz .

puanlama

Tüm kediler tüm avcılara aynı sayıda yarışır . Mevcut puanları sık sık güncellemeye çalışacağım, etkinlik azaldığında kazananlar belirlenecektir.

Bu meydan okuma bu eski flash oyundan esinlenmiştir

Test ve yapıcı geri bildirimde bulunduğunuz için @PhiNotPi'ye teşekkür ederiz.

Güncel Skorlar (Maç başına 100 oyun)

Name              Score      Rank   Author

RandCatcher       191962     8      flawr   
StupidFill        212688     9      flawr
Achilles          77214      6      The E
Agamemnon         74896      5      The E
CloseCatcher      54776      4      randomra
ForwordCatcher    93814      7      MegaTom  
Dijkstra          47558      2      TheNumberOne
HexCatcher        48644      3      randomra
ChoiceCatcher     43834      1      randomra

RandCat            77490     9      flawr
StupidRightCat     81566     6      flawr
SpiralCat          93384     5      CoolGuy
StraightCat        80930     7      CoolGuy
FreeCat           106294     3      randomra
RabidCat           78616     8      cain
Dijkstra's Cat    115094     1      TheNumberOne
MaxCat             98400     4      Manu
ChoiceCat         113612     2      randomra

1
Bence bu tür bir meydan okuma polisler ve soyguncular içindi.
SuperJedi224

4
@flawr CnR etiketini iki düşman alt zorluk içeren tüm zorluklara genişletmek (ve hem bunu hem de KotH'yi etiket olarak kullanmaktan yanayım). CnR etiketi wiki'si, bu türdeki ilk zorluklardan çok etkilenir. (Ayrıca, polisleri ve soyguncuları yanlış yola soktunuz.;))
Martin Ender

1
Kedilerin kendi yöntemleriyle alıcıların tepkilerini içe aktarmasını main.Controller, çağırmasını getCatchers()ve benzetmesini / sabote etmesini ne engeller takeTurn?
LegionMammal978

12
@ LegionMammal978 Sporculuk.
Martin Ender

2
@feersum bu yardımcı oluyor mu? (Siyah (mavi) noktalar aynı hücreyi temsil eder.)
kusur

Yanıtlar:


5

FreeCat

Alan değişmezse, 3 adımdan sonra mümkün olan en fazla yolu verecek hareketi seçer.

FreeCat vs Aşil:

FreeCat vs Aşil

package players;
/**
 * @author randomra
 */

import java.util.Arrays;

import main.Field;

public class FreeCat implements Cat {

    final int[][] turns = { { -1, 1 }, { 0, 1 }, { -1, 0 }, { 1, 0 },
            { 0, -1 }, { 1, -1 } };// all valid moves
    final int turnCheck = 3;

    public String getName() {
        return "FreeCat";
    }

    public int[] takeTurn(Field f) {

        int[] pos = f.findCat();
        int[] bestMove = { 0, 1 };
        int bestMoveCount = -1;
        for (int[] t : turns) {
            int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
            int moveCount = free_count(currPos, turnCheck, f);
            if (moveCount > bestMoveCount) {
                bestMoveCount = moveCount;
                bestMove = t;
            }
        }
        return bestMove;
    }

    private int free_count(int[] pos, int turnsLeft, Field f) {
        if (f.isValidPosition(pos) || Arrays.equals(pos, f.findCat())) {
            if (turnsLeft == 0) {
                return 1;
            }
            int routeCount = 0;
            for (int[] t : turns) {
                int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
                int moveCount = free_count(currPos, turnsLeft - 1, f);
                routeCount += moveCount;
            }
            return routeCount;
        }
        return 0;
    }
}

3

Dijkstra Kedisi

Efendisinin ana algoritmasını öğrendi ve uyguladı. İlgili alıcı sınıfındaki bazı yöntemlere bağımlı olduğunu unutmayın.

Dijkstra's Cat vs Hexcatcher (güncellenmesi gerekiyor):

resim açıklamasını buraya girin

package players;

import main.Field;
import players.Dijkstra; //Not needed import. Should already be available.

/**
 * @author TheNumberOne
 *
 * Escapes from the catcher.
 * Uses Dijkstras methods.
 */

public class DijkstrasCat implements Cat{

    private static final int[][] possibleMoves = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};
    @Override
    public String getName() {
        return "Dijkstra's Cat";
    }

    @Override
    public int[] takeTurn(Field f) {
        int[] me = f.findCat();
        int[] bestMove = {-1,1};
        int bestOpenness = Integer.MAX_VALUE;
        for (int[] move : possibleMoves){
            int[] newPos = Dijkstra.normalize(new int[]{me[0]+move[0],me[1]+move[1]});
            if (!f.isValidMove(move)){
                continue;
            }
            int openness = Dijkstra.openness(newPos, f, true)[1];
            if (openness < bestOpenness || (openness == bestOpenness && Math.random() < .5)){
                bestOpenness = openness;
                bestMove = move;
            }
        }
        return bestMove;
    }
}

Nasıl çalışır:

Yönetim kurulunun kendisiyle ilgili sertliğini en aza indiren hareketi bulmaya çalışır. Daha fazla bilgi için ilgili yakalayıcının gönderisine bakın.

Güncelleme ile:

Şimdi su kovalarının bazen oluşturduğu garip geometrik şekillerden kaçınıyor.


3

MaxCat

Minimax algoritmasını uygulamayı denedim. Ancak, sınırlı zaman nedeniyle çok iyi performans göstermiyor. Düzenleme: Şimdi multithreading kullanıyor, ancak (en az benim bilgisayar) derinliği daha yüksek ayarlayamıyorum. Aksi takdirde bir zaman aşımı oluşur. 6 veya daha fazla çekirdekli bir PC kullanmak, bu sunum çok daha iyi olurdu :)

MaxCat vs Dijkstra:

MaxCat vs Dijkstra

package players;

import java.util.ArrayList;
import java.util.List;

import main.Field;

public class MaxCat implements Cat {
    final int[][] turns = { { -1, 1 }, { 0, 1 }, { -1, 0 }, { 1, 0 }, { 0, -1 }, { 1, -1 } };

    public String getName() {
        return "MaxCat";
    }

    public int[] takeTurn(Field f) {
        List<CatThread> threads = new ArrayList<>();
        int[] pos = f.findCat();
        for (int[] turn : turns) {
            if(f.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY){
                CatThread thread = new CatThread();
                thread.bestMove = turn;
                thread.field = new Field(f);
                thread.start();
                threads.add(thread);
            }
        }
        for (CatThread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {}
        }
        int best = Integer.MIN_VALUE;
        int[] bestMove = { -1, 1 };
        for (CatThread thread : threads) {
            if (thread.score > best) {
                best = thread.score;
                bestMove = thread.bestMove;
            }
        }
        return bestMove;
    }

    class CatThread extends Thread {
        private Field field;
        private int[] bestMove;
        private int score;
        private final int DEPTH = 3;

        @Override
        public void run() {
            score = max(DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE);       
        }

        int max(int depth, int alpha, int beta) {
            int pos[] = field.findCat();
            if (depth == 0 || field.isFinished()) {
                int moveCount = 0;
                for (int[] turn : turns) {
                    if(field.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY)
                        moveCount++;
                }
                return DEPTH-depth + moveCount;
            }
            int maxValue = alpha;
            for (int[] turn : turns) {
                if(field.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY) {
                    field.executeMove(turn);
                    int value = min(depth-1, maxValue, beta);
                    field.executeMove(new int[]{-turn[0], -turn[1]});
                    if (value > maxValue) {
                        maxValue = value;
                        if (maxValue >= beta)
                            break;
                    }
                }
            }
            return maxValue;
        }

        int min(int depth, int alpha, int beta) {
            if (depth == 0 || field.isFinished()) {
                int moveCount = 0;
                for (int[] turn : turns) {
                    int pos[] = field.findCat();
                    if(field.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY)
                        moveCount++;
                }   
                return -depth - moveCount;
            }
            int[][] f = field.field;
            int minValue = beta;
            List<int[]> moves = generateBucketMoves();
            for (int[] move : moves) {
                f[move[0]][move[1]] = Field.BUCKET;
                int value = max(depth-1, alpha, minValue);
                f[move[0]][move[1]] = Field.EMPTY;
                if (value < minValue) {
                    minValue = value;
                    if (minValue <= alpha)
                        break;
                }
            }
            return minValue;
        }

        private List<int[]> generateBucketMoves() {
            int[][] f = field.field;
            List<int[]> list = new ArrayList<>();
            for (int i = 0; i < f.length; i++) {
                for (int j = 0; j < f[i].length; j++) {
                    if (f[i][j] == Field.EMPTY) {
                        list.add(new int[]{i,j});
                    }
                }
            }
            return list;
        }
    }
}

Aslında Fieldkamu kurucusunu yapabilirsiniz . Henüz dosyaları güncellemediğim için özür dilerim, ancak bunu daha önce tartıştık!
flawr

@flawr Ah güzel, teşekkürler!
commonguy

2

SpiralCat

Spiral bir şekilde hareket eder. O

  • Sol üstteki daireye geçmeye çalışır
  • Mümkünse, sağ üst daireye geçmeye çalışır
  • Mümkünse, doğru daireye geçmeye çalışır
  • Mümkünse, sağ alt daireye geçmeye çalışır
  • Mümkünse, sol alt daireye gitmeye çalışır

SpiralCat ve Agamemnon:

SpiralCat ve Agamemnon Karşılaştırması

package players;
/**
 * @author Cool Guy
 */

import main.Field;

public class SpiralCat implements Cat{
    public String getName(){
        return "SpiralCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{1,0},{1,-1},{0,-1},{-1,0}};//all valid moves
        int[] move;
        int i = -1;
        do {
            i++;
            move = turns[i];
        } while(f.isValidMove(move) == false);
        return move;
    }
}

Hangi hatalarla karşılaştığınızı biliyor musunuz? Ben değiştirmek tek şey değiştirmeden olacağını turns[i]üzere turns[i%6](bu durum, meydana DEĞİL olmalıdır) sınırların dışında kaçınmak için.
flawr

@flawr, Lanet olsun. Kelime seçimi kötü. Demek istediğim bu kedi çok zeki değil. Bazen, bu kedi sadece bir çıkış yolu olsa bile sol üst daire ve sağ alt daire arasında
değişir

@flawr, Kullanmam gerekiyor turns[i%6]mu? Yani, takeTurnkedi engellendiyse çağrılmayacak, değil mi?
Spikatrix

Hayır, programda bir hatayla karşılaştığınızı düşündüğümü düşündüm, bu yüzden olası nedenleri arıyordum. Ama haklısın, açıkçası (eğer her şey doğruysa) i>=6asla gerçekleşmemelidir.
flawr

2

RabidCat

RabidCat'ın hidrofobisi var, bu yüzden su kovalarından korkuyor. En yakın olanı bulur ve ters yönde koşar.

RabidCat vs ForwordCatcher:

rabidcat_vs_forwordcatcher

package players;

import java.util.Random;

import main.Field;

/**
* Run away from water buckets
* @author cain
*
*/

public class RabidCat implements Cat {

public RabidCat() {
}

@Override
public String getName() {
    return "RabidCat";
}

@Override
public int[] takeTurn(Field f) {
    int[][] directions = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};

    //where am I?
    int[] position = {0,0};
    for(int i = 0; i < 12; i++){
        for(int j = 0; j < 12; j++){
            if(f.read(i,j) == -1){
                position[0] = i;
                position[1] = j;
            }
        }
    }

    //Find the closest water
    int direction = 0;
    for(int d = 0; d < 10; d++){
        if(f.read(position[0] + d, position[1] - d) == 1 && f.isValidMove(directions[0])){
            direction = 1;
            break;
        }
        if(f.read(position[0], position[1] - d) == 1 && f.isValidMove(directions[1])){
            direction = 2;
            break;
        }
        if(f.read(position[0] + d, position[1]) == 1 && f.isValidMove(directions[2])){
            direction = 3;
            break;
        }
        if(f.read(position[0] - d, position[1]) == 1 && f.isValidMove(directions[3])){
            direction = 4;
            break;
        }
        if(f.read(position[0], position[1] + d) == 1 && f.isValidMove(directions[4])){
            direction = 5;
            break;
        }
        if(f.read(position[0] - d, position[1] + d) == 1 && f.isValidMove(directions[5])){
            direction = 6;
            break;
        }
    }

    //If there is no water near, wander
    while(direction == 0){
        Random rand = new Random();
        direction = rand.nextInt(6) + 1;
        if(!f.isValidMove(directions[direction - 1])){
            direction = 0;
        }
    }
    return directions[direction - 1];
}

}

Vay, gerçekten CloseCatcher tarafından harap olsun
Cain

2

ChoiceCat

Olası her yeni kedi pozisyonu için iyiliğini kontrol edip en iyisini seçiyoruz. İyilik, kedi pozisyonundan hesapladığımız pozisyondan daha uzakta olan en iyi iki komşu hücrenin fonksiyonudur. Sadece iki hücre kullanıyoruz çünkü biri bloke edilebilir ve kedinin kurtulmak için sadece bir tane daha ihtiyacı vardır. Bizim fonksiyonumuz bir büyük ve bir kötü olmak üzere iki oldukça iyi hücreyi tercih eder. Kepçeli pozisyonların skoru 0 ve en uzaktaki serbest hücreler skoru 1'dir.

ChoiceCat şu anki kedilerden daha iyi puan alıyor gibi görünüyor.

ChoiceCat ve ChoiceCatcher karşılaştırması:

ChoiceCat ve ChoiceCatcher karşılaştırması

package players;
/**
 * @author randomra
 */
import java.util.Arrays;

import main.Field;

public class ChoiceCat implements Cat {

    private class Values {
        public final int size;
        private double[][] f;

        Values(int size) {
            this.size = size;
            f = new double[size][size];
        }

        public double read(int[] p) {
            int i = p[0];
            int j = p[1];
            i = (i % size + size) % size;
            j = (j % size + size) % size;
            return f[i][j];
        }

        private double write(int[] p, double v) {
            int i = p[0];
            int j = p[1];
            i = (i % size + size) % size;
            j = (j % size + size) % size;
            return f[i][j] = v;
        }
    }

    final int[][] turns = { { -1, 1 }, { 0, 1 }, { 1, 0 }, { 1, -1 },
            { 0, -1 }, { -1, 0 } };// all valid moves CW order
    final int stepCheck = 5;

    public String getName() {
        return "ChoiceCat";
    }

    public int[] takeTurn(Field f) {

        int[] pos = f.findCat();
        int[] bestMove = { 0, 1 };
        double bestMoveValue = -1;
        for (int[] t : turns) {
            int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
            double moveValue = movePosValue(currPos, f);
            if (moveValue > bestMoveValue) {
                bestMoveValue = moveValue;
                bestMove = t;
            }
        }
        return bestMove;
    }

    private double movePosValue(int[] pos, Field f) {

        Values v = new Values(f.SIZE);

        for (int ring = stepCheck; ring >= 0; ring--) {
            for (int phase = 0; phase < 2; phase++) {
                for (int sidepos = 0; sidepos < Math.max(1, ring); sidepos++) {
                    for (int side = 0; side < 6; side++) {
                        int[] evalPos = new int[2];
                        for (int coord = 0; coord < 2; coord++) {
                            evalPos[coord] = pos[coord] + turns[side][coord]
                                    * sidepos + turns[(side + 1) % 6][coord]
                                    * (ring - sidepos);
                        }
                        if (phase == 0) {
                            if (ring == stepCheck) {
                                // on outmost ring, init value
                                v.write(evalPos, -1);
                            } else {
                                v.write(evalPos, posValue(evalPos, v, f));
                            }
                        } else {
                            // finalize position value for next turn
                            v.write(evalPos, -v.read(evalPos));
                        }
                    }
                }
            }
        }

        return -v.read(pos);
    }

    private double posValue(int[] pos, Values v, Field f) {
        if (f.read(pos[0], pos[1]) == Field.BUCKET) {
            return 0;
        }
        int count = 0;
        double[] product = new double[6];
        for (int[] t : turns) {
            int[] tPos = new int[] { pos[0] + t[0], pos[1] + t[1] };
            if (v.read(tPos) > 0) {
                product[count] = 1 - 1 / (v.read(tPos) + 1);
                count++;
            }
        }
        Arrays.sort(product);
        double fp = 1;
        for (int i = 0; i < Math.min(count,2); i++) {
            fp *= product[5-i];
        }
        double retValue = Math.min(count,2) + fp;
        return -retValue;
    }
}

1

StupidRightCat

Bu sadece kontrolörü test etmek için yapıldı. Kedi mümkün olduğunda sağa hareket eder, aksi takdirde rastgele bir yönde hareket eder.

package players;

import main.Field;

public class StupidRightCat implements Cat{
    public String getName(){
        return "StupidRightCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};//all valid moves
        int[] move;

        if(f.isValidMove(turns[3])){
            return turns[3];
        } else {
            do {
                move = turns[(int) (turns.length * Math.random())];
            } while(f.isValidMove(move)==false);
            return move;//chose one at random
        }
    }
}

1

RandCat

Bu sadece kontrolörü test etmek için yapıldı. Kedi rastgele hareket eder.

package players;

import main.Field;

public class RandCat implements Cat{
    public String getName(){
        return "RandCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};//all valid moves
        int[] move;
        do {
            move = turns[(int) (turns.length * Math.random())];
        } while(f.isValidMove(move)==false);
        return move;//chose one at random
    }
}

1

StraightCat

Bu kedi düz hareket ediyor.

Başlangıçta, rastgele bir yön seçer ve yapamayana kadar bu yönde hareket etmeye devam eder, bu durumda yönü saat yönünde bir sonraki geçerli yöne kaydırır ve bu işlemi tekrarlar.

StraightCat ve Agamemnon:

StraightCat vs Agamemnon

package players;
/**
 * @author Cool Guy
 */

import main.Field;

public class StraightCat implements Cat{

    int lastDirection = -1; //Holds the last direction the cat moved
    public String getName(){
        return "StraightCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{1,0},{1,-1},{0,-1},{-1,0}};//all valid moves

        if(lastDirection == -1)
          lastDirection = (int) (turns.length * Math.random());

        int[] move = turns[lastDirection];
        int i = lastDirection;

        while(true)
        {
            if(f.isValidMove(move))
                break;
            i = (i+1)%6;
            lastDirection = i;
            move = turns[i];
        }
        return move;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.