Go oyununu puanla


23

Bir Go oyunu puanlama hepsi çok kolay olmayan bir iştir. Geçmişte, meydana gelebilecek bütün garip köşe davalarını kapsayacak şekilde kuralların nasıl tasarlanacağı hakkında bazı tartışmalar yapıldı. Neyse ki, bu görevde yaşam ve ölüm ya da seki tespiti gibi karmaşık şeyler yapmak zorunda değilsiniz. Bu görevde, Komi'siz Tromp-Taylor kurallarına göre bir oyun puanlayan bir program uygulamanız gerekiyor .
Puanlama işlemi oldukça basittir:

Renkli olmayan bir nokta olan P'nin, P'nin renginin P noktasından (C) bir noktaya (dikey veya yatay olarak) bitişik noktaları olması halinde C'ye ulaştığı söylenir.
Bir oyuncunun puanı, renginin puan sayısıdır. , artı yalnızca rengine ulaşan boş noktaların sayısı.

Örneğin, aşağıdaki panoyu göz önünde bulundurun. X, OVe -anlamında olabildikleri, siyah, beyaz ve renksiz kavşaklar:

- - - X - O - - -
- - - X - O - - -
- - - X - O - - -
- - - X O - - O -
X X X O - O O - -
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -

Puanlama kuralını uygulamak aşağıdaki sonucu verir. x, oVe -siyah, beyaz, kimse noktaları olarak sayılır renksiz kesişimleri temsil eder.

x x x X - O o o o
x x x X - O o o o
x x x X - O o o o
x x x X O o o O o
X X X O o O O o o
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -

Diyagrama göre, siyah 23 puan, beyaz 29 bölgedir. Bu nedenle, programınız W+6bu pano için yazdırılmalıdır .

Umarım bu şekilde yeterince açıktır.

Giriş ve çıkış

Giriş tam olarak içeren bir dizedir karakter X, O, n derleme zamanında bilinmemektedir. Programınız giriş akışındaki diğer tüm karakterleri yoksaymalıdır. Karakter sayısı n²'ye eşit olacak şekilde n tamsayısı yoksa davranış tanımlanmaz . N'nin [0, 255] içinde olduğunu varsayabilirsiniz .-XO-

Karakter dizisi n satır ve sütunlardan oluşan bir Go-board olarak yorumlanır . Çıktı, ondalık gösterimde toplam beyaz ve siyah nokta miktarının farkının mutlak değeridir. Beyazın daha fazla puanı varsa, öneklenir W+, siyahın daha çok puanı varsa ön eki olur B+. Her iki oyuncunun da eşit miktarda puana sahip olması durumunda, çıktı şöyledir Jigo.

Girdi, uygulama tarafından tanımlanmış bir şekilde okunmalıdır. Giriş, kaynak kodunun bir parçası olmayabilir.

Kazanma koşulları

Bu kod golfü. Her zamanki kod-golf kuralları geçerlidir. Kaynağında en az karakter bulunan gönderim kazanır. Yalnızca spesifikasyonu tam olarak uygulayan programlar kazanabilir.

Test durumları

Giriş:

- - - X - O - - -
- - - X - O - - -
- - - X - O - - -
- - - X O - - O -
X X X O - O O - -
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -

Çıktı: W+6

Giriş:

Xavier is insane -- says Oliver

Çıktı: Jigo

Inpout:

Code-Golf

Çıktı: Jigo

Giriş:

-XXXXXXX-XOOOOOOOXXO-OXXXOXXXOX--XOXXOOX
-
XOOXXOX--XOXXXOXXXO-OXXOOOOOOOX-XXXXXXX-

Çıktı: B+21

Giriş:

- - X O O O O X X - - - - - - X O O -
- X X O X O X X O X X X X X X - X O -
- X O O X X X - O O O X O O X X X O -
- X O O O X X O O O O O O X X X O - -
- - X X O X - X X X X O O O O O O O -
- - X O O X X X - X X X O O O X X O -
- - X O - O X O X O O O O O X X X O -
- X O O - O O O X X X X X O O X O - -
- X X X O - - - O X O X X X O X O - -
X O O O O - - O - O O O O X X X O O -
X X O - - - O - - O O X X - - X X O O
X O O O - - O - O O X - - - - X O O X
- X X X O O X O O X X - - - - X X X X
X - X X X O X X O O X - - X X O X O O
X X O O X O X O X X - - - X O O O O -
X O - O X X X O X - - - - - X O - - -
O O - O X O O O O X X - X X X X O - -
O O - O O O X O X X - - X - X X O - -
- - O - - O X X X - - - - X O O O - -

Çıktı: B+6

Yakında daha fazla test aracı gelecek.

referans uygulaması

ANSI C'de yazılmış bir referans uygulaması yarattım . Bu uygulama standart girdiden girdi okur ve çıktıyı standart çıktıya yazar.

/* http://codegolf.stackexchange.com/q/6693/134
 * reference implementation
 * by user FUZxxl
 */

#include <stdio.h>
#include <stdlib.h>

#define MAXBOARD 256

/* bit 0x01: black colour
 * bit 0x02: white colour
 * bit 0x04: there is a stone on the intersection
 */

enum colour {
    UNCOLOURED    = 0x0,
    BLACK_REACHED = 0x1,
    WHITE_REACHED = 0x2,
    BOTH_REACHED  = 0x3,
    HAS_STONE     = 0x4,
    BLACK         = 0x5,
    WHITE         = 0x6
};

static enum colour board[MAXBOARD * MAXBOARD] = { 0 };

static int bsize = 0;

static void read_input(void);
static void fill_board(void);
static void show_score(void);

int main()
{
    read_input();
    fill_board();
    show_score();
    return EXIT_SUCCESS;
}

static void read_input(void)
{
    int n = 0;
    int invalue;

    while ((invalue = getchar()) != EOF) {
        switch (invalue) {
            case '-': board[n++] = UNCOLOURED; break;
            case 'X': board[n++] = BLACK; break;
            case 'O': board[n++] = WHITE; break;
        }
    }

    while (bsize * bsize < n) bsize++;

    /* your program may exhibit undefined behaviour if this is true */
    if (bsize * bsize != n) exit(EXIT_FAILURE);
}

static void fill_board(void)
{
    int i,j;
    int changes;
    enum colour here, top, bottom, left, right, accum;

    do {
        changes = 0;

        for (i = 0; i < bsize; ++i) {
            for (j = 0; j < bsize; ++j) {

                here   = board[i * bsize + j];
                if (here >= BOTH_REACHED) continue;

                top    = i == 0 ? UNCOLOURED : board[(i - 1) * bsize + j];
                left   = j == 0 ? UNCOLOURED : board[i * bsize + j - 1];
                bottom = i == bsize-1 ? UNCOLOURED : board[(i + 1) * bsize + j];
                right  = j == bsize-1 ? UNCOLOURED : board[i * bsize + j + 1];

                accum = here | top | bottom | left | right;
                accum &= ~HAS_STONE;

                changes |= board[i * bsize + j] != accum;

                board[i * bsize + j] = accum;

            }
        }

    } while (changes);
}

static void show_score(void) {
    int w = 0, b = 0, n;

    for (n = 0; n < bsize*bsize; ++n) switch (board[n] & ~HAS_STONE) {
        case BLACK_REACHED: ++b; break;
        case WHITE_REACHED: ++w; break;
    }

    if (b != w)
        printf("%s%i\n",b>w?"B+":"W+",abs(b-w));
    else
        printf("Jigo\n");
}

Muhtemelen en son çıktısını mı kastediyorsunuz W+7?
dmckee

Hayır ... Bu sonuca nasıl geldiniz?
FUZxxl

Er ... Ben farz S+(daha önce ya mümkün çıkışı listelenmiş çünkü bir yazım hatası oldu W+, B+ya Jigo) ve benim klavyede baktım ve gördüm Syakındır W... Yoksa Dvorak kullanıyorsunuz?
dmckee

@dmckee Sanırım "S", "Siyah" yerine Alman "Schwarz" dan geliyor.
Howard

Oh ... Haklısın. Bunun için üzgünüm
FUZxxl

Yanıtlar:


2

GolfScript (105 bayt)

{'-XO'?}/]-1-.{2*3%}%{.,:N),{.*N=}?/{{[{.2$+1={+.}*}*]}%zip}N*[]*.1--,\}2*-.{.0>'W+B+'2/=\abs}{;'Jigo'}if

Çevrimiçi demo .

Sel-dolgu benim önceki bu cevabından uyarlanmıştır .

Solüsyon, orijinal tahtanın bir kopyasını X, diğerini de O ile doldurur. Böylece her iki renkle ulaşılabilen boş hücreler her ikisi için de puanlanır, ancak çıkarma işleminde iptal edilir.


Yeterince adil. Bu raundu kazanabilirsin.
FUZxxl

6

C ( 438 434 413 382 364 336 322 298 294 292 290 karakter)

#define I b[d*g+e
a;b[65536];c;d;e;f;g;main(){for(;d=getchar()+1;f++)b[f]=d-80?d-89?d-46&&
f--:5:6,g+=g*g<f;while(!c--)for(d=g;d--;)for(e=g;e--;)I]<3?a=3&(I]|!!d*I
-g]|!!e*I-1]|(d<g-1)*I+g]|(e<g-1)*I+1]),c&=I]==a,I]=a:0;while(f--)c+=b[f
]%2-b[f]/2%2;printf(c?"%c+%i":"Jigo",c>0?66:87,abs(c));}

Geliştirilmiş okunaklılık için ilki dışındaki tüm yeni satırlar. Yorumlanmış ve biraz daha okunaklı bir sürüm burada bulunabilir .

Bu cevap temelde referans çözümdür, ancak tüm bu işe yaramaz şeyler (örneğin [ intzaten farklı bir şeye ihtiyaç duyan ?] Ve standartlara uygunluk [ana geri dönüş değeri? Lütfen!] Gibi )

Düzeltmeler ve iyileştirmeler

438 → 434

Ben kendimi 0standarda göre otomatik olarak başlattıklarına ikna ettikten sonra değişkenlerin açıkça başlatılması düştü .

434 → 413

Kaldırılan durum ifadesi: Renklendirilmemiş bir kavşak hem siyah hem de beyazdan ulaşılabilirse, programı basitleştirmek için her ikisinde de bir nokta olarak sayabiliriz. Olumsuzluğu önlemek için mantıksal dalların anahtarı.

413 → 382

Bir parantez çifti kaydetmek diçin atayın getchar()+1. bSıfır olarak başlatılan varsayım uyarınca, caseifadeleri yeniden sıralayın , tüm breakifadeleri atın . (a>b?c:0)daha uzun (a>b)*c. (d+1)*g+edaha uzun d*g+e+g.

382 → 364

Geliştirilmiş döngü, çıktıda yeni satır yok, daha kısa çıktı yordamları.

364 → 336

Bu switchifadeden kurtuldum . (Teşekkürler Howard!), İki karakter için puan farkını takip edin. cBir karakter için olumsuzlayın . büyük veya cümlede dört karakter.

336 → 323

Değiştirilmesi &, %dört karakter için tutucuların çıkarılmasını sağlar. Karekök giriş döngüsünde dokuz ya da öylesine karakter (evet!) ifBoyunca kaynaştırıldı, bir karakter için kaldırıldı .

323 → 298

HSık görülen ve hacimli b[d*g+e]yapıyı değiştirmek için makro tanıtıldı .

298 → 294

Değişim a&=~4için a&=3sadece her en düşük üç bayt gözlemlemek olarak a. Ayrıca gelen döngü gövdesine değiştirildi ((a=I])<3)?a|=...için I]<3?a=I]|...hangi iki karakter kısadır. Ayrıca, bir karakter daha kısa olan hyeniden kullanım yerine tanıtın c.

294 → 292

hDeğişkeni ortadan kaldırmak . Biz testi Eğer cile !c--yerine !c++, csel-dolgu döngünün sonunda 0 eşittir ve amaç için bu şekilde kullanılabilir h(yani tutarak puanı) önce kullanılmıştır.

292 → 290

Yapı yerine d-46?f--:0sahip d-46&&f--bir karakter ile daha kısa olan ve iki atamaları kombine aiç döngü.


1
Switch ifadesini {b[f]=d-80?d-89?d-46?f--:0:5:6;f++;}birkaç karakter kaydetmek gibi bir şeyle değiştirebilirsiniz .
Howard

@Howard: Evet. Bu gerçekten iyi çalıştı! Teşekkür ederim
FUZxxl

"Gelişmiş okunaklılık için" - sanki.
saat

@tomsmeding Bir satır kaydırmak çok daha az okunaklı. Ayrıca, yorumlanmış bir sürüm ile bağlantılı.
FUZxxl

@ FUZxxl Bu şakaydı. :) Ayrıca, 1 satırdan daha iyi olduğunu söylerken haklısın.
14'te

6

J ( 140 136 131 129 119 117 116 karakter)

J becerilerimi geliştirdikten sonra, sonunda J'ye gönderim yapabilirim.

exit echo>(*{'Jigo';('B+',":);'W+',":@|)+/,-/1 2=/(]OR(0=[)*[:OR((,.|.)0,i:1)|.!.0])^:_~($~,~@%:@#)3-.~'-XO'i:1!:1]3

Bu başvuru tarafından uygulanan algoritma referans uygulamasına çok benzer, ancak kullanılan alanların işleniş biçiminde farklıdır.

İşte çözüm, kolay anlaşılabilirlik için daha fazla parçaya bölünmüş durumda. Golfedilmiş çözüm bundan biraz farklı, ancak fark çok büyük değil.

input =. 3 -.~ '-XO' i: 1!:1 ] 3
board =. ($~ ,~@%:@#) input
NB. shift up, down, left, right
rotm =. (,. |.) 0 , i: 1
fill =. ] OR (0 = [) * [: OR rotm |.!.0 ]
filledboard =. fill^:_~ board
score =. +/ , -/ 1 2 =/ filledboard
echo > (* { 'Jigo' ; ('B+' , ":) ; ('W+', ":@|)) score
exit 0

5

GolfScript, 190 karakter

{"XO-"?)},:v,.),\{\.*=}+,~:s.*:`0\,{s%!\2*+}/:r;88{0v@{=\2*+}+/}:%~79%1${{:<.r|r^2*|<2/r|r^|<2s?:h/|<h*|1$|1$^2`?(&}`*}:a~@@a\;.2$|2${^2*)2base{+}*}:m~@2$|@m-.{"BW"1/1$0>="+"@abs}{;"Jigo"}if

Senaryo, başlangıçta düşündüğümden çok daha uzun oldu. Herhangi bir girişi STDIN'e iletin; program sona erdiğinde çıkış yazdırılır.


2

Yakut (314)

biraz daha zaman ile daha kısa yapılabilir:

q={?-=>0,?X=>5,?O=>6};b=[];$<.chars{|c|(t=q[c])&&b<<t}
z=Math.sqrt b.size
loop{c=b.each_with_index.map{|h,i|
next h if h>2
x=i%z
y=i/z
u=y<1?0:b[i-z]
l=x<1?0:b[i-1]
d=y>z-2?0:b[i+z]
r=x>z-2?0:b[i+1]
~4&(h|u|d|l|r)}
break if c==b
b=c}
b.map!{|h|h&~4}
s=b.count(1)-b.count(2)
puts s==0?"Jigo":s>0?"B+#{s}":"W+#{-s}"
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.